tor-commits
Threads by month
- ----- 2025 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
December 2014
- 20 participants
- 797 discussions

[stem/master] Changing HiddenServicePort to be a three value tuple
by atagar@torproject.org 20 Dec '14
by atagar@torproject.org 20 Dec '14
20 Dec '14
commit 590d548cad596df44674d68099ba69a7b230a5e7
Author: Damian Johnson <atagar(a)torproject.org>
Date: Sat Dec 13 14:32:07 2014 -0800
Changing HiddenServicePort to be a three value tuple
Our Controller hidden service method's HiddenServicePort was a string. This is
clunky because it left parsing that string to our caller. The string might be
three different formats, anything from a simple port to two ports and an
address.
Our get_hidden_service_conf() now provides a list of three value tuples...
"HiddenServicePort": [
(port, target_address, target_port),
]
This both normalizes and means no parsing necessary.
---
stem/control.py | 110 ++++++++++++++++++++++++++------------
test/integ/control/controller.py | 16 +++---
2 files changed, 83 insertions(+), 43 deletions(-)
diff --git a/stem/control.py b/stem/control.py
index cace3ad..a90dfcb 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -2106,8 +2106,8 @@ class Controller(BaseController):
"/var/lib/tor/hidden_service_with_two_ports/": {
"HiddenServiceAuthorizeClient": "stealth a, b",
"HiddenServicePort": [
- "8020 127.0.0.1:8020", # the ports order is kept
- "8021 127.0.0.1:8021"
+ (8020, "127.0.0.1", 8020), # the ports order is kept
+ (8021, "127.0.0.1", 8021)
],
"HiddenServiceVersion": "2"
},
@@ -2150,7 +2150,25 @@ class Controller(BaseController):
directory = v
service_dir_map[directory] = {'HiddenServicePort': []}
elif k == 'HiddenServicePort':
- service_dir_map[directory]['HiddenServicePort'].append(v)
+ port = target_port = v
+ target_address = '127.0.0.1'
+
+ if not v.isdigit():
+ port, target = v.split()
+
+ if target.isdigit():
+ target_port = target
+ else:
+ target_address, target_port = target.split(':')
+
+ if not stem.util.connection.is_valid_port(port):
+ raise stem.ProtocolError('GETCONF provided an invalid HiddenServicePort port (%s): %s' % (port, content))
+ elif not stem.util.connection.is_valid_ipv4_address(target_address):
+ raise stem.ProtocolError('GETCONF provided an invalid HiddenServicePort target address (%s): %s' % (target_address, content))
+ elif not stem.util.connection.is_valid_port(target_port):
+ raise stem.ProtocolError('GETCONF provided an invalid HiddenServicePort target port (%s): %s' % (target_port, content))
+
+ service_dir_map[directory]['HiddenServicePort'].append((int(port), target_address, int(target_port)))
else:
service_dir_map[directory][k] = v
@@ -2162,6 +2180,22 @@ class Controller(BaseController):
the same format as
:func:`~stem.control.Controller.get_hidden_service_conf`.
+ For convenience the HiddenServicePort entries can be an integer, string, or
+ tuple. If an **int** then we treat it as just a port. If a **str** we pass
+ that directly as the HiddenServicePort. And finally, if a **tuple** then
+ it's expected to be the **(port, target_address, target_port)** as provided
+ by :func:`~stem.control.Controller.get_hidden_service_conf`.
+
+ This is to say the following three are equivalent...
+
+ ::
+
+ "HiddenServicePort": [
+ 80,
+ '80 127.0.0.1:80',
+ (80, '127.0.0.1', 80),
+ ]
+
.. versionadded:: 1.3.0
:param dict conf: configuration dictionary
@@ -2183,14 +2217,22 @@ class Controller(BaseController):
for k, v in conf[directory].items():
if k == 'HiddenServicePort':
- for port in v:
- hidden_service_options.append(('HiddenServicePort', port))
+ for entry in v:
+ if isinstance(entry, int):
+ entry = '%s 127.0.0.1:%s' % (entry, entry)
+ elif isinstance(entry, str):
+ pass # just pass along what the user gave us
+ elif isinstance(entry, tuple):
+ port, target_address, target_port = entry
+ entry = '%s %s:%s' % (port, target_address, target_port)
+
+ hidden_service_options.append(('HiddenServicePort', entry))
else:
hidden_service_options.append((k, str(v)))
self.set_options(hidden_service_options)
- def create_hidden_service(self, path, port, target = None):
+ def create_hidden_service(self, path, port, target_address = None, target_port = None):
"""
Create a new hidden service. If the directory is already present, a
new port is added.
@@ -2199,7 +2241,9 @@ class Controller(BaseController):
:param str path: path for the hidden service's data directory
:param int port: hidden service port
- :param str target: optional ipaddr:port target e.g. '127.0.0.1:8080'
+ :param str target_address: address of the service, by default 127.0.0.1
+ :param int target_port: port of the service, by default this is the same as
+ **port**
:returns: **True** if the hidden service is created, **False** if the
hidden service port is already in use
@@ -2209,26 +2253,31 @@ class Controller(BaseController):
if not stem.util.connection.is_valid_port(port):
raise ValueError("%s isn't a valid port number" % port)
+ elif target_address and not stem.util.connection.is_valid_ipv4_address(target_address):
+ raise ValueError("%s isn't a valid IPv4 address" % target_address)
+ elif target_port is not None and not stem.util.connection.is_valid_port(target_port):
+ raise ValueError("%s isn't a valid port number" % target_port)
+
+ port = int(port)
+ target_address = target_address if target_address else '127.0.0.1'
+ target_port = port if target_port is None else int(target_port)
- port, conf = str(port), self.get_hidden_service_conf()
+ conf = self.get_hidden_service_conf()
if path in conf:
ports = conf[path]['HiddenServicePort']
- if target is None:
- if port in ports or '%s 127.0.0.1:%s' % (port, port) in ports:
- return False
- elif '%s %s' % (port, target) in ports:
+ if (port, target_address, target_port) in ports:
return False
else:
conf[path] = {'HiddenServicePort': []}
- conf[path]['HiddenServicePort'].append('%s %s' % (port, target) if target else port)
+ conf[path]['HiddenServicePort'].append((port, target_address, target_port))
self.set_hidden_service_conf(conf)
return True
- def remove_hidden_service(self, path, port = None, target = None):
+ def remove_hidden_service(self, path, port = None):
"""
Discontinues a given hidden service.
@@ -2236,7 +2285,6 @@ class Controller(BaseController):
:param str path: path for the hidden service's data directory
:param int port: hidden service port
- :param str target: optional ipaddr:port target e.g. '127.0.0.1:8080'
:returns: **True** if the hidden service is discontinued, **False** if it
wasn't running in the first place
@@ -2244,36 +2292,28 @@ class Controller(BaseController):
:raises: :class:`stem.ControllerError` if the call fails
"""
- if not stem.util.connection.is_valid_port(port):
+ if port and not stem.util.connection.is_valid_port(port):
raise ValueError("%s isn't a valid port number" % port)
- port, conf = str(port), self.get_hidden_service_conf()
+ port = int(port) if port else None
+ conf = self.get_hidden_service_conf()
if path not in conf:
return False
- if port:
- if not target:
- longport = '%s 127.0.0.1:%s' % (port, port)
+ if not port:
+ del conf[path]
+ else:
+ to_remove = [entry for entry in conf[path]['HiddenServicePort'] if entry[0] == port]
- if port in conf[path]['HiddenServicePort']:
- conf[path]['HiddenServicePort'].remove(port)
- elif longport in conf[path]['HiddenServicePort']:
- conf[path]['HiddenServicePort'].remove(longport)
- else:
- return False # wasn't configured to be a hidden service
- else:
- longport = '%s %s' % (port, target)
+ if not to_remove:
+ return False
- if longport in conf[path]['HiddenServicePort']:
- conf[path]['HiddenServicePort'].remove(longport)
- else:
- return False # wasn't configured to be a hidden service
+ for entry in to_remove:
+ conf[path]['HiddenServicePort'].remove(entry)
if not conf[path]['HiddenServicePort']:
- del(conf[path]) # no ports left, drop it entirely
- else:
- del(conf[path])
+ del conf[path] # no ports left
self.set_hidden_service_conf(conf)
return True
diff --git a/test/integ/control/controller.py b/test/integ/control/controller.py
index adaaf8d..386eb8e 100644
--- a/test/integ/control/controller.py
+++ b/test/integ/control/controller.py
@@ -482,17 +482,17 @@ class TestController(unittest.TestCase):
initialconf = {
'test_hidden_service1/': {
'HiddenServicePort': [
- '8020 127.0.0.1:8020',
- '8021 127.0.0.1:8021',
+ (8020, '127.0.0.1', 8020),
+ (8021, '127.0.0.1', 8021),
],
'HiddenServiceVersion': '2',
},
'test_hidden_service2/': {
'HiddenServiceAuthorizeClient': 'stealth a, b',
'HiddenServicePort': [
- '8030 127.0.0.1:8030',
- '8031 127.0.0.1:8031',
- '8032 127.0.0.1:8032',
+ (8030, '127.0.0.1', 8030),
+ (8031, '127.0.0.1', 8031),
+ (8032, '127.0.0.1', 8032),
]
},
'test_hidden_service_empty/': {
@@ -506,13 +506,13 @@ class TestController(unittest.TestCase):
# add already existing services, with/without explicit target
self.assertFalse(controller.create_hidden_service('test_hidden_service1/', 8020))
- self.assertFalse(controller.create_hidden_service('test_hidden_service1/', 8021, target = '127.0.0.1:8021'))
+ self.assertFalse(controller.create_hidden_service('test_hidden_service1/', 8021, target_port = 8021))
self.assertDictEqual(initialconf, controller.get_hidden_service_conf())
# add a new service, with/without explicit target
self.assertTrue(controller.create_hidden_service('test_hidden_serviceX/', 8888))
- self.assertTrue(controller.create_hidden_service('test_hidden_serviceX/', 8989, target = '127.0.0.1:8021'))
+ self.assertTrue(controller.create_hidden_service('test_hidden_serviceX/', 8989, target_port = 8021))
conf = controller.get_hidden_service_conf()
self.assertEqual(4, len(conf))
@@ -525,7 +525,7 @@ class TestController(unittest.TestCase):
# remove a service completely, it should now be gone
- controller.remove_hidden_service('test_hidden_serviceX/', 8989, target = '127.0.0.1:8021')
+ controller.remove_hidden_service('test_hidden_serviceX/', 8989)
self.assertEqual(3, len(controller.get_hidden_service_conf()))
finally:
controller.set_hidden_service_conf({}) # drop hidden services created during the test
1
0

[stem/master] Having create_hidden_service() return the *.onion address
by atagar@torproject.org 20 Dec '14
by atagar@torproject.org 20 Dec '14
20 Dec '14
commit 260a73ca78a6ffbd6e8b781c3c4558df0f40204e
Author: Damian Johnson <atagar(a)torproject.org>
Date: Sat Dec 13 16:11:41 2014 -0800
Having create_hidden_service() return the *.onion address
This isn't reliable since tor restricts the hidden service directory to only be
readable by the tor user. This sucks, since it's handy to have the hidden
service address and this is the only way to get it. But oh well, more useful
than returning a boolean as we did before.
---
stem/control.py | 35 +++++++++++++++++++++++++++++++----
test/integ/control/controller.py | 18 +++++++++++-------
2 files changed, 42 insertions(+), 11 deletions(-)
diff --git a/stem/control.py b/stem/control.py
index a90dfcb..77a5e3b 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -2237,6 +2237,10 @@ class Controller(BaseController):
Create a new hidden service. If the directory is already present, a
new port is added.
+ This method returns our *.onion address by reading the hidden service
+ directory. However, this directory is only readable by the tor user, so if
+ unavailable this method returns None.
+
.. versionadded:: 1.3.0
:param str path: path for the hidden service's data directory
@@ -2245,8 +2249,8 @@ class Controller(BaseController):
:param int target_port: port of the service, by default this is the same as
**port**
- :returns: **True** if the hidden service is created, **False** if the
- hidden service port is already in use
+ :returns: **str** of the onion address for the hidden service if it can be
+ retrieved, **None** otherwise
:raises: :class:`stem.ControllerError` if the call fails
"""
@@ -2268,14 +2272,37 @@ class Controller(BaseController):
ports = conf[path]['HiddenServicePort']
if (port, target_address, target_port) in ports:
- return False
+ return
else:
conf[path] = {'HiddenServicePort': []}
conf[path]['HiddenServicePort'].append((port, target_address, target_port))
self.set_hidden_service_conf(conf)
- return True
+ if self.is_localhost():
+ if not os.path.isabs(path):
+ cwd = stem.util.system.cwd(self.get_pid(None))
+
+ if cwd:
+ path = stem.util.system.expand_path(path, cwd)
+
+ if os.path.isabs(path):
+ start_time = time.time()
+ hostname_path = os.path.join(path, 'hostname')
+
+ while not os.path.exists(hostname_path):
+ wait_time = time.time() - start_time
+
+ if wait_time >= 3:
+ return
+ else:
+ time.sleep(0.05)
+
+ try:
+ with open(hostname_path) as hostname_file:
+ return hostname_file.read().strip()
+ except:
+ pass
def remove_hidden_service(self, path, port = None):
"""
diff --git a/test/integ/control/controller.py b/test/integ/control/controller.py
index 386eb8e..8b9759c 100644
--- a/test/integ/control/controller.py
+++ b/test/integ/control/controller.py
@@ -505,27 +505,31 @@ class TestController(unittest.TestCase):
# add already existing services, with/without explicit target
- self.assertFalse(controller.create_hidden_service('test_hidden_service1/', 8020))
- self.assertFalse(controller.create_hidden_service('test_hidden_service1/', 8021, target_port = 8021))
+ self.assertEqual(None, controller.create_hidden_service('test_hidden_service1/', 8020))
+ self.assertEqual(None, controller.create_hidden_service('test_hidden_service1/', 8021, target_port = 8021))
self.assertDictEqual(initialconf, controller.get_hidden_service_conf())
# add a new service, with/without explicit target
- self.assertTrue(controller.create_hidden_service('test_hidden_serviceX/', 8888))
- self.assertTrue(controller.create_hidden_service('test_hidden_serviceX/', 8989, target_port = 8021))
+ hs_path = os.path.join(os.getcwd(), 'test_hidden_serviceX')
+ hs_address1 = controller.create_hidden_service(hs_path, 8888)
+ hs_address2 = controller.create_hidden_service(hs_path, 8989, target_port = 8021)
+
+ self.assertEqual(hs_address1, hs_address2)
+ self.assertTrue(hs_address1.endswith('.onion'))
conf = controller.get_hidden_service_conf()
self.assertEqual(4, len(conf))
- self.assertEqual(2, len(conf['test_hidden_serviceX/']['HiddenServicePort']))
+ self.assertEqual(2, len(conf[hs_path]['HiddenServicePort']))
# remove a hidden service, the service dir should still be there
- controller.remove_hidden_service('test_hidden_serviceX/', 8888)
+ controller.remove_hidden_service(hs_path, 8888)
self.assertEqual(4, len(controller.get_hidden_service_conf()))
# remove a service completely, it should now be gone
- controller.remove_hidden_service('test_hidden_serviceX/', 8989)
+ controller.remove_hidden_service(hs_path, 8989)
self.assertEqual(3, len(controller.get_hidden_service_conf()))
finally:
controller.set_hidden_service_conf({}) # drop hidden services created during the test
1
0

[stem/master] Having create_hidden_service() provide a namedtuple
by atagar@torproject.org 20 Dec '14
by atagar@torproject.org 20 Dec '14
20 Dec '14
commit 5ae9899ebe5251a46bae86ea3650ec337787dc85
Author: Damian Johnson <atagar(a)torproject.org>
Date: Sun Dec 14 10:24:28 2014 -0800
Having create_hidden_service() provide a namedtuple
On reflection it's handy for this method to return more than just a
maybe-read-maybe-not hostname. Instead providing back a namedtuple with the
hidden service attributes. Extra advantage is that this can be used as a
boolean to determine 'did we create or update a hidden service'.
---
stem/control.py | 65 ++++++++++++++++++++++++--------------
test/integ/control/controller.py | 12 ++++---
2 files changed, 48 insertions(+), 29 deletions(-)
diff --git a/stem/control.py b/stem/control.py
index 77a5e3b..4d8b170 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -357,6 +357,12 @@ AccountingStats = collections.namedtuple('AccountingStats', [
'write_limit',
])
+CreateHiddenServiceOutput = collections.namedtuple('CreateHiddenServiceOutput', [
+ 'path',
+ 'hostname',
+ 'config',
+])
+
def with_default(yields = False):
"""
@@ -2235,11 +2241,18 @@ class Controller(BaseController):
def create_hidden_service(self, path, port, target_address = None, target_port = None):
"""
Create a new hidden service. If the directory is already present, a
- new port is added.
+ new port is added. This provides a **namedtuple** of the following...
+
+ * path (str) - hidden service directory
- This method returns our *.onion address by reading the hidden service
- directory. However, this directory is only readable by the tor user, so if
- unavailable this method returns None.
+ * hostname (str) - onion address of the service, this is only retrieved
+ if we can read the hidden service directory
+
+ * config (dict) - tor's new hidden service configuration
+
+ Our *.onion address is fetched by reading the hidden service directory.
+ However, this directory is only readable by the tor user, so if unavailable
+ the **hostname** will be **None**.
.. versionadded:: 1.3.0
@@ -2249,8 +2262,7 @@ class Controller(BaseController):
:param int target_port: port of the service, by default this is the same as
**port**
- :returns: **str** of the onion address for the hidden service if it can be
- retrieved, **None** otherwise
+ :returns: **CreateHiddenServiceOutput** if we create or update a hidden service, **None** otherwise
:raises: :class:`stem.ControllerError` if the call fails
"""
@@ -2268,41 +2280,46 @@ class Controller(BaseController):
conf = self.get_hidden_service_conf()
- if path in conf:
- ports = conf[path]['HiddenServicePort']
-
- if (port, target_address, target_port) in ports:
- return
- else:
- conf[path] = {'HiddenServicePort': []}
+ if path in conf and (port, target_address, target_port) in conf[path]['HiddenServicePort']:
+ return None
- conf[path]['HiddenServicePort'].append((port, target_address, target_port))
+ conf.setdefault(path, OrderedDict()).setdefault('HiddenServicePort', []).append((port, target_address, target_port))
self.set_hidden_service_conf(conf)
+ hostname = None
+
if self.is_localhost():
- if not os.path.isabs(path):
+ hostname_path = os.path.join(path, 'hostname')
+
+ if not os.path.isabs(hostname_path):
cwd = stem.util.system.cwd(self.get_pid(None))
if cwd:
- path = stem.util.system.expand_path(path, cwd)
+ hostname_path = stem.util.system.expand_path(hostname_path, cwd)
- if os.path.isabs(path):
+ if os.path.isabs(hostname_path):
start_time = time.time()
- hostname_path = os.path.join(path, 'hostname')
while not os.path.exists(hostname_path):
wait_time = time.time() - start_time
if wait_time >= 3:
- return
+ break
else:
time.sleep(0.05)
- try:
- with open(hostname_path) as hostname_file:
- return hostname_file.read().strip()
- except:
- pass
+ if os.path.exists(hostname_path):
+ try:
+ with open(hostname_path) as hostname_file:
+ hostname = hostname_file.read().strip()
+ except:
+ pass
+
+ return CreateHiddenServiceOutput(
+ path = path,
+ hostname = hostname,
+ config = conf,
+ )
def remove_hidden_service(self, path, port = None):
"""
diff --git a/test/integ/control/controller.py b/test/integ/control/controller.py
index 8b9759c..e482281 100644
--- a/test/integ/control/controller.py
+++ b/test/integ/control/controller.py
@@ -512,8 +512,8 @@ class TestController(unittest.TestCase):
# add a new service, with/without explicit target
hs_path = os.path.join(os.getcwd(), 'test_hidden_serviceX')
- hs_address1 = controller.create_hidden_service(hs_path, 8888)
- hs_address2 = controller.create_hidden_service(hs_path, 8989, target_port = 8021)
+ hs_address1 = controller.create_hidden_service(hs_path, 8888).hostname
+ hs_address2 = controller.create_hidden_service(hs_path, 8989, target_port = 8021).hostname
self.assertEqual(hs_address1, hs_address2)
self.assertTrue(hs_address1.endswith('.onion'))
@@ -536,9 +536,11 @@ class TestController(unittest.TestCase):
# clean up the hidden service directories created as part of this test
- shutil.rmtree('test_hidden_service1')
- shutil.rmtree('test_hidden_service2')
- shutil.rmtree('test_hidden_serviceX')
+ for path in ('test_hidden_service1', 'test_hidden_service2', 'test_hidden_serviceX'):
+ try:
+ shutil.rmtree(path)
+ except:
+ pass
def test_set_conf(self):
"""
1
0

