diff options
author | Matthias Baumgartner <dev@igsor.net> | 2023-01-25 16:19:03 +0100 |
---|---|---|
committer | Matthias Baumgartner <dev@igsor.net> | 2023-01-25 16:19:03 +0100 |
commit | 41fdbe254cbfc74896080b9f5820f856067da537 (patch) | |
tree | b55543ee23d2e372f2c4424cd91a7d6ef421562b /tagit | |
parent | f6de8a2f568419fd4ea818f3791242f177a87fba (diff) | |
download | tagit-41fdbe254cbfc74896080b9f5820f856067da537.tar.gz tagit-41fdbe254cbfc74896080b9f5820f856067da537.tar.bz2 tagit-41fdbe254cbfc74896080b9f5820f856067da537.zip |
tagging ported
Diffstat (limited to 'tagit')
-rw-r--r-- | tagit/actions/__init__.py | 5 | ||||
-rw-r--r-- | tagit/actions/tagging.kv | 11 | ||||
-rw-r--r-- | tagit/actions/tagging.py | 162 | ||||
-rw-r--r-- | tagit/apps/port-config.yaml | 12 | ||||
-rw-r--r-- | tagit/assets/icons/scalable/tagging/add_tag.svg | 296 | ||||
-rw-r--r-- | tagit/assets/icons/scalable/tagging/edit_tag.svg | 303 |
6 files changed, 782 insertions, 7 deletions
diff --git a/tagit/actions/__init__.py b/tagit/actions/__init__.py index bf99807..6416a4b 100644 --- a/tagit/actions/__init__.py +++ b/tagit/actions/__init__.py @@ -19,6 +19,7 @@ from . import misc from . import planes from . import search #from . import session +from . import tagging # exports __all__: typing.Sequence[str] = ( @@ -85,8 +86,8 @@ class ActionBuilder(BuilderBase): #'RotateLeft': objects.RotateLeft, #'RotateRight': objects.RotateRight, #'DeleteObject': objects.DeleteObject, - #'AddTag': objects.AddTag, - #'EditTag': objects.EditTag, + 'AddTag': tagging.AddTag, + 'EditTag': tagging.EditTag, #'SetRank1': objects.SetRank1, #'SetRank2': objects.SetRank2, #'SetRank3': objects.SetRank3, diff --git a/tagit/actions/tagging.kv b/tagit/actions/tagging.kv new file mode 100644 index 0000000..53ba926 --- /dev/null +++ b/tagit/actions/tagging.kv @@ -0,0 +1,11 @@ +#:import resource_find kivy.resources.resource_find + +<AddTag>: + source: resource_find('atlas://objects/add_tag') + tooltip: 'Add tags to items' + +<EditTag>: + source: resource_find('atlas://objects/edit_tag') + tooltip: 'Edit tags of items' + +## EOF ## diff --git a/tagit/actions/tagging.py b/tagit/actions/tagging.py new file mode 100644 index 0000000..c6d920d --- /dev/null +++ b/tagit/actions/tagging.py @@ -0,0 +1,162 @@ +""" + +Part of the tagit module. +A copy of the license is provided with the project. +Author: Matthias Baumgartner, 2022 +""" +# standard imports +from functools import reduce, partial +import operator +import os + +# kivy imports +from kivy.lang import Builder +import kivy.properties as kp + +# tagit imports +from tagit import config, dialogues +from tagit.utils import ns +from tagit.utils.bsfs import Namespace +from tagit.widgets import Binding + +# inner-module imports +from .action import Action + +# constants +TAGS_SEPERATOR = ',' +TAG_PREFIX = Namespace('http://example.com/me/tag') + +# exports +__all__ = [] + + +## code ## + +# load kv +Builder.load_file(os.path.join(os.path.dirname(__file__), 'tagging.kv')) + +# classes +class AddTag(Action): + """Add tags to the selected items.""" + text = kp.StringProperty('Add tag') + + def ktrigger(self, evt): + return Binding.check(evt, self.cfg('bindings', 'objects', 'add_tag')) + + def apply(self): + if len(self.root.browser.selection) > 0: + tags = self.root.session.storage.all(ns.bsfs.Tag).label(node=True) + dlg = dialogues.SimpleInput( + suggestions=set(tags.values()), + suggestion_sep=TAGS_SEPERATOR) + dlg.bind(on_ok=partial(self.add_tags, tags)) + dlg.open() + + else: + dialogues.Error(text='You must select some images first.').open() + + def add_tags(self, tags, wx): + # user-specified labels + labels = {t.strip() for t in wx.text.split(TAGS_SEPERATOR) if len(t.strip())} + # label to tag mapping + lut = {label: tag for tag, label in tags.items()} + # get previous tags + tags = {lut[lbl] for lbl in labels if lbl in lut} + # create new tag nodes and set their label + # FIXME: deny adding tags if tag vocabulary is fixed (ontology case) + # FIXME: replace with proper tag factory + for lbl in labels: + if lbl not in lut: + tag = self.root.session.storage.node(ns.bsfs.Tag, TAG_PREFIX[lbl]) + tag.set(ns.bst.label, lbl) + tags.add(tag) + with self.root.browser as browser, \ + self.root.session as session: + # get objects + ents = browser.unfold(browser.selection) + # collect tags + tags = reduce(operator.add, tags) # FIXME: mb/port: pass set once supported by Nodes.set + # set tags + ents.set(ns.bse.tag, tags) + session.dispatch('on_predicate_modified', 'tag', ents, tags) + # cursor and selection might become invalid. Will be fixed in Browser. + + +class EditTag(Action): + """Edit tags of the selected items""" + text = kp.StringProperty('Edit tags') + + def ktrigger(self, evt): + return Binding.check(evt, self.cfg('bindings', 'objects', 'edit_tag')) + + def apply(self): + with self.root.browser as browser: + if len(browser.selection) > 0: + # get all known tags + all_tags = self.root.session.storage.all(ns.bsfs.Tag).label(node=True) + # get selection tags + ent_tags = browser.unfold(browser.selection).tag.label(node=True) + if len(ent_tags) == 0: + text = '' + else: + sep = TAGS_SEPERATOR + ' ' + text = sep.join(sorted(set.intersection(*ent_tags.values()))) + + dlg = dialogues.SimpleInput( + text=text, + suggestions=set(all_tags.values()), + suggestion_sep=TAGS_SEPERATOR, + ) + dlg.bind(on_ok=partial(self.edit_tag, ent_tags, all_tags)) + dlg.open() + + else: + dialogues.Error(text='You must select some images first.').open() + + def edit_tag(self, original, tags, wx): + """Add or remove tags from images. + *original* and *modified* are strings, split at *TAGS_SEPERATOR*. + Tags are added and removed with respect to the difference between those two sets. + """ + # user-specified labels + labels = {t.strip() for t in wx.text.split(TAGS_SEPERATOR) if len(t.strip())} + # label differences + original_labels = {lbl for lbls in original.values() for lbl in lbls} + removed_labels = original_labels - labels + added_labels = labels - original_labels + # get tags of removed labels + removed = {tag for tag, lbl in tags.items() if lbl in removed_labels} + removed = reduce(operator.add, removed) + # get tags of added labels + # FIXME: deny adding tags if tag vocabulary is fixed (ontology case) + lut = {label: tag for tag, label in tags.items()} + added = {lut[lbl] for lbl in added_labels if lbl in lut} + # FIXME: replace with proper tag factory + for lbl in added_labels: + if lbl not in lut: + tag = self.root.session.storage.node(ns.bsfs.Tag, TAG_PREFIX[lbl]) + tag.set(ns.bst.label, lbl) + added.add(tag) + added = reduce(operator.add, added) + # apply differences + with self.root.browser as browser, \ + self.root.session as session: + ents = browser.unfold(browser.selection) + ents.set(ns.bse.tag, added) + #ents.remove(ns.bse.tag, removed) # FIXME: mb/port + session.dispatch('on_predicate_modified', 'tag', ents, added | removed) + # cursor and selection might become invalid. Will be fixed in Browser. + +## config ## + +# keybindings + +config.declare(('bindings', 'objects', 'add_tag'), + config.Keybind(), Binding.simple('t', Binding.mCTRL, Binding.mSHIFT), + __name__, AddTag.text.defaultvalue, AddTag.__doc__) + +config.declare(('bindings', 'objects', 'edit_tag'), + config.Keybind(), Binding.simple('e', Binding.mCTRL), + __name__, EditTag.text.defaultvalue, EditTag.__doc__) + +## EOF ## diff --git a/tagit/apps/port-config.yaml b/tagit/apps/port-config.yaml index 872ac29..33afbbd 100644 --- a/tagit/apps/port-config.yaml +++ b/tagit/apps/port-config.yaml @@ -37,6 +37,8 @@ ui: - SelectNone - SelectMulti - SelectRange + - AddTag + - EditTag - ShowHelp browser: maxcols: 8 @@ -45,9 +47,9 @@ ui: sidebar_left: - Menu - ShowDashboard - #- AddTag - #- EditTag - AddToken + - AddTag + - EditTag #- CreateGroup #- DissolveGroup - SelectAll @@ -94,9 +96,9 @@ ui: - SelectRange - SelectAdditive - SelectSubtractive - # tagging: - # - AddTag - # - EditTag + tagging: + - AddTag + - EditTag # - SetRank1 # - SetRank3 # - SetRank5 diff --git a/tagit/assets/icons/scalable/tagging/add_tag.svg b/tagit/assets/icons/scalable/tagging/add_tag.svg new file mode 100644 index 0000000..6e73d56 --- /dev/null +++ b/tagit/assets/icons/scalable/tagging/add_tag.svg @@ -0,0 +1,296 @@ +<?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" + width="100mm" + height="100mm" + id="svg2" + version="1.1" + inkscape:version="0.92.3 (2405546, 2018-03-11)" + sodipodi:docname="add_tag.svg" + inkscape:export-filename="../../kivy/objects/add_tag.png" + inkscape:export-xdpi="7.6199999" + inkscape:export-ydpi="7.6199999"> + <defs + id="defs4"> + <inkscape:path-effect + effect="bspline" + id="path-effect906" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect850" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect850-3" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect850-7" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect850-7-3" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect850-7-6" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect906-9" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect906-2" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect906-9-0" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect906-93" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect906-9-6" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect906-26" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect906-9-9" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect906-20" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.4" + inkscape:cx="-207.59181" + inkscape:cy="167.43915" + inkscape:document-units="mm" + inkscape:current-layer="layer1" + showgrid="false" + showguides="true" + inkscape:guide-bbox="true" + inkscape:snap-global="false" + inkscape:snap-bbox="true" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0" + inkscape:window-width="1920" + inkscape:window-height="1151" + inkscape:window-x="0" + inkscape:window-y="25" + inkscape:window-maximized="1" + inkscape:pagecheckerboard="true" + units="mm" + inkscape:bbox-paths="true" + inkscape:bbox-nodes="true" + inkscape:snap-bbox-edge-midpoints="true" + inkscape:snap-bbox-midpoints="true" + inkscape:object-paths="true" + inkscape:snap-intersection-paths="true" + inkscape:snap-smooth-nodes="true" + inkscape:snap-midpoints="true" + inkscape:snap-object-midpoints="true" + inkscape:snap-center="true" + inkscape:snap-text-baseline="true" + inkscape:snap-page="true" + inkscape:lockguides="false"> + <sodipodi:guide + orientation="0,1" + position="13.637059,643.40404" + id="guide3788" + inkscape:locked="false" /> + <sodipodi:guide + position="188.97638,188.97638" + orientation="0,1" + id="guide1099" + inkscape:locked="false" + inkscape:label="" + inkscape:color="rgb(0,0,255)" /> + <sodipodi:guide + position="188.97638,188.97638" + orientation="1,0" + id="guide1101" + inkscape:locked="false" + inkscape:label="" + inkscape:color="rgb(0,0,255)" /> + </sodipodi:namedview> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-167.28122,-322.85977)"> + <g + transform="matrix(0.846821,-1.0151333,1.0151333,0.846821,-484.44796,260.70334)" + id="g870" + style="stroke:#c8c8c8;stroke-width:14.89931583;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"> + <circle + r="23.687183" + cy="510.56808" + cx="261.76941" + id="path839" + style="opacity:1;fill:none;fill-opacity:1;stroke:#c8c8c8;stroke-width:14.89931583;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:fill markers stroke" /> + <g + style="stroke:#c8c8c8;stroke-width:14.89931583;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + transform="translate(-9.9999667e-7,6.2227844)" + id="g864"> + <path + style="fill:none;stroke:#c8c8c8;stroke-width:14.89931583;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 274.44346,437.98197 79.87503,66.36332 V 698.87342 H 169.22033 V 504.34529 l 80.13837,-66.36306" + id="path837" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccccc" /> + <path + style="opacity:1;fill:none;fill-opacity:1;stroke:#c8c8c8;stroke-width:14.89931583;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:fill markers stroke" + id="path839-3" + sodipodi:type="arc" + sodipodi:cx="-420.58212" + sodipodi:cy="-313.05319" + sodipodi:rx="20.524721" + sodipodi:ry="20.524721" + sodipodi:start="0.40543239" + sodipodi:end="1.917446" + sodipodi:open="true" + d="m -401.7213,-304.95791 a 20.524721,20.524721 0 0 1 -25.83407,11.20855" + transform="rotate(-156.62757)" /> + </g> + </g> + <g + id="g848" + transform="translate(342.14286,-91.176621)"> + <path + inkscape:original-d="m -17.767337,666.45535 c 30.71351,-37.05555 61.4269,-74.11251 92.14015,-111.17087" + inkscape:path-effect="#path-effect906-26" + inkscape:connector-curvature="0" + id="path904-18" + d="M -17.767337,666.45535 C 12.945407,629.39916 43.658794,592.3422 74.372813,555.28448" + style="fill:none;stroke:#c8c8c8;stroke-width:15.01094818;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + inkscape:original-d="M 83.888173,656.93999 C 46.832623,626.22647 9.7756729,595.51308 -27.282697,564.79983" + inkscape:path-effect="#path-effect906-20" + inkscape:connector-curvature="0" + id="path904-2" + d="M 83.888173,656.93999 C 46.831985,626.22724 9.7750303,595.51386 -27.282697,564.79983" + style="fill:none;stroke:#c8c8c8;stroke-width:15.01094818;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + </g> + </g> +</svg> diff --git a/tagit/assets/icons/scalable/tagging/edit_tag.svg b/tagit/assets/icons/scalable/tagging/edit_tag.svg new file mode 100644 index 0000000..c7d64e1 --- /dev/null +++ b/tagit/assets/icons/scalable/tagging/edit_tag.svg @@ -0,0 +1,303 @@ +<?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" + width="100mm" + height="100mm" + id="svg2" + version="1.1" + inkscape:version="0.92.3 (2405546, 2018-03-11)" + sodipodi:docname="edit_tag.svg" + inkscape:export-filename="../../kivy/objects/edit_tag.png" + inkscape:export-xdpi="7.6199999" + inkscape:export-ydpi="7.6199999"> + <defs + id="defs4"> + <inkscape:path-effect + effect="bspline" + id="path-effect906" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect850" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect850-3" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect850-7" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect850-7-3" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect850-7-6" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect906-9" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect906-2" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect906-9-0" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect906-93" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect906-9-6" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect906-26" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect906-9-9" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + <inkscape:path-effect + effect="bspline" + id="path-effect906-20" + is_visible="true" + weight="33.333333" + steps="2" + helper_size="0" + apply_no_weight="true" + apply_with_weight="true" + only_selected="false" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.4" + inkscape:cx="-97.948957" + inkscape:cy="170.29629" + inkscape:document-units="mm" + inkscape:current-layer="layer1" + showgrid="false" + showguides="true" + inkscape:guide-bbox="true" + inkscape:snap-global="true" + inkscape:snap-bbox="true" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0" + inkscape:window-width="1920" + inkscape:window-height="1151" + inkscape:window-x="0" + inkscape:window-y="25" + inkscape:window-maximized="1" + inkscape:pagecheckerboard="true" + units="mm" + inkscape:bbox-paths="true" + inkscape:bbox-nodes="true" + inkscape:snap-bbox-edge-midpoints="true" + inkscape:snap-bbox-midpoints="true" + inkscape:object-paths="true" + inkscape:snap-intersection-paths="true" + inkscape:snap-smooth-nodes="true" + inkscape:snap-midpoints="true" + inkscape:snap-object-midpoints="true" + inkscape:snap-center="true" + inkscape:snap-text-baseline="true" + inkscape:snap-page="true" + inkscape:lockguides="false"> + <sodipodi:guide + orientation="0,1" + position="13.637059,643.40404" + id="guide3788" + inkscape:locked="false" /> + <sodipodi:guide + position="188.97638,188.97638" + orientation="0,1" + id="guide1099" + inkscape:locked="false" + inkscape:label="" + inkscape:color="rgb(0,0,255)" /> + <sodipodi:guide + position="188.97638,188.97638" + orientation="1,0" + id="guide1101" + inkscape:locked="false" + inkscape:label="" + inkscape:color="rgb(0,0,255)" /> + </sodipodi:namedview> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-167.28122,-322.85977)"> + <g + id="g1018" + transform="matrix(0.77049115,0.63859513,-0.63859513,0.77049115,403.95705,-187.73351)"> + <g + style="stroke:#c8c8c8;stroke-width:14.89931583;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="g870" + transform="matrix(0.00420274,-1.3209979,1.3209979,0.00420274,-397.55803,911.5166)"> + <circle + style="opacity:1;fill:none;fill-opacity:1;stroke:#c8c8c8;stroke-width:14.89931583;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:fill markers stroke" + id="path839" + cx="261.76941" + cy="510.56808" + r="23.687183" /> + <g + id="g864" + transform="translate(-9.9999667e-7,6.2227844)" + style="stroke:#c8c8c8;stroke-width:14.89931583;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"> + <path + sodipodi:nodetypes="cccccc" + inkscape:connector-curvature="0" + id="path837" + d="m 274.44346,437.98197 79.87503,66.36332 V 698.87342 H 169.22033 V 504.34529 l 80.13837,-66.36306" + style="fill:none;stroke:#c8c8c8;stroke-width:14.89931583;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + transform="rotate(-156.62757)" + d="m -401.7213,-304.95791 a 20.524721,20.524721 0 0 1 -25.83407,11.20855" + sodipodi:open="true" + sodipodi:end="1.917446" + sodipodi:start="0.40543239" + sodipodi:ry="20.524721" + sodipodi:rx="20.524721" + sodipodi:cy="-313.05319" + sodipodi:cx="-420.58212" + sodipodi:type="arc" + id="path839-3" + style="opacity:1;fill:none;fill-opacity:1;stroke:#c8c8c8;stroke-width:14.89931583;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:fill markers stroke" /> + </g> + </g> + <path + inkscape:original-d="m 500.54332,620.98029 c -48.09424,-10e-4 -96.18948,-10e-4 -144.28572,0" + inkscape:path-effect="#path-effect906" + inkscape:connector-curvature="0" + id="path904" + d="m 500.54332,620.98029 c -48.09424,0 -96.18948,0 -144.28572,0" + style="fill:none;stroke:#c8c8c8;stroke-width:15;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + inkscape:original-d="m 500.54332,567.766 c -48.09424,-10e-4 -96.18948,-10e-4 -144.28572,0" + inkscape:path-effect="#path-effect906-26" + inkscape:connector-curvature="0" + id="path904-18" + d="m 500.54332,567.766 c -48.09424,0 -96.18948,0 -144.28572,0" + style="fill:none;stroke:#c8c8c8;stroke-width:15;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + inkscape:original-d="m 500.54332,514.55171 c -48.09424,-10e-4 -96.18948,-10e-4 -144.28572,0" + inkscape:path-effect="#path-effect906-20" + inkscape:connector-curvature="0" + id="path904-2" + d="m 500.54332,514.55171 c -48.09424,0 -96.18948,0 -144.28572,0" + style="fill:none;stroke:#c8c8c8;stroke-width:15;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + </g> + </g> +</svg> |