nelumba 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. data/.gitignore +6 -0
  2. data/.travis.yml +9 -0
  3. data/Gemfile +20 -0
  4. data/README.md +242 -0
  5. data/Rakefile +7 -0
  6. data/assets/lotus_logo_purple.png +0 -0
  7. data/assets/lotus_logo_purple.svg +262 -0
  8. data/lib/nelumba.rb +47 -0
  9. data/lib/nelumba/activity.rb +250 -0
  10. data/lib/nelumba/application.rb +11 -0
  11. data/lib/nelumba/article.rb +11 -0
  12. data/lib/nelumba/atom/account.rb +50 -0
  13. data/lib/nelumba/atom/address.rb +56 -0
  14. data/lib/nelumba/atom/author.rb +176 -0
  15. data/lib/nelumba/atom/category.rb +41 -0
  16. data/lib/nelumba/atom/comment.rb +96 -0
  17. data/lib/nelumba/atom/entry.rb +216 -0
  18. data/lib/nelumba/atom/feed.rb +198 -0
  19. data/lib/nelumba/atom/generator.rb +40 -0
  20. data/lib/nelumba/atom/link.rb +79 -0
  21. data/lib/nelumba/atom/name.rb +57 -0
  22. data/lib/nelumba/atom/organization.rb +62 -0
  23. data/lib/nelumba/atom/person.rb +179 -0
  24. data/lib/nelumba/atom/portable_contacts.rb +117 -0
  25. data/lib/nelumba/atom/source.rb +179 -0
  26. data/lib/nelumba/atom/thread.rb +60 -0
  27. data/lib/nelumba/audio.rb +39 -0
  28. data/lib/nelumba/badge.rb +11 -0
  29. data/lib/nelumba/binary.rb +52 -0
  30. data/lib/nelumba/bookmark.rb +30 -0
  31. data/lib/nelumba/category.rb +49 -0
  32. data/lib/nelumba/collection.rb +34 -0
  33. data/lib/nelumba/comment.rb +47 -0
  34. data/lib/nelumba/crypto.rb +144 -0
  35. data/lib/nelumba/device.rb +11 -0
  36. data/lib/nelumba/discover.rb +362 -0
  37. data/lib/nelumba/event.rb +57 -0
  38. data/lib/nelumba/feed.rb +173 -0
  39. data/lib/nelumba/file.rb +43 -0
  40. data/lib/nelumba/generator.rb +53 -0
  41. data/lib/nelumba/group.rb +11 -0
  42. data/lib/nelumba/identity.rb +63 -0
  43. data/lib/nelumba/image.rb +30 -0
  44. data/lib/nelumba/link.rb +56 -0
  45. data/lib/nelumba/note.rb +34 -0
  46. data/lib/nelumba/notification.rb +229 -0
  47. data/lib/nelumba/object.rb +251 -0
  48. data/lib/nelumba/person.rb +306 -0
  49. data/lib/nelumba/place.rb +34 -0
  50. data/lib/nelumba/product.rb +30 -0
  51. data/lib/nelumba/publisher.rb +44 -0
  52. data/lib/nelumba/question.rb +30 -0
  53. data/lib/nelumba/review.rb +30 -0
  54. data/lib/nelumba/service.rb +11 -0
  55. data/lib/nelumba/subscription.rb +117 -0
  56. data/lib/nelumba/version.rb +3 -0
  57. data/lib/nelumba/video.rb +43 -0
  58. data/nelumba.gemspec +28 -0
  59. data/spec/activity_spec.rb +116 -0
  60. data/spec/application_spec.rb +136 -0
  61. data/spec/article_spec.rb +136 -0
  62. data/spec/atom/comment_spec.rb +455 -0
  63. data/spec/atom/feed_spec.rb +684 -0
  64. data/spec/audio_spec.rb +164 -0
  65. data/spec/badge_spec.rb +136 -0
  66. data/spec/binary_spec.rb +218 -0
  67. data/spec/bookmark.rb +150 -0
  68. data/spec/collection_spec.rb +152 -0
  69. data/spec/comment_spec.rb +128 -0
  70. data/spec/crypto_spec.rb +126 -0
  71. data/spec/device_spec.rb +136 -0
  72. data/spec/event_spec.rb +239 -0
  73. data/spec/feed_spec.rb +252 -0
  74. data/spec/file_spec.rb +190 -0
  75. data/spec/group_spec.rb +136 -0
  76. data/spec/helper.rb +10 -0
  77. data/spec/identity_spec.rb +67 -0
  78. data/spec/image_spec.rb +150 -0
  79. data/spec/link_spec.rb +30 -0
  80. data/spec/note_spec.rb +163 -0
  81. data/spec/notification_spec.rb +89 -0
  82. data/spec/person_spec.rb +244 -0
  83. data/spec/place_spec.rb +162 -0
  84. data/spec/product_spec.rb +150 -0
  85. data/spec/question_spec.rb +156 -0
  86. data/spec/review_spec.rb +149 -0
  87. data/spec/service_spec.rb +136 -0
  88. data/spec/video_spec.rb +164 -0
  89. data/test/example_feed.atom +393 -0
  90. data/test/example_feed_empty_author.atom +336 -0
  91. data/test/example_feed_false_connected.atom +359 -0
  92. data/test/example_feed_link_without_href.atom +134 -0
  93. data/test/example_page.html +4 -0
  94. data/test/mime_type_bug_feed.atom +874 -0
  95. metadata +288 -0
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ doc/*
6
+ *.rbc
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ script: bundle exec rake test
3
+ rvm:
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - 2.0.0
7
+ - ruby-head
8
+ - rbx
9
+ script: "bundle exec rake test"
data/Gemfile ADDED
@@ -0,0 +1,20 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ostatus.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem "rake" # rakefile
8
+ gem "minitest", "4.7.0" # test framework (specified here for prior rubies)
9
+ gem "ansi" # minitest colors
10
+ gem "turn" # minitest output
11
+ gem "mocha" # stubs
12
+ end
13
+
14
+ platforms :rbx do
15
+ gem "json"
16
+ gem "racc"
17
+ gem "rubysl"
18
+ end
19
+
20
+ gem "nelumba-i18n", :git => "git://github.com/hotsh/nelumba-i18n.git"
@@ -0,0 +1,242 @@
1
+ # Nelumba
2
+
3
+ [![Build Status](https://travis-ci.org/hotsh/nelumba.png?branch=master)](https://travis-ci.org/hotsh/nelumba)
4
+
5
+ This gem implements federated protocols which let your website connect and interact with any website implementing a federated space.
6
+ Users of a federated service can communicate, produce and consume with users of all sites within that federation as one large community while also allowing them
7
+ to host such websites on their own servers or choice of hosting provider.
8
+ Specifically, this gem deals with handling the data streams and the technologies that are related to Nelumba/pump.io such as ActivityStreams, PortableContacts, Webfinger, PubSubHubbub, and Salmon.
9
+
10
+ One such application of this library (in its older form) is [rstat.us](https://rstat.us), which is a Twitter-like service that you can host yourself.
11
+
12
+ ## Related libraries
13
+
14
+ * [nelumba-i18n](https://github.com/hotsh/nelumba-i18n) - Localization for activity-streams social applications.
15
+ * [nelumba-mongodb](https://github.com/hotsh/nelumba-mongodb) - Persistence layer for nelumba objects.
16
+ * [rack-nelumba](https://github.com/hotsh/rack-nelumba) - Rack middleware to provide nelumba controllers for HTTP access to nelumba data.
17
+ * [nelumba-site](https://github.com/hotsh/nelumba-site) - A Nelumba based, full-featured website.
18
+
19
+ ## Usage
20
+
21
+ Currently, only the immutable interface is available.
22
+
23
+ ```
24
+ require 'nelumba'
25
+
26
+ author = Nelumba::Person.new(:uri => "https://rstat.us/users/wilkie",
27
+ :email => "wilkie@xomb.org",
28
+ :name => "wilkie")
29
+
30
+ blog_post = Nelumba::Activity.new(:activity => :post,
31
+ :title => "Nelumba gem",
32
+ :actor => author,
33
+ :content => "Long blog post",
34
+ :content_type => "text/html",
35
+ :id => "1",
36
+ :uri => "http://blog.davewilkinsonii.com/posts/ostatus_gem",
37
+ :published => Time.now)
38
+
39
+ feed = Nelumba::Feed.new(:title => "wilkie writes a thing",
40
+ :url => "http://blog.davewilkinsonii.com",
41
+ :rights => "CC0",
42
+ :hubs => ["http://hub.davewilkinsonii.com"],
43
+ :authors => [author],
44
+ :published => Time.now,
45
+ :entries => [blog_post])
46
+ ```
47
+
48
+ To generate an Atom representation:
49
+
50
+ ```
51
+ feed.to_atom
52
+ ```
53
+
54
+ To generate a collection of Nelumba objects from Atom:
55
+
56
+ ```
57
+ Nelumba.feed_from_url("https://rstat.us/users/wilkieii/feed")
58
+ ```
59
+
60
+ ## Object Documentation
61
+
62
+ ### Feed
63
+
64
+ The Feed is the aggregate. It holds a collection of entries written by a set of authors or contributors. It's the container for content.
65
+
66
+ #### Usage
67
+
68
+ ```
69
+ author = Nelumba::Person.new(:name => "Kelly")
70
+ feed = Nelumba::Feed.new(:title => "My Feed",
71
+ :id => "1",
72
+ :url => "http://example.com/feeds/1",
73
+ :authors => [author])
74
+ ```
75
+
76
+ #### Fields
77
+ ```
78
+ id => The unique identifier for this feed.
79
+ url => The url that represents this feed.
80
+ title => The title for this feed. Defaults: "Untitled"
81
+ title_type => The content type for the title.
82
+ subtitle => The subtitle for this feed.
83
+ subtitle_type => The content type for the subtitle.
84
+ authors => The list of Nelumba::Person's for this feed.
85
+ Defaults: []
86
+ contributors => The list of Nelumba::Person's that contributed to this
87
+ feed. Defaults: []
88
+ entries => The list of Nelumba::Activity's for this feed.
89
+ Defaults: []
90
+ icon => The url of the icon that represents this feed. It
91
+ should have an aspect ratio of 1 horizontal to 1
92
+ vertical and optimized for presentation at a
93
+ small size.
94
+ logo => The url of the logo that represents this feed. It
95
+ should have an aspect ratio of 2 horizontal to 1
96
+ vertical.
97
+ categories => An array of Nelumba::Category's that describe how to
98
+ categorize and describe the content of the feed.
99
+ Defaults: []
100
+ rights => A String depicting the rights of entries without
101
+ explicit rights of their own. SHOULD NOT be machine
102
+ interpreted.
103
+ updated => The DateTime representing when this feed was last
104
+ modified.
105
+ published => The DateTime representing when this feed was originally
106
+ published.
107
+ salmon_url => The url of the salmon endpoint, if one exists, for this
108
+ feed.
109
+ links => An array of Nelumba::Link that adds relations to other
110
+ resources.
111
+ generator => An Nelumba::Generator representing the agent
112
+ responsible for generating this feed.
113
+ ```
114
+
115
+ ### Activity
116
+
117
+ Something that is done by a person. It has a verb, which suggests what was done
118
+ (e.g. :follow, or :unfollow, or :post) and it has an object, which is the
119
+ content. The content type is what the entity represents and governs how to
120
+ interpret the object. It can be a :note or :post or :image, etc.
121
+
122
+ #### Usage
123
+ ```
124
+ entry = Nelumba::Activity.new(:type => :note,
125
+ :title => "wilkie's Daily Update",
126
+ :content => "My day is going really well!",
127
+ :id => "123",
128
+ :url => "http://example.com/entries/123")
129
+ ```
130
+
131
+ #### Fields
132
+ ```
133
+ :title => The title of the entry. Defaults: "Untitled"
134
+ :actor => An Nelumba::Person responsible for generating this entry.
135
+ :content => The content of the entry. Defaults: ""
136
+ :content_type => The MIME type of the content.
137
+ :published => The DateTime depicting when the entry was originally
138
+ published.
139
+ :updated => The DateTime depicting when the entry was modified.
140
+ :url => The canonical url of the entry.
141
+ :id => The unique id that identifies this entry.
142
+ :activity => The activity this entry represents. Either a single string
143
+ denoting what type of object this entry represents, or an
144
+ entire Nelumba::Activity when a more detailed description is
145
+ appropriate.
146
+ :in_reply_to => An Nelumba::Activity for which this entry is a response.
147
+ Or an array of Nelumba::Activity's that this entry is a
148
+ response to. Use this when this Activity is a reply
149
+ to an existing Activity.
150
+ ```
151
+
152
+ ### Person
153
+
154
+ This represents a person that creates or contributes content in the feed.
155
+ Feed and Activity can both have one or more Persons or Contributors. One can
156
+ represent a great deal of information about a person.
157
+
158
+ #### Usage
159
+
160
+ ```
161
+ author = Nelumba::Person.new(:name => "wilkie",
162
+ :uri => "https://rstat.us/users/wilkie",
163
+ :email => "wilkie@xomb.org",
164
+ :preferredUsername => "wilkie",
165
+ :organization => {:name => "Hackers of the Severed Hand",
166
+ :department => "Software",
167
+ :title => "Founder"},
168
+ :gender => "androgynous",
169
+ :display_name => "Dave Wilkinson",
170
+ :birthday => Time.new(1987, 2, 9))
171
+ ```
172
+
173
+ #### Fields
174
+
175
+ ```
176
+ :name => The name of the author. Defaults: "anonymous"
177
+ :id => The identifier that uniquely identifies the
178
+ contact.
179
+ :nickname => The nickname of the contact.
180
+ :gender => The gender of the contact.
181
+ :note => A note for this contact.
182
+ :display_name => The display name for this contact.
183
+ :preferred_username => The preferred username for this contact.
184
+ :updated => A DateTime representing when this contact was
185
+ last updated.
186
+ :published => A DateTime representing when this contact was
187
+ originally created.
188
+ :birthday => A DateTime representing a birthday for this
189
+ contact.
190
+ :anniversary => A DateTime representing an anniversary for this
191
+ contact.
192
+ :extended_name => A Hash representing the name of the contact.
193
+ :formatted => The full name of the contact
194
+ :family_name => The family name. "Last name" in Western contexts.
195
+ :given_name => The given name. "First name" in Western contexts.
196
+ :middle_name => The middle name.
197
+ :honorific_prefix => "Title" in Western contexts. (e.g. "Mr." "Mrs.")
198
+ :honorific_suffix => "Suffix" in Western contexts. (e.g. "Esq.")
199
+ :organization => A Hash representing the organization of which the
200
+ contact belongs.
201
+ :name => The name of the organization (e.g. company, school,
202
+ etc) This field is required. Will be used for sorting.
203
+ :department => The department within the organization.
204
+ :title => The title or role within the organization.
205
+ :type => The type of organization. Canonical values include
206
+ "job" or "school"
207
+ :start_date => A DateTime representing when the contact joined
208
+ the organization.
209
+ :end_date => A DateTime representing when the contact left the
210
+ organization.
211
+ :location => The physical location of this organization.
212
+ :description => A free-text description of the role this contact
213
+ played in this organization.
214
+ :account => A Hash describing the authorative account for the
215
+ author.
216
+ :domain => The top-most authoriative domain for this account. (e.g.
217
+ "twitter.com") This is the primary field. Is required.
218
+ Used for sorting.
219
+ :username => An alphanumeric username, typically chosen by the user.
220
+ :userid => A user id, typically assigned, that uniquely refers to
221
+ the user.
222
+ :address => A Hash describing the address of the contact.
223
+ :formatted => A formatted representating of the address. May
224
+ contain newlines.
225
+ :street_address => The full street address. May contain newlines.
226
+ :locality => The city or locality component.
227
+ :region => The state or region component.
228
+ :postal_code => The zipcode or postal code component.
229
+ :country => The country name component.
230
+ :uri => The uri that uniquely identifies this author.
231
+ :email => The email of the author.
232
+ ```
233
+
234
+ ## TODO
235
+
236
+ * General cleanup and abstraction of elements of Atom et al that aren't very consistent or useful.
237
+ * Add a persistence layer and allow this to be mixed with Rails and Sinatra style models.
238
+ * Add rails/sinatra aides to allow rapid development of Nelumba powered websites.
239
+ * Add already written osub/opub functionality to allow this gem to subscribe directly to other Nelumba powered websites.
240
+ * Add Webfinger user identity and verification written in the Salmon library and pull the remaining logic out of rstat.us.
241
+ * Add JSON backend.
242
+ * Write a PuSH hub to aid in small-scale deployment. (Possibly as a detached project. Nelumba talks to the hub via a socket.)
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rake/testtask'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.pattern = "spec/**/*_spec.rb"
7
+ end
@@ -0,0 +1,262 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!-- Created with Inkscape (http://www.inkscape.org/) -->
3
+
4
+ <svg
5
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
6
+ xmlns:cc="http://creativecommons.org/ns#"
7
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8
+ xmlns:svg="http://www.w3.org/2000/svg"
9
+ xmlns="http://www.w3.org/2000/svg"
10
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12
+ width="411.54999"
13
+ height="411.54999"
14
+ id="svg5725"
15
+ version="1.1"
16
+ inkscape:version="0.48.2 r9819"
17
+ sodipodi:docname="New document 59">
18
+ <defs
19
+ id="defs5727" />
20
+ <sodipodi:namedview
21
+ id="base"
22
+ pagecolor="#ffffff"
23
+ bordercolor="#666666"
24
+ borderopacity="1.0"
25
+ inkscape:pageopacity="0.0"
26
+ inkscape:pageshadow="2"
27
+ inkscape:zoom="0.35"
28
+ inkscape:cx="229.34674"
29
+ inkscape:cy="126.4625"
30
+ inkscape:document-units="px"
31
+ inkscape:current-layer="layer1"
32
+ showgrid="false"
33
+ fit-margin-top="10"
34
+ fit-margin-left="10"
35
+ fit-margin-right="10"
36
+ fit-margin-bottom="10"
37
+ inkscape:window-width="1920"
38
+ inkscape:window-height="1058"
39
+ inkscape:window-x="-8"
40
+ inkscape:window-y="-8"
41
+ inkscape:window-maximized="1" />
42
+ <metadata
43
+ id="metadata5730">
44
+ <rdf:RDF>
45
+ <cc:Work
46
+ rdf:about="">
47
+ <dc:format>image/svg+xml</dc:format>
48
+ <dc:type
49
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
50
+ <dc:title></dc:title>
51
+ </cc:Work>
52
+ </rdf:RDF>
53
+ </metadata>
54
+ <g
55
+ inkscape:label="Layer 1"
56
+ inkscape:groupmode="layer"
57
+ id="layer1"
58
+ transform="translate(-145.65325,-247.27465)">
59
+ <g
60
+ transform="matrix(-2.6456033e-8,1.5070386,-1.5070386,-2.6456033e-8,1540.9511,-56.394592)"
61
+ id="g4799-0-7-6-0-0"
62
+ style="fill:#441650;stroke:#ddafe9"
63
+ inkscape:export-filename="C:\Users\wilkie\Pictures\lotus_avatar.png"
64
+ inkscape:export-xdpi="10.57"
65
+ inkscape:export-ydpi="10.57">
66
+ <path
67
+ sodipodi:nodetypes="ccacccc"
68
+ inkscape:connector-curvature="0"
69
+ id="path4648-5-0-7-0-9-8"
70
+ d="m 314.30878,699.69468 c -3.36113,3.36113 -13.98266,11.85868 -7.9375,35.08303 10.35109,-6.17393 21.61773,-8.80467 32.96875,-8.55714 11.3068,0.24656 23.65603,3.92474 32.4375,9.9473 6.04516,-23.22435 -4.17012,-33.11206 -7.53125,-36.47319 -11.56406,-14.53668 -22.15345,-18.95866 -25.125,-30.53125 -3.13528,11.45869 -14.70913,19.33728 -24.8125,30.53125 z"
71
+ style="fill:#441650;stroke:#ddafe9;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
72
+ <path
73
+ sodipodi:nodetypes="ccacccc"
74
+ inkscape:connector-curvature="0"
75
+ id="path4648-5-7-1-7-3-4-8"
76
+ d="m 404.02684,724.21119 c -4.59139,-1.23026 -17.26125,-6.18 -34.35155,10.66743 10.52233,5.87735 18.43393,14.31917 23.89508,24.27321 5.43987,9.91526 8.42909,22.44909 7.60413,33.06535 23.13546,-6.37691 26.59083,-20.16746 27.82109,-24.75885 6.8071,-17.28311 5.34195,-28.66478 13.87833,-37.02451 -11.49115,3.01411 -24.10114,-3.06984 -38.84708,-6.22263 z"
77
+ style="fill:#441650;stroke:#ddafe9;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
78
+ <path
79
+ sodipodi:nodetypes="ccacccc"
80
+ inkscape:connector-curvature="0"
81
+ id="path4648-5-7-5-46-7-8-7-0"
82
+ d="m 427.64223,813.60848 c -1.23026,-4.59139 -3.27859,-18.03868 -26.41404,-24.4156 0.17123,12.05128 -3.1838,23.12384 -9.07368,32.83035 -5.86693,9.6687 -15.22694,18.52436 -24.83337,23.11805 17.0903,16.84744 30.76095,12.9446 35.35234,11.71435 18.37116,-2.74644 27.4954,-9.70613 39.00333,-6.49327 -8.35587,-8.44458 -9.39201,-22.40712 -14.03458,-36.75388 z"
83
+ style="fill:#441650;stroke:#ddafe9;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
84
+ <path
85
+ sodipodi:nodetypes="ccacccc"
86
+ inkscape:connector-curvature="0"
87
+ id="path4648-5-7-5-4-0-3-0-8-6"
88
+ d="m 361.52776,878.92821 c 3.36113,-3.36113 13.98266,-11.85869 7.93751,-35.08303 -10.3511,6.17393 -21.61773,8.80467 -32.96876,8.55714 -11.3068,-0.24657 -23.65603,-3.92474 -32.4375,-9.94731 -6.04516,23.22435 4.17012,33.11207 7.53125,36.4732 11.56406,14.53667 22.15345,18.95865 25.125,30.53124 3.13528,-11.45869 14.70913,-19.33728 24.8125,-30.53124 z"
89
+ style="fill:#441650;stroke:#ddafe9;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
90
+ <path
91
+ sodipodi:nodetypes="ccacccc"
92
+ inkscape:connector-curvature="0"
93
+ id="path4648-5-7-5-4-1-7-3-1-3-8"
94
+ d="m 272.0597,854.6617 c 4.59139,1.23026 17.26125,6.17999 34.35155,-10.66743 -10.52233,-5.87735 -18.43394,-14.31917 -23.89508,-24.27322 -5.43987,-9.91526 -8.42909,-22.44909 -7.60413,-33.06535 -23.13546,6.37691 -26.59083,20.16746 -27.82109,24.75885 -6.8071,17.28311 -5.34195,28.66478 -13.87833,37.02451 11.49115,-3.01411 24.10114,3.06984 38.84708,6.22264 z"
95
+ style="fill:#441650;stroke:#ddafe9;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
96
+ <path
97
+ sodipodi:nodetypes="ccacccc"
98
+ inkscape:connector-curvature="0"
99
+ id="path4648-5-7-5-4-1-2-1-5-2-5-1"
100
+ d="m 248.63238,764.90272 c 1.23026,4.59139 3.27859,18.03868 26.41404,24.4156 -0.17123,-12.05128 3.18379,-23.12384 9.07368,-32.83035 5.86694,-9.6687 15.22694,-18.52435 24.83337,-23.11805 -17.09029,-16.84744 -30.76095,-12.9446 -35.35234,-11.71434 -18.37116,2.74643 -27.4954,9.70612 -39.00333,6.49327 8.35587,8.44457 9.39201,22.40711 14.03458,36.75387 z"
101
+ style="fill:#441650;stroke:#ddafe9;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
102
+ </g>
103
+ <g
104
+ transform="matrix(0.65174623,1.1288576,-1.1288576,0.65174623,1022.0797,-443.02901)"
105
+ id="g4799-0-7-1-9"
106
+ style="fill:#ddafe9;stroke:#672178"
107
+ inkscape:export-filename="C:\Users\wilkie\Pictures\lotus_avatar.png"
108
+ inkscape:export-xdpi="10.57"
109
+ inkscape:export-ydpi="10.57">
110
+ <path
111
+ sodipodi:nodetypes="ccacccc"
112
+ inkscape:connector-curvature="0"
113
+ id="path4648-5-0-7-2-8"
114
+ d="m 314.30878,699.69468 c -3.36113,3.36113 -13.98266,11.85868 -7.9375,35.08303 10.35109,-6.17393 21.61773,-8.80467 32.96875,-8.55714 11.3068,0.24656 23.65603,3.92474 32.4375,9.9473 6.04516,-23.22435 -4.17012,-33.11206 -7.53125,-36.47319 -11.56406,-14.53668 -22.15345,-18.95866 -25.125,-30.53125 -3.13528,11.45869 -14.70913,19.33728 -24.8125,30.53125 z"
115
+ style="fill:#ddafe9;stroke:#672178;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
116
+ <path
117
+ sodipodi:nodetypes="ccacccc"
118
+ inkscape:connector-curvature="0"
119
+ id="path4648-5-7-1-7-0-9"
120
+ d="m 404.02684,724.21119 c -4.59139,-1.23026 -17.26125,-6.18 -34.35155,10.66743 10.52233,5.87735 18.43393,14.31917 23.89508,24.27321 5.43987,9.91526 8.42909,22.44909 7.60413,33.06535 23.13546,-6.37691 26.59083,-20.16746 27.82109,-24.75885 6.8071,-17.28311 5.34195,-28.66478 13.87833,-37.02451 -11.49115,3.01411 -24.10114,-3.06984 -38.84708,-6.22263 z"
121
+ style="fill:#ddafe9;stroke:#672178;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
122
+ <path
123
+ sodipodi:nodetypes="ccacccc"
124
+ inkscape:connector-curvature="0"
125
+ id="path4648-5-7-5-46-7-1-7"
126
+ d="m 427.64223,813.60848 c -1.23026,-4.59139 -3.27859,-18.03868 -26.41404,-24.4156 0.17123,12.05128 -3.1838,23.12384 -9.07368,32.83035 -5.86693,9.6687 -15.22694,18.52436 -24.83337,23.11805 17.0903,16.84744 30.76095,12.9446 35.35234,11.71435 18.37116,-2.74644 27.4954,-9.70613 39.00333,-6.49327 -8.35587,-8.44458 -9.39201,-22.40712 -14.03458,-36.75388 z"
127
+ style="fill:#ddafe9;stroke:#672178;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
128
+ <path
129
+ sodipodi:nodetypes="ccacccc"
130
+ inkscape:connector-curvature="0"
131
+ id="path4648-5-7-5-4-0-3-6-2"
132
+ d="m 361.52776,878.92821 c 3.36113,-3.36113 13.98266,-11.85869 7.93751,-35.08303 -10.3511,6.17393 -21.61773,8.80467 -32.96876,8.55714 -11.3068,-0.24657 -23.65603,-3.92474 -32.4375,-9.94731 -6.04516,23.22435 4.17012,33.11207 7.53125,36.4732 11.56406,14.53667 22.15345,18.95865 25.125,30.53124 3.13528,-11.45869 14.70913,-19.33728 24.8125,-30.53124 z"
133
+ style="fill:#ddafe9;stroke:#672178;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
134
+ <path
135
+ sodipodi:nodetypes="ccacccc"
136
+ inkscape:connector-curvature="0"
137
+ id="path4648-5-7-5-4-1-7-3-4-2"
138
+ d="m 272.0597,854.6617 c 4.59139,1.23026 17.26125,6.17999 34.35155,-10.66743 -10.52233,-5.87735 -18.43394,-14.31917 -23.89508,-24.27322 -5.43987,-9.91526 -8.42909,-22.44909 -7.60413,-33.06535 -23.13546,6.37691 -26.59083,20.16746 -27.82109,24.75885 -6.8071,17.28311 -5.34195,28.66478 -13.87833,37.02451 11.49115,-3.01411 24.10114,3.06984 38.84708,6.22264 z"
139
+ style="fill:#ddafe9;stroke:#672178;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
140
+ <path
141
+ sodipodi:nodetypes="ccacccc"
142
+ inkscape:connector-curvature="0"
143
+ id="path4648-5-7-5-4-1-2-1-5-0-8"
144
+ d="m 248.63238,764.90272 c 1.23026,4.59139 3.27859,18.03868 26.41404,24.4156 -0.17123,-12.05128 3.18379,-23.12384 9.07368,-32.83035 5.86694,-9.6687 15.22694,-18.52435 24.83337,-23.11805 -17.09029,-16.84744 -30.76095,-12.9446 -35.35234,-11.71434 -18.37116,2.74643 -27.4954,9.70612 -39.00333,6.49327 8.35587,8.44457 9.39201,22.40711 14.03458,36.75387 z"
145
+ style="fill:#ddafe9;stroke:#672178;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
146
+ </g>
147
+ <g
148
+ id="g4799-6-2"
149
+ style="fill:#bc5fd3;stroke:#672178"
150
+ transform="translate(13.327535,-336.34786)"
151
+ inkscape:export-filename="C:\Users\wilkie\Pictures\lotus_avatar.png"
152
+ inkscape:export-xdpi="10.57"
153
+ inkscape:export-ydpi="10.57">
154
+ <path
155
+ sodipodi:nodetypes="ccacccc"
156
+ inkscape:connector-curvature="0"
157
+ id="path4648-5-1-8"
158
+ d="m 314.30878,699.69468 c -3.36113,3.36113 -13.98266,11.85868 -7.9375,35.08303 10.35109,-6.17393 21.61773,-8.80467 32.96875,-8.55714 11.3068,0.24656 23.65603,3.92474 32.4375,9.9473 6.04516,-23.22435 -4.17012,-33.11206 -7.53125,-36.47319 -11.56406,-14.53668 -22.15345,-18.95866 -25.125,-30.53125 -3.13528,11.45869 -14.70913,19.33728 -24.8125,30.53125 z"
159
+ style="fill:#bc5fd3;stroke:#672178;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
160
+ <path
161
+ sodipodi:nodetypes="ccacccc"
162
+ inkscape:connector-curvature="0"
163
+ id="path4648-5-7-8-9"
164
+ d="m 404.02684,724.21119 c -4.59139,-1.23026 -17.26125,-6.18 -34.35155,10.66743 10.52233,5.87735 18.43393,14.31917 23.89508,24.27321 5.43987,9.91526 8.42909,22.44909 7.60413,33.06535 23.13546,-6.37691 26.59083,-20.16746 27.82109,-24.75885 6.8071,-17.28311 5.34195,-28.66478 13.87833,-37.02451 -11.49115,3.01411 -24.10114,-3.06984 -38.84708,-6.22263 z"
165
+ style="fill:#bc5fd3;stroke:#672178;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
166
+ <path
167
+ sodipodi:nodetypes="ccacccc"
168
+ inkscape:connector-curvature="0"
169
+ id="path4648-5-7-5-9-0"
170
+ d="m 427.64223,813.60848 c -1.23026,-4.59139 -3.27859,-18.03868 -26.41404,-24.4156 0.17123,12.05128 -3.1838,23.12384 -9.07368,32.83035 -5.86693,9.6687 -15.22694,18.52436 -24.83337,23.11805 17.0903,16.84744 30.76095,12.9446 35.35234,11.71435 18.37116,-2.74644 27.4954,-9.70613 39.00333,-6.49327 -8.35587,-8.44458 -9.39201,-22.40712 -14.03458,-36.75388 z"
171
+ style="fill:#bc5fd3;stroke:#672178;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
172
+ <path
173
+ sodipodi:nodetypes="ccacccc"
174
+ inkscape:connector-curvature="0"
175
+ id="path4648-5-7-5-4-8-7"
176
+ d="m 361.52776,878.92821 c 3.36113,-3.36113 13.98266,-11.85869 7.93751,-35.08303 -10.3511,6.17393 -21.61773,8.80467 -32.96876,8.55714 -11.3068,-0.24657 -23.65603,-3.92474 -32.4375,-9.94731 -6.04516,23.22435 4.17012,33.11207 7.53125,36.4732 11.56406,14.53667 22.15345,18.95865 25.125,30.53124 3.13528,-11.45869 14.70913,-19.33728 24.8125,-30.53124 z"
177
+ style="fill:#bc5fd3;stroke:#672178;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
178
+ <path
179
+ sodipodi:nodetypes="ccacccc"
180
+ inkscape:connector-curvature="0"
181
+ id="path4648-5-7-5-4-1-4-8"
182
+ d="m 272.0597,854.6617 c 4.59139,1.23026 17.26125,6.17999 34.35155,-10.66743 -10.52233,-5.87735 -18.43394,-14.31917 -23.89508,-24.27322 -5.43987,-9.91526 -8.42909,-22.44909 -7.60413,-33.06535 -23.13546,6.37691 -26.59083,20.16746 -27.82109,24.75885 -6.8071,17.28311 -5.34195,28.66478 -13.87833,37.02451 11.49115,-3.01411 24.10114,3.06984 38.84708,6.22264 z"
183
+ style="fill:#bc5fd3;stroke:#672178;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
184
+ <path
185
+ sodipodi:nodetypes="ccacccc"
186
+ inkscape:connector-curvature="0"
187
+ id="path4648-5-7-5-4-1-2-14-1"
188
+ d="m 248.63238,764.90272 c 1.23026,4.59139 3.27859,18.03868 26.41404,24.4156 -0.17123,-12.05128 3.18379,-23.12384 9.07368,-32.83035 5.86694,-9.6687 15.22694,-18.52435 24.83337,-23.11805 -17.09029,-16.84744 -30.76095,-12.9446 -35.35234,-11.71434 -18.37116,2.74643 -27.4954,9.70612 -39.00333,6.49327 8.35587,8.44457 9.39201,22.40711 14.03458,36.75387 z"
189
+ style="fill:#bc5fd3;stroke:#672178;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
190
+ </g>
191
+ <g
192
+ transform="matrix(0.8660254,0.5,-0.5,0.8660254,453.27246,-399.62181)"
193
+ id="g4799-0-3-5"
194
+ style="fill:#672178;stroke:#ddafe9"
195
+ inkscape:export-filename="C:\Users\wilkie\Pictures\lotus_avatar.png"
196
+ inkscape:export-xdpi="10.57"
197
+ inkscape:export-ydpi="10.57">
198
+ <path
199
+ sodipodi:nodetypes="ccacccc"
200
+ inkscape:connector-curvature="0"
201
+ id="path4648-5-0-9-8"
202
+ d="m 314.30878,699.69468 c -3.36113,3.36113 -13.98266,11.85868 -7.9375,35.08303 10.35109,-6.17393 21.61773,-8.80467 32.96875,-8.55714 11.3068,0.24656 23.65603,3.92474 32.4375,9.9473 6.04516,-23.22435 -4.17012,-33.11206 -7.53125,-36.47319 -11.56406,-14.53668 -22.15345,-18.95866 -25.125,-30.53125 -3.13528,11.45869 -14.70913,19.33728 -24.8125,30.53125 z"
203
+ style="fill:#672178;stroke:#ddafe9;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
204
+ <path
205
+ sodipodi:nodetypes="ccacccc"
206
+ inkscape:connector-curvature="0"
207
+ id="path4648-5-7-1-8-6"
208
+ d="m 404.02684,724.21119 c -4.59139,-1.23026 -17.26125,-6.18 -34.35155,10.66743 10.52233,5.87735 18.43393,14.31917 23.89508,24.27321 5.43987,9.91526 8.42909,22.44909 7.60413,33.06535 23.13546,-6.37691 26.59083,-20.16746 27.82109,-24.75885 6.8071,-17.28311 5.34195,-28.66478 13.87833,-37.02451 -11.49115,3.01411 -24.10114,-3.06984 -38.84708,-6.22263 z"
209
+ style="fill:#672178;stroke:#ddafe9;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
210
+ <path
211
+ sodipodi:nodetypes="ccacccc"
212
+ inkscape:connector-curvature="0"
213
+ id="path4648-5-7-5-46-8-1"
214
+ d="m 427.64223,813.60848 c -1.23026,-4.59139 -3.27859,-18.03868 -26.41404,-24.4156 0.17123,12.05128 -3.1838,23.12384 -9.07368,32.83035 -5.86693,9.6687 -15.22694,18.52436 -24.83337,23.11805 17.0903,16.84744 30.76095,12.9446 35.35234,11.71435 18.37116,-2.74644 27.4954,-9.70613 39.00333,-6.49327 -8.35587,-8.44458 -9.39201,-22.40712 -14.03458,-36.75388 z"
215
+ style="fill:#672178;stroke:#ddafe9;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
216
+ <path
217
+ sodipodi:nodetypes="ccacccc"
218
+ inkscape:connector-curvature="0"
219
+ id="path4648-5-7-5-4-0-0-2"
220
+ d="m 361.52776,878.92821 c 3.36113,-3.36113 13.98266,-11.85869 7.93751,-35.08303 -10.3511,6.17393 -21.61773,8.80467 -32.96876,8.55714 -11.3068,-0.24657 -23.65603,-3.92474 -32.4375,-9.94731 -6.04516,23.22435 4.17012,33.11207 7.53125,36.4732 11.56406,14.53667 22.15345,18.95865 25.125,30.53124 3.13528,-11.45869 14.70913,-19.33728 24.8125,-30.53124 z"
221
+ style="fill:#672178;stroke:#ddafe9;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
222
+ <path
223
+ sodipodi:nodetypes="ccacccc"
224
+ inkscape:connector-curvature="0"
225
+ id="path4648-5-7-5-4-1-7-8-4"
226
+ d="m 272.0597,854.6617 c 4.59139,1.23026 17.26125,6.17999 34.35155,-10.66743 -10.52233,-5.87735 -18.43394,-14.31917 -23.89508,-24.27322 -5.43987,-9.91526 -8.42909,-22.44909 -7.60413,-33.06535 -23.13546,6.37691 -26.59083,20.16746 -27.82109,24.75885 -6.8071,17.28311 -5.34195,28.66478 -13.87833,37.02451 11.49115,-3.01411 24.10114,3.06984 38.84708,6.22264 z"
227
+ style="fill:#672178;stroke:#ddafe9;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
228
+ <path
229
+ sodipodi:nodetypes="ccacccc"
230
+ inkscape:connector-curvature="0"
231
+ id="path4648-5-7-5-4-1-2-1-7-2"
232
+ d="m 248.63238,764.90272 c 1.23026,4.59139 3.27859,18.03868 26.41404,24.4156 -0.17123,-12.05128 3.18379,-23.12384 9.07368,-32.83035 5.86694,-9.6687 15.22694,-18.52435 24.83337,-23.11805 -17.09029,-16.84744 -30.76095,-12.9446 -35.35234,-11.71434 -18.37116,2.74643 -27.4954,9.70612 -39.00333,6.49327 8.35587,8.44457 9.39201,22.40711 14.03458,36.75387 z"
233
+ style="fill:#672178;stroke:#ddafe9;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
234
+ </g>
235
+ <path
236
+ sodipodi:type="arc"
237
+ style="fill:#ddafe9;stroke:#cd87de;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
238
+ id="path2985-2-5-7-5"
239
+ sodipodi:cx="385.3732"
240
+ sodipodi:cy="533.64886"
241
+ sodipodi:rx="63.134533"
242
+ sodipodi:ry="63.134533"
243
+ d="m 448.50773,533.64886 a 63.134533,63.134533 0 1 1 -126.26906,0 63.134533,63.134533 0 1 1 126.26906,0 z"
244
+ transform="translate(-34.169945,-80.733702)"
245
+ inkscape:export-filename="C:\Users\wilkie\Pictures\lotus_avatar.png"
246
+ inkscape:export-xdpi="10.57"
247
+ inkscape:export-ydpi="10.57" />
248
+ <path
249
+ sodipodi:type="arc"
250
+ style="fill:#d5e5ff;stroke:#5f5fd3;stroke-width:13;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
251
+ id="path2985-5-8-8-8"
252
+ sodipodi:cx="385.3732"
253
+ sodipodi:cy="533.64886"
254
+ sodipodi:rx="63.134533"
255
+ sodipodi:ry="63.134533"
256
+ d="m 448.50773,533.64886 a 63.134533,63.134533 0 1 1 -126.26906,0 63.134533,63.134533 0 1 1 126.26906,0 z"
257
+ transform="matrix(0.87075378,0,0,0.87075378,15.863104,-11.627123)"
258
+ inkscape:export-filename="C:\Users\wilkie\Pictures\lotus_avatar.png"
259
+ inkscape:export-xdpi="10.57"
260
+ inkscape:export-ydpi="10.57" />
261
+ </g>
262
+ </svg>