[stem/master] remove_hidden_service() cound't drop the last hidden service
by atagar@torproject.org 20 Dec '14
by atagar@torproject.org 20 Dec '14
20 Dec '14
commit 7e0c12e1ca24a8d39735b0db72051c554b50c2ae
Author: Damian Johnson <atagar(a)torproject.org>
Date: Mon Dec 15 12:22:20 2014 -0800
remove_hidden_service() cound't drop the last hidden service
When calling remove_hidden_service() to remove our last hidden service we made
a 'SETCONF <nothing>' call, which left our hidden service configured. Calling
RESETCONF instead so we drop it for realz.
---
stem/control.py | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/stem/control.py b/stem/control.py
index 4d8b170..4d45b8d 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -2214,6 +2214,13 @@ class Controller(BaseController):
impossible or if there's a syntax error in the configuration values
"""
+ # If we're not adding or updating any hidden services then call RESETCONF
+ # so we drop existing values. Otherwise calling SETCONF is a no-op.
+
+ if not conf:
+ self.reset_conf('HiddenServiceDir')
+ return
+
# Convert conf dictionary into a list of ordered config tuples
hidden_service_options = []
1
0
commit 8dab21ce2a3e3e112c74a549cf8c4c45e89d2abe
Author: Damian Johnson <atagar(a)torproject.org>
Date: Thu Dec 18 07:24:12 2014 -0800
Hidden service tutorial page entry
Just the listing, not the tutorial (... yet).
---
docs/_static/label/over_the_river.png | Bin 0 -> 4264 bytes
docs/_static/label/resources/over_the_river.xcf | Bin 0 -> 9156 bytes
.../section/tutorials/resources/riding_hood.svg | 393 ++++++++++++++++++++
docs/_static/section/tutorials/riding_hood.png | Bin 0 -> 10579 bytes
docs/tutorials.rst | 21 +-
5 files changed, 412 insertions(+), 2 deletions(-)
diff --git a/docs/_static/label/over_the_river.png b/docs/_static/label/over_the_river.png
new file mode 100644
index 0000000..30205f9
Binary files /dev/null and b/docs/_static/label/over_the_river.png differ
diff --git a/docs/_static/label/resources/over_the_river.xcf b/docs/_static/label/resources/over_the_river.xcf
new file mode 100644
index 0000000..7c3b875
Binary files /dev/null and b/docs/_static/label/resources/over_the_river.xcf differ
diff --git a/docs/_static/section/tutorials/resources/riding_hood.svg b/docs/_static/section/tutorials/resources/riding_hood.svg
new file mode 100644
index 0000000..c283d47
--- /dev/null
+++ b/docs/_static/section/tutorials/resources/riding_hood.svg
@@ -0,0 +1,393 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ sodipodi:docname="riding_hood.svg"
+ viewBox="0 0 400.29 463.27"
+ version="1.1"
+ inkscape:version="0.48.3.1 r9886"
+ width="100%"
+ height="100%"
+ inkscape:export-filename="/home/atagar/Desktop/stem/docs/_static/section/tutorials/resources/riding_hood.png"
+ inkscape:export-xdpi="26.752357"
+ inkscape:export-ydpi="26.752357">
+ <defs
+ id="defs60" />
+ <title
+ id="title4375">Little Red Riding Hood</title>
+ <sodipodi:namedview
+ id="base"
+ fit-margin-left="0"
+ inkscape:zoom="1.8142728"
+ borderopacity="1.0"
+ inkscape:current-layer="layer2"
+ inkscape:cx="125.40397"
+ inkscape:cy="244.12298"
+ inkscape:object-paths="false"
+ inkscape:window-maximized="1"
+ showgrid="false"
+ fit-margin-right="0"
+ inkscape:document-units="px"
+ bordercolor="#666666"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:snap-smooth-nodes="false"
+ inkscape:object-nodes="false"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ pagecolor="#ffffff"
+ inkscape:window-height="1056"
+ fit-margin-top="0" />
+ <g
+ id="layer2"
+ inkscape:label="Réteg"
+ inkscape:groupmode="layer"
+ transform="translate(-169.87 -169.25)">
+ <path
+ id="path4667"
+ style="fill:#000000"
+ sodipodi:type="inkscape:offset"
+ d="m252.78 36.688c-1.4573 0.04059-2.8734 0.15596-4.25 0.40625-3.6739 0.66798-16.15 1.0553-29.562 3.3438-13.413 2.2884-28.318 6.4752-38.531 15.938-2.295 2.1263-6.259 7.0168-11.75 13.875s-12.19 15.431-18.812 23.969c-6.6229 8.5375-13.175 17.022-18.312 23.688-5.1376 6.6652-8.9765 11.653-9.8125 12.656-1.9797 2.3756-4.8228 5.4926-7.5312 8.0625s-5.7584 4.5843-6.0938 4.6875c-2.2918 0.70518-4.5933 1.6406-6.375 3.9062-0.44542 0.5664-0.90305 1.265-1.0938 2.25-0.1907 0.98496 0.0253 2.2622 0.59375 3.1875 1.1369 1.8506 2.7599 2.3759 4.5938 2.8125 3.3919 0.8076 6.6891 0.76851 9.4375 0.65625s5.0856-0.24094 5.9688-0.0937c3.1874 0.53123 7.6564 1.5604 12.688 0.21875 1.3404-0.35745 2.9243-0.42452 4.3438-0.46875 0.015 0.24253-0.0411 0.42671 0 0.6875 0.29143 1.8492 2.1097 4.2224 4.5312 4.7812 1.9862 0.45834 3.6306 0.32221 5.0312 0.0312 0.93145 1.0668 2.1949 1.9915 3.9688 2.625 2.3666 0.84522 4.423 0.97589 5.875 1.0625 1.452 0.0866 2.2018 0.14642 3 0.5 5.3663 2.377 13.308 9.5441 15.406 11.875 0.314
46 0.34941 2.0766 2.1764 2.8438 3.0312-2.2976-0.23538-4.0696-0.50247-6.3438 0.53125-3.1078 1.4126-5.7535 4.0594-8.0625 6.9062-1.1545 1.4234-2.1862 2.9031-2.9688 4.3438-0.78257 1.4406-1.4375 2.7417-1.4375 4.625 0-0.19101-0.48174 1.3631-1.5 3.1562-0.77292 1.3611-1.6685 3.0265-2.4062 4.8438-0.99498 0.34651-2.1138 0.72002-2.6562 0.875-2.1282 0.60807-3.7478 2.2316-4.6875 4.0938-0.6191 1.2268-0.91313 2.6115-1.0625 4.0625-3.2534 1.6324-6.8241 3.4184-10.031 4.9375-1.8742 0.88772-3.6159 1.6736-5 2.25-1.3841 0.57638-2.5568 0.95067-2.6562 0.96875-0.7172 0.1304-1.8422-0.16786-3.6562-0.96875-1.3148-0.58046-3.0106-1.2627-4.9375-1.75-3.68-12.2-10.47-20.29-18.53-25.12-8.3691-5.0231-17.803-6.7679-26.312-7.5-2.4651-1.0038-5.1022-1.7351-7.9062-1.9062-11.909-0.72673-23.959 3.4-33.812 11.25-23.887 5.902-37.871 29.761-34.344 57.625 0.68602 5.4195 1.7417 10.28 3.1562 14.594a3.3074 3.3074 0 0 0 0.03125 0.0312 3.3074 3.3074 0 0 0 0.15625 0.375c0.27355 0.81955 0.52605 1.6472 0.84375 2.4688 0.13801 0.35645 0.
27569 0.66257 0.375 0.90625 0.34087 0.83761 0.69598 1.6227 1.0312 2.3438-0.18396-0.39574-0.17374-0.31692 0.09375 0.25 0.39032 0.8272 0.80068 1.6036 1.2188 2.375 0.2072 0.38252 0.40253 0.7723 0.625 1.1562 0.29487 0.50873 0.57488 0.91962 0.78125 1.25 0.18752 0.30028 0.40807 0.6574 0.65625 1.0312-0.00916-0.0138 0.043968 0.0864 0.21875 0.34375 0.37265 0.54879 0.75734 1.0712 1.125 1.5625 1.0872 1.4528 2.2593 2.8359 3.5312 4.125 0.35745 0.36261 0.4888 0.45622 0.34375 0.3125 1.9178 1.8985 3.9789 3.5849 6.1875 5.0312 0.0089 0.006 0.06099 0.043 0.1875 0.125a3.3074 3.3074 0 0 0 0.03125 0c0.65919 0.42611 1.3549 0.86162 2.0938 1.2812 0.33622 0.19067 0.37494 0.20328 0.125 0.0625 0.67398 0.37973 1.3691 0.76546 2.0938 1.125 0.39629 0.19689 0.69718 0.32235 0.875 0.40625 0.45197 0.21294 0.88585 0.38982 1.2812 0.5625 0.20538 0.0899 0.52218 0.25315 0.96875 0.4375 0.64066 0.26389 1.3034 0.50604 1.9688 0.75 0.4812 0.17669 0.89332 0.31597 1.25 0.4375 0.45205 0.15382 0.87904 0.30124 1.3125 0.4375 0.24191
0.0762 0.58762 0.18117 1.0312 0.3125 0.30613 0.0904 0.47811 0.14998 0.5 0.15625 0.55906 0.16069 1.151 0.30609 1.7812 0.46875 0.6646 0.17132 1.3311 0.34742 2 0.5 0.0098 0.002 0.0214-0.002 0.03125 0 0.34859 0.0792 0.70445 0.14888 1.0312 0.21875 0.39637 0.24496 0.77786 0.48309 1.1875 0.71875 0.53397 0.30697 1.0858 0.60839 1.6562 0.90625 0.08572 0.0448 0.24678 0.12148 0.5 0.25 0.89466 0.45346 0.92573 0.48091 0.09375 0.0625v-0.0312c0.67198 0.3392 1.3751 0.69287 2.0625 1 0.68074 0.30353 1.3567 0.5987 2.0625 0.875 0.37217 0.14612 0.45822 0.15516 0.21875 0.0625 0.60578 0.23413 1.2317 0.458 1.9062 0.6875 2.7256 0.93046 5.509 1.6068 8.375 2.0938 0.33764 0.0573 0.68252 0.13471 1.0312 0.1875 1.1885 0.18035 2.4463 0.32323 3.7188 0.4375 0.40122 0.0359 0.7014 0.0763 0.9375 0.0937 2.0956 0.15651 4.2268 0.23298 6.4375 0.1875a3.3074 3.3074 0 0 0 0.03125 0c0.23663-0.006 0.14528-0.0233 0.21875-0.0312 0.11523 0.0115-0.09274 0.0233 0.125 0.0312 1.1692 0.0441 1.9423-0.15094 3.3125-0.4375s3.0734-0.70827 5.
0625-1.3438c3.9783-1.271 9.04-3.3133 14.375-6.4375 10.67-6.2484 22.486-16.947 28.219-34.156 0.1555-0.46606 0.30614-0.91905 0.4375-1.3438 0.0975-0.31632 0.18925-0.57492 0.25-0.78125h-0.0312c0.11358-0.38462 0.25133-0.79783 0.375-1.25 0.12788-0.46887 0.22441-0.95852 0.34375-1.4375 1.0263-0.26645 1.7391-0.39741 3.5625-1.0938 1.4075-0.5375 2.8573-1.1774 4.1875-2.0938 1.3302-0.91632 3.0312-2.3001 3.0312-4.875 0-1.335-0.24581-2.5743-0.4375-4.1562-0.19169-1.582-0.37232-3.3599-0.375-5.0625-0.003-1.7026 0.197-3.2958 0.59375-4.4375s0.87714-1.7668 1.625-2.1875c3.5228-1.9816 10.605-5.6901 16.562-8.8125 0.60106 0.90666 1.2771 1.7618 2.125 2.5 1.7868 1.5558 4.7774 2.4891 7.4062 1.4375 0.97667-0.39067 2.6301-0.95588 4.125-1.5 0.35096 1.4182 1.348 4.1517 4 5.625 3.3163 1.8424 6.1578 2.5472 7.3438 2.8125 0.4712 0.48902 1.0669 1.1247 2.4688 2.2812 1.8535 1.5292 3.8825 3.5 7.375 3.5 2.5233 0 6.1426-0.74054 10.438-1.9688 4.2949-1.2282 8.7814-2.8074 11.938-5.4375 1.5519-1.2932 3.4645-3.4698 5.5312-5.9375
0.65707 1.0368 1.3385 2.2295 1.9688 3.125 1.4278 2.0288 2.5812 3.5967 4.3125 4.7812 4.401 3.0112 7.9875 8.8759 8.1875 12.875 0.0689 1.3776-0.6343 4.24-1.3125 6.9375-0.3391 1.3488-0.68486 2.6784-0.75 4.125-0.0651 1.4466 0.19953 3.5637 2.0312 4.9375 2.0553 1.5414 4.1419 1.8804 6 2.125-0.12564 0.61523-0.24847 1.3679-0.375 1.875-0.28604 1.1464-0.63672 1.8582-0.53125 1.75-0.0672 0.0641-0.10104 0.0952-0.1875 0.15625-0.39219 0.27674-1.0024 0.68021-1.7812 1.1562-1.5577 0.95207-3.7672 2.2136-6.375 3.6562-5.2157 2.8852-12.061 6.4885-18.969 10.062-6.9076 3.574-13.867 7.1197-19.312 9.8125-2.7228 1.3464-5.0888 2.4853-6.8438 3.3125-1.755 0.82723-3.2599 1.4237-3 1.3438-2.3782 0.73175-11.414 4.0606-20.906 7.6562-4.746 1.7978-9.4816 3.6268-13.312 5.1562-3.8309 1.5294-6.46 2.553-8.0625 3.4688-2.6981 1.5418-4.4173 3.969-4.6875 6.625s1.4511 5.7134 4.2812 6.5625c0.97969 0.29391 2.3387 0.96919 3.3438 1.6562 1.005 0.68706 1.4675 1.605 1.3125 1.0625-0.0632-0.22119-0.25881 0.1771-0.125 2.0625s1.4891 4.0994
3.8438 5.7812c0.44379 0.31699 3.1485 2.6274 6.3438 5.5s7.1707 6.4826 11.188 10.031c4.0168 3.5486 8.0673 7.0389 11.5 9.75 1.7164 1.3556 3.282 2.508 4.6562 3.4062 1.3743 0.89824 2.3083 1.6087 4.0938 1.9062 0.43107 0.0718 2.9484 0.99191 4.6562 1.5625-10.11 12.412-19.799 26.206-21.781 29.062-0.2342-0.18764-0.43548-0.48921-0.6875-0.65625-0.69748-0.4623-1.4389-0.85432-2.4375-1.0938-0.99864-0.23943-2.7722-0.41528-4.2188 1.0312-0.76465 0.76465-0.87901 1.2036-1.0938 1.6875-0.21474 0.48389-0.38333 0.9862-0.5625 1.5312-0.35833 1.0901-0.70746 2.3615-1.0312 3.6875-0.64757 2.652-1.1801 5.3592-1.375 7.125 0.0456-0.41299-0.15093 0.59261-0.5 1.6562s-0.8517 2.4696-1.4688 4.125c-1.2341 3.3108-2.9207 7.5765-4.75 11.906-1.8293 4.3297-3.8087 8.73-5.625 12.406-1.8163 3.6762-3.5969 6.7154-4.4375 7.7188-0.97276 1.1612-1.0843 3.2715-0.5625 4.4062 0.52176 1.1348 1.2278 1.7013 1.9375 2.2188 1.4194 1.0349 3.1053 1.6937 5.0312 2.0312 1.926 0.33753 4.0896 0.31951 6.25-0.5625s4.1814-2.833 5.0938-5.5c1.4528-4.2465
2.417-10.269 3.9375-16.5 1.5205-6.2308 3.6174-12.535 6.5312-16.531a3.3074 3.3074 0 0 0 0.4375 -0.875c10.244-11.099 19.106-25.901 30.562-38.094 0.0301-0.0321 0.0636-0.0617 0.0937-0.0937a3.3074 3.3074 0 0 0 0 -0.0312 3.3074 3.3074 0 0 0 0.0312 0c0.95094-1.0092 1.869-2.0079 2.8125-2.9375-0.0332 0.0326 0.10591-0.0509 0.375-0.3125 0.49524-0.48313 0.91059-0.93554 1.3125-1.3125 0.0175-0.0163 0.13331-0.084 0.3125-0.25 0.19485-0.18113 0.37146-0.35468 0.5625-0.53125 2.0242 0.74597 4.0705 1.5128 5.75 2.0625 2.2366 0.73212 3.6771 1.3125 5.6875 1.3125 1.9888 0 3.9358-0.42432 5.6875-1.2812 1.5047-0.7361 3.0192-1.9005 3.7812-3.7812l3.2812-4.625c2.932 0.74817 10.341 3.1294 18.562 5.2188 4.3467 1.1047 8.8022 2.0842 12.906 2.625 4.104 0.5408 7.7972 0.76369 11.031-0.1875 4.4014-1.2945 9.2839-3.4657 13.219-5.75 1.9674-1.1422 3.6892-2.2887 5.0625-3.5312 0.68664-0.6213 1.2938-1.2498 1.8125-2.0625 0.32617-0.51107 0.5677-1.2077 0.71875-1.9688l2.5312-5.5312c3.2664 0.0218 6.8512 0.02 10.5-0.21875 2.1555-0.1
4102 4.1941-0.34058 6.125-0.65625-2.2932 12.753-2.2437 24.993-3.375 37-0.0259 0.0243-0.0697 0.0715-0.0937 0.0937-0.2485 0.23039-0.74056 0.50057-0.0625 0.0937a3.3074 3.3074 0 0 0 -1.625 2.8438s-0.0101 1.8777 0.34375 3.9375c0.17692 1.0299 0.43874 2.1268 1 3.2812 0.56126 1.1545 1.6945 2.7148 3.7812 3.0625 1.8824 0.31373 2.5615-0.27025 3.375-0.6875 0.81347-0.41725 1.5891-0.95096 2.4688-1.5625 1.7594-1.2231 3.834-2.8288 6.0625-4.5625 4.457-3.4674 9.64-7.4224 13.281-9.25 3.643-1.8285 9.4988-3.4333 14.75-4.8438 2.6256-0.70522 5.1259-1.3667 7.25-2.0938 2.1241-0.72707 3.8282-1.2445 5.4375-2.9688 0.87931-0.94211 1.3892-2.2872 1.4062-3.4688s-0.32299-2.196-0.75-3.0625c-0.85402-1.733-2.1334-3.0858-3.625-4.3438-2.9832-2.5159-6.5745-4.7115-10.781-4.375-1.4339 0.11471-2.4464 0.53612-3.6875 1.0938-1.2411 0.55763-2.6245 1.2894-4.0938 2.125-2.9385 1.6713-6.2764 3.7896-9.4688 5.9062-5.3943 3.5766-8.8476 6.0845-10.25 7.0938a3.3074 3.3074 0 0 0 -0.9 -0.39c0.2352-6.1442 2.0063-14.699 5.3125-25.062 0.32536
-1.0199 0.6766-2.0968 1.0312-3.1562 12.081-2.5381 25.769-9.337 30.156-11.75 7.1789-3.9484 9.8125-12.531 9.8125-12.531a3.3074 3.3074 0 0 0 -0.31 -2.84s-4.59-7.548-9.4375-15.719c-2.4238-4.0854-4.9219-8.3404-6.9062-11.844-1.9843-3.5033-3.5333-6.5186-3.7812-7.1562-1.2838-3.3013-3.9295-6.6195-7.5625-9.7188-3.633-3.0992-8.294-5.9054-13.656-7.4375-4.1272-1.1792-13.517-5.5075-21.812-9.9375-4.1477-2.215-8.086-4.4758-11.125-6.375-2.5701-1.6061-3.9757-2.7798-4.5-3.1875 0.0205-0.29986 0.0782-0.62063 0.0937-0.90625 0.781-0.53163 1.5555-1.0665 2.2812-1.7188 1.5215 1.2809 3.291 2.2803 5.5938 2.1875a3.3074 3.3074 0 0 0 3.1875 -3.2812c2.4336-2.1293 10.952-9.6084 16.188-14.844 4.0665-4.0665 7.5212-6.2013 9.4062-7.2812 0.34424 0.29096 0.36107 0.1779 0.84375 0.78125 1.2708 1.5886 2.4276 1.5499 3.375 1.6875 0.94742 0.13758 1.895 0.15582 2.9375 0.125 2.0849-0.0616 4.5277-0.33226 6.9688-0.65625s4.8616-0.70302 6.8125-1 3.8055-0.46875 3.5625-0.46875c1.2946 0 2.2932-0.70625 2.8125-1.25 0.51927-0.54375 0.7795
2-1.0356 1-1.5 0.44097-0.92878 0.68985-1.8484 0.9375-2.9062 0.4953-2.1157 0.85724-4.6996 1.1562-7.375 0.59802-5.3508 0.90625-10.667 0.90625-12.5 0-2.5745-1.2648-3.6406-2.4375-4.875s-2.6055-2.3781-4.1875-3.4062c-1.582-1.0282-3.3018-1.9272-5.0625-2.5-1.7607-0.57284-3.671-1.0281-5.8438-0.0625-2.5258 1.1226-4.2146 2.9634-5.2812 4.5-0.97232-0.34759-1.1835-0.48561-2.5625-0.84375-1.4548-0.37782-3.0382-0.73176-4.6562-0.78125-1.618-0.0495-3.5612 0.03-5.25 1.7188-1.0724 1.0724-1.325 2.1208-1.5312 3.0938-0.20621 0.97298-0.26045 1.9615-0.28125 3-0.0416 2.077 0.12288 4.3876 0.375 6.6562 0.25212 2.2687 0.58666 4.4925 0.84375 6.2188 0.10064 0.67579 0.17884 1.1949 0.25 1.6875-0.28422 0.2227-0.48833 0.38867-0.90625 0.6875-1.4239 1.0182-3.5126 2.3864-5.8438 3.8438-3.6113 2.2577-7.5234 4.4637-11.062 6.4375 0.29665-1.2394 0.35867-1.8936 0.375-2.1562 0.20441-0.49471 1.0313-2.3576 1.8125-5.375 0.87647-3.3854 1.7522-7.5381 0.375-11.531-1.3844-4.014-4.6414-6.9573-8.25-9.5625-1.3036-0.94113-2.7123-1.7354-4.
0938-2.5625 0.43569-0.84433 0.51212-1.5762 0.46875-2-0.10445-1.0208-0.36454-1.3664-0.59375-1.8438-0.45841-0.95466-1.059-1.9282-1.7812-3-1.4444-2.1437-3.2666-4.541-4.6875-6.125-0.924-1.03-2.29-2.0879-3.4688-3.1562 0.0682 0.0184 0.11918 0.0441 0.1875 0.0625 2.8031 0.75353 5.6573 1.4822 8.3438 1.875 2.6865 0.39276 5.1939 0.6062 7.6875-0.34375 2.6036-0.99183 4.3429-2.9444 6.2188-5.2812 1.8758-2.3369 3.6959-5.1651 5.375-8.0938 3.3581-5.8572 6.0816-11.815 6.9688-15.719 0.63676-2.8017 0.2803-6.0226-0.3125-10.781-0.5928-4.7586-1.6034-10.593-2.9688-16.656-2.7308-12.126-6.6245-25.019-12.125-32.562-4.1968-5.7555-8.1915-17.611-10.906-28.375-2.7148-10.764-4.3541-20.454-4.7812-22.875-0.51916-2.9419-1.7823-5.0226-3.125-6.25-1.2398-1.1334-2.675-1.5608-2.9062-1.625v-0.03125s-0.15374-0.03061-0.15625-0.03125c-0.25749-0.06596-13.482-3.4414-23.719-3.1562zm-88.344 372.22 0.0625 0.0312c-0.1135 0.20659-0.25794 0.52963-0.9375 0.9375 0.32023-0.19214 0.6048-0.6032 0.875-0.96875z"
+ inkscape:original="M 252.875 40 C 251.52234 40.03768 250.26182 40.137056 249.125 40.34375 C 240.03044 41.99731 201.42779 41.45018 182.6875 58.8125 C 175.89466 65.10586 128.41514 127.72683 124.28125 132.6875 C 120.14736 137.64816 112.67645 145.36638 109.09375 146.46875 C 105.51105 147.57112 100.83755 150.87203 106.625 152.25 C 112.41244 153.62796 118.47414 152.2301 121.78125 152.78125 C 125.08836 153.33244 128.95986 154.16487 133.09375 153.0625 C 135.11479 152.52356 137.32253 152.38112 139.0625 152.375 C 139.51726 152.374 139.93426 152.39195 140.3125 152.40625 C 140.3229 152.40663 140.33345 152.40586 140.34375 152.40625 C 141.45843 152.44985 142.1875 152.53125 142.1875 152.53125 C 142.1875 152.53125 142.05696 152.79786 141.90625 153.25 C 141.89365 153.2864 141.8877 153.2736 141.875 153.3125 C 141.42664 154.68887 140.91317 157.41986 143.5625 158.03125 C 145.90826 158.57258 147.76742 158.04995 148.78125 157.625 C 148.95233 157.5533 149.06534 157.50038 149.1875 157.4375 C 149.476
01 157.2954 149.625 157.21875 149.625 157.21875 C 149.622 157.24175 149.59105 157.32629 149.59375 157.46875 C 149.56425 158.04383 149.78287 159.6546 152.9375 160.78125 C 156.79579 162.15922 159.21403 161.18964 162.03125 162.4375 C 168.3815 165.25029 176.08217 172.36907 178.5625 175.125 C 179.69175 176.37973 183.39766 180.64959 187.84375 184.96875 C 181.60396 183.83839 175.74198 183.10023 173.96875 183.90625 C 169.68154 185.85498 163.4375 193.66327 163.4375 196.78125 C 163.4375 199.40891 159.85049 203.41018 158.71875 207.40625 C 157.10183 207.99374 155.48198 208.55426 154.46875 208.84375 C 152.24002 209.48053 150.78699 212.20156 150.96875 215.9375 C 143.72804 219.57261 133.5499 224.704 130.71875 225.21875 C 126.96744 225.90081 123.49126 222.39359 119.03125 222.03125 C 112.41417 196.77219 92.701231 191.25076 75.96875 189.875 C 73.647546 188.86952 71.194722 188.22122 68.59375 188.0625 C 57.3611 187.37703 45.821144 191.31225 36.46875 198.96875 C 13.829472 204.13911 0.50408469 226.34176
3.90625 253.21875 C 4.5693484 258.4572 5.5979793 263.10216 6.9375 267.1875 C 6.94682 267.1979 6.959296 267.20845 6.96875 267.21875 C 6.981752 267.25835 6.986937 267.30425 7 267.34375 C 7.290537 268.22113 7.5860655 269.07826 7.90625 269.90625 C 8.0166368 270.19135 8.1361504 270.47064 8.25 270.75 C 8.5553943 271.50043 8.8887022 272.22769 9.21875 272.9375 C 9.255752 273.0171 9.275192 273.10843 9.3125 273.1875 C 9.6754124 273.95661 10.04596 274.68384 10.4375 275.40625 C 10.633485 275.76807 10.828217 276.11835 11.03125 276.46875 C 11.260313 276.86395 11.51207 277.24409 11.75 277.625 C 11.94754 277.94133 12.140176 278.25585 12.34375 278.5625 C 12.41881 278.67551 12.486624 278.79454 12.5625 278.90625 C 12.89565 279.39687 13.245081 279.8778 13.59375 280.34375 C 14.610877 281.70289 15.667929 282.96501 16.8125 284.125 C 16.91088 284.2248 17.025706 284.30787 17.125 284.40625 C 18.882378 286.14598 20.782142 287.67043 22.8125 289 C 22.87523 289.0411 22.937021 289.0842 23 289.125 C 23.63132 289.5
3309 24.281629 289.93998 24.9375 290.3125 C 24.97788 290.3354 25.02202 290.3522 25.0625 290.375 C 25.6998 290.73407 26.34035 291.07894 27 291.40625 C 27.265224 291.53802 27.543735 291.65444 27.8125 291.78125 C 28.204039 291.96572 28.601069 292.13828 29 292.3125 C 29.302363 292.4448 29.599702 292.5922 29.90625 292.71875 C 30.510456 292.96762 31.129903 293.21013 31.75 293.4375 C 32.141502 293.58125 32.539802 293.70824 32.9375 293.84375 C 33.352817 293.98507 33.765561 294.11736 34.1875 294.25 C 34.510348 294.35164 34.829586 294.4658 35.15625 294.5625 C 35.311377 294.6083 35.469023 294.6428 35.625 294.6875 C 36.185708 294.84867 36.740976 295.00875 37.3125 295.15625 C 37.95222 295.32116 38.597129 295.47633 39.25 295.625 C 39.581556 295.7006 39.915125 295.77215 40.25 295.84375 C 40.470545 295.89085 40.684287 295.95461 40.90625 296 C 41.400418 296.31173 41.900957 296.61556 42.40625 296.90625 C 42.91424 297.19829 43.418588 297.47905 43.9375 297.75 C 44.094051 297.8319 44.248729 297.92005 44
.40625 298 C 44.43545 298.0148 44.47077 298.01655 44.5 298.03125 C 45.124472 298.34647 45.766979 298.65188 46.40625 298.9375 C 47.045365 299.22247 47.690442 299.49426 48.34375 299.75 C 48.40539 299.7742 48.469487 299.7886 48.53125 299.8125 C 49.124157 300.04166 49.708485 300.26324 50.3125 300.46875 C 52.85089 301.33531 55.473744 301.97645 58.1875 302.4375 C 58.510156 302.4923 58.83139 302.54457 59.15625 302.59375 C 60.306358 302.76827 61.480023 302.92562 62.65625 303.03125 C 62.957256 303.05815 63.259899 303.07135 63.5625 303.09375 C 65.580581 303.24447 67.605142 303.32409 69.6875 303.28125 C 69.813073 303.27825 69.937227 303.2556 70.0625 303.25 C 70.12531 303.257 70.18698 303.27895 70.25 303.28125 C 73.387916 303.39958 107.10266 295.80498 117.96875 263.1875 C 118.10788 262.7705 118.24338 262.3318 118.375 261.90625 C 118.4509 261.65996 118.52041 261.40532 118.59375 261.15625 C 118.70999 260.76261 118.82786 260.36963 118.9375 259.96875 C 119.22031 258.93182 119.48247 257.8656 119.718
75 256.78125 C 119.72775 256.73985 119.7411 256.69765 119.75 256.65625 L 119.78125 256.78125 C 119.78125 256.78125 129.9375 254.46172 129.9375 251.34375 C 129.9375 248.22578 126.7953 236.13272 133.03125 232.625 C 137.27598 230.23734 146.1328 225.57598 152.5625 222.21875 C 154.11178 225.87408 156.57669 228.74433 159.53125 227.5625 C 161.15653 226.91239 163.66128 226.00941 166.03125 225.15625 C 166.07075 225.17615 166.11765 225.20225 166.15625 225.21875 C 168.88447 226.38799 166.96103 229.89501 170.46875 231.84375 C 173.97647 233.79248 177.875 234.5625 177.875 234.5625 C 177.875 234.5625 182.94452 240.03125 186.0625 240.03125 C 189.18047 240.03125 201.63554 237.30372 206.3125 233.40625 C 207.96892 232.0259 211.06386 228.42379 214.34375 224.375 C 217.32736 229.50136 220.25816 233.91018 222.125 235.1875 C 227.36126 238.7702 231.4744 245.11315 231.75 250.625 C 231.98518 255.32845 228.17026 262.47144 230.375 264.125 C 231.69973 265.11854 234.21473 265.60604 236.09375 265.84375 C 236.07225
265.84075 236.05285 265.8158 236.03125 265.8125 C 236.6712 265.8977 237.429 265.99357 238.3125 266.0625 C 238.2794 266.27099 238.25265 266.48078 238.21875 266.6875 C 237.63117 270.26782 236.91036 273.51645 236.15625 274.59375 C 234.2271 277.34968 181.5827 304.08513 178 305.1875 C 174.41729 306.28987 140.26454 318.98276 136.40625 321.1875 C 132.54795 323.39224 132.52532 327.51697 135.28125 328.34375 C 138.03717 329.17053 141.63632 331.38335 142.1875 333.3125 C 142.73869 335.24164 140.79796 336.61908 144.65625 339.375 C 148.51455 342.13093 176.07059 368.57948 181.03125 369.40625 C 182.73969 369.69099 186.45245 371.0141 190.6875 372.59375 C 190.645 372.64375 190.6051 372.69985 190.5625 372.75 C 190.29429 373.06641 190.05188 373.36428 189.78125 373.6875 C 189.48568 374.04002 189.2042 374.39014 188.90625 374.75 C 177.54017 388.48989 164.625 407.21875 164.625 407.21875 L 161.75 407.21875 C 161.7998 407.13895 161.824 407.06186 161.875 407.03125 C 162.84937 406.44663 159.34937 403.93189 15
8.375 404.90625 C 157.40064 405.88062 155.56136 414.14848 155.25 416.96875 C 154.92042 419.95407 142.89196 450.35616 137.71875 456.53125 C 135.94895 458.6438 147.27915 463.34269 149.8125 455.9375 C 152.34586 448.53232 153.89818 431.38517 160.71875 422.03125 C 160.70555 421.93015 160.6993 421.79399 160.6875 421.6875 C 170.882 410.90833 179.96076 395.47086 192.09375 382.59375 L 192.125 382.59375 C 193.08237 381.57776 194.03661 380.57375 195.03125 379.59375 C 195.15247 379.47468 195.2844 379.36848 195.40625 379.25 C 195.86631 378.80119 196.31224 378.34615 196.78125 377.90625 C 196.88299 377.81115 196.99157 377.71963 197.09375 377.625 C 197.5872 377.1663 198.08971 376.69798 198.59375 376.25 C 198.65475 376.1959 198.72004 376.14763 198.78125 376.09375 C 198.9083 375.98146 199.0285 375.86158 199.15625 375.75 C 204.67386 377.81234 209.67122 379.59375 211.34375 379.59375 C 214.26546 379.59375 217.49511 378.1944 217.9375 376.1875 L 222.71875 369.46875 C 223.05164 369.52205 223.39188 369.6061
1 223.75 369.6875 C 229.81304 371.06546 256.2861 380.44342 265.65625 377.6875 C 273.79714 375.29312 284.61708 369.34255 284.25 366.5625 L 287.8125 358.75 C 295.00493 358.8472 306.04963 358.751 310.71875 356.625 C 307.25094 371.16599 307.8659 385.28483 306.40625 399.625 C 305.58748 400.44481 304.91684 401.06865 304.71875 401.1875 C 304.71875 401.1875 304.72375 407.829 307.0625 408.21875 C 309.40098 408.6085 321.89287 396.63217 330.25 392.4375 C 338.60369 388.24456 354.02178 386.1731 356.75 383.25 C 359.47823 380.3269 350.52809 373.1415 345.65625 373.53125 C 340.78442 373.92099 317.96875 390.46875 317.96875 390.46875 L 316.21875 389.3125 C 316.21875 389.3125 314.71024 390.92661 313.96875 391.71875 C 312.83532 384.65899 314.7401 373.87383 319.15625 360.03125 C 319.66333 358.44178 320.20856 356.79349 320.78125 355.125 C 332.40032 353.13671 347.55565 345.61157 351.90625 343.21875 C 357.4181 340.18723 360.1875 332.46875 360.1875 332.46875 C 360.1875 332.46875 341.7104 302.17941 339.78125
297.21875 C 337.8521 292.25808 330.39574 284.81842 320.75 282.0625 C 311.10426 279.30657 283.84402 264.67079 280.8125 260.8125 C 280.91991 259.68626 280.98832 258.6823 281.03125 257.75 C 281.04775 257.39259 281.02525 257.08528 281.03125 256.75 C 283.26046 255.38383 285.26556 253.88244 286.46875 251.875 C 288.057 254.07618 289.81952 255.71537 292.0625 255.625 C 292.0625 255.625 292.0334 254.88177 292 254.21875 C 293.15607 253.20988 303.68003 244.00747 309.21875 238.46875 C 315.06495 232.62255 321.28125 229.5 321.28125 229.5 C 321.28125 229.5 322.84726 230.30127 324.40625 232.25 C 325.96524 234.19874 343.13027 230.6875 345.46875 230.6875 C 347.80723 230.6875 348.96875 211.19697 348.96875 208.46875 C 348.96875 205.74052 339.60147 199.09727 336.09375 200.65625 C 332.58603 202.21524 331.03125 206.125 331.03125 206.125 C 331.03125 206.125 321.68223 202.22402 319.34375 204.5625 C 317.00527 206.90098 320.125 222.50352 320.125 224.0625 C 320.125 225.26969 305.2043 234.37471 297.1875 238.625
L 294.25 236.53125 C 295.73871 234.1169 295.96875 231.0625 295.96875 231.0625 C 295.96875 231.0625 300.13147 221.23971 298.28125 215.875 C 296.33281 210.2255 287.31842 205.00549 280.5 201.75 C 282.35784 201.27846 284.20755 201.07272 286.03125 201.25 C 287.25795 201.36925 282.47849 194.66919 280 191.90625 C 276.6389 188.15941 269.87079 183.08839 266.125 180.375 C 266.23821 180.3575 266.35672 180.34955 266.46875 180.34375 C 271.70501 180.06816 288.24381 187.23599 294.03125 185.03125 C 299.8187 182.82651 309.18454 164.37554 310.5625 158.3125 C 311.94047 152.24947 305.33324 114.19719 295.6875 100.96875 C 286.04176 87.74031 280.26428 53.02882 279.4375 48.34375 C 278.61072 43.65868 275.84375 43.09375 275.84375 43.09375 C 275.84375 43.09375 262.34365 39.736253 252.875 40 z M 95.0625 211.15625 C 98.018406 214.10071 100.33415 218.01727 102.09375 223.09375 C 101.26837 223.21389 100.5267 223.37222 99.875 223.5625 C 98.582847 219.34078 96.970577 215.13105 95.0625 211.15625 z M 103.5625 252.5937
5 C 104.25261 252.8108 104.66725 252.94168 104.875 253 C 104.56804 254.54175 104.20058 256.06001 103.75 257.5625 C 103.57117 258.12999 103.38738 258.69269 103.1875 259.25 C 103.1979 259.248 103.20845 259.252 103.21875 259.25 C 102.69577 260.79936 102.06544 262.29466 101.40625 263.78125 C 102.46069 259.89804 103.19005 256.11454 103.5625 252.59375 z "
+ transform="translate(169.79 169.25)"
+ inkscape:radius="3.3071101" />
+ <path
+ id="path3928"
+ sodipodi:nodetypes="cscc"
+ style="fill:#a05a2c"
+ inkscape:connector-curvature="0"
+ d="m220.61 367.22c-31.124-2.3999-50.968 23.108-46.898 55.26 5.3718 42.437 33.97 44.647 69.087 45.35z" />
+ <path
+ id="path4254"
+ sodipodi:nodetypes="cccc"
+ style="fill:#784421"
+ inkscape:connector-curvature="0"
+ d="m176.72 436.44c7.95 24.246 27.276 29.454 51.375 30.875l-28.94-26.07c-6.236 0.77949-18.93-0.91503-22.438-4.8125z" />
+ <path
+ id="path3926"
+ sodipodi:nodetypes="sssss"
+ style="fill:#a05a2c"
+ inkscape:connector-curvature="0"
+ d="m238.39 357.32c-26.756-1.6328-55.394 22.874-51.536 61.733 3.8583 38.859 25.847 54.016 52.638 53.465 18.736-0.38547 34.173-35.551 34.173-55.67 0-20.118-12.131-58.116-35.276-59.528z" />
+ <path
+ id="path3916"
+ style="fill:#ffccaa"
+ inkscape:connector-curvature="0"
+ d="m462.24 410.06c2.7282-0.38975 27.672-15.2 27.672-16.759s-3.118-17.149-0.7795-19.487c2.3385-2.3385 11.692 1.559 11.692 1.559s1.559-3.8975 5.0667-5.4565 12.862 5.0667 12.862 7.7949-1.1692 22.216-3.5077 22.216-19.487 3.5077-21.046 1.559-3.118-2.7282-3.118-2.7282-6.236 3.118-12.082 8.9642c-5.8462 5.8462-17.928 16.369-17.928 16.369z" />
+ <path
+ id="path3904"
+ sodipodi:nodetypes="ccsccc"
+ style="fill:#aa0000"
+ inkscape:connector-curvature="0"
+ d="m461.85 404.21 5.4564 3.8975s-5.2237 7.2185-5.5902 12.216c-0.0807 1.0996 0.13374 4.5432 0.13374 4.5432-5.0131 0.20197-7.5954-8.1034-11.303-12.472z" />
+ <path
+ id="path3918"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#550000"
+ inkscape:connector-curvature="0"
+ d="m408.15 435.31 40.65-8.13c3.8216-2.1645 7.4692-4.4378 8.4056-8.4056l-5.7874-2.4803-47.953 9.7835-3.3071 6.6142c2.4255 0.88861 0.67313 2.0558 7.9922 2.6181z" />
+ <path
+ id="path3908"
+ sodipodi:nodetypes="cssccccccc"
+ style="fill:#782121"
+ inkscape:connector-curvature="0"
+ d="m529.96 501.73s-2.7559 7.7166-8.2678 10.748c-5.5118 3.0315-28.386 14.331-39.41 12.126-11.024-2.2047-23.15 0-23.15 0l-5.0839 11.203-57.751-2.3844-9.8485 13.811-8.3406-9.6772 63.662-52.914z" />
+ <path
+ id="path3906"
+ style="fill:#2b0000"
+ inkscape:connector-curvature="0"
+ d="m402.92 355.94c1.1024 0.27559 25.906-1.378 25.906-1.378l8.2678 24.252 10.197 38.859-14.055 0.82678z" />
+ <path
+ id="path3902"
+ sodipodi:nodetypes="cscsccc"
+ style="fill:#c83737"
+ inkscape:connector-curvature="0"
+ d="m442.36 367.58s22.511 8.2238 25.723 17.539c1.8502 5.3647-2.3385 15.2-2.3385 15.2s-0.32287 4.7438-3.0511 7.0823-13.708 6.9486-13.708 6.9486l-15.98-40.144z" />
+ <path
+ id="path4266"
+ style="fill:#784421"
+ inkscape:connector-curvature="0"
+ d="m238.03 368.03c-6.2372 0.4693-16.188 9.6875-16.188 9.6875l33.094 1.0938s-9.6557-9.9232-15.719-10.75c-0.37894-0.0517-0.77169-0.0625-1.1875-0.0312zm26.812 67.844-58.156 2.1875s-2.667 4.8034-0.25 8.5625c3.8308 5.958 14.875 15.156 14.875 15.156-2.6124 1.8304-1.8939 6.0401-14.125 1 8.9408 6.9885 20.137 9.9692 32.312 9.7188 12.397-0.25505 23.32-15.725 29.312-32l-3.9688-4.625z" />
+ <path
+ id="path3924"
+ sodipodi:nodetypes="sssssss"
+ style="fill:#a05a2c"
+ inkscape:connector-curvature="0"
+ d="m236.46 373.3c24.099-1.9502 35.631 6.1477 38.859 35.551 2.6668 24.295-16.86 49.139-34.449 50.709-9.7276 0.86831-5.5166 12.776-0.82678 12.953 3.8387 0.14475 53.435-11.224 50.985-65.867-1.9794-44.136-32.911-47.388-53.465-47.953-8.2369-0.22641-7.7629 15.145-1.1024 14.606z" />
+ <path
+ id="path4247"
+ sodipodi:nodetypes="csccccc"
+ style="fill:#784421"
+ inkscape:connector-curvature="0"
+ d="m275.25 408.31c0.0207 0.17997 0.0426 0.34959 0.0625 0.53125 0.76996 7.0144-0.18496 13.637-2.3438 19.656 5.9136-0.95938 10.776 0.60365 14.094 5.875 1.9037-5.1057 3.2481-10.884 3.7812-17.406l-0.46-8.66z" />
+ <path
+ id="path3914"
+ sodipodi:nodetypes="cssssscsccsscc"
+ style="fill:#ffccaa"
+ inkscape:connector-curvature="0"
+ d="m328.17 381.61c-1.559 0.38975-23.385 12.082-27.672 12.862-4.2872 0.7795-8.1847-3.8975-13.641-3.118-5.4565 0.77949-16.369 0-19.098 2.3385-2.7282 2.3385-1.559 5.0667-0.38975 7.4052s-3.5077 15.59-1.1692 17.539c2.3385 1.9487 8.7693 3.7026 8.7693 3.7026s-0.19487-6.4308 4.8718-6.4308c6.2481 0 8.1847 4.2872 8.1847 4.2872l1.559 5.8462s10.133-2.3385 10.133-5.4564c0-3.118-3.118-15.2 3.118-18.708 6.236-3.5077 26.503-14.031 26.503-14.031z" />
+ <path
+ id="path3900"
+ style="fill:#aa0000"
+ inkscape:connector-curvature="0"
+ d="m334.01 374.59s-7.0154 2.7282-9.7437 3.5077c-2.7282 0.7795-4.2872 4.677-3.118 9.7437s4.2872 10.523 8.1847 8.9642c3.8975-1.559 12.862-4.677 12.862-4.677z" />
+ <path
+ id="path3910"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#ffccaa"
+ inkscape:connector-curvature="0"
+ d="m487.57 507.11c-12.512 23.324-8.7952 45.025-12.082 67.426l10.133-8.1847c-5.5889-8.8456-0.24493-31.054 12.862-62.749z" />
+ <path
+ id="path3912"
+ sodipodi:nodetypes="cccccc"
+ style="fill:#ffccaa"
+ inkscape:connector-curvature="0"
+ d="m369.87 532.05c-11.303 9.3539-35.467 44.431-35.467 44.431h-5.8462l-1.559 17.928c15.4-14.126 27.357-40.106 49.108-54.954z" />
+ <path
+ id="path4131"
+ style="fill:#d38d5f"
+ inkscape:connector-curvature="0"
+ d="m369.88 532.06c-4.0493 3.3512-9.7579 9.9976-15.406 17.156l7.4375 2.625c4.2955-4.5585 8.9367-8.7906 14.188-12.375l-6.22-7.4z" />
+ <path
+ id="path4136"
+ style="fill:#d38d5f"
+ inkscape:connector-curvature="0"
+ d="m498.5 503.59-10.938 3.5c-4.9893 9.3009-7.3549 18.349-8.6562 27.281 2.97-1.4544 6.5286-3.276 10.031-5.0938 2.4433-7.6586 5.6561-16.241 9.5625-25.688z" />
+ <path
+ id="path3896"
+ sodipodi:nodetypes="cssssssssssssssscssccc"
+ style="fill:#c83737"
+ inkscape:connector-curvature="0"
+ d="m409.53 424.01s-1.6536 17.087-3.5827 19.843c-1.9292 2.7559-54.567 29.488-58.15 30.591-3.5827 1.1024-37.756 13.78-41.614 15.984-3.8583 2.2047-3.8583 6.3386-1.1024 7.1654 2.7559 0.82678 6.3386 3.0315 6.8898 4.9607 0.55119 1.9291-1.378 3.3071 2.4803 6.063s31.418 29.213 36.378 30.04c4.9607 0.82678 26.457 10.197 30.315 10.197 3.8583 0 8.2678-2.4803 6.063-5.5118-2.2047-3.0315 0.27559-5.7874 6.3386-4.4095 6.063 1.378 32.52 10.748 41.89 7.9922 9.3701-2.7559 22.323-10.197 17.638-12.126-4.6851-1.9292-5.7874-6.8898-1.378-6.8898 4.4095 0 27.284 1.1024 30.591-3.3071 3.3071-4.4095 27.559-22.874 34.173-23.425 6.6142-0.55118 13.504 0.55119 13.504 0.55119s-18.465-30.315-20.394-35.276c-1.9292-4.9607-9.3701-12.402-19.016-15.158-9.6457-2.7559-36.929-17.362-39.961-21.221 0.81787-8.5758-0.10833-10.631-4.6851-19.843z" />
+ <path
+ id="path4115"
+ style="fill:#782121"
+ inkscape:connector-curvature="0"
+ d="m445.91 410.22-36.38 13.78s-0.6153 6.3577-1.5312 11.938c2.8949-1.8949 9.6782-5.8543 16.969-6.6875 9.6457-1.1024 17.372-0.54257 18.75-1.0938 1.378-0.55119 1.375-4.6875 1.375-4.6875s0.25836 3.3125 2.1875 3.3125c0.85456 0 2.2419 0.0983 3.5312 0.21875 0.28397-6.1667-0.93056-8.7793-4.9062-16.781z" />
+ <path
+ id="path3894"
+ style="fill:#a02c2c"
+ inkscape:connector-curvature="0"
+ d="m373.16 372.75s13.514 28.105 18.75 31.688c5.2363 3.5827 9.3494 9.9256 9.625 15.438 0.23518 4.7034-3.5797 11.846-1.375 13.5 1.3247 0.99354 3.8397 1.481 5.7188 1.7188-1.9927-0.30349-4.4634-0.99645-3.7812-2.5312 1.1024-2.4803 18.585-7.7888 28.375-9.9375 4.6874-1.0288 12.415 0.55414 14.344-1.375 1.9292-1.9292-14.688-40.938-14.688-40.938l-56.97-7.56zm67.562 0.28125-9.5938 6.0312s13.398 38.054 14.5 39.156c1.1024 1.1024 2.6643 2.3704 4.4062 1.375 1.9292-1.1024 7.5978-2.328 6.25 1.4688 1.7914-2.6181 1.2282-5.1447-1-7.125-1.0974-0.97533-3.5611-8.93-7.5938-17.562-4.738-10.143-3-15.628-6.9688-23.344zm-33.656 62.188c0.64899 0.0605 1.0938 0.0937 1.0938 0.0937s-0.43922-0.0292-1.0938-0.0937z" />
+ <path
+ id="path4120"
+ sodipodi:nodetypes="cccccccccsccc"
+ style="fill:#782121"
+ inkscape:connector-curvature="0"
+ d="m440.72 373.03-9.5938 6.0312s1.0514 2.9566 2.5 7.0312c3.4624-1.6273 6.4759-3.3775 9.8438-4.6562-0.53432-2.7373-1.2032-5.3993-2.75-8.4062zm-52.75 1.6875-12.562 2.5938c2.7842 5.5507 7.6679 14.913 11.719 21.156l7.8125-6.4375s24.246 0.84105 27.829-0.53691c2.0579-0.79149 8.3111-3.0679 10.077-4.6818-1.6026-3.8724-2.7188-6.5-2.7188-6.5z" />
+ <path
+ id="path3898"
+ style="fill:#c83737"
+ inkscape:connector-curvature="0"
+ d="m376.11 358.22s-28.062-7.0154-32.349-5.0667c-4.2872 1.9487-10.523 9.7437-10.523 12.862 0 3.118-5.0667 8.1847-5.0667 12.862 0 4.677 5.0667 14.421 7.7949 15.59 2.7282 1.1692 0.77949 4.677 4.2872 6.6257s7.4052 2.7282 7.4052 2.7282 5.0667 5.4565 8.1847 5.4565 15.59-2.7282 20.267-6.6257 20.657-25.334 20.657-25.334z" />
+ <path
+ id="path3886"
+ style="fill:#a02c2c"
+ inkscape:connector-curvature="0"
+ d="m433.22 347.69-10.156 11.719 11.906 20.25c7.1728-5.58 14.125-9.8094 20.844-9.1562 1.2267 0.11925-3.5528-6.5808-6.0312-9.3438-4.7488-5.2938-16.562-13.469-16.562-13.469zm-75.781 2.1875s11.603 25.344 22.875 32.531c16.279 10.381 50.332 6.9544 54.031-2.5l-8.5625-14.594-12.406-10.75-55.938-4.6875z" />
+ <path
+ id="path3876"
+ sodipodi:nodetypes="csaccsssssccc"
+ style="fill:#782121"
+ inkscape:connector-curvature="0"
+ d="m342.84 330.59s21.496 28.937 25.355 31.418c3.8583 2.4803 16.673 6.8523 24.803 4.6851 5.2568-1.4013 7.9233-9.9902 12.402-10.61 9.5482-2.7927 12.768 4.5395 19.016 7.0276 0 0 6.6142-13.228 11.85-13.504 5.2363-0.27559 21.772 6.8898 27.559 4.6851 5.7874-2.2047 15.158-20.669 16.536-26.732s-5.2362-44.095-14.882-57.323c-9.6457-13.228-15.433-47.953-16.26-52.638-0.82678-4.6851-3.5827-5.2363-3.5827-5.2363-9.159-0.77949-59.804 5.7874-59.804 5.7874z" />
+ <path
+ id="path4146"
+ sodipodi:nodetypes="ccccssccssccc"
+ style="fill:#501616"
+ inkscape:connector-curvature="0"
+ d="m430.88 283.19-18.906 64.906c8.3752-2.0268 16.365-1.4288 24.75 0.1875l17.13 4.296c3.3128 0 16.254-14.039 17.361-23.794 1.3895-12.252-1.5681-33.908-5.0758-40.729-3.5077-6.8206-35.258-4.8669-35.258-4.8669zm-72.5 8s-4.4912 51.648-0.59375 58.469c3.8975 6.8206 12.308 11.487 22.601 4.8564 6.009-3.871 12.276-3.6984 23.774-2.9189l-0.1875-17.719z" />
+ <path
+ id="path3868"
+ sodipodi:nodetypes="cccsccc"
+ style="fill:#d38d5f"
+ inkscape:connector-curvature="0"
+ d="m412.84 337.75-14.344 1.375 5.1875 12.844c3.4878 0.64294 7.0879 1.236 8.3952 1.9006 5.6864 2.891 7.2811 4.6082 9.8986 8.2278l2.2189 0.95225c-4.5644-6.9023-8.7469-15.389-11.356-25.299z" />
+ <path
+ id="path3067"
+ style="fill:#ffccaa"
+ inkscape:connector-curvature="0"
+ d="m436.54 231.65s34.173 40.788 35.276 64.489c1.1024 23.701-15.433 45.197-42.441 47.953-27.008 2.7559-44.095 1.1024-62.835-24.803-18.74-25.906-2.7559-91.497-2.7559-91.497z" />
+ <path
+ id="path3837"
+ sodipodi:nodetypes="cscsccssscc"
+ style="fill:#28170b"
+ inkscape:connector-curvature="0"
+ d="m359.37 286.35s27.453-17.376 34.173-29.764c5.3154-9.7981 4.4764-15.227 4.4764-15.227s10.963 8.4731 23.089 10.678c12.126 2.2047 33.071 4.4095 33.071 4.4095l4.4095 6.6142s13.78-2.2047 15.984-6.6142c2.2047-4.4095 1.6536-18.189-11.024-26.457-12.677-8.2678-21.532-17.855-41.5-16.107-28.773 2.5193-42.831 13.902-42.831 13.902z" />
+ <path
+ id="path3839"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#000000"
+ inkscape:connector-curvature="0"
+ d="m396.76 288.46c5.6239-5.6506 14.192-11.739 28.062-4.677l-2.3385 3.118-1.358-1.6538c-9.0122-6.0555-16.859 0.72686-24.365 3.2128z" />
+ <path
+ id="path3841"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#000000"
+ inkscape:connector-curvature="0"
+ d="m442.17 281.64c-2.9396-0.34095-1.2111-2.2379-1.3641-3.5077 8.801-10.515 16.312-5.2627 19.487-2.7282-6.6217-3.794-15.027-0.032-17.149 3.118z" />
+ <path
+ id="path3870"
+ sodipodi:nodetypes="cccc"
+ style="fill:#a05a2c"
+ inkscape:connector-curvature="0"
+ d="m 406.46063,309.18524 1.38165,1.38164 c -3.15232,0.74477 -4.74846,3.98336 -5.63271,6.8018 0.19898,-3.86096 1.76712,-5.90774 4.25106,-8.18313 z" />
+ <path
+ id="path3843"
+ sodipodi:nodetypes="csccsc"
+ style="fill:#000000"
+ inkscape:connector-curvature="0"
+ d="m 405.39628,310.95144 c 5.41074,4.35865 2.85569,3.90777 7.51499,4.20833 4.65929,0.3006 52.30416,-11.87364 52.30416,-11.87364 l 1.50297,-1.2024 c 0,0 -2.57402,26.86011 -16.23206,31.56251 -17.25785,5.94253 -36.37213,-2.25448 -45.08975,-22.69527 z" />
+ <path
+ id="path3845"
+ sodipodi:nodetypes="cccssc"
+ style="fill:#ffffff"
+ inkscape:connector-curvature="0"
+ d="m 411.41216,316.35801 49.74896,-11.57284 1.50297,10.67123 c 0,0 -3.57328,12.94724 -8.86802,15.93204 -15.18545,8.56105 -32.1641,-0.1503 -35.47052,-4.35865 -2.96127,-3.76895 -6.91378,-10.67124 -6.91378,-10.67124 z" />
+ <path
+ id="path3866"
+ sodipodi:nodetypes="ccc"
+ style="fill:#a05a2c"
+ inkscape:connector-curvature="0"
+ d="m428.53 292.55c8.2683 4.3004 15.87 1.12 11.108-6.2359 1.4887 5.6811-1.7655 7.1395-11.108 6.2359z" />
+ <path
+ id="path3872"
+ sodipodi:nodetypes="cccccc"
+ style="fill:#b3b3b3"
+ inkscape:connector-curvature="0"
+ d="m 420.6982,323.96269 8.50243,-0.85024 -0.21255,-2.65693 1.16909,2.44437 c 4.2307,0.18786 8.90889,-1.4145 13.39071,-2.23181 -8.29342,2.80309 -16.82362,3.0421 -22.84952,3.29461 z" />
+ <path
+ id="path3874"
+ sodipodi:nodetypes="cssssssscscsssssasssc"
+ style="fill:#c83737"
+ inkscape:connector-curvature="0"
+ d="m445.63 212.36s-17.638-4.4095-26.732-2.7559c-9.0946 1.6536-47.678 1.1024-66.418 18.465-6.7928 6.2934-54.292 68.898-58.426 73.859-4.1339 4.9607-11.575 12.677-15.158 13.78-3.5827 1.1024-8.2678 4.4095-2.4803 5.7874 5.7874 1.378 11.85 0 15.158 0.55118 3.3071 0.55119 7.1654 1.378 11.299 0.27559 4.1339-1.1024 9.0946-0.55118 9.0946-0.55118s-2.2047 4.6851 1.378 5.5118c3.5827 0.82678 6.063-0.82678 6.063-0.82678s-0.55119 2.2047 3.3071 3.5827 6.2773 0.4057 9.0946 1.6536c6.3502 2.8128 14.055 9.9213 16.536 12.677 2.4803 2.7559 17.333 20.119 25.355 20.394 0.9314 0.0319-2.1516-0.70731-3.666-2.6058-2.4332-3.0504-6.3973-7.8437-7.1017-12.619-5.8484-39.646 20.202-110.15 26.201-117.34 2.1332-2.557-0.82677-1.378-0.55118-4.4095s3.0663-8.1815 8.5434-7.9922c8.3556 0.28881 39.692-7.561 48.504-7.441z" />
+ <path
+ id="path3888"
+ sodipodi:nodetypes="sssss"
+ style="fill:#e9c6af"
+ inkscape:connector-curvature="0"
+ d="m419.17 367.58c-4.1814 1.5838-0.29262 6.0318 2.5334 4.2872 4.0896-2.5248 8.6987-3.5242 13.057-5.2616 2.0221-0.80619 0.0594-4.9534-2.7282-3.8975z" />
+ <path
+ id="path3890"
+ d="m423.95 374.4c-4.0874 1.8127-0.29262 6.0318 2.5334 4.2872 4.0896-2.5248 6.5667-4.0837 11.108-5.2616 3.4837-0.90363 0.28905-5.2034-2.4359-3.9949z"
+ sodipodi:nodetypes="sssss"
+ style="fill:#e9c6af"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path3920"
+ sodipodi:nodetypes="csssssc"
+ style="fill:#550000"
+ inkscape:connector-curvature="0"
+ d="m330.51 591.29c-0.58462-4.4821 0.19488-14.421 1.1692-15.005 0.97437-0.58462-2.5334-3.118-3.5077-2.1436-0.97436 0.97437-2.8066 9.2619-3.118 12.082-0.32958 2.9853-12.365 33.384-17.539 39.559-1.7698 2.1126 9.5488 6.8206 12.082-0.58463 2.5334-7.4052 4.0923-24.554 10.913-33.908z" />
+ <path
+ id="path3922"
+ sodipodi:nodetypes="cccssasc"
+ style="fill:#550000"
+ inkscape:connector-curvature="0"
+ d="m474.52 570.44c0.97437-0.58462 11.498-11.887 11.498-11.887l1.7539 1.1692s22.8-16.564 27.672-16.954c4.8718-0.38975 13.836 6.8206 11.108 9.7437-2.7282 2.9231-18.149 4.9661-26.503 9.159-8.3571 4.1947-20.851 16.174-23.19 15.785-2.3385-0.38975-2.3385-7.0154-2.3385-7.0154z" />
+ <path
+ id="path3930"
+ sodipodi:nodetypes="csccscsssccc"
+ style="fill:#f4eed7"
+ inkscape:connector-curvature="0"
+ d="m236.73 374.68c-14.331-2.8937-35.551 16.26-35.276 38.307 0.2756 22.047 5.2363 23.701 5.2363 23.701l-0.82678 3.3071s15.433 18.74 22.874 19.016c7.441 0.27559 9.0946-4.4095 9.0946-4.4095s-0.82678 4.4095 6.3386 3.3071 23.425-14.606 24.528-28.11c1.1024-13.504-3.5827-45.473-10.197-49.882-6.6142-4.4095-11.575-3.5827-11.575-3.5827l-1.6536 1.1024z" />
+ <path
+ id="path4151"
+ style="fill:#c8c4b7"
+ inkscape:connector-curvature="0"
+ d="m201.78 420.81c1.1789 14.621 4.9062 15.875 4.9062 15.875l-0.81 3.32s15.434 18.724 22.875 19c7.441 0.27559 9.0938-4.4062 9.0938-4.4062s-0.82165 4.4149 6.3438 3.3125c4.2799-0.65844 11.774-5.7604 17.375-12.625-6.0825 2.9203-12.237 5.658-20.688 3.25 0 0.30005-12.13 6.2873-18.469 0.5625-5.1294-4.6327-14.875-14.062-14.875-14.062l2.1875-3.8438-7.9375-10.375z" />
+ <path
+ id="path3932"
+ style="fill:#550000"
+ inkscape:connector-curvature="0"
+ d="m238.09 375.12c2.4583 2.7892 4.5962 5.7338 5.6875 10.781 0.337 1.5586 0.78577 5.1442 1.2188 9.4375-1.1998 0.0565-2.339 0.0937-3.3438 0.0937-2.4379 0-8.0844-0.47953-14.312-1.0938-1.4924-6.6313-3.4085-13.401-4.7188-16.75-1.1389 0.62285-2.2952 1.3112-3.4062 2.0938 2.3233 4.1434 3.9209 9.2943 4.9688 14.344-6.4272-0.65817-12.233-1.3068-16.625-1.8125-0.77609 1.2501-1.5059 2.539-2.1562 3.875 5.2128 0.68798 14.091 1.833 19.594 2.4375 0.69276 4.6331 0.9149 8.8729 0.84375 11.719-0.0658 2.6312-0.49168 6.299-1.0625 10.188-6.0842-0.59368-18.031-2.4583-23.219-3.2812 0.077 1.7255 0.20961 3.2834 0.34375 4.7188 5.6788 0.86785 18.8 2.8688 21.031 3.1875 0.2046 0.0292 0.59764 0.0394 1.0938 0.0312-1.0342 6.2334-2.225 12.366-2.8438 15.562-0.19025 0.98298-0.54084 2.047-0.96875 3.125-3.5059-0.18127-9.1178-1.1472-12.625-1.7812 0.69598 0.79984 1.5571 1.7461 2.5938 2.875 2.514 0.27668 5.6933 0.6238 9.125 0.96875-0.91101 1.8883-1.9732 3.7378-2.9688 5.3125 0.64994 0.60817 1.3061 1.2021 1.9688 1.7812 1
.5457-2.1946 3.24-4.7201 4.375-6.7812 7.2176 0.69891 14.339 1.3031 16.031 1.125 1.3005-0.1369 2.3594-0.85 3.2188-1.6875-1.7847 4.5159-3.6964 8.1428-5.25 10.75 0.85823-0.92045 1.1562-1.75 1.1562-1.75s-0.0513 0.33797 0 0.78125c1.5772-2.9021 3.7076-7.0366 5.7188-11.781 0.0136-0.0221 0.018-0.0406 0.0312-0.0625 0.51126-0.84506 0.78125-1.5 0.78125-1.5s11.48 1.3364 12.844 1.5312c0.31929 0.0456 1.1795-0.35621 2.25-1-1.2599 3.363-2.7627 6.5018-4.0312 8.9688 0.50885-0.4321 1.0274-0.87826 1.5312-1.3438 1.2176-2.4191 2.5668-5.3923 3.8125-8.4688 1.8701-1.2176 3.9753-2.7413 5.6562-3.9688 0.85009-1.793 1.4808-3.6458 1.875-5.5-1.2187 1.2046-3.3784 3.301-5.9688 5.375 1.5678-4.2397 2.715-7.989 2.6875-9.4375-0.0413-2.175-0.12055-5.208-0.21875-8.2812 1.7196-0.65162 2.923-1.379 3.75-2.0312-0.10104-1.423-0.22405-2.8885-0.375-4.375-0.93557 0.73761-1.9715 1.5218-3.1562 2.2188-0.0939 0.0553-0.23873 0.0995-0.375 0.15625-0.26997-6.8199-0.68513-14.324-1.375-20.031 0.73425-0.31869 1.3662-0.59735 1.875-0.84375-0
.22312-0.93551-0.44805-1.8355-0.6875-2.7188-0.48191 0.36391-1.0345 0.74392-1.5312 1-0.39343-2.5701-0.86084-4.5761-1.4062-5.625-1.6412-3.1562-3.7552-6.5988-5.3438-9.125-0.54156-0.28337-1.0862-0.53199-1.5938-0.75 0.91425 1.2331 2.0005 3.017 3.0312 5.5938 0.65974 1.6494 1.4284 5.5595 2.1562 10.531-2.8895 0.43045-7.3137 0.94359-11.5 1.25-0.24633-4.8702-0.58277-8.8117-1-10.031-1.1308-3.3055-2.7557-6.1864-4.2188-8.4062l-4.9688-1.5938zm22.125 21.875c0.78201 5.9766 1.4565 13.004 1.8125 19.594-3.0908 0.66366-8.0185 1.3723-13.25 2 0.0239-5.8367-0.0704-13.66-0.34375-20.438 4.8565-0.30585 9.1126-0.6009 10.156-0.75 0.48113-0.0687 1.049-0.22984 1.625-0.40625zm-14.938 1.3438c0.65877 7.0396 1.2436 15.098 1.5 20.469-7.7153 0.88626-15.35 1.5764-18.531 1.7188 0.78957-5.01 1.3795-9.6593 1.3125-12.406-0.0549-2.2502-0.56696-5.609-1.2812-9.2812 3.7412 0.16141 10.638-0.14077 17-0.5zm16.938 22.344c0.18575 5.647 0.0725 10.676-0.5 13.938-0.24495 1.3955-0.60143 2.8411-1.0312 4.2812-1.2595 0.89671-2.395 1.56-3.
25 1.75-3.2141 0.71425-10.878-0.95369-12.188-1.25 1.786-4.8048 3.1606-9.7962 3.4062-14.156 0.0343-0.60967 0.072-1.5757 0.0937-2.4688 5.8082-0.71561 10.964-1.4797 13.469-2.0938zm-15.28 2.32c0.00055 0.45811-0.0119 0.82011-0.0312 1.0938-0.42533 6.0078-1.6032 11.441-3.0938 16.219-0.50909 0.52621-1.1882 1.2137-2.1562 2.0938-1.9068 1.7335-12.727 1.1561-17.844 1.2812 0.0304-0.10134 0.0734-0.22095 0.0937-0.3125 0.43407-1.9533 2.1796-10.177 3.625-18.469 4.76-0.32475 12.272-1.0573 19.406-1.9062z" />
+ <path
+ id="path4107"
+ style="fill:#a02c2c"
+ inkscape:connector-curvature="0"
+ d="m326.75 307.41c-1.3831 0.00039-3.3348 3.7662-3.8438 4.8125-1.3277 2.7292-3.3027 10.433-4.3438 14.656 0.53461-0.22408 0.84375-0.4375 0.84375-0.4375s-0.0431 0.28357 0.0312 0.6875c2.9089-4.6719 8.7932-13.981 8.7188-15.656-0.13397-3.0144-0.68176-4.0627-1.4062-4.0625zm-12.469 4.4375c-1.0718 0.0974-2.4796 0.59726-3.8438 2.1562-1.8757 2.1436-1.8103 5.6319-1.5938 7.625 1.819-0.006 3.125 0.15625 3.125 0.15625s-0.15144 0.31281-0.3125 0.8125l0.15625-0.0312c1.4828-4.1125 2.464-6.346 4.2812-10.531 0 0-0.7407-0.28494-1.8125-0.1875z" />
+ <path
+ id="path4127"
+ sodipodi:nodetypes="csccsssc"
+ style="fill:#a02c2c"
+ inkscape:connector-curvature="0"
+ d="m475.55 462.11c1.6536-0.27559-5.577 7.6366-15.187 11.107-17.337 6.2611-56.62 41.74-70.124 64.614 0 0-3.4351-0.12395-4.255 2.9439-0.33267 2.5806 2.3809 2.9432 1.0536 5.3155-1.4278 2.5521-8.5657 2.8358-7.441 1.783 6.2261-5.8281 28.339-39.682 62.788-65.592 14.047-10.565 29.845-13.514 33.166-20.171z" />
+ <path
+ id="path4129"
+ sodipodi:nodetypes="cascsasssc"
+ style="fill:#a02c2c"
+ inkscape:connector-curvature="0"
+ d="m449.22 526.39s1.1029-10.783 3.1693-15.709c6.7172-16.012 29.351-41.477 29.213-43.13-0.13779-1.6536-2.8937-4.2717-2.8937-4.2717s1.7914 5.0985 0.82678 5.6496c-1.9912 1.1378-23.168 28.065-29.488 44.784-3.3627 8.8955-4.5473 28.662-3.9961 28.248 0.55118-0.41339 8.5903-4.7274 7.441-6.2008-1.1091-1.4218-3.9264-2.3817-4.3406-3.5827-0.68898-1.998-0.48229-3.5138 0.0689-5.7874z" />
+ <path
+ id="path4252"
+ sodipodi:nodetypes="ccssccsccc"
+ style="fill:#d38d5f"
+ inkscape:connector-curvature="0"
+ d="m493.31 384.05c7.0807-2.5735 5.8406-3.6785 7.1654-5.2362 0 0-2.8229 10.294-1.378 15.158 0.63337 2.1317 2.621 3.6064 4.1339 5.2362 3.0566 3.2927 6.1034-2.1424 3.0315-5.5118 2.9883 3.1614 3.7882 5.3658 7.7166 5.7874l-12.815 1.5158c-3.1325 0.37052-2.8134-8.4974-4.4095-12.815l-3.9961 3.5827c1.0172-2.9889 2.3671-6.1442 0.55118-7.7166z" />
+ <path
+ id="path4568"
+ sodipodi:nodetypes="cccsc"
+ style="fill:#a02c2c"
+ inkscape:connector-curvature="0"
+ d="m357.47 228.87 29.898-1.3012c0.18003 1.9552 0.83437 3.3185 1.8513 3.4103 0 0-27.867-2.9231-29.231-1.3641-1.3641 1.559-2.5179-0.74497-2.5179-0.74497z" />
+ </g>
+ <metadata
+ id="metadata58">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title>Little Red Riding Hood</dc:title>
+ <dc:date>2011-10-15T18:09:37</dc:date>
+ <dc:description />
+ <dc:source>https://openclipart.org/detail/163771/little-red-riding-hood-by-tzunghaor</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>tzunghaor</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>basket</rdf:li>
+ <rdf:li>fairy tale</rdf:li>
+ <rdf:li>girl</rdf:li>
+ <rdf:li>hood</rdf:li>
+ <rdf:li>jump</rdf:li>
+ <rdf:li>red</rdf:li>
+ <rdf:li>skip</rdf:li>
+ <rdf:li>skirt</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/publicdomain/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+</svg>
diff --git a/docs/_static/section/tutorials/riding_hood.png b/docs/_static/section/tutorials/riding_hood.png
new file mode 100644
index 0000000..764eb13
Binary files /dev/null and b/docs/_static/section/tutorials/riding_hood.png differ
diff --git a/docs/tutorials.rst b/docs/tutorials.rst
index 271ccea..f4db5bd 100644
--- a/docs/tutorials.rst
+++ b/docs/tutorials.rst
@@ -26,6 +26,11 @@ Tutorial
License: Public Domain
Alternate: https://openclipart.org/detail/174179/miroir-rectangulaire-by-defaz36-174179
+ * Over the River and Through the Wood - riding_hood.png
+ Source: https://openclipart.org/detail/163771/little-red-riding-hood-by-tzunghaor
+ Author: tzunghaor
+ License: Public Domain
+
* East of the Sun & West of the Moon - windrose.png
Source: https://commons.wikimedia.org/wiki/File:Compass_card_%28sl%29.svg
Author: Andrejj
@@ -43,8 +48,8 @@ Tutorial
Author: Unknown (jarda?)
License: Public Domain
-Getting started with any new library can be rather daunting, so let's get our
-feet wet by jumping straight in with some tutorials...
+Getting started with any new library can be daunting, so let's get our feet wet
+by jumping straight in with some tutorials...
.. list-table::
:widths: 1 10
@@ -90,6 +95,18 @@ feet wet by jumping straight in with some tutorials...
This walks you through both where to get them and a small script to tell
you the fastest Tor exits.
+ * - .. image:: /_static/section/tutorials/riding_hood.png
+ :target: tutorials/over_the_river.html
+
+ - .. image:: /_static/label/over_the_river.png
+ :target: tutorials/over_the_river.html
+
+ `Hidden services
+ <https://www.torproject.org/docs/hidden-services.html.en>`_ are a way
+ of providing a service that isn't easily trackable. As a dissident, for
+ instance, this could let you safely publish a blog without getting your
+ door kicked down. Here we'll walk you through an example.
+
* - .. image:: /_static/section/tutorials/windrose.png
:target: tutorials/east_of_the_sun.html
1
0
commit f926385948690109327ef44b6f5faa835b9c206b
Author: Damian Johnson <atagar(a)torproject.org>
Date: Sat Dec 20 13:19:42 2014 -0800
Hidden service tutorial
Writing a tutorial for creating hidden services. This is based on a nice one by
Jordan Wright...
https://jordan-wright.github.io/blog/2014/10/06/creating-tor-hidden-service…
---
docs/_static/hidden_service.png | Bin 0 -> 25348 bytes
docs/_templates/layout.html | 1 +
docs/contents.rst | 1 +
docs/tutorials/over_the_river.rst | 87 +++++++++++++++++++++++++++++++++++++
4 files changed, 89 insertions(+)
diff --git a/docs/_static/hidden_service.png b/docs/_static/hidden_service.png
new file mode 100644
index 0000000..679b3be
Binary files /dev/null and b/docs/_static/hidden_service.png differ
diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html
index 3884fc0..32657da 100644
--- a/docs/_templates/layout.html
+++ b/docs/_templates/layout.html
@@ -26,6 +26,7 @@
<li><a href="{{ pathto('tutorials/to_russia_with_love') }}">Client Usage</a></li>
<li><a href="{{ pathto('tutorials/tortoise_and_the_hare') }}">Event Listening</a></li>
<li><a href="{{ pathto('tutorials/mirror_mirror_on_the_wall') }}">Tor Descriptors</a></li>
+ <li><a href="{{ pathto('tutorials/over_the_river') }}">Hidden Services</a></li>
<li><a href="{{ pathto('tutorials/east_of_the_sun') }}">Utilities</a></li>
<li><a href="{{ pathto('tutorials/down_the_rabbit_hole') }}">Interpreter</a></li>
<li><a href="{{ pathto('tutorials/double_double_toil_and_trouble') }}">Examples</a></li>
diff --git a/docs/contents.rst b/docs/contents.rst
index cb4e578..db703a2 100644
--- a/docs/contents.rst
+++ b/docs/contents.rst
@@ -9,6 +9,7 @@ Contents
tutorials/to_russia_with_love
tutorials/tortoise_and_the_hare
tutorials/mirror_mirror_on_the_wall
+ tutorials/over_the_river
tutorials/east_of_the_sun
tutorials/down_the_rabbit_hole
tutorials/double_double_toil_and_trouble
diff --git a/docs/tutorials/over_the_river.rst b/docs/tutorials/over_the_river.rst
new file mode 100644
index 0000000..968f53d
--- /dev/null
+++ b/docs/tutorials/over_the_river.rst
@@ -0,0 +1,87 @@
+Over the River and Through the Wood
+===================================
+
+`Hidden services <https://www.torproject.org/docs/hidden-services.html.en>`_ give you a way of providing a service without exposing your address. These services are only accessible through Tor or `Tor2web <https://tor2web.org/>`_, and useful for a surprising number of things...
+
+ * Hosting an anonymized site. This is usually the first thing that comes to mind, and something we'll demonstrate in a sec.
+ * Providing an endpoint Tor users can reach without exiting the Tor network. This eliminates the risk of an unreliable or malicious exit getting in the way. A great example of this is `Facebook <http://arstechnica.com/security/2014/10/facebook-offers-hidden-service-to-t…>`_.
+ * Personal services. For instance you can host your home SSH server as a hidden service to prevent eavesdroppers from knowing where you live while traveling abroad.
+
+Hidden services can be `configured through your torrc <https://www.torproject.org/docs/tor-manual.html.en#_hidden_service_options>`_, but Stem also provides some methods to easily work with them...
+
+ * :func:`~stem.control.Controller.create_hidden_service`
+ * :func:`~stem.control.Controller.remove_hidden_service`
+ * :func:`~stem.control.Controller.get_hidden_service_conf`
+ * :func:`~stem.control.Controller.set_hidden_service_conf`
+
+The main threat to your anonymity when running a hidden service is the service itself. Debug information for instance might leak your real address, undermining what Tor provides. This includes the following example, **do not rely on it not to leak**.
+
+But with that out of the way lets take a look at a simple example based on one by `Jordan Wright <https://jordan-wright.github.io/blog/2014/10/06/creating-tor-hidden-service…>`_...
+
+::
+
+ import os
+ import shutil
+
+ from stem.control import Controller
+ from flask import Flask
+
+ app = Flask(__name__)
+
+
+ @app.route('/')
+ def index():
+ return "<h1>Hi Grandma!</h1>"
+
+
+ print ' * Connecting to tor'
+
+ with Controller.from_port() as controller:
+ controller.authenticate()
+
+ # All hidden services have a directory on disk. Lets put ours in tor's data
+ # directory.
+
+ hidden_service_dir = os.path.join(controller.get_conf('DataDirectory', '/tmp'), 'hello_world')
+
+ # Create a hidden service where visitors of port 80 get redirected to local
+ # port 5000 (this is where Flask runs by default).
+
+ print " * Creating our hidden service in %s" % hidden_service_dir
+ result = controller.create_hidden_service(hidden_service_dir, 80, target_port = 5000)
+
+ # The hostname is only available when we can read the hidden service
+ # directory. This requires us to be running with the same user as tor.
+
+ if result.hostname:
+ print " * Our service is available at %s, press ctrl+c to quit" % result.hostname
+ else:
+ print " * Unable to determine our service's hostname, probably due to being unable to read the hidden service directory"
+
+ try:
+ app.run()
+ finally:
+ # Shut down the hidden service and clean it off disk. Note that you *don't*
+ # want to delete the hidden service directory if you'd like to have this
+ # same *.onion address in the future.
+
+ print " * Shutting down our hidden service"
+ controller.remove_hidden_service(hidden_service_dir)
+ shutil.rmtree(hidden_service_dir)
+
+Now if we run this...
+
+::
+
+ % python example.py
+ * Connecting to tor
+ * Creating our hidden service in /home/atagar/.tor/hello_world
+ * Our service is available at uxiuaxejc3sxrb6i.onion, press ctrl+c to quit
+ * Running on http://127.0.0.1:5000/
+ 127.0.0.1 - - [15/Dec/2014 13:05:43] "GET / HTTP/1.1" 200 -
+ * Shutting down our hidden service
+
+... we'll have a service we can visit via the `Tor Browser Bundle <https://www.torproject.org/download/download-easy.html.en>`_...
+
+.. image:: /_static/hidden_service.png
+
1
0

20 Dec '14
commit 2281830e864176f49aa44927366b824ae3fd3be7
Merge: 2ae1c7f 730ab25
Author: Damian Johnson <atagar(a)torproject.org>
Date: Sat Dec 20 13:38:08 2014 -0800
Hidden service tutorial and improvements
Hidden service tutorial based on a nice one by Jordan Wright...
https://jordan-wright.github.io/blog/2014/10/06/creating-tor-hidden-service…
This includes a few improvements to our new hidden service methods along the
way to make them even nicer for common use cases.
docs/_static/hidden_service.png | Bin 0 -> 25348 bytes
docs/_static/label/over_the_river.png | Bin 0 -> 4264 bytes
docs/_static/label/resources/over_the_river.xcf | Bin 0 -> 9156 bytes
.../section/tutorials/resources/riding_hood.svg | 393 ++++++++++++++++++++
docs/_static/section/tutorials/riding_hood.png | Bin 0 -> 10579 bytes
docs/_templates/layout.html | 1 +
docs/contents.rst | 1 +
docs/tutorials.rst | 21 +-
docs/tutorials/over_the_river.rst | 87 +++++
stem/control.py | 179 ++++++---
test/integ/control/controller.py | 36 +-
test/unit/tutorial.py | 73 ++++
12 files changed, 730 insertions(+), 61 deletions(-)
1
0

20 Dec '14
commit 730ab250aa473645c498d1a17254e494fb6ec115
Author: Damian Johnson <atagar(a)torproject.org>
Date: Sat Dec 20 13:36:54 2014 -0800
Unit test for hidden service tutorial example
---
docs/tutorials/over_the_river.rst | 2 +-
test/unit/tutorial.py | 73 +++++++++++++++++++++++++++++++++++++
2 files changed, 74 insertions(+), 1 deletion(-)
diff --git a/docs/tutorials/over_the_river.rst b/docs/tutorials/over_the_river.rst
index 968f53d..b7aa8f4 100644
--- a/docs/tutorials/over_the_river.rst
+++ b/docs/tutorials/over_the_river.rst
@@ -16,7 +16,7 @@ Hidden services can be `configured through your torrc <https://www.torproject.or
The main threat to your anonymity when running a hidden service is the service itself. Debug information for instance might leak your real address, undermining what Tor provides. This includes the following example, **do not rely on it not to leak**.
-But with that out of the way lets take a look at a simple example based on one by `Jordan Wright <https://jordan-wright.github.io/blog/2014/10/06/creating-tor-hidden-service…>`_...
+But with that out of the way lets take a look at a simple `Flask <http://flask.pocoo.org/>`_ example based on one by `Jordan Wright <https://jordan-wright.github.io/blog/2014/10/06/creating-tor-hidden-service…>`_...
::
diff --git a/test/unit/tutorial.py b/test/unit/tutorial.py
index 1ee6396..5a861b6 100644
--- a/test/unit/tutorial.py
+++ b/test/unit/tutorial.py
@@ -17,6 +17,13 @@ try:
except ImportError:
from mock import Mock, patch
+OVER_THE_RIVER_OUTPUT = """\
+ * Connecting to tor
+ * Creating our hidden service in /home/atagar/.tor/hello_world
+ * Our service is available at uxiuaxejc3sxrb6i.onion, press ctrl+c to quit
+ * Shutting down our hidden service
+"""
+
MIRROR_MIRROR_OUTPUT = """\
1. speedyexit (102.13 KB/s)
2. speedyexit (102.13 KB/s)
@@ -49,6 +56,72 @@ class TestTutorial(unittest.TestCase):
self.assertEqual('My Tor relay has read 33406 bytes and written 29649.\n', stdout_mock.getvalue())
@patch('sys.stdout', new_callable = StringIO.StringIO)
+ @patch('shutil.rmtree')
+ @patch('stem.control.Controller.from_port', spec = Controller)
+ def test_over_the_river(self, from_port_mock, rmtree_mock, stdout_mock):
+ def tutorial_example(app):
+ import os
+ import shutil
+
+ from stem.control import Controller
+
+ @app.route('/')
+ def index():
+ return "<h1>Hi Grandma!</h1>"
+
+ print ' * Connecting to tor'
+
+ with Controller.from_port() as controller:
+ controller.authenticate()
+
+ # All hidden services have a directory on disk. Lets put ours in tor's data
+ # directory.
+
+ hidden_service_dir = os.path.join(controller.get_conf('DataDirectory', '/tmp'), 'hello_world')
+
+ # Create a hidden service where visitors of port 80 get redirected to local
+ # port 5000 (this is where flask runs by default).
+
+ print " * Creating our hidden service in %s" % hidden_service_dir
+ result = controller.create_hidden_service(hidden_service_dir, 80, target_port = 5000)
+
+ # The hostname is only available we can read the hidden service directory.
+ # This requires us to be running with the same user as tor.
+
+ if result.hostname:
+ print " * Our service is available at %s, press ctrl+c to quit" % result.hostname
+ else:
+ print " * Unable to determine our service's hostname, probably due to being unable to read the hidden service directory"
+
+ try:
+ app.run()
+ finally:
+ # Shut down the hidden service and clean it off disk. Note that you *don't*
+ # want to delete the hidden service directory if you'd like to have this
+ # same *.onion address in the future.
+
+ print " * Shutting down our hidden service"
+ controller.remove_hidden_service(hidden_service_dir)
+ shutil.rmtree(hidden_service_dir)
+
+ flask_mock = Mock()
+
+ hidden_service_data = Mock()
+ hidden_service_data.hostname = 'uxiuaxejc3sxrb6i.onion'
+
+ controller = from_port_mock().__enter__()
+ controller.get_conf.return_value = '/home/atagar/.tor'
+ controller.create_hidden_service.return_value = hidden_service_data
+
+ tutorial_example(flask_mock)
+
+ controller.get_conf.assert_called_once_with('DataDirectory', '/tmp')
+ controller.create_hidden_service.assert_called_once_with('/home/atagar/.tor/hello_world', 80, target_port = 5000)
+ rmtree_mock.assert_called_once_with('/home/atagar/.tor/hello_world')
+
+ self.assertEqual(OVER_THE_RIVER_OUTPUT, stdout_mock.getvalue())
+
+ @patch('sys.stdout', new_callable = StringIO.StringIO)
@patch('stem.descriptor.remote.DescriptorDownloader')
def test_mirror_mirror_on_the_wall_1(self, downloader_mock, stdout_mock):
def tutorial_example():
1
0

