summaryrefslogtreecommitdiff
path: root/haunt
diff options
context:
space:
mode:
authorJakob L. Kreuze <zerodaysfordays@sdf.org>2023-08-12 16:40:11 -0400
committerJakob L. Kreuze <zerodaysfordays@sdf.org>2023-08-12 16:40:11 -0400
commitdac324a63bc0e1645fb01ab56dc2dc0d1c98c9de (patch)
tree82dc6b58d857f6c47a4cd6f57e0918ac79edd8c9 /haunt
parent802859a04fe50a9befc87e956f563c6153f43725 (diff)
[api] Identify comments based on clearnet/darknet
Diffstat (limited to 'haunt')
-rw-r--r--haunt/api.scm10
-rw-r--r--haunt/jakob/dynamic/capabilities/comments.scm27
-rw-r--r--haunt/jakob/dynamic/capabilities/common.scm4
-rw-r--r--haunt/jakob/dynamic/schema-comments.sql3
-rw-r--r--haunt/jakob/dynamic/util.scm23
-rw-r--r--haunt/jakob/utils/comments.scm15
-rw-r--r--haunt/static/image/i2p.svg1
-rw-r--r--haunt/static/image/tor.svg42
8 files changed, 104 insertions, 21 deletions
diff --git a/haunt/api.scm b/haunt/api.scm
index 354e1b6..1e71064 100644
--- a/haunt/api.scm
+++ b/haunt/api.scm
@@ -25,6 +25,7 @@
(jakob dynamic errors)
(jakob dynamic logging)
(jakob dynamic rate-limiter)
+ (jakob dynamic util)
(json)
(rnrs conditions)
(rnrs exceptions)
@@ -54,12 +55,9 @@
(define (clearnet-only handler)
(lambda (request body)
- (let ((originating-ip (assoc-ref (request-headers request) 'x-forwarded-for)))
- (if (and (or (string-prefix? "127." originating-ip)
- (string-suffix? ":1" originating-ip))
- (not (%debug-enabled)))
- (panic "This API is only available on the clearnet." #:code 403)
- (handler request body)))))
+ (if (and (from-darknet? request) (not (%debug-enabled)))
+ (panic "This API is only available on the clearnet." #:code 403)
+ (handler request body))))
(define (handle-api-request request body endpoint)
"Route handler for the API server."
diff --git a/haunt/jakob/dynamic/capabilities/comments.scm b/haunt/jakob/dynamic/capabilities/comments.scm
index 33f2429..ee2a52d 100644
--- a/haunt/jakob/dynamic/capabilities/comments.scm
+++ b/haunt/jakob/dynamic/capabilities/comments.scm
@@ -42,17 +42,21 @@
This interface exists for dynamically generating the comment view from Haunt."
(define (make-internal-comment~ . args)
- (let* ((args-needing-processing (take-right args 3))
+ (let* ((args-needing-processing (take-right args 4))
(approved (list-ref args-needing-processing 0))
(approved (string->date approved "~Y~m~d ~H~M~S.~N"))
(reactions (list-ref args-needing-processing 1))
(reactions (if reactions
(with-input-from-string reactions read)
'()))
- (replies (list-ref args-needing-processing 2)))
-
+ (originating-network (list-ref args-needing-processing 2))
+ (replies (list-ref args-needing-processing 3)))
(apply make-internal-comment
- (append (drop-right args 3) (list approved reactions replies)))))
+ `(,@(drop-right args 4)
+ ,approved
+ ,reactions
+ ,replies
+ ,originating-network))))
(define (order-comments comments)
(define seen (make-hash-table))
(define (id comment) (first comment))
@@ -78,7 +82,7 @@ This interface exists for dynamically generating the comment view from Haunt."
(hash-append! seen 'terminal parsed))
(pass (cdr cur) initial-comments remaining)))))
(pass comments comments '()))
- (let* ((query "SELECT id, name, subject, email, comment, url, approved, reactions, reply_to
+ (let* ((query "SELECT id, name, subject, email, comment, url, approved, reactions, originating_network, reply_to
FROM comments WHERE slug = $1 and approved IS NOT NULL")
(result (exec-query conn query (list slug))))
(if (positive? (length result))
@@ -106,6 +110,10 @@ This is a wrapper around `get-comments-by-slug'."
(define (put-comment request body)
"API endpoint handler for submitting a comment"
+ (define (request-originating-network request)
+ (cond ((from-tor? request) "tor")
+ ((from-i2p? request) "i2p")
+ (else "clearnet")))
(define (valid-comment? form-data)
(and (assoc "slug" form-data)
(assoc "name" form-data)
@@ -124,9 +132,9 @@ This is a wrapper around `get-comments-by-slug'."
(string->number (assoc-value form-data "captcha-id"))))))
(define (insert-comment form-data)
(exec-query conn
- "INSERT INTO comments (submitted, slug, name, subject,
- email, url, comment, reply_to)
- VALUES (now(), $1, $2, $3, $4, $5, $6, $7);"
+ "INSERT INTO comments (submitted, slug, name, subject, email,
+ url, comment, reply_to, originating_network)
+ VALUES (now(), $1, $2, $3, $4, $5, $6, $7, $8);"
(list (assoc-value form-data "slug")
(assoc-value form-data "name")
(assoc-value form-data "subject")
@@ -136,7 +144,8 @@ This is a wrapper around `get-comments-by-slug'."
(if (and (assoc-value form-data "reply-to")
(positive? (string-length (assoc-value form-data "reply-to"))))
(assoc-value form-data "reply-to")
- #f)))
+ #f)
+ (request-originating-network request)))
(values (build-response
#:code 307
#:headers '((Location . "https://jakob.space")))
diff --git a/haunt/jakob/dynamic/capabilities/common.scm b/haunt/jakob/dynamic/capabilities/common.scm
index 0e7d7b8..2bca1a2 100644
--- a/haunt/jakob/dynamic/capabilities/common.scm
+++ b/haunt/jakob/dynamic/capabilities/common.scm
@@ -31,6 +31,7 @@
internal-comment-publish-time
internal-comment-reactions
internal-comment-replies
+ internal-comment-originating-network
sort-comments))
(define-json-mapping <internal-comment>
@@ -57,7 +58,8 @@
(vector->list x)))
(lambda (x) (list->vector (map (lambda (y)
(json-string->scm (internal-comment->json y)))
- x)))))
+ x))))
+ (originating-network internal-comment-originating-network))
(define (sort-comments comments)
"Sort COMMENTS, a list of `<internal-comment>' chronologically"
diff --git a/haunt/jakob/dynamic/schema-comments.sql b/haunt/jakob/dynamic/schema-comments.sql
index 1f2edc7..8519f4b 100644
--- a/haunt/jakob/dynamic/schema-comments.sql
+++ b/haunt/jakob/dynamic/schema-comments.sql
@@ -9,7 +9,8 @@ CREATE TABLE comments(
url VARCHAR(100),
comment VARCHAR(1024) NOT NULL,
reactions VARCHAR(1024),
- reply_to INT
+ reply_to INT,
+ originating_network VARCHAR(100)
);
-- Use `now' for `submitted'.
diff --git a/haunt/jakob/dynamic/util.scm b/haunt/jakob/dynamic/util.scm
index f6f0382..e34ae91 100644
--- a/haunt/jakob/dynamic/util.scm
+++ b/haunt/jakob/dynamic/util.scm
@@ -20,6 +20,7 @@
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-19)
#:use-module (srfi srfi-26)
+ #:use-module (web request)
#:use-module (web uri)
#:export (assoc-value
acons-normalize
@@ -27,7 +28,10 @@
decode-form
date<?
hash-append!
- emoji?))
+ emoji?
+ from-tor?
+ from-i2p?
+ from-darknet?))
(define (assoc-value alist key)
"Return the `car' of `(assoc alist key)' if truthy"
@@ -110,3 +114,20 @@ to express my God-given constitutional rights!"
(<= #x270A codepoint #x270D)
(= codepoint #x1F37B)
(= codepoint #x1F440)))))
+
+(define (from-tor? request)
+ "Return whether or not REQUEST was sent by the Tor daemon"
+ (let ((originating-ip (assoc-ref (request-headers request) 'x-forwarded-for)))
+ (or (string=? "127.0.0.1" originating-ip)
+ (string=? "::1" originating-ip))))
+
+(define (from-i2p? request)
+ "Return whether or not REQUEST was sent by i2pd"
+ (let ((originating-ip (assoc-ref (request-headers request) 'x-forwarded-for)))
+ (and (or (string-prefix? "127." originating-ip)
+ (string-suffix? ":1" originating-ip))
+ (not (from-tor? request)))))
+
+(define (from-darknet? request)
+ "Return whether or not REQUEST was sent by a darknet tunnel"
+ (or (from-tor? request) (from-i2p? request)))
diff --git a/haunt/jakob/utils/comments.scm b/haunt/jakob/utils/comments.scm
index f38bb18..4b38fd2 100644
--- a/haunt/jakob/utils/comments.scm
+++ b/haunt/jakob/utils/comments.scm
@@ -110,9 +110,18 @@
`(img (@ (class "comment-source-identifier")
(alt "Icon for comments posted externally and syndicated by Webmention")
(src "/static/image/webmention-logo.png")))
- `(img (@ (class "comment-source-identifier")
- (alt "Icon for comments posted on jakob.space")
- (src "/static/image/lambda.svg"))))
+ (match (internal-comment-originating-network comment)
+ ("tor" `(img (@ (class "comment-source-identifier")
+ (alt "Icon for comments posted on jakob.space via Tor;
+The Tor logo belongs to The Tor Project, Inc. and is licensed under the CC BY 3.0 US")
+ (src "/static/image/lambda.svg"))))
+ ("i2p" `(img (@ (class "comment-source-identifier")
+ (alt "Icon for comments posted on jakob.space via I2P;
+The I2P logo belongs to The I2P Project, and is licensed under the CC BY 4.0")
+ (src "/static/image/lambda.svg"))))
+ (_ `(img (@ (class "comment-source-identifier")
+ (alt "Icon for comments posted on jakob.space")
+ (src "/static/image/lambda.svg"))))))
(div (@ (class "p-author h-card author"))
(img (@ (class "u-photo") (src ,(comment-photo comment)))))
(div (@ (class "metaline"))
diff --git a/haunt/static/image/i2p.svg b/haunt/static/image/i2p.svg
new file mode 100644
index 0000000..dfc85a8
--- /dev/null
+++ b/haunt/static/image/i2p.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512"><path fill="#fff" d="M0 0v512h512V0H0z"/><path fill="#010101" d="M153 239c-19.3 10-36 24.8-54.3 36.5-9.8 8.3-25.3 12.6-28.7 26 10.3 23 37.5 34 53.6 53 23.2 14.8 12.4 37.4 10.8 58.5-.6 19.8 8 38.2 19.5 53.8 0 14-32 35-4 41 32-.2 63 1.3 95 0 19-6.4 41 2.6 61-2.3 23-1.2 47-.3 70-2.6 23-16-28-31-1.6-47 14-18 10.7-42 5.5-62 18-15 18.3-37 20-58 5-20 14-39 19-59-4-24-39-42-46-57 18-29 27-64 20-98-6.6-55-51-101-105-113-60-15-128 17-155.5 72.5-16 31-18 68.4-9.4 102 5.6 20.4 17 38 29.6 54.4z"/><path fill="#576e57" d="M328 25l1 1z"/><path fill="#444b19" d="M267 26l1 1-1-1z"/><path fill="#ffff01" d="M180 329l18 8c9.2-17.5 14.8-38.4 21.6-57 2.3-6.3 3.5-17 9.5-21.2 5-3.3 15-.5 20 0 11 1 24 .7 34-1.7 53-11 90-57 92-111 3-73-69-132-141-117-44 10-76 44-88 86-10 38 2 79 28 107 7 8 15 14 24 20 3.8 3 10 5 11 10 1.4 6-4.3 14-6 19-6 20-16.4 39-21.2 59z"/><path fill="#444b19" d="M275 27l1 1-1-1m-39 1l1 1-1-1m-8 2l1 1-1-1z"/><path fill="#6c6c02" d="M291 31l1 1-1-1z"/><path fill="#989801" d="M207 38l1 1-1-1zm105 2l1 1-1-1z"/><path fill="#444b19" d="M313 40l1 1-1-1z"/><path fill="#6c6c02" d="M320 44l1 1-1-1z"/><path fill="#444b19" d="M321 45l1 1-1-1m-130 2l1 1-1-1z"/><path fill="#989801" d="M192 47l1 1-1-1zm-2 1l1 1-1-1z"/><path fill="#444b19" d="M326 48l1 1-1-1z"/><path fill="#989801" d="M327 49l1 1-1-1"/><path fill="#9fc79f" d="M359 50l1 1-1-1z"/><path fill="#989801" d="M186 51l1 1-1-1m-1 1l1 1-1-1m-1 1l1 1-1-1z"/><path fill="#6c6c02" d="M182 54l1 1-1-1m-1 1l1 1-1-1z"/><path fill="#9fc79f" d="M334 55l1 1-1-1z"/><path fill="#6c6c02" d="M180 56l1 1-1-1z"/><path fill="#989801" d="M179 57l1 1-1-1m-1 1l1 1-1-1m-1 1l1 1z"/><path fill="#6c6c02" d="M176 60l1 1-1-1m-1 1l1 1-1-1z"/><path fill="#989801" d="M341 61l1 1-1-1z"/><path fill="#6c6c02" d="M174 62l1 1-1-1z"/><path fill="#989801" d="M342 62l1 1-1-1z"/><path fill="#6c6c02" d="M173 63l1 1-1-1z"/><path fill="#989801" d="M343 63l1 1-1-1m-171 1l1 1-1-1m172 0l1 1-1-1m-173 1l1 1-1-1m-1 1l1 1-1-1z"/><path fill="#010101" d="M299 75.5c-52.4 11-36.2 92.8 16 81.7 52.7-11.2 36.3-92.8-16-81.7z"/><path fill="#444b19" d="M354 77l1 1-1-1z"/><path fill="#6c6c02" d="M161 78l1 1-1-1z"/><path fill="#010101" d="M203 78.4c-42 5.6-52.3 62.7-12 80 7.5 3 18 2.6 26 1.4 48.6-7.5 34.8-87.8-14-81.4z"/><path fill="#989801" d="M289 78l1 1-1-1m35 0l1 1-1-1z"/><path fill="#444b19" d="M355 78l1 1-1-1z"/><path fill="#989801" d="M221 80l1 1-1-1z"/><path fill="#9fc79f" d="M328 80l1 1-1-1z"/><path fill="#6c6c02" d="M356 80l1 1-1-1zm-74 2l1 1-1-1z"/><path fill="#444b19" d="M185 83l1 1-1-1z"/><path fill="#989801" d="M281 83l1 1-1-1z"/><path fill="#6c6c02" d="M358 83l1 1-1-1m-174 1l1 1-1-1z"/><path fill="#444b19" d="M228 84l1 1-1-1z"/><path fill="#989801" d="M280 84l1 1-1-1z"/><path fill="#444b19" d="M359 84l1 1-1-1z"/><path fill="#6c6c02" d="M182 85l1 1-1-1m48 0l1 1-1-1z"/><path fill="#444b19" d="M334 85l1 1-1-1z"/><path fill="#6c6c02" d="M359 85l1 1-1-1m-203 1l1 1-1-1m25 0l1 1-1-1m50 0l1 1-1-1z"/><path fill="#989801" d="M277 86l1 1-1-1z"/><path fill="#444b19" d="M305 86l1 1-1-1zm30 0l1 1-1-1zm-103 1l1 1-1-1z"/><path fill="#989801" d="M276 87l1 1-1-1z"/><path fill="#fff" d="M283 134c3-6.3 4.8-9.4 10.2-11.7 15.7-7 24.5 8.4 22.8 21.7 38.8-11.2 14-72-22-54-4.3 2.3-8.2 6-11 10-3 4.5-5.2 9.5-5.7 15-.6 7 2.6 13 5.7 19z"/><path fill="#989801" d="M360 87l1 1-1-1m-205 1l1 1-1-1z"/><path fill="#6c6c02" d="M178 88l1 1-1-1z"/><path fill="#444b19" d="M276 88l1 1z"/><path fill="#576e57" d="M297 88l1 1-1-1z"/><path fill="#444b19" d="M235 89l1 1-1-1z"/><path fill="#6c6c02" d="M275 89l1 1-1-1z"/><path fill="#779375" d="M319 89l1 1-1-1z"/><path fill="#9fc79f" d="M201 90l1 1-1-1z"/><path fill="#FFF" d="M196 147c-2-8-3-15 3.4-21.8 10.5-11 28.7-3.6 30.6 10.8 9.5-9.4 6-29.2-3.2-37.7-12.5-11.8-32-10.4-43 2.7-3.6 4.5-5.2 9.2-6 15-.8 5.6.2 12 2.5 17 3.2 6.8 9 11.2 15.7 14z"/><path fill="#989801" d="M274 90l1 1-1-1z"/><path fill="#576e57" d="M320 90l1 1-1-1z"/><path fill="#989801" d="M175 91l1 1z"/><path fill="#444b19" d="M197 91l1 1-1-1z"/><path fill="#576e57" d="M215 91l1 1-1-1z"/><path fill="#989801" d="M273 91l1 1-1-1z"/><path fill="#9fc79f" d="M291 91l1 1-1-1zm-1 1l1 1-1-1z"/><path fill="#444b19" d="M324 92l1 1-1-1z"/><path fill="#6c6c02" d="M238 93l1 1-1-1m34 0l1 1-1-1z"/><path fill="#576e57" d="M288 93l1 1-1-1z"/><path fill="#95bb95" d="M289 93l1 1-1-1z"/><path fill="#444b19" d="M325 93l1 1-1-1z"/><path fill="#6c6c02" d="M173 94l1 1-1-1z"/><path fill="#9fc79f" d="M191 94l1 1-1-1z"/><path fill="#779375" d="M221 94l1 1-1-1z"/><path fill="#444b19" d="M222 94l1 1-1-1"/><path fill="#6c6c02" d="M271 94l1 1-1-1z"/><path fill="#95bb95" d="M287 94l1 1-1-1z"/><path fill="#779375" d="M326 94l1 1-1-1z"/><path fill="#444b19" d="M240 95l1 1-1-1z"/><path fill="#9fc79f" d="M286 95l1 1-1-1z"/><path fill="#989801" d="M364 95l1 1z"/><path fill="#9fc79f" d="M285 96l1 1-1-1zm-1 1l1 1-1-1z"/><path fill="#576e57" d="M126 99l1 1-1-1z"/><path fill="#9fc79f" d="M185 99l1 1-1-1z"/><path fill="#444b19" d="M366 99l1 1-1-1z"/><path fill="#6c6c02" d="M169 100l1 1-1-1z"/><path fill="#9fc79f" d="M184 100l1 1-1-1z"/><path fill="#989801" d="M345 100l1 1-1-1m21 0l1 1-1-1z"/><path fill="#6c6c02" d="M149 101l1 1-1-1z"/><path fill="#9fc79f" d="M182 102l1 1-1-1z"/><path fill="#444b19" d="M230 102l1 1-1-1z"/><path fill="#6c6c02" d="M244 102l1 1-1-1z"/><path fill="#444b19" d="M346 103l1 1-1-1zm-113 4l1 1-1-1z"/><path fill="#989801" d="M166 108l1 1-1-1z"/><path fill="#6c6c02" d="M246 108l1 1-1-1z"/><path fill="#576e57" d="M278 108l1 1-1-1"/><path fill="#444b19" d="M369 108l1 1-1-1m-223 1l1 1-1-1z"/><path fill="#576e57" d="M178 109l1 1-1-1z"/><path fill="#95bb95" d="M234 110l1 1-1-1z"/><path fill="#444b19" d="M372 117l1 1-1-1z"/><path fill="#576e57" d="M213 119l1 1-1-1z"/><path fill="#779375" d="M206 120l1 1-1-1"/><path fill="#9fc79f" d="M295 121l1 1-1-1z"/><path fill="#576e57" d="M304 121l1 1-1-1z"/><path fill="#444b19" d="M221 122l1 1-1-1z"/><path fill="#6c6c02" d="M143 123l1 1-1-1z"/><path fill="#9fc79f" d="M200 123l1 1-1-1z"/><path fill="#576e57" d="M223 123l1 1-1-1z"/><path fill="#9fc79f" d="M199 124l1 1-1-1z"/><path fill="#576e57" d="M224 124l1 1-1-1m54 0l1 1-1-1z"/><path fill="#9fc79f" d="M289 124l1 1-1-1z"/><path fill="#926a61" d="M310 124l1 1-1-1z"/><path fill="#95bb95" d="M311 124l1 1-1-1z"/><path fill="#9fc79f" d="M198 125l1 1-1-1z"/><path fill="#444b19" d="M225 125l1 1-1-1z"/><path fill="#989801" d="M247 125l1 1-1-1z"/><path fill="#6c6c02" d="M266 125l1 1-1-1z"/><path fill="#9fc79f" d="M312 125l1 1-1-1z"/><path fill="#444b19" d="M166 130l1 1-1-1z"/><path fill="#9fc79f" d="M195 130l1 1-1-1z"/><path fill="#95bb95" d="M315 130l1 1-1-1z"/><path fill="#926a61" d="M179 131l1 1-1-1z"/><path fill="#9fc79f" d="M229 131l1 1-1-1z"/><path fill="#779375" d="M233 131l1 1-1-1z"/><path fill="#576e57" d="M281 131l1 1-1-1z"/><path fill="#95bb95" d="M284 131l1 1-1-1z"/><path fill="#9fc79f" d="M282 132l1 1-1-1z"/><path fill="#989801" d="M345 132l1 1-1-1m-178 1l1 1-1-1z"/><path fill="#444b19" d="M180 133l1 1-1-1z"/><path fill="#576e57" d="M194 133l1 1-1-1z"/><path fill="#444b19" d="M232 133l1 1-1-1zm-1 2l1 1-1-1"/><path fill="#6c6c02" d="M169 138l1 1-1-1z"/><path fill="#444b19" d="M243 138l1 1-1-1m28 0l1 1-1-1z"/><path fill="#6c6c02" d="M342 138l1 1-1-1z"/><path fill="#9fc79f" d="M169 139l1 1-1-1z"/><path fill="#989801" d="M243 139l1 1-1-1z"/><path fill="#6c6c02" d="M272 139l1 1-1-1z"/><path fill="#444b19" d="M325 139l1 1-1-1z"/><path fill="#9fc79f" d="M342 139l1 1-1-1m-100 1l1 1-1-1z"/><path fill="#989801" d="M273 141l1 1-1-1z"/><path fill="#6c6c02" d="M274 142l1 1-1-1zm1 1l1 1-1-1z"/><path fill="#444b19" d="M190 144l1 1-1-1z"/><path fill="#6c6c02" d="M276 144l1 1-1-1z"/><path fill="#576e57" d="M192 145l1 1-1-1z"/><path fill="#444b19" d="M237 146l1 1-1-1z"/><path fill="#6c6c02" d="M175 147l1 1z"/><path fill="#989801" d="M237 147l1 1-1-1m42 0l1 1-1-1z"/><path fill="#6c6c02" d="M176 148l1 1-1-1z"/><path fill="#444b19" d="M236 148l1 1-1-1z"/><path fill="#989801" d="M280 148l1 1-1-1z"/><path fill="#444b19" d="M177 149l1 1-1-1z"/><path fill="#989801" d="M281 149l1 1-1-1z"/><path fill="#444b19" d="M178 150l1 1-1-1z"/><path fill="#6c6c02" d="M282 150l1 1-1-1z"/><path fill="#989801" d="M328 152l1 1-1-1z"/><path fill="#444b19" d="M182 153l1 1-1-1z"/><path fill="#6c6c02" d="M325 153l1 1-1-1z"/><path fill="#989801" d="M326 153l1 1-1-1"/><path fill="#444b19" d="M184 154l1 1-1-1z"/><path fill="#989801" d="M229 154l1 1-1-1"/><path fill="#6c6c02" d="M320 155l1 1-1-1z"/><path fill="#989801" d="M223 157l1 1-1-1m-32 1l1 1z"/><path fill="#9fc79f" d="M215 160l1 1-1-1z"/><path fill="#6c6c02" d="M143 162l1 1zm226 15l1 1-1-1z"/><path fill="#989801" d="M367 183l1 1z"/><path fill="#6c6c02" d="M149 184l1 1-1-1z"/><path fill="#989801" d="M366 185l1 1-1-1z"/><path fill="#444b19" d="M366 186l1 1-1-1z"/><path fill="#576e57" d="M390 187l1 1-1-1z"/><path fill="#989801" d="M364 190l1 1-1-1m-212 1l1 1-1-1z"/><path fill="#444b19" d="M364 191l1 1-1-1z"/><path fill="#989801" d="M153 193l1 1-1-1m207 5l1 1z"/><path fill="#6c6c02" d="M156 199l1 1-1-1z"/><path fill="#444b19" d="M157 200l1 1-1-1z"/><path fill="#6c6c02" d="M359 200l1 1-1-1z"/><path fill="#444b19" d="M359 201l1 1-1-1z"/><path fill="#989801" d="M161 207l1 1-1-1z"/><path fill="#444b19" d="M355 207l1 1-1-1z"/><path fill="#989801" d="M162.3 208.7c-108.2 202.2-54 101 0 0z"/><path fill="#444b19" d="M354 208l1 1-1-1z"/><path fill="#989801" d="M163 210l1 1-1-1m3 4l1 1-1-1m1 1l1 1-1-1m182 0l1 1-1-1m-181 1l1 1-1-1zm2 3l1 1-1-1m1 1l1 1-1-1m1 1l1 1-1-1m172 0l1 1-1-1z"/><path fill="#6c6c02" d="M173 222l1 1-1-1z"/><path fill="#989801" d="M343 222l1 1-1-1m-1 1l1 1-1-1z"/><path fill="#6c6c02" d="M175 224l1 1-1-1z"/><path fill="#989801" d="M341 224l1 1-1-1z"/><path fill="#6c6c02" d="M176 225l1 1-1-1z"/><path fill="#989801" d="M177 226l1 1-1-1m1 1l1 1-1-1m1 1l1 1-1-1m158 0l1 1-1-1z"/><path fill="#6c6c02" d="M180 229l1 1-1-1z"/><path fill="#989801" d="M336 229l1 1-1-1z"/><path fill="#6c6c02" d="M181 230l1 1-1-1z"/><path fill="#989801" d="M334 230l1 1-1-1z"/><path fill="#444b19" d="M335 230l1 1-1-1z"/><path fill="#6c6c02" d="M182 231l1 1-1-1z"/><path fill="#989801" d="M184 232l1 1-1-1m1 1l1 1-1-1m1 1l1 1-1-1m1 1l1 1-1-1m3 2l1 1z"/><path fill="#6c6c02" d="M326 237l1 1-1-1z"/><path fill="#444b19" d="M191 238l1 1-1-1z"/><path fill="#989801" d="M192 238l1 1-1-1z"/><path fill="#6c6c02" d="M320 241l1 1-1-1m-1 1l1 1-1-1z"/><path fill="#5a081a" d="M334 248c-222.7 176-111.3 88 0 0z"/><path fill="#ff013d" d="M237 270c-8.5 16-15.4 36.6-20 54-1.4 5-6.3 11.7-5 17 3.2 12.8 17.2 22.5 29 25.6 22.3 5.8 48.2 7.5 70-1 4-1.6 9.7-3 12-6.8 2-3.6.8-9 1.2-12.8 1-10.2 6.5-18.5 16.8-21 0-9 1.7-18.7 8.5-25.5 4-4 10.2-6 14-1.2 9.8 12.3-3.6 27.7 12.5 36.7 13.8-29.4 26.3-75-15-88.7-5.2-1.8-11.4-4.7-17-4-10.3 1-22.7 14-32.4 18.6-22.3 10-50.6 14-74.6 9z"/><path fill="#444b19" d="M199 243l1 1-1-1z"/><path fill="#989801" d="M315 244l1 1z"/><path fill="#444b19" d="M202 245l1 1-1-1z"/><path fill="#989801" d="M313 245l1 1-1-1z"/><path fill="#6c6c02" d="M314 245l1 1-1-1z"/><path fill="#989801" d="M311 246l1 1-1-1z"/><path fill="#444b19" d="M205 247l1 1-1-1z"/><path fill="#5a081a" d="M365 247l1 1-1-1z"/><path fill="#6c6c02" d="M206.7 249.3c-137.8 175-69 87.6 0 0z"/><path fill="#576e57" d="M401 250l1 1-1-1z"/><path fill="#5a081a" d="M181 251c-120.7 174-60.3 87 0 0zm147 0l1 1-1-1z"/><path fill="#a30127" d="M181 253c-120.7 172.7-60.3 86.3 0 0z"/><path fill="#ff013d" d="M137 338c3.2-4.2 6.6-7.2 11-10-2-4-6.7-6.5-7.5-11-1.6-9.4 12.2-21 20.5-21.8 4.4-.5 12.3 5 15.5 3 2.5-1.7 3.4-6.6 4.5-9.2 3-7.5 13-26 8-33.7-2.5-4-7.7-3.8-13.4-2.2-7.6 3-16 8-19.6 10-13.6 8-26.5 17-39 27-4 3-12.3 8-13.5 13-1.2 6 3 11 6.2 14 7.7 9 17.2 17 27.3 22z"/><path fill="#a30127" d="M185.7 252.3c-123.8 173-62 86.6 0 0zM170 255l1 1-1-1z"/><path fill="#989801" d="M289 255l1 1-1-1z"/><path fill="#a30127" d="M320 256l1 1-1-1z"/><path fill="#444b19" d="M230 257l1 1-1-1z"/><path fill="#989801" d="M281 257l1 1-1-1z"/><path fill="#5a081a" d="M318 257l1 1-1-1zm-154.7 1.7c-109 169-54.4 84.4 0 0z"/><path fill="#6c6c02" d="M205 258l1 1-1-1m23 0l1 1-1-1z"/><path fill="#5a081a" d="M161 259l1 1z"/><path fill="#6c6c02" d="M227 259l1 1-1-1z"/><path fill="#a30127" d="M160.3 260.7c-107 167.5-53.4 83.7 0 0z"/><path fill="#444b19" d="M226 260l1 1-1-1z"/><path fill="#a30127" d="M154 263l1 1-1-1"/><path fill="#989801" d="M223 267l1 1-1-1z"/><path fill="#5a081a" d="M386 267l1 1-1-1m-198 1l1 1-1-1z"/><path fill="#989801" d="M201 268l1 1-1-1z"/><path fill="#444b19" d="M223.3 268.7c-149 162.2-74.4 81 0 0z"/><path fill="#6c6c02" d="M222 270c-148 161.3-74 80.7 0 0z"/><path fill="#5a081a" d="M236 270l1 1-1-1z"/><path fill="#989801" d="M200 271c-133.3 160.7-66.7 80.3 0 0z"/><path fill="#5a081a" d="M245 271l1 1-1-1"/><path fill="#a30127" d="M139 273l1 1-1-1z"/><path fill="#5a081a" d="M186.3 273.7c-124.2 159-62 79.4 0 0z"/><path fill="#a30127" d="M137 274l1 1-1-1z"/><path fill="#6c6c02" d="M199 274l1 1-1-1z"/><path fill="#a30127" d="M185 275l1 1z"/><path fill="#444b19" d="M198.5 276.6c-132.3 157-66.2 78.5 0 0z"/><path fill="#a30127" d="M234 275l1 1-1-1zm-100 1l1 1-1-1zm-1 1l1 1-1-1z"/><path fill="#5a081a" d="M131 278l1 1-1-1m53.3.7s0 1 .4.6c0 0 0-1-.4-.6zm-54.3.3l1 1-1-1z"/><path fill="#a30127" d="M183.3 280.7c-122.2 154.2-61 77 0 0z"/><path fill="#5a081a" d="M127 281l1 1-1-1z"/><path fill="#a30127" d="M125.7 282.3c-.5.5.6.4.6.4.5-.5-.6-.4-.6-.4z"/><path fill="#6c6c02" d="M218 282l1 1-1-1z"/><path fill="#5a081a" d="M231 282l1 1-1-1m-107 1l1 1-1-1z"/><path fill="#9fc79f" d="M83 286l1 1-1-1z"/><path fill="#444b19" d="M216.3 287.7c-144.2 149.5-72 74.7 0 0z"/><path fill="#a30127" d="M180 289l1 1-1-1z"/><path fill="#989801" d="M215 289c-143.3 148.7-71.7 74.3 0 0z"/><path fill="#6c6c02" d="M193 290l1 1-1-1m22.3.7s0 1 .4.6c0 0 0-1-.4-.6z"/><path fill="#989801" d="M192.3 293.7c-128.2 145.5-64 72.7 0 0z"/><path fill="#a30127" d="M109 295l1 1-1-1m57 0c-110.7 144.7-55.3 72.3 0 0z"/><path fill="#5a081a" d="M178.3 295.7c-119 144.2-59.4 72 0 0z"/><path fill="#6c6c02" d="M191.3 295.7c-127.5 144.2-63.7 72 0 0z"/><path fill="#989801" d="M213 295l1 1-1-1z"/><path fill="#a30127" d="M108 296l1 1-1-1m46.7.3c-103 143.8-51.6 72 0 0z"/><path fill="#6c6c02" d="M213 296l1 1-1-1z"/><path fill="#a30127" d="M107 297l1 1z"/><path fill="#5a081a" d="M171.3 297.7c-114.2 143-57 71.4 0 0z"/><path fill="#989801" d="M191 297l1 1-1-1z"/><path fill="#a30127" d="M226 297l1 1-1-1m-119.7 1.7c-71 142.2-35.4 71 0 0z"/><path fill="#5a081a" d="M177 298l1 1-1-1z"/><path fill="#444b19" d="M190.3 298.7c-127 142.2-63.4 71 0 0z"/><path fill="#5a081a" d="M173.7 299.3c-115.8 141.8-58 71 0 0z"/><path fill="#a30127" d="M176 299l1 1-1-1m-74 3c-68 140-34 70 0 0z"/><path fill="#5a081a" d="M147 302c1 1 1 1 0 0"/><path fill="#6c6c02" d="M188 304l1 1-1-1z"/><path fill="#989801" d="M210 304l1 1-1-1z"/><path fill="#6c6c02" d="M209 306l1 1-1-1z"/><path fill="#444b19" d="M208 312c-138.7 133.3-69.3 66.7 0 0z"/><path fill="#a30127" d="M106 312l1 1z"/><path fill="#444b19" d="M185 312l1 1-1-1z"/><path fill="#6c6c02" d="M207.3 312.7c-138.2 133-69 66.4 0 0z"/><path fill="#a30127" d="M107 313l1 1-1-1z"/><path fill="#5a081a" d="M140 313c-93.3 132.7-46.7 66.3 0 0z"/><path fill="#989801" d="M185 313l1 1-1-1z"/><path fill="#a30127" d="M108 314l1 1-1-1z"/><path fill="#989801" d="M206.3 314.7c-137.5 131.5-68.7 65.7 0 0z"/><path fill="#a30127" d="M109 315l1 1-1-1m1.3 1.7c-73.5 130.2-36.7 65 0 0z"/><path fill="#444b19" d="M183.3 317.7c-122.2 129.5-61 64.7 0 0z"/><path fill="#a30127" d="M111 318l1 1-1-1m1 1l1 1-1-1z"/><path fill="#989801" d="M183 319l1 1-1-1z"/><path fill="#5a081a" d="M218 319l1 1-1-1z"/><path fill="#a30127" d="M382 320l1 1-1-1m-267 1l1 1-1-1m1 1l1 1zm1 1l1 1-1-1m1 1l1 1-1-1m28 1l1 1-1-1m2.3 1.7c-99 123.5-49.4 61.7 0 0z"/><path fill="#444b19" d="M180 326l1 1-1-1z"/><path fill="#a30127" d="M335 326l1 1-1-1m-213 1l1 1-1-1m93.3.7c-143.5 123-71.7 61.4 0 0zm-92.3.3l1 1-1-1z"/><path fill="#5a081a" d="M147 328l1 1-1-1z"/><path fill="#6c6c02" d="M201 328l1 1-1-1z"/><path fill="#444b19" d="M201.3 329.7c-134.2 121.5-67 60.7 0 0z"/><path fill="#5a081a" d="M214.3 329.7c-143 121.5-71.4 60.7 0 0z"/><path fill="#989801" d="M184 330l1 1-1-1z"/><path fill="#5a081a" d="M373 333l1 1z"/><path fill="#444b19" d="M191 334l1 1-1-1z"/><path fill="#989801" d="M192 334l1 1-1-1z"/><path fill="#6c6c02" d="M199 334l1 1-1-1z"/><path fill="#a30127" d="M327 334l1 1-1-1z"/><path fill="#5a081a" d="M374 334l1 1-1-1z"/><path fill="#6c6c02" d="M194.3 335.7c-129.5 117.5-64.7 58.7 0 0z"/><path fill="#5a081a" d="M375 335l1 1-1-1m-241.3 1.3c-89 117-44.6 58.6 0 0z"/><path fill="#444b19" d="M195 336l1 1-1-1z"/><path fill="#989801" d="M198.3 336.7c-132.2 117-66 58.4 0 0z"/><path fill="#9fc79f" d="M104 337l1 1-1-1z"/><path fill="#444b19" d="M197 337l1 1-1-1z"/><path fill="#926a61" d="M343 338l1 1-1-1z"/><path fill="#fbb5a7" d="M344 338.7c-8.5 3.5-8.5 27.2-1.4 32.3 3.8 2.8 17.2-.7 21.4-2.3 23.5-9.5-4.6-36-20-30z"/><path fill="#444b19" d="M341 339l1 1-1-1m-1 1l1 1-1-1z"/><path fill="#926a61" d="M357 340l1 1-1-1z"/><path fill="#a30127" d="M211 341l1 1-1-1zm1 1l1 1-1-1z"/><path fill="#926a61" d="M339 342l1 1-1-1m22 0l1 1-1-1z"/><path fill="#5a081a" d="M324 343l1 1-1-1z"/><path fill="#b9867c" d="M159 344c-106 112-53 56 0 0z"/><path fill="#a30127" d="M213 344l1 1-1-1z"/><path fill="#444b19" d="M364 344l1 1-1-1z"/><path fill="#fbb5a7" d="M201 365c-6.8-9-22-17.4-33-19.5-4.5-1-12.2-1.7-14.2 3.6-2.6 7 4 13 9.2 16 11.8 6 26 4 38 1z"/><path fill="#926a61" d="M168 345l1 1-1-1z"/><path fill="#5a081a" d="M214.3 345.7c-143 111-71.4 55.4 0 0z"/><path fill="#444b19" d="M365 345l1 1-1-1z"/><path fill="#a30127" d="M215 347l1 1-1-1z"/><path fill="#b9867c" d="M176 348l1 1-1-1z"/><path fill="#444b19" d="M178.7 349.3c-119 108.5-59.6 54.3 0 0z"/><path fill="#5a081a" d="M216 349l1 1-1-1z"/><path fill="#926a61" d="M180.7 350.3c-120.5 107.8-60.3 54 0 0z"/><path fill="#5a081a" d="M217 350l1 1-1-1z"/><path fill="#444b19" d="M370 350l1 1-1-1z"/><path fill="#b9867c" d="M182 351l1 1-1-1z"/><path fill="#576e57" d="M183 351l1 1-1-1z"/><path fill="#5a081a" d="M218 351l1 1-1-1z"/><path fill="#576e57" d="M371 351l1 1-1-1z"/><path fill="#444b19" d="M185 352l1 1-1-1zm-32 2c-102 105.3-51 52.7 0 0z"/><path fill="#5a081a" d="M222 356l1 1-1-1"/><path fill="#926a61" d="M192 357l1 1-1-1z"/><path fill="#5a081a" d="M223 357l1 1-1-1z"/><path fill="#b9867c" d="M155 358l1 1-1-1z"/><path fill="#444b19" d="M338 358l1 1-1-1z"/><path fill="#b9867c" d="M194.7 359.3c-129.8 101.8-65 51 0 0z"/><path fill="#5a081a" d="M320 361l1 1-1-1z"/><path fill="#926a61" d="M199 362l1 1-1-1z"/><path fill="#a30127" d="M319 362l1 1-1-1z"/><path fill="#926a61" d="M200 363l1 1-1-1z"/><path fill="#5a081a" d="M229 363l1 1-1-1z"/><path fill="#444b19" d="M161 364l1 1-1-1z"/><path fill="#926a61" d="M162 364l1 1-1-1m39 0l-1 2h2c0-2 .3-1.4-1-2z"/><path fill="#444b19" d="M163.7 365.3c-109 97.8-54.6 49 0 0z"/><path fill="#b9867c" d="M199 365l1 1-1-1z"/><path fill="#5a081a" d="M311.7 365.3c-207.8 97.8-104 49 0 0z"/><path fill="#444b19" d="M196 366c-130.7 97.3-65.3 48.7 0 0z"/><path fill="#576e57" d="M134 367l1 1-1-1z"/><path fill="#b9867c" d="M191 367l1 1-1-1z"/><path fill="#a30127" d="M244 367l1 1-1-1m61 0l1 1-1-1z"/><path fill="#444b19" d="M366 367l1 1-1-1z"/><path fill="#926a61" d="M364 368l1 1-1-1z"/><path fill="#5a081a" d="M298 369l1 1-1-1z"/><path fill="#95bb95" d="M357 385c-17 3.2-27 3-31-16-12 1.6-23.6 7.8-36 9.6-4 .6-11-1-14.3 2-5 4.8-5.4 14-5.7 20.4-.3 4.7-2.4 9.3-1.6 14 1.7 10.3 13.3 21.2 19.7 29 5 5.7 11 14.3 18 16.5 9 2.4 17-4.7 23-8.8 10-6 20-13.5 25-23.7 3-4.8 1-11.8 1-17 1-8.7 2-17.3 2-26z"/><path fill="#444b19" d="M358 370l1 1-1-1z"/><path fill="#576e57" d="M305 375l1 1-1-1z"/><path fill="#9fc79f" d="M157 384c0 14-.5 26 5.2 39 4.8 11 11 21 19 30 7 7.7 14.8 9 24.8 9 17.2 0 33.7-6.2 42.5-22 11-20 3.6-55-21.5-61.3-8-2-23.7 6.3-32 8-13.7 3-24.8-.4-38-2.7z"/><path fill="#779375" d="M290 378l1 1-1-1zm-61 1l1 1-1-1z"/><path fill="#576e57" d="M216 380c-144 88-72 44 0 0z"/><path fill="#444b19" d="M274.7 381.3c-183 87-91.6 43.6 0 0z"/><path fill="#779375" d="M232.3 381.7c-155 87-77.4 43.4 0 0z"/><path fill="#95bb95" d="M211 382c-140.7 86.7-70.3 43.3 0 0z"/><path fill="#444b19" d="M273 385c-182 84.7-91 42.3 0 0z"/><path fill="#779375" d="M208 383l1 1-1-1m27 0l1 1-1-1m1 1l1 1-1-1"/><path fill="#576e57" d="M162 385l1 1-1-1z"/><path fill="#444b19" d="M238 385l1 1-1-1zm1 1l1 1-1-1m33 0l1 1-1-1"/><path fill="#9fc79f" d="M137 387l1 1-1-1z"/><path fill="#779375" d="M191 387l1 1-1-1z"/><path fill="#576e57" d="M240 387l1 1-1-1m1 1l1 1-1-1m1 1l1 1-1-1m-106 1l1 1-1-1m107 0l1 1-1-1z"/><path fill="#9fc79f" d="M136 391l1 1-1-1z"/><path fill="#576e57" d="M244 391l1 1-1-1m2 3l1 1z"/><path fill="#779375" d="M155 395l1 1-1-1z"/><path fill="#444b19" d="M251 403l1 1-1-1z"/><path fill="#576e57" d="M365 406c-1 6.8 1.4 18.2-1.5 24.2-7.2 15.3-24.4 25.4-38.5 33.7-6.6 3-13.2 7-21 5-16.8-6-21-26-35-34 0 9 .3 16 3.7 25 17.6 42 71.5 11 89.5-14 7.4-11 13.3-30 2.8-40m-208 3l1 1-1-1z"/><path fill="#779375" d="M268 416l1 1-1-1zm-15 9l1 1z"/><path fill="#444b19" d="M274 426l1 1z"/><path fill="#779375" d="M275 427l1 1-1-1zm3 4l1 1-1-1z"/><path fill="#576e57" d="M155 432c2.6 11 11 20.8 17.3 30 2 3.3 4.5 8.6 8 10.4 4.6 2.4 11.7 2.2 16.7 2.8 15.3 1.8 33.3 2.6 48-2.5 5.6-2 11.8-4 14.7-9.7 3-5.7-.6-14-1.7-20-5.6 6-9.4 12.4-16 17.5-14.2 11-43 17.8-59 6-12.4-9-17.4-24.2-28-34.5m11 0l1 1-1-1m113 0l1 1-1-1z"/><path fill="#444b19" d="M362 432l1 1-1-1z"/><path fill="#576e57" d="M167 433l1 1-1-1zm182 0l1 1-1-1z"/><path fill="#444b19" d="M280 434l1 1-1-1m1 1l1 1-1-1z"/><path fill="#576e57" d="M282 436l1 1-1-1z"/><path fill="#444b19" d="M169 437l1 1-1-1zm188 0l1 1-1-1z"/><path fill="#779375" d="M170 438l1 1-1-1"/><path fill="#444b19" d="M356 438l1 1-1-1m-186 1l1 1-1-1z"/><path fill="#576e57" d="M284 439l1 1-1-1z"/><path fill="#444b19" d="M355 439l1 1-1-1m-197 1l1 1-1-1m13 0l1 1-1-1z"/><path fill="#576e57" d="M248 440l1 1-1-1z"/><path fill="#444b19" d="M285 440l1 1-1-1z"/><path fill="#779375" d="M343 440l1 1-1-1z"/><path fill="#444b19" d="M354 440l1 1-1-1m-11 1l1 1-1-1m-54 4l1 1-1-1m-30 7c-172.7 40-86.3 20 0 0z"/><path fill="#576e57" d="M290 446l1 1-1-1zm-54 7l1 1-1-1m90 0l1 1-1-1z"/><path fill="#444b19" d="M341 453l1 1-1-1zm-44 1l1 1-1-1zm58 0l1 1-1-1z"/><path fill="#576e57" d="M233 455l1 1-1-1z"/><path fill="#444b19" d="M248 455l1 1-1-1m38 0l1 1-1-1m12 0l1 1-1-1z"/><path fill="#576e57" d="M320 456l1 1-1-1z"/><path fill="#444b19" d="M321 456l1 1-1-1z"/><path fill="#779375" d="M229 457l1 1-1-1z"/><path fill="#444b19" d="M288 457l1 1-1-1z"/><path fill="#779375" d="M319 457l1 1-1-1z"/><path fill="#444b19" d="M289 458l1 1z"/><path fill="#9fc79f" d="M375 459l1 1-1-1z"/><path fill="#576e57" d="M200 462c-133.3 33.3-66.7 16.7 0 0z"/></svg> \ No newline at end of file
diff --git a/haunt/static/image/tor.svg b/haunt/static/image/tor.svg
new file mode 100644
index 0000000..ff0f894
--- /dev/null
+++ b/haunt/static/image/tor.svg
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="500" height="500" viewBox="0 0 500 500" xml:space="preserve">
+<defs>
+</defs>
+<rect x="0" y="0" width="100%" height="100%" fill="transparent"></rect>
+<g transform="matrix(0 0 0 0 0 0)" id="4fc577b5-c66b-46cc-95ea-aa650b6bee37" >
+</g>
+<g transform="matrix(1 0 0 1 250 250)" id="1e5c576a-bbc5-453b-bf9f-d6e354a4a78e" >
+<rect style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,255,255); fill-rule: nonzero; opacity: 1; visibility: hidden;" vector-effect="non-scaling-stroke" x="-250" y="-250" rx="0" ry="0" width="500" height="500" />
+</g>
+<g transform="matrix(2.58 0 0 2.58 302.85 86.5)" >
+<path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(171,205,3); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-275.75, -93.3)" d="M 264.513 77.977773 L 259.596 97.50677400000001 C 266.561 83.713773 277.623 73.33477300000001 290.325 64.183773 C 281.038 74.972773 272.57099999999997 85.76277400000001 267.381 96.551774 C 276.12199999999996 84.259773 287.86699999999996 77.43177299999999 301.114 72.92477299999999 C 283.496 88.63077399999999 269.51171999999997 105.48405 258.85871999999995 122.41904999999998 L 250.39171999999994 118.73204999999999 C 251.89271999999994 105.21104999999999 257.0009999999999 91.36277399999999 264.5129999999999 77.97777299999998 z" stroke-linecap="round" />
+</g>
+<g transform="matrix(2.58 0 0 2.58 202.88 314.38)" >
+<path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,252,219); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-237.32, -181.37)" d="M 241.90113 115.14152 L 258.01713 121.82746 C 258.01713 125.92546 257.684 138.42449 260.24651 142.11149 C 287.0494 176.63059 282.54 245.82478 254.817 247.59978 C 212.60044 247.59978 196.5 218.92078 196.5 192.56177000000002 C 196.5 168.52477000000002 225.316 152.54577000000003 242.525 138.34277000000003 C 246.895 134.51877000000002 246.13613 126.06752000000003 241.90113 115.14152000000003 z" stroke-linecap="round" />
+</g>
+<g transform="matrix(2.58 0 0 2.58 329.25 322.02)" >
+<path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(125,70,152); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-285.93, -184.3)" d="M 258.02197 121.58695 L 263.83 124.54977 C 263.284 128.37277 264.103 136.84177 267.926 139.02577 C 284.86199999999997 149.54176999999999 300.84 161.01377 307.123 172.48577 C 329.521 212.91178 291.417 250.33178 258.503 246.78078 C 276.394 233.53278 281.584 206.35577 274.892 176.71877 C 272.161 165.10977 267.926 154.59377 260.414 142.71177 C 257.15979 136.87931 258.29597 129.64595 258.02197 121.58695 z" stroke-linecap="round" />
+</g>
+<g transform="matrix(2.58 0 0 2.58 250 311.11)" >
+<path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-255.61, -180.13)" d="M 255.226 120.58877 L 267.244 122.22776999999999 C 263.69300000000004 133.97277 274.21000000000004 142.16676999999999 277.624 144.07977 C 285.27201 148.31377 292.64701 152.68376999999998 298.52001 158.00977 C 309.58301 168.11577 315.86501 182.31977 315.86501 197.34277 C 315.86501 212.22877 309.03601 226.56877 297.56401 236.12877 C 286.77501 245.14277 271.889 248.96677 257.412 248.96677 C 248.39799999999997 248.96677 240.33999999999997 248.55777 231.59999999999997 245.68877 C 211.66099999999997 238.99677 196.77399999999997 221.92577 195.54499999999996 201.43877 C 194.45199999999997 185.45977 198.00299999999996 173.30477000000002 210.43199999999996 160.60377 C 216.84999999999997 153.91177 229.82499999999996 146.26377 238.70299999999997 140.11777 C 243.07399999999998 137.11277 247.71699999999998 128.64477 238.83899999999997 112.66677000000001 L 240.61499999999998 111.30077000000001 L 253.77158999999997 120.11280000000002 L 242.664 115.53477000000002 C 243.61999999999998 116.90077000000002 246.21499999999997 123.04677000000002 246.762 124.82177000000003 C 247.991 129.87477000000004 247.445 134.79277000000002 246.352 136.97677000000002 C 240.75300000000001 147.08377000000002 231.193 149.81477 224.228 155.55077000000003 C 211.936 165.65677000000002 198.55200000000002 173.71477000000004 200.054 201.43877000000003 C 200.737 215.09577000000004 211.39000000000001 231.75777000000002 227.368 239.54277000000002 C 236.382 243.91377000000003 246.762 245.68877 257.278 246.23477000000003 C 266.701 246.64477000000002 284.72901 241.04477000000003 294.56201000000004 232.85077 C 305.07801000000006 224.11077 310.95101000000005 210.86277 310.95101000000005 197.34277 C 310.95101000000005 183.68477000000001 305.48801000000003 170.71077 295.24501000000004 161.55977000000001 C 289.37201000000005 156.23377000000002 279.67600000000004 149.81477 273.66700000000003 146.39977000000002 C 267.658 142.98577000000003 260.146 133.42577000000003 262.60400000000004 124.27577000000002 z" stroke-linecap="round" />
+</g>
+<g transform="matrix(2.58 0 0 2.58 186.45 348.06)" >
+<path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-230.86, -194.27)" d="M 251.539 140.80177 C 250.30999999999997 147.08477 248.944 158.41977 243.481 162.65377 C 241.159 164.29177 238.837 165.93177 236.379 167.56977 C 226.546 174.26277000000002 216.712 180.54377 212.206 196.65977 C 211.25 200.07477 212.07 203.76177 212.89 207.17577 C 215.34799999999998 217.00877 222.313 227.66177 227.77599999999998 233.94477 C 227.77599999999998 234.21777 228.86899999999997 234.90077 228.86899999999997 235.17377000000002 C 233.37599999999998 240.50077000000002 234.74199999999996 242.00277000000003 251.81299999999996 245.82577 L 251.40299999999996 247.73877000000002 C 241.15999999999997 245.00777000000002 232.69299999999996 242.54977000000002 227.36599999999996 236.40277 C 227.36599999999996 236.26677 226.40999999999997 235.30977000000001 226.40999999999997 235.30977000000001 C 220.67399999999998 228.75377 213.70799999999997 217.82877000000002 211.11399999999998 207.58577000000002 C 210.158 203.48777 209.33899999999997 200.34777000000003 210.43099999999998 196.11277 C 215.07399999999998 179.45177 225.18099999999998 172.89577000000003 235.42399999999998 165.93077000000002 C 237.74599999999998 164.42877000000001 240.47699999999998 163.06177000000002 242.66199999999998 161.28677000000002 C 246.89499999999998 158.14677000000003 249.21599999999998 148.58577000000002 251.539 140.80177000000003 z" stroke-linecap="round" />
+</g>
+<g transform="matrix(2.58 0 0 2.58 224.13 380.53)" >
+<path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-245.38, -206.7)" d="M 255.90625 166.74951 C 256.04325 173.85151 255.35 177.41425999999998 257.125 182.46826 C 258.217 185.47225999999998 261.907 189.56975999999997 263 193.53076 C 264.502 198.85775999999998 266.138 204.72976999999997 266 208.28077 C 266 212.37876 265.74375 220.02326 263.96875 228.21826 C 262.61513 234.98934 259.49552 240.79978999999997 254.25 244.09326 C 248.87673 242.98682 242.56776 241.09805 238.84375 237.90576 C 231.60575 231.62375999999998 225.195 221.11926 224.375 211.96826 C 223.693 204.45727 230.64775 193.37975999999998 240.34375 187.78076 C 248.53775 183.00075999999999 250.44375 177.55300999999997 252.21875 168.81201 C 249.76075 176.46000999999998 247.45225 182.87125999999998 239.53125 186.96826 C 228.05925 192.97726 222.17275 203.06452 222.71875 212.62451 C 223.53775 224.91550999999998 228.46025 233.24400999999997 238.15625 239.93701 C 242.25325 242.80500999999998 249.9075 245.83576 254.6875 246.65576 L 254.6875 246.03076 C 258.31243 245.35188 263.00568 239.39809 265.34375 231.34326 C 267.39275 224.10526 268.2005 214.84125999999998 268.0625 208.96827 C 267.9255 205.55427 266.4195 198.16026 263.6875 191.46826 C 262.1855 187.78125999999997 259.878 184.09450999999999 258.375 181.49951 C 256.738 178.90250999999998 256.72625 173.30451 255.90625 166.74951 z" stroke-linecap="round" />
+</g>
+<g transform="matrix(2.58 0 0 2.58 240.35 411.95)" >
+<path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-251.56, -218.72)" d="M 255.09375 193.53076 C 255.22975 198.31076 257.14975 204.43526999999997 257.96875 210.71827 C 258.65275 215.36226 258.35575 220.02651 258.21875 224.12451 C 258.0838 228.86774 256.50355 237.36668999999998 254.34375 241.49951 C 252.30702 240.56547999999998 251.51081 239.50028999999998 250.1875 237.78076 C 248.5495 235.45875999999998 247.43675 233.13675999999998 246.34375 230.40576 C 245.52475 228.35675999999998 244.56725 226.01175999999998 244.15625 223.28076 C 243.61025 219.18375999999998 243.76325 212.77426 248.40625 206.21827 C 251.95725 201.02826 252.771 200.63351 254 194.62451 C 252.36 199.95050999999998 251.1375 200.49351 247.3125 204.99952 C 243.0795 209.91652 242.375 217.15876 242.375 223.03076 C 242.375 225.48976 243.3555 228.21801 244.3125 230.81201 C 245.4045 233.54401 246.34175 236.26400999999998 247.84375 238.31201 C 250.10171 241.63282999999998 252.99173 243.52122999999997 254.40625 243.87451 C 254.41525 243.87651 254.42825 243.87250999999998 254.43745 243.87451 C 254.46775000000002 243.88151 254.50235 243.90000999999998 254.53115000000003 243.90571 L 254.53115000000003 243.74946 C 257.18097 240.79509 258.77559 237.86012 259.3124 234.90571 C 259.9954 231.35471 260.1524 227.79596 260.5624 223.56196 C 260.9714 220.01096 260.67465000000004 215.22796 259.71865 210.31197 C 258.35365 204.16597000000002 256.04965000000004 197.89971 255.09365000000003 193.53071 z" stroke-linecap="round" />
+</g>
+<g transform="matrix(2.58 0 0 2.58 272.78 340.19)" >
+<path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-264.05, -191.27)" d="M 255.499 135.06577 C 255.636 142.16676999999999 256.182 155.41576999999998 258.094 160.60476999999997 C 258.64 162.37976999999998 263.693 170.16476999999998 267.243 179.58776999999998 C 269.702 186.14377 270.248 192.15276999999998 270.658 193.92776999999998 C 272.297 201.71276999999998 270.248 214.82376999999997 267.516 227.25176999999996 C 266.151 233.94376999999997 261.507 242.27476999999996 256.18100000000004 245.55276999999995 L 255.08900000000003 247.46476999999996 C 258.09400000000005 247.32776999999996 265.468 240.08976999999996 268.06300000000005 231.07576999999995 C 272.434 215.77976999999996 274.20900000000006 208.67776999999995 272.16100000000006 191.74276999999995 C 271.88800000000003 190.10276999999996 271.20500000000004 184.50476999999995 268.61000000000007 178.49476999999996 C 264.78600000000006 169.34376999999995 259.3230000000001 160.60376999999997 258.6410000000001 158.82776999999996 C 257.41100000000006 155.96076999999997 255.77200000000008 143.53276999999997 255.49900000000008 135.06576999999996 z" stroke-linecap="round" />
+</g>
+<g transform="matrix(2.58 0 0 2.58 279.5 327.55)" >
+<path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-266.65, -186.41)" d="M 258.06151 125.35303 C 257.65636 132.65115 257.548 135.33877 258.913 140.66477 C 260.415 146.53777 268.064 155.00477 271.205 164.70177 C 277.214 183.27577000000002 275.712 207.58577000000002 271.341 226.56877 C 269.70300000000003 233.25977 261.91700000000003 242.95777 254.133 246.09777 L 259.869 247.46377 C 263.01000000000005 247.32677 271.067 239.81577000000001 274.209 231.21177 C 279.261 217.69077 280.218 201.57577 278.169 184.64077 C 278.032 183.00177 275.29999999999995 168.38877 272.70599999999996 162.24277 C 269.018 153.09277 262.462 144.89777 261.78 143.12377 C 260.55199999999996 140.11877 257.85348999999997 133.88015000000001 258.06151 125.35303 z" stroke-linecap="round" />
+</g>
+<g transform="matrix(2.58 0 0 2.58 246.81 319.25)" id="rect2556" >
+<rect style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" x="-0.275" y="-63.01" rx="0" ry="0" width="0.55" height="126.02" />
+</g>
+</svg>