summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Presence/main.hs98
-rw-r--r--modules.svg359
2 files changed, 269 insertions, 188 deletions
diff --git a/Presence/main.hs b/Presence/main.hs
index 8c2371f4..cfc7154c 100644
--- a/Presence/main.hs
+++ b/Presence/main.hs
@@ -57,6 +57,74 @@ import Network.Socket (Family(AF_INET,AF_INET6))
57import Holumbus.Data.MultiMap as MM (MultiMap) 57import Holumbus.Data.MultiMap as MM (MultiMap)
58import qualified Holumbus.Data.MultiMap as MM 58import qualified Holumbus.Data.MultiMap as MM
59 59
60{- PresenceState
61 -
62 - This is the global state for the xmpp daemon.
63 - It is not directly accessed outside of this module.
64 -}
65data PresenceState = PresenceState
66 { hostname :: Peer -- ByteString, TODO: remove this, its always LocalHost now
67
68 -- currentTTY - a string such as "tty7" which is kept up to date as console
69 -- switches occur.
70 , currentTTY :: TVar ByteString
71
72 -- activeUsers - a is a set of triples representing data in /var/run/utmp
73 -- it is kept up to date by an inotify watch on that file.
74 , activeUsers :: TVar (Set (UserName, Tty, ProcessID))
75
76 -- subscriberMap - the idea was to allow subscribing to a particular user only.
77 -- When that user becomes present, an announcement would be sent
78 -- on the channel associated with him. This functionality is currently
79 -- unused and may be removed soon if it's decided its unneccessary.
80 , subscriberMap :: TVar (Map JID (RefCount,TChan Presence)) -- UNUSED as yet
81
82 -- localSubscriber - a channel and reference count where all presence events are
83 -- announced.
84 , localSubscriber :: TMVar (RefCount,TChan Presence) -- TODO: rename this, its not just locals
85 -- ... or make a seperate channel for remotes
86
87 -- rosterChannel - a channel and reference count where all roster change events are
88 -- announced
89 , rosterChannel :: TMVar (RefCount,TChan RosterEvent)
90
91
92 -- remoteUsers - a cache of remote users considered to be online. These are sent to a client
93 -- on connect so that it can populate it's notion of online users.
94 , remoteUsers :: TVar (Map Peer (RefCount,TVar (MultiMap JabberUser (JabberResource,JabberShow))))
95
96 -- outGoingConnections - a set of channels that may be used to send messages to remote peers.
97 , outGoingConnections :: TVar (Map Peer (TChan OutBoundMessage, ThreadId))
98 }
99
100
101
102
103{- newPresenceState
104 -
105 - This is a smart constructor for the global state.
106 - This is currently used only from Main.start and PresenceState
107 - records are not created by any means other than this constructor.
108 -}
109newPresenceState hostname = atomically $ do
110 tty <- newTVar ""
111 us <- newTVar (Set.empty)
112 subs <- newTVar (Map.empty)
113 locals_greedy <- newEmptyTMVar
114 rchan <- newEmptyTMVar
115 remotes <- newTVar (Map.empty)
116 server_connections <- newServerConnections
117 return $ PresenceState hostname tty us subs locals_greedy rchan remotes server_connections
118
119
120data ClientSession = ClientSession {
121 localhost :: Peer, -- ByteString,
122 unix_uid :: (IORef (Maybe (UserID,L.ByteString))),
123 unix_resource :: (IORef (Maybe L.ByteString)),
124 chans :: TVar [RefCountedChan],
125 presence_state :: PresenceState
126}
127
60type RefCount = Int 128type RefCount = Int
61 129
62type JabberResource = L.ByteString 130type JabberResource = L.ByteString
@@ -70,18 +138,6 @@ splitResource (JID (Just n) p r ) = Just (JabberUser n p, r)
70 138
71unsplitResource (JabberUser n p) r = JID (Just n) p r 139unsplitResource (JabberUser n p) r = JID (Just n) p r
72 140
73data PresenceState = PresenceState
74 { hostname :: Peer -- ByteString, TODO: remove this, its always LocalHost now
75 , currentTTY :: TVar ByteString
76 , activeUsers :: TVar (Set (UserName, Tty, ProcessID))
77 , subscriberMap :: TVar (Map JID (RefCount,TChan Presence)) -- UNUSED as yet
78 , localSubscriber :: TMVar (RefCount,TChan Presence) -- TODO: rename this, its not just locals
79 -- ... or make a seperate channel for remotes
80 , rosterChannel :: TMVar (RefCount,TChan RosterEvent)
81 , remoteUsers :: TVar (Map Peer (RefCount,TVar (MultiMap JabberUser (JabberResource,JabberShow))))
82 , outGoingConnections :: TVar (Map Peer (TChan OutBoundMessage, ThreadId))
83 }
84
85 141
86rosterPush msg state = do 142rosterPush msg state = do
87 let rchan = rosterChannel state 143 let rchan = rosterChannel state
@@ -102,14 +158,6 @@ getJabberUserForId muid =
102 ) 158 )
103 muid 159 muid
104 160
105data ClientSession = ClientSession {
106 localhost :: Peer, -- ByteString,
107 unix_uid :: (IORef (Maybe (UserID,L.ByteString))),
108 unix_resource :: (IORef (Maybe L.ByteString)),
109 chans :: TVar [RefCountedChan],
110 presence_state :: PresenceState
111}
112
113cmpJID newitem jid = do 161cmpJID newitem jid = do
114 -- putStrLn $ "Comparing "<++>bshow jid 162 -- putStrLn $ "Comparing "<++>bshow jid
115 olditem <- parseHostNameJID jid 163 olditem <- parseHostNameJID jid
@@ -513,16 +561,6 @@ update_presence locals_greedy subscribers state getStatus =
513 sendPresence chan jid status 561 sendPresence chan jid status
514 putStrLn $ bshow jid <++> " " <++> bshow status 562 putStrLn $ bshow jid <++> " " <++> bshow status
515 563
516newPresenceState hostname = atomically $ do
517 tty <- newTVar ""
518 us <- newTVar (Set.empty)
519 subs <- newTVar (Map.empty)
520 locals_greedy <- newEmptyTMVar
521 rchan <- newEmptyTMVar
522 remotes <- newTVar (Map.empty)
523 server_connections <- newServerConnections
524 return $ PresenceState hostname tty us subs locals_greedy rchan remotes server_connections
525
526sendProbes state jid = do 564sendProbes state jid = do
527 L.putStrLn $ "sending probes for " <++> bshow jid 565 L.putStrLn $ "sending probes for " <++> bshow jid
528 withJust (name jid) $ \user -> do 566 withJust (name jid) $ \user -> do
diff --git a/modules.svg b/modules.svg
index 7ca9243f..350ab062 100644
--- a/modules.svg
+++ b/modules.svg
@@ -5,215 +5,258 @@
5 --> 5 -->
6<!-- Title: G Pages: 1 --> 6<!-- Title: G Pages: 1 -->
7<svg width="932pt" height="576pt" 7<svg width="932pt" height="576pt"
8 viewBox="0.00 0.00 932.23 576.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 8 viewBox="0.00 0.00 932.21 576.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
9<g id="graph1" class="graph" transform="scale(0.753017 0.753017) rotate(0) translate(4 760.923)"> 9<g id="graph1" class="graph" transform="scale(0.757895 0.757895) rotate(0) translate(4 756)">
10<title>G</title> 10<title>G</title>
11<polygon fill="white" stroke="white" points="-4,5 -4,-760.923 1235,-760.923 1235,5 -4,5"/> 11<polygon fill="white" stroke="white" points="-4,5 -4,-756 1227,-756 1227,5 -4,5"/>
12<g id="graph2" class="cluster"><title>cluster_0</title> 12<g id="graph2" class="cluster"><title>cluster_0</title>
13<polygon fill="#ccffcc" stroke="#ccffcc" points="1088,-204.689 1088,-368.867 1222,-368.867 1222,-204.689 1088,-204.689"/> 13<polygon fill="#ccffcc" stroke="#ccffcc" points="1080,-176.509 1080,-318.083 1214,-318.083 1214,-176.509 1080,-176.509"/>
14<text text-anchor="middle" x="1155" y="-352.267" font-family="Times Roman,serif" font-size="14.00">Data</text> 14<text text-anchor="middle" x="1147" y="-301.483" font-family="Times Roman,serif" font-size="14.00">Data</text>
15</g> 15</g>
16<g id="graph3" class="cluster"><title>cluster_1</title> 16<g id="graph3" class="cluster"><title>cluster_1</title>
17<polygon fill="#ccffcc" stroke="#ccffcc" points="146,-17.0574 146,-509.59 284,-509.59 284,-17.0574 146,-17.0574"/> 17<polygon fill="#ccffcc" stroke="#ccffcc" points="1030,-454.142 1030,-671.1 1172,-671.1 1172,-454.142 1030,-454.142"/>
18<text text-anchor="middle" x="215" y="-492.99" font-family="Times Roman,serif" font-size="14.00">Text</text> 18<text text-anchor="middle" x="1101" y="-654.5" font-family="Times Roman,serif" font-size="14.00">Holumbus</text>
19</g> 19</g>
20<g id="graph4" class="cluster"><title>cluster_2</title> 20<g id="graph4" class="cluster"><title>cluster_2</title>
21<polygon fill="#99ff99" stroke="#99ff99" points="154,-34.1148 154,-439.229 276,-439.229 276,-34.1148 154,-34.1148"/> 21<polygon fill="#99ff99" stroke="#99ff99" points="1038,-468.851 1038,-610.425 1164,-610.425 1164,-468.851 1038,-468.851"/>
22<text text-anchor="middle" x="215" y="-422.629" font-family="Times Roman,serif" font-size="14.00">XML</text> 22<text text-anchor="middle" x="1101" y="-593.825" font-family="Times Roman,serif" font-size="14.00">Data</text>
23</g> 23</g>
24<g id="graph5" class="cluster"><title>cluster_3</title> 24<g id="graph5" class="cluster"><title>cluster_3</title>
25<polygon fill="#66ff66" stroke="#66ff66" points="162,-51.1723 162,-368.867 268,-368.867 268,-51.1723 162,-51.1723"/> 25<polygon fill="#ccffcc" stroke="#ccffcc" points="934,-14.709 934,-439.433 1072,-439.433 1072,-14.709 934,-14.709"/>
26<text text-anchor="middle" x="215" y="-352.267" font-family="Times Roman,serif" font-size="14.00">Stream</text> 26<text text-anchor="middle" x="1003" y="-422.833" font-family="Times Roman,serif" font-size="14.00">Text</text>
27</g> 27</g>
28<!-- u5 --> 28<g id="graph6" class="cluster"><title>cluster_4</title>
29<g id="node1" class="node"><title>u5</title> 29<polygon fill="#99ff99" stroke="#99ff99" points="942,-29.4181 942,-378.758 1064,-378.758 1064,-29.4181 942,-29.4181"/>
30<ellipse fill="none" stroke="black" cx="192" cy="-565.057" rx="62.0391" ry="18"/> 30<text text-anchor="middle" x="1003" y="-362.158" font-family="Times Roman,serif" font-size="14.00">XML</text>
31<text text-anchor="middle" x="192" y="-560.957" font-family="Times Roman,serif" font-size="14.00">FGConsole</text> 31</g>
32<g id="graph7" class="cluster"><title>cluster_5</title>
33<polygon fill="#66ff66" stroke="#66ff66" points="950,-44.1271 950,-318.083 1056,-318.083 1056,-44.1271 950,-44.1271"/>
34<text text-anchor="middle" x="1003" y="-301.483" font-family="Times Roman,serif" font-size="14.00">Stream</text>
35</g>
36<!-- u6 -->
37<g id="node1" class="node"><title>u6</title>
38<ellipse fill="none" stroke="black" cx="219" cy="-516.709" rx="62.0391" ry="18"/>
39<text text-anchor="middle" x="219" y="-512.609" font-family="Times Roman,serif" font-size="14.00">FGConsole</text>
32</g> 40</g>
33<!-- monitortty --> 41<!-- monitortty -->
34<g id="node3" class="node"><title>monitortty</title> 42<g id="node3" class="node"><title>monitortty</title>
35<ellipse fill="none" stroke="black" cx="69" cy="-260.057" rx="68.9883" ry="18"/> 43<ellipse fill="none" stroke="black" cx="69" cy="-224.709" rx="68.9883" ry="18"/>
36<text text-anchor="middle" x="69" y="-255.957" font-family="Times Roman,serif" font-size="14.00">monitortty.c</text> 44<text text-anchor="middle" x="69" y="-220.609" font-family="Times Roman,serif" font-size="14.00">monitortty.c</text>
37</g> 45</g>
38<!-- u5&#45;&gt;monitortty --> 46<!-- u6&#45;&gt;monitortty -->
39<g id="edge2" class="edge"><title>u5&#45;&gt;monitortty</title> 47<g id="edge2" class="edge"><title>u6&#45;&gt;monitortty</title>
40<path fill="none" stroke="black" d="M184.674,-546.892C163.951,-495.505 104.817,-348.872 80.0855,-287.546"/> 48<path fill="none" stroke="black" d="M209.843,-498.883C184.476,-449.502 113.178,-310.708 82.8901,-251.749"/>
41<polygon fill="black" stroke="black" points="83.2736,-286.093 76.2875,-278.128 76.7816,-288.711 83.2736,-286.093"/> 49<polygon fill="black" stroke="black" points="85.9108,-249.969 78.2281,-242.673 79.6843,-253.167 85.9108,-249.969"/>
42</g> 50</g>
43<!-- u14 --> 51<!-- u15 -->
44<g id="node4" class="node"><title>u14</title> 52<g id="node4" class="node"><title>u15</title>
45<ellipse fill="none" stroke="black" cx="445" cy="-565.057" rx="79.9115" ry="18"/> 53<ellipse fill="none" stroke="black" cx="529" cy="-516.709" rx="79.9115" ry="18"/>
46<text text-anchor="middle" x="445" y="-560.957" font-family="Times Roman,serif" font-size="14.00">LocalPeerCred</text> 54<text text-anchor="middle" x="529" y="-512.609" font-family="Times Roman,serif" font-size="14.00">LocalPeerCred</text>
47</g> 55</g>
48<!-- u8 --> 56<!-- u9 -->
49<g id="node8" class="node"><title>u8</title> 57<g id="node8" class="node"><title>u9</title>
50<ellipse fill="none" stroke="black" cx="386" cy="-107.057" rx="62.0391" ry="18"/> 58<ellipse fill="none" stroke="black" cx="324" cy="-91.709" rx="62.0391" ry="18"/>
51<text text-anchor="middle" x="386" y="-102.957" font-family="Times Roman,serif" font-size="14.00">SocketLike</text> 59<text text-anchor="middle" x="324" y="-87.609" font-family="Times Roman,serif" font-size="14.00">SocketLike</text>
52</g> 60</g>
53<!-- u14&#45;&gt;u8 --> 61<!-- u15&#45;&gt;u9 -->
54<g id="edge48" class="edge"><title>u14&#45;&gt;u8</title> 62<g id="edge60" class="edge"><title>u15&#45;&gt;u9</title>
55<path fill="none" stroke="black" d="M428.552,-547.074C400.919,-515.501 346.22,-446.806 326,-377.057 308.304,-316.015 312.088,-296.072 326,-234.057 334.236,-197.346 354.338,-158.755 369.012,-133.885"/> 63<path fill="none" stroke="black" d="M466.584,-505.417C385.334,-487.001 246.476,-441.956 185,-341.709 151.775,-287.53 156.934,-255.732 185,-198.709 204.791,-158.499 247.762,-129.159 280.723,-111.48"/>
56<polygon fill="black" stroke="black" points="372.169,-135.428 374.334,-125.057 366.174,-131.814 372.169,-135.428"/> 64<polygon fill="black" stroke="black" points="282.465,-114.519 289.726,-106.804 279.239,-108.307 282.465,-114.519"/>
57</g> 65</g>
58<!-- u13 --> 66<!-- u3 -->
59<g id="node5" class="node"><title>u13</title> 67<g id="node12" class="node"><title>u3</title>
60<ellipse fill="none" stroke="black" cx="705" cy="-260.057" rx="68.9883" ry="18"/> 68<ellipse fill="none" stroke="black" cx="772" cy="-224.709" rx="78.0216" ry="18"/>
61<text text-anchor="middle" x="705" y="-255.957" font-family="Times Roman,serif" font-size="14.00">NestingXML</text> 69<text text-anchor="middle" x="772" y="-220.609" font-family="Times Roman,serif" font-size="14.00">ControlMaybe</text>
62</g> 70</g>
63<!-- u12 --> 71<!-- u15&#45;&gt;u3 -->
64<g id="node6" class="node"><title>u12</title> 72<g id="edge58" class="edge"><title>u15&#45;&gt;u3</title>
65<ellipse fill="none" stroke="black" cx="878" cy="-260.057" rx="86.1654" ry="18"/> 73<path fill="none" stroke="black" d="M543.835,-498.883C585.183,-449.197 701.864,-308.988 750.401,-250.664"/>
66<text text-anchor="middle" x="878" y="-255.957" font-family="Times Roman,serif" font-size="14.00">GetHostByAddr</text> 74<polygon fill="black" stroke="black" points="753.344,-252.599 757.05,-242.673 747.963,-248.121 753.344,-252.599"/>
67</g> 75</g>
68<!-- u9 --> 76<!-- u14 -->
69<g id="node7" class="node"><title>u9</title> 77<g id="node5" class="node"><title>u14</title>
70<ellipse fill="none" stroke="black" cx="552" cy="-260.057" rx="66.0138" ry="18"/> 78<ellipse fill="none" stroke="black" cx="263" cy="-224.709" rx="68.9883" ry="18"/>
71<text text-anchor="middle" x="552" y="-255.957" font-family="Times Roman,serif" font-size="14.00">XMPPTypes</text> 79<text text-anchor="middle" x="263" y="-220.609" font-family="Times Roman,serif" font-size="14.00">NestingXML</text>
80</g>
81<!-- u11 -->
82<g id="node6" class="node"><title>u11</title>
83<ellipse fill="none" stroke="black" cx="490" cy="-91.709" rx="86.1654" ry="18"/>
84<text text-anchor="middle" x="490" y="-87.609" font-family="Times Roman,serif" font-size="14.00">GetHostByAddr</text>
85</g>
86<!-- u10 -->
87<g id="node7" class="node"><title>u10</title>
88<ellipse fill="none" stroke="black" cx="454" cy="-224.709" rx="66.0138" ry="18"/>
89<text text-anchor="middle" x="454" y="-220.609" font-family="Times Roman,serif" font-size="14.00">XMPPTypes</text>
72</g> 90</g>
73<!-- u9&#45;&gt;u8 --> 91<!-- u10&#45;&gt;u11 -->
74<g id="edge44" class="edge"><title>u9&#45;&gt;u8</title> 92<g id="edge54" class="edge"><title>u10&#45;&gt;u11</title>
75<path fill="none" stroke="black" d="M532.958,-242.506C503.313,-215.184 446.05,-162.405 412.425,-131.413"/> 93<path fill="none" stroke="black" d="M458.93,-206.495C465.016,-184.01 475.427,-145.547 482.505,-119.399"/>
76<polygon fill="black" stroke="black" points="414.545,-128.607 404.82,-124.404 409.801,-133.755 414.545,-128.607"/> 94<polygon fill="black" stroke="black" points="485.895,-120.27 485.129,-109.703 479.138,-118.441 485.895,-120.27"/>
95</g>
96<!-- u10&#45;&gt;u9 -->
97<g id="edge52" class="edge"><title>u10&#45;&gt;u9</title>
98<path fill="none" stroke="black" d="M436.737,-207.048C414.107,-183.895 374.271,-143.14 348.519,-116.794"/>
99<polygon fill="black" stroke="black" points="350.827,-114.148 341.334,-109.443 345.821,-119.041 350.827,-114.148"/>
77</g> 100</g>
78<!-- u2 --> 101<!-- u2 -->
79<g id="node12" class="node"><title>u2</title> 102<g id="node13" class="node"><title>u2</title>
80<ellipse fill="none" stroke="black" cx="992" cy="-107.057" rx="111.181" ry="18"/> 103<ellipse fill="none" stroke="black" cx="705" cy="-91.709" rx="111.181" ry="18"/>
81<text text-anchor="middle" x="992" y="-102.957" font-family="Times Roman,serif" font-size="14.00">ByteStringOperators</text> 104<text text-anchor="middle" x="705" y="-87.609" font-family="Times Roman,serif" font-size="14.00">ByteStringOperators</text>
105</g>
106<!-- u10&#45;&gt;u2 -->
107<g id="edge50" class="edge"><title>u10&#45;&gt;u2</title>
108<path fill="none" stroke="black" d="M484.276,-208.666C528.957,-184.991 612.7,-140.617 663.204,-113.856"/>
109<polygon fill="black" stroke="black" points="665.033,-116.848 672.23,-109.073 661.755,-110.663 665.033,-116.848"/>
110</g>
111<!-- u8 -->
112<g id="node9" class="node"><title>u8</title>
113<ellipse fill="none" stroke="black" cx="588" cy="-224.709" rx="50.0315" ry="18"/>
114<text text-anchor="middle" x="588" y="-220.609" font-family="Times Roman,serif" font-size="14.00">ServerC</text>
82</g> 115</g>
83<!-- u9&#45;&gt;u2 --> 116<!-- u8&#45;&gt;u9 -->
84<g id="edge42" class="edge"><title>u9&#45;&gt;u2</title> 117<g id="edge48" class="edge"><title>u8&#45;&gt;u9</title>
85<path fill="none" stroke="black" d="M592.999,-245.801C672.041,-218.316 845.623,-157.957 935.531,-126.693"/> 118<path fill="none" stroke="black" d="M558.739,-209.968C511.373,-186.105 417.82,-138.975 364.227,-111.975"/>
86<polygon fill="black" stroke="black" points="936.721,-129.985 945.017,-123.395 934.422,-123.373 936.721,-129.985"/> 119<polygon fill="black" stroke="black" points="365.529,-108.712 355.024,-107.339 362.38,-114.963 365.529,-108.712"/>
120</g>
121<!-- u8&#45;&gt;u2 -->
122<g id="edge46" class="edge"><title>u8&#45;&gt;u2</title>
123<path fill="none" stroke="black" d="M603.296,-207.322C623.392,-184.477 658.857,-144.162 682.145,-117.69"/>
124<polygon fill="black" stroke="black" points="684.973,-119.774 688.95,-109.954 679.717,-115.15 684.973,-119.774"/>
87</g> 125</g>
88<!-- u7 --> 126<!-- u7 -->
89<g id="node9" class="node"><title>u7</title> 127<g id="node10" class="node"><title>u7</title>
90<ellipse fill="none" stroke="black" cx="418" cy="-260.057" rx="50.0315" ry="18"/> 128<ellipse fill="none" stroke="black" cx="666" cy="-516.709" rx="39.1069" ry="18"/>
91<text text-anchor="middle" x="418" y="-255.957" font-family="Times Roman,serif" font-size="14.00">ServerC</text> 129<text text-anchor="middle" x="666" y="-512.609" font-family="Times Roman,serif" font-size="14.00">XMPP</text>
92</g> 130</g>
93<!-- u7&#45;&gt;u8 --> 131<!-- u7&#45;&gt;u14 -->
94<g id="edge40" class="edge"><title>u7&#45;&gt;u8</title> 132<g id="edge44" class="edge"><title>u7&#45;&gt;u14</title>
95<path fill="none" stroke="black" d="M414.204,-241.905C408.694,-215.565 398.433,-166.502 391.924,-135.379"/> 133<path fill="none" stroke="black" d="M645.394,-501.171C637.062,-495.139 627.244,-488.342 618,-482.709 501.721,-411.854 448.727,-431.086 346,-341.709 316.214,-315.794 291.489,-277.107 276.98,-251.405"/>
96<polygon fill="black" stroke="black" points="395.265,-134.257 389.792,-125.186 388.413,-135.69 395.265,-134.257"/> 134<polygon fill="black" stroke="black" points="280.001,-249.636 272.106,-242.571 273.872,-253.018 280.001,-249.636"/>
97</g> 135</g>
98<!-- u7&#45;&gt;u2 --> 136<!-- u7&#45;&gt;u10 -->
99<g id="edge38" class="edge"><title>u7&#45;&gt;u2</title> 137<g id="edge40" class="edge"><title>u7&#45;&gt;u10</title>
100<path fill="none" stroke="black" d="M448.222,-245.537C457.341,-241.485 467.464,-237.307 477,-234.057 626.523,-183.105 806.896,-143.414 909.641,-122.769"/> 138<path fill="none" stroke="black" d="M651.837,-499.733C626.34,-468.935 571.424,-401.498 529,-341.709 507.458,-311.349 484.639,-275.086 469.908,-251.063"/>
101<polygon fill="black" stroke="black" points="910.522,-126.163 919.643,-120.771 909.151,-119.298 910.522,-126.163"/> 139<polygon fill="black" stroke="black" points="472.875,-249.205 464.678,-242.493 466.9,-252.852 472.875,-249.205"/>
102</g> 140</g>
103<!-- u6 --> 141<!-- u7&#45;&gt;u9 -->
104<g id="node10" class="node"><title>u6</title> 142<g id="edge38" class="edge"><title>u7&#45;&gt;u9</title>
105<ellipse fill="none" stroke="black" cx="628" cy="-565.057" rx="39.1069" ry="18"/> 143<path fill="none" stroke="black" d="M645.232,-501.429C636.877,-495.433 627.086,-488.593 618,-482.709 514.479,-415.674 451.377,-441.568 379,-341.709 365.991,-323.761 339.851,-181.932 328.95,-120.225"/>
106<text text-anchor="middle" x="628" y="-560.957" font-family="Times Roman,serif" font-size="14.00">XMPP</text> 144<polygon fill="black" stroke="black" points="332.335,-119.264 327.158,-110.02 325.441,-120.475 332.335,-119.264"/>
107</g>
108<!-- u6&#45;&gt;u13 -->
109<g id="edge36" class="edge"><title>u6&#45;&gt;u13</title>
110<path fill="none" stroke="black" d="M632.586,-546.892C645.532,-495.611 682.425,-349.476 697.964,-287.926"/>
111<polygon fill="black" stroke="black" points="701.384,-288.681 700.438,-278.128 694.597,-286.967 701.384,-288.681"/>
112</g>
113<!-- u6&#45;&gt;u12 -->
114<g id="edge34" class="edge"><title>u6&#45;&gt;u12</title>
115<path fill="none" stroke="black" d="M641.937,-548.24C669.136,-515.399 731.167,-440.408 783,-377.057 808.641,-345.719 837.998,-309.514 857.207,-285.778"/>
116<polygon fill="black" stroke="black" points="859.987,-287.907 863.556,-277.931 854.545,-283.504 859.987,-287.907"/>
117</g>
118<!-- u6&#45;&gt;u9 -->
119<g id="edge30" class="edge"><title>u6&#45;&gt;u9</title>
120<path fill="none" stroke="black" d="M623.473,-546.892C610.695,-495.611 574.281,-349.476 558.944,-287.926"/>
121<polygon fill="black" stroke="black" points="562.317,-286.985 556.503,-278.128 555.525,-288.678 562.317,-286.985"/>
122</g>
123<!-- u6&#45;&gt;u8 -->
124<g id="edge28" class="edge"><title>u6&#45;&gt;u8</title>
125<path fill="none" stroke="black" d="M596.378,-554.222C536.905,-531.909 409.819,-474.575 359,-377.057 317.261,-296.964 353.182,-185.405 373.853,-134.429"/>
126<polygon fill="black" stroke="black" points="377.137,-135.646 377.756,-125.069 370.677,-132.952 377.137,-135.646"/>
127</g>
128<!-- u6&#45;&gt;u7 -->
129<g id="edge26" class="edge"><title>u6&#45;&gt;u7</title>
130<path fill="none" stroke="black" d="M612.563,-548.355C583.688,-516.602 520.501,-444.646 477,-377.057 458.171,-347.803 440.783,-311.747 429.834,-287.456"/>
131<polygon fill="black" stroke="black" points="432.95,-285.849 425.688,-278.135 426.554,-288.694 432.95,-285.849"/>
132</g>
133<!-- u6&#45;&gt;u2 -->
134<g id="edge24" class="edge"><title>u6&#45;&gt;u2</title>
135<path fill="none" stroke="black" d="M663.506,-557.586C736.057,-540.242 900.551,-489.826 973,-377.057 998.279,-337.711 995.734,-196.32 993.351,-135.358"/>
136<polygon fill="black" stroke="black" points="996.844,-135.131 992.929,-125.286 989.85,-135.424 996.844,-135.131"/>
137</g> 145</g>
138<!-- u10 --> 146<!-- u7&#45;&gt;u8 -->
139<g id="node21" class="node"><title>u10</title> 147<g id="edge36" class="edge"><title>u7&#45;&gt;u8</title>
140<ellipse fill="none" stroke="black" cx="215" cy="-260.057" rx="45.1673" ry="18"/> 148<path fill="none" stroke="black" d="M661.121,-498.443C647.906,-448.974 611.356,-312.144 595.5,-252.786"/>
141<text text-anchor="middle" x="215" y="-255.957" font-family="Times Roman,serif" font-size="14.00">Render</text> 149<polygon fill="black" stroke="black" points="598.84,-251.726 592.877,-242.968 592.077,-253.533 598.84,-251.726"/>
142</g> 150</g>
143<!-- u6&#45;&gt;u10 --> 151<!-- u7&#45;&gt;u3 -->
144<g id="edge32" class="edge"><title>u6&#45;&gt;u10</title> 152<g id="edge34" class="edge"><title>u7&#45;&gt;u3</title>
145<path fill="none" stroke="black" d="M594.052,-556.11C523.356,-535.848 359.029,-480.025 264,-377.057 240.765,-351.882 227.675,-314.098 220.979,-288.327"/> 153<path fill="none" stroke="black" d="M672.471,-498.883C690.36,-449.604 740.573,-311.28 762.052,-252.114"/>
146<polygon fill="black" stroke="black" points="224.334,-287.31 218.566,-278.423 217.533,-288.968 224.334,-287.31"/> 154<polygon fill="black" stroke="black" points="765.356,-253.267 765.479,-242.673 758.777,-250.879 765.356,-253.267"/>
147</g> 155</g>
148<!-- u3 --> 156<!-- u7&#45;&gt;u2 -->
149<g id="node11" class="node"><title>u3</title> 157<g id="edge32" class="edge"><title>u7&#45;&gt;u2</title>
150<ellipse fill="none" stroke="black" cx="1145" cy="-565.057" rx="39.1069" ry="18"/> 158<path fill="none" stroke="black" d="M666.288,-498.707C667.234,-450.124 671.041,-312.34 685,-198.709 688.312,-171.752 694.208,-141.339 698.744,-119.846"/>
151<text text-anchor="middle" x="1145" y="-560.957" font-family="Times Roman,serif" font-size="14.00">UTmp</text> 159<polygon fill="black" stroke="black" points="702.229,-120.289 700.907,-109.777 695.385,-118.818 702.229,-120.289"/>
160</g>
161<!-- u12 -->
162<g id="node25" class="node"><title>u12</title>
163<ellipse fill="none" stroke="black" cx="1003" cy="-224.709" rx="45.1673" ry="18"/>
164<text text-anchor="middle" x="1003" y="-220.609" font-family="Times Roman,serif" font-size="14.00">Render</text>
165</g>
166<!-- u7&#45;&gt;u12 -->
167<g id="edge42" class="edge"><title>u7&#45;&gt;u12</title>
168<path fill="none" stroke="black" d="M696.807,-505.505C754.706,-483.007 880.527,-427.069 954,-341.709 976.349,-315.744 989.63,-278.131 996.612,-252.614"/>
169<polygon fill="black" stroke="black" points="1000.03,-253.376 999.146,-242.818 993.253,-251.623 1000.03,-253.376"/>
152</g> 170</g>
153<!-- u4 --> 171<!-- u4 -->
154<g id="node16" class="node"><title>u4</title> 172<g id="node11" class="node"><title>u4</title>
155<ellipse fill="none" stroke="black" cx="1155" cy="-260.057" rx="59.065" ry="18"/> 173<ellipse fill="none" stroke="black" cx="983" cy="-516.709" rx="39.1069" ry="18"/>
156<text text-anchor="middle" x="1155" y="-255.957" font-family="Times Roman,serif" font-size="14.00">BitSyntax</text> 174<text text-anchor="middle" x="983" y="-512.609" font-family="Times Roman,serif" font-size="14.00">UTmp</text>
157</g> 175</g>
158<!-- u3&#45;&gt;u4 --> 176<!-- u5 -->
159<g id="edge22" class="edge"><title>u3&#45;&gt;u4</title> 177<g id="node17" class="node"><title>u5</title>
160<path fill="none" stroke="black" d="M1145.6,-546.892C1147.27,-495.717 1152.05,-350.08 1154.07,-288.309"/> 178<ellipse fill="none" stroke="black" cx="1147" cy="-224.709" rx="59.065" ry="18"/>
161<polygon fill="black" stroke="black" points="1157.58,-288.237 1154.41,-278.128 1150.58,-288.008 1157.58,-288.237"/> 179<text text-anchor="middle" x="1147" y="-220.609" font-family="Times Roman,serif" font-size="14.00">BitSyntax</text>
180</g>
181<!-- u4&#45;&gt;u5 -->
182<g id="edge30" class="edge"><title>u4&#45;&gt;u5</title>
183<path fill="none" stroke="black" d="M993.012,-498.883C1020.75,-449.502 1098.7,-310.708 1131.81,-251.749"/>
184<polygon fill="black" stroke="black" points="1135.07,-253.106 1136.91,-242.673 1128.96,-249.678 1135.07,-253.106"/>
162</g> 185</g>
163<!-- u1 --> 186<!-- u1 -->
164<g id="node13" class="node"><title>u1</title> 187<g id="node14" class="node"><title>u1</title>
165<ellipse fill="none" stroke="black" cx="825" cy="-565.057" rx="62.0391" ry="18"/> 188<ellipse fill="none" stroke="black" cx="826" cy="-516.709" rx="62.0391" ry="18"/>
166<text text-anchor="middle" x="825" y="-560.957" font-family="Times Roman,serif" font-size="14.00">ConfigFiles</text> 189<text text-anchor="middle" x="826" y="-512.609" font-family="Times Roman,serif" font-size="14.00">ConfigFiles</text>
190</g>
191<!-- u1&#45;&gt;u3 -->
192<g id="edge28" class="edge"><title>u1&#45;&gt;u3</title>
193<path fill="none" stroke="black" d="M822.622,-498.443C813.493,-449.077 788.274,-312.711 777.261,-253.156"/>
194<polygon fill="black" stroke="black" points="780.637,-252.165 775.377,-242.968 773.754,-253.438 780.637,-252.165"/>
167</g> 195</g>
168<!-- u1&#45;&gt;u2 --> 196<!-- u1&#45;&gt;u2 -->
169<g id="edge20" class="edge"><title>u1&#45;&gt;u2</title> 197<g id="edge26" class="edge"><title>u1&#45;&gt;u2</title>
170<path fill="none" stroke="black" d="M850.455,-548.572C892.344,-519.73 974.321,-455.637 1006,-377.057 1039.34,-294.35 1015.49,-185.696 1000.96,-135.16"/> 198<path fill="none" stroke="black" d="M834.525,-498.52C857.009,-447.706 912.623,-301.263 859,-198.709 837.813,-158.189 793.52,-129.924 757.852,-112.663"/>
171<polygon fill="black" stroke="black" points="1004.23,-133.878 998.031,-125.289 997.524,-135.871 1004.23,-133.878"/> 199<polygon fill="black" stroke="black" points="759.061,-109.364 748.519,-108.298 756.095,-115.705 759.061,-109.364"/>
172</g> 200</g>
173<!-- u0 --> 201<!-- u0 -->
174<g id="node14" class="node"><title>u0</title> 202<g id="node15" class="node"><title>u0</title>
175<ellipse fill="none" stroke="black" cx="726" cy="-718.057" rx="34.2406" ry="18"/> 203<ellipse fill="none" stroke="black" cx="781" cy="-718.709" rx="34.2406" ry="18"/>
176<text text-anchor="middle" x="726" y="-713.957" font-family="Times Roman,serif" font-size="14.00">Main</text> 204<text text-anchor="middle" x="781" y="-714.609" font-family="Times Roman,serif" font-size="14.00">Main</text>
177</g> 205</g>
178<!-- u0&#45;&gt;u5 --> 206<!-- u0&#45;&gt;u6 -->
179<g id="edge14" class="edge"><title>u0&#45;&gt;u5</title> 207<g id="edge18" class="edge"><title>u0&#45;&gt;u6</title>
180<path fill="none" stroke="black" d="M695.76,-709.393C608.807,-684.48 357.24,-612.402 245.998,-580.529"/> 208<path fill="none" stroke="black" d="M752.156,-709.054C693.283,-689.277 555.123,-642.496 440,-600.709 379.432,-578.724 310.044,-552.116 265.428,-534.821"/>
181<polygon fill="black" stroke="black" points="246.895,-577.145 236.318,-577.755 244.967,-583.874 246.895,-577.145"/> 209<polygon fill="black" stroke="black" points="266.609,-531.525 256.021,-531.17 264.077,-538.051 266.609,-531.525"/>
182</g> 210</g>
183<!-- u0&#45;&gt;u14 --> 211<!-- u0&#45;&gt;u15 -->
184<g id="edge18" class="edge"><title>u0&#45;&gt;u14</title> 212<g id="edge22" class="edge"><title>u0&#45;&gt;u15</title>
185<path fill="none" stroke="black" d="M702.042,-705.013C653.665,-678.672 543.894,-618.904 484.662,-586.653"/> 213<path fill="none" stroke="black" d="M759.768,-704.643C728.021,-683.325 666.706,-641.035 618,-600.709 595.435,-582.026 571.359,-559.101 553.945,-541.923"/>
186<polygon fill="black" stroke="black" points="486.063,-583.43 475.607,-581.722 482.716,-589.578 486.063,-583.43"/> 214<polygon fill="black" stroke="black" points="556.004,-539.034 546.443,-534.47 551.071,-544.001 556.004,-539.034"/>
187</g> 215</g>
188<!-- u0&#45;&gt;u6 --> 216<!-- u0&#45;&gt;u7 -->
189<g id="edge16" class="edge"><title>u0&#45;&gt;u6</title> 217<g id="edge20" class="edge"><title>u0&#45;&gt;u7</title>
190<path fill="none" stroke="black" d="M714.949,-700.804C697.818,-674.059 664.743,-622.421 644.691,-591.116"/> 218<path fill="none" stroke="black" d="M770.996,-701.136C750.776,-665.62 704.944,-585.116 681.08,-543.198"/>
191<polygon fill="black" stroke="black" points="647.502,-589.016 639.161,-582.483 641.608,-592.791 647.502,-589.016"/> 219<polygon fill="black" stroke="black" points="684.052,-541.344 676.063,-534.385 677.969,-544.807 684.052,-541.344"/>
220</g>
221<!-- u0&#45;&gt;u4 -->
222<g id="edge16" class="edge"><title>u0&#45;&gt;u4</title>
223<path fill="none" stroke="black" d="M802.876,-704.86C833.726,-684.607 890.636,-644.524 930,-600.709 945.655,-583.284 959.619,-560.699 969.279,-543.337"/>
224<polygon fill="black" stroke="black" points="972.492,-544.753 974.186,-534.295 966.34,-541.414 972.492,-544.753"/>
192</g> 225</g>
193<!-- u0&#45;&gt;u3 --> 226<!-- u0&#45;&gt;u3 -->
194<g id="edge12" class="edge"><title>u0&#45;&gt;u3</title> 227<g id="edge14" class="edge"><title>u0&#45;&gt;u3</title>
195<path fill="none" stroke="black" d="M754.142,-707.781C826.683,-681.292 1020.24,-610.614 1104.67,-579.783"/> 228<path fill="none" stroke="black" d="M775.812,-700.918C769.42,-677.992 758.928,-636.787 755,-600.709 740.924,-471.406 759.014,-315.863 767.76,-253.057"/>
196<polygon fill="black" stroke="black" points="1105.98,-583.031 1114.18,-576.313 1103.58,-576.456 1105.98,-583.031"/> 229<polygon fill="black" stroke="black" points="771.28,-253.167 769.226,-242.773 764.35,-252.179 771.28,-253.167"/>
197</g> 230</g>
198<!-- u0&#45;&gt;u2 --> 231<!-- u0&#45;&gt;u2 -->
199<g id="edge10" class="edge"><title>u0&#45;&gt;u2</title> 232<g id="edge12" class="edge"><title>u0&#45;&gt;u2</title>
200<path fill="none" stroke="black" d="M748.026,-704.054C782.394,-681.485 849.636,-634.372 896,-583.057 968.9,-502.374 997.434,-481.412 1028,-377.057 1053.25,-290.868 1021.22,-183.963 1003,-134.514"/> 233<path fill="none" stroke="black" d="M802.772,-704.719C830.744,-685.294 877.96,-647.237 897,-600.709 925.504,-531.054 935.45,-283.188 885,-198.709 859.147,-155.419 808.473,-127.629 767.461,-111.25"/>
201<polygon fill="black" stroke="black" points="1006.27,-133.253 999.46,-125.137 999.723,-135.729 1006.27,-133.253"/> 234<polygon fill="black" stroke="black" points="768.659,-107.961 758.069,-107.629 766.14,-114.492 768.659,-107.961"/>
202</g> 235</g>
203<!-- u0&#45;&gt;u1 --> 236<!-- u0&#45;&gt;u1 -->
204<g id="edge8" class="edge"><title>u0&#45;&gt;u1</title> 237<g id="edge10" class="edge"><title>u0&#45;&gt;u1</title>
205<path fill="none" stroke="black" d="M737.164,-700.804C754.378,-674.201 787.527,-622.97 807.814,-591.617"/> 238<path fill="none" stroke="black" d="M784.993,-700.783C792.846,-665.534 810.348,-586.97 819.747,-544.78"/>
206<polygon fill="black" stroke="black" points="810.924,-593.253 813.419,-582.956 805.047,-589.45 810.924,-593.253"/> 239<polygon fill="black" stroke="black" points="823.193,-545.407 821.951,-534.885 816.36,-543.885 823.193,-545.407"/>
207</g> 240</g>
208<!-- u11 --> 241<!-- u16 -->
209<g id="node20" class="node"><title>u11</title> 242<g id="node20" class="node"><title>u16</title>
210<ellipse fill="none" stroke="black" cx="215" cy="-107.057" rx="38.9134" ry="18"/> 243<ellipse fill="none" stroke="black" cx="1101" cy="-516.709" rx="55.0898" ry="18"/>
211<text text-anchor="middle" x="215" y="-102.957" font-family="Times Roman,serif" font-size="14.00">Token</text> 244<text text-anchor="middle" x="1101" y="-512.609" font-family="Times Roman,serif" font-size="14.00">MultiMap</text>
212</g> 245</g>
213<!-- u10&#45;&gt;u11 --> 246<!-- u0&#45;&gt;u16 -->
214<g id="edge46" class="edge"><title>u10&#45;&gt;u11</title> 247<g id="edge24" class="edge"><title>u0&#45;&gt;u16</title>
215<path fill="none" stroke="black" d="M215,-241.905C215,-215.565 215,-166.502 215,-135.379"/> 248<path fill="none" stroke="black" d="M811.634,-710.657C863.554,-695.83 970.18,-660.171 1042,-600.709 1061.05,-584.934 1076.79,-561.571 1087.21,-543.486"/>
216<polygon fill="black" stroke="black" points="218.5,-135.186 215,-125.186 211.5,-135.186 218.5,-135.186"/> 249<polygon fill="black" stroke="black" points="1090.36,-545.018 1092.16,-534.577 1084.24,-541.618 1090.36,-545.018"/>
250</g>
251<!-- u13 -->
252<g id="node24" class="node"><title>u13</title>
253<ellipse fill="none" stroke="black" cx="1003" cy="-91.709" rx="38.9134" ry="18"/>
254<text text-anchor="middle" x="1003" y="-87.609" font-family="Times Roman,serif" font-size="14.00">Token</text>
255</g>
256<!-- u12&#45;&gt;u13 -->
257<g id="edge56" class="edge"><title>u12&#45;&gt;u13</title>
258<path fill="none" stroke="black" d="M1003,-206.495C1003,-184.235 1003,-146.314 1003,-120.186"/>
259<polygon fill="black" stroke="black" points="1006.5,-120.13 1003,-110.13 999.5,-120.13 1006.5,-120.13"/>
217</g> 260</g>
218</g> 261</g>
219</svg> 262</svg>