[translation/tor-launcher-network-settings] Update translations for tor-launcher-network-settings
by translation@torproject.org 20 Dec '14
by translation@torproject.org 20 Dec '14
20 Dec '14
commit 87e6e951897e745ac8cf0bd151eb2ea42b00f864
Author: Translation commit bot <translation(a)torproject.org>
Date: Sat Dec 20 20:15:32 2014 +0000
Update translations for tor-launcher-network-settings
---
az/network-settings.dtd | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/az/network-settings.dtd b/az/network-settings.dtd
index b026d3d..4da37f8 100644
--- a/az/network-settings.dtd
+++ b/az/network-settings.dtd
@@ -2,23 +2,23 @@
<!-- For "first run" wizard: -->
-<!ENTITY torsettings.prompt "Before you connect to the Tor network, you need to provide information about this computer's Internet connection.">
+<!ENTITY torsettings.prompt "Tor şəbəkəsinə qoşulmaq üçün, kompüterin intrenet bağlantısı haqqında bəzi məlumatları verməlisiniz.">
<!ENTITY torSettings.yes "Bəli">
<!ENTITY torSettings.no "Xeyr">
<!ENTITY torSettings.firstQuestion "Which of the following best describes your situation?">
<!ENTITY torSettings.configurePrompt1 "This computer's Internet connection is censored or proxied.">
-<!ENTITY torSettings.configurePrompt2 "I need to configure bridge or proxy settings.">
+<!ENTITY torSettings.configurePrompt2 "Mən proksi və ya körpü quraşdırmalıyam.">
<!ENTITY torSettings.configure "Quraşdır">
<!ENTITY torSettings.connectPrompt2 "I would like to connect directly to the Tor network.">
-<!ENTITY torSettings.connectPrompt3 "This will work in most situations.">
+<!ENTITY torSettings.connectPrompt3 "Bu əksər hallarda işləyir.">
<!ENTITY torSettings.connect "Qoşul">
<!ENTITY torSettings.proxyQuestion "Bu kompüterin İnernetə qoşulmaq üçün proksiyə ehtiyacı var?">
<!-- see https://www.torproject.org/docs/proxychain.html.en -->
-<!ENTITY torSettings.proxyHelp "If you are not sure how to answer this question, look at the Internet settings in another browser to see whether it is configured to use a proxy.">
-<!ENTITY torSettings.enterProxy "Proxy parametrlərini daxil edin">
+<!ENTITY torSettings.proxyHelp "Əgər siz bu suala nə cavab verəcəyinizə əmin deyilsinizsə, proksinin necə konfiqurasiya edildiyini öyrənmək üçün başqa bir brauzerin parametrlərinə nəzər salın ">
+<!ENTITY torSettings.enterProxy "Proksy parametrlərini daxil edin">
<!ENTITY torSettings.bridgeQuestion "Does your Internet Service Provider (ISP) block or otherwise censor connections to the Tor Network?">
<!ENTITY torSettings.bridgeHelp "If you are not sure how to answer this question, choose No.  If you choose Yes, you will be asked to configure Tor Bridges, which are unlisted relays that make it more difficult to block connections to the Tor Network.">
<!ENTITY torSettings.bridgeSettingsPrompt "You may use the provided set of bridges or you may obtain and enter a custom set of bridges.">
@@ -30,7 +30,7 @@
<!ENTITY torsettings.optional "Əlavə">
-<!ENTITY torsettings.useProxy.checkbox "This computer needs to use a proxy to access the Internet">
+<!ENTITY torsettings.useProxy.checkbox "Bu kompüte İnternetə qoşulmaq üçün proksi istifadə etməlidir">
<!ENTITY torsettings.useProxy.type "Proxy Tipi:">
<!ENTITY torsettings.useProxy.address "Ünvan:">
<!ENTITY torsettings.useProxy.address.placeholder "İP ünvanı və ya anakompüterin adı">
1
0

[translation/tor-launcher-network-settings] Update translations for tor-launcher-network-settings
by translation@torproject.org 20 Dec '14
by translation@torproject.org 20 Dec '14
20 Dec '14
commit e75b75f286c2a1cb29f9cd4a635d75efb38253a2
Author: Translation commit bot <translation(a)torproject.org>
Date: Sat Dec 20 19:45:36 2014 +0000
Update translations for tor-launcher-network-settings
---
az/network-settings.dtd | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/az/network-settings.dtd b/az/network-settings.dtd
index 3cf2d1d..b026d3d 100644
--- a/az/network-settings.dtd
+++ b/az/network-settings.dtd
@@ -1,4 +1,4 @@
-<!ENTITY torsettings.dialog.title "Tor Network Settings">
+<!ENTITY torsettings.dialog.title "Tor şəbəkə paramertləri">
<!-- For "first run" wizard: -->
@@ -10,32 +10,32 @@
<!ENTITY torSettings.firstQuestion "Which of the following best describes your situation?">
<!ENTITY torSettings.configurePrompt1 "This computer's Internet connection is censored or proxied.">
<!ENTITY torSettings.configurePrompt2 "I need to configure bridge or proxy settings.">
-<!ENTITY torSettings.configure "Configure">
+<!ENTITY torSettings.configure "Quraşdır">
<!ENTITY torSettings.connectPrompt2 "I would like to connect directly to the Tor network.">
<!ENTITY torSettings.connectPrompt3 "This will work in most situations.">
-<!ENTITY torSettings.connect "Connect">
+<!ENTITY torSettings.connect "Qoşul">
-<!ENTITY torSettings.proxyQuestion "Does this computer need to use a proxy to access the Internet?">
+<!ENTITY torSettings.proxyQuestion "Bu kompüterin İnernetə qoşulmaq üçün proksiyə ehtiyacı var?">
<!-- see https://www.torproject.org/docs/proxychain.html.en -->
<!ENTITY torSettings.proxyHelp "If you are not sure how to answer this question, look at the Internet settings in another browser to see whether it is configured to use a proxy.">
-<!ENTITY torSettings.enterProxy "Enter the proxy settings.">
+<!ENTITY torSettings.enterProxy "Proxy parametrlərini daxil edin">
<!ENTITY torSettings.bridgeQuestion "Does your Internet Service Provider (ISP) block or otherwise censor connections to the Tor Network?">
<!ENTITY torSettings.bridgeHelp "If you are not sure how to answer this question, choose No.  If you choose Yes, you will be asked to configure Tor Bridges, which are unlisted relays that make it more difficult to block connections to the Tor Network.">
<!ENTITY torSettings.bridgeSettingsPrompt "You may use the provided set of bridges or you may obtain and enter a custom set of bridges.">
<!-- Other: -->
-<!ENTITY torsettings.startingTor "Waiting for Tor to start…">
-<!ENTITY torsettings.restartTor "Restart Tor">
+<!ENTITY torsettings.startingTor "Torun açılması üçün gözləyin...">
+<!ENTITY torsettings.restartTor "Tor`u yenidən başlat">
-<!ENTITY torsettings.optional "Optional">
+<!ENTITY torsettings.optional "Əlavə">
<!ENTITY torsettings.useProxy.checkbox "This computer needs to use a proxy to access the Internet">
-<!ENTITY torsettings.useProxy.type "Proxy Type:">
-<!ENTITY torsettings.useProxy.address "Address:">
-<!ENTITY torsettings.useProxy.address.placeholder "IP address or hostname">
+<!ENTITY torsettings.useProxy.type "Proxy Tipi:">
+<!ENTITY torsettings.useProxy.address "Ünvan:">
+<!ENTITY torsettings.useProxy.address.placeholder "İP ünvanı və ya anakompüterin adı">
<!ENTITY torsettings.useProxy.port "Port:">
-<!ENTITY torsettings.useProxy.username "Username:">
+<!ENTITY torsettings.useProxy.username "İstifadəçi adı:">
<!ENTITY torsettings.useProxy.password "Şifrə:">
<!ENTITY torsettings.useProxy.type.socks4 "SOCKS 4">
<!ENTITY torsettings.useProxy.type.socks5 "SOCKS 5">
@@ -57,6 +57,6 @@
<!ENTITY torsettings.bridgeHelp2 "Use a web browser to visit https://bridges.torproject.org">
<!ENTITY torsettings.bridgeHelp3Heading "Through the Email Autoresponder">
<!ENTITY torsettings.bridgeHelp3.emailDesc "Send email to bridges(a)torproject.org with the line 'get bridges' by itself in the body of the message.  However, to make it harder for an attacker to learn a lot of bridge addresses, you must send this request from one of the following email providers (listed in order of preference):">
-<!ENTITY torsettings.bridgeHelp3.emailList "https://www.riseup.net, https://mail.google.com, or https://mail.yahoo.com">
+<!ENTITY torsettings.bridgeHelp3.emailList "https://www.riseup.net, https://mail.google.com, və ya https://mail.yahoo.com">
<!ENTITY torsettings.bridgeHelp4Heading "Through the Help Desk">
<!ENTITY torsettings.bridgeHelp4 "As a last resort, you can request bridge addresses by sending a polite email message to help(a)rt.torproject.org.  Please note that a person will need to respond to each request.">
1
0