02021-01-20 stream

This commit is contained in:
Suzanne Soy 2021-01-21 21:58:20 +00:00
commit 13d0f27d7d
9 changed files with 3454 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
__pycache__

184
GIMPCommand.py Normal file
View File

@ -0,0 +1,184 @@
import FreeCAD
import FreeCADGui as Gui
import subprocess
import PySide
import re
from PySide import QtGui
from PySide import QtCore
class Tool():
def __init__(self, name, *, start_command_and_args, xwininfo_filter_re, extra_xprop_filter):
self.name = name
self.start_command_and_args = start_command_and_args
self.xwininfo_filter_re = re.compile(xwininfo_filter_re)
self.extra_xprop_filter = extra_xprop_filter
class Tools():
def __init__(self, *tools):
self.__dict__ = {tool.name: tool for tool in tools}
def __getitem__(self, k): return self.__dict__[k]
# tool-specific infos:
tools = Tools(
Tool('Mousepad',
start_command_and_args = ['mousepad', '--disable-server'],
xwininfo_filter_re = r'mousepad',
extra_xprop_filter = lambda processId, windowId, i: True),
Tool('Inkscape',
start_command_and_args = ['inkscape'],
xwininfo_filter_re = r'inkscape',
extra_xprop_filter = lambda processId, windowId, i: x11prop(windowId, 'WM_STATE', 'WM_STATE') is not None),
Tool('GIMP',
start_command_and_args = ['env', '-i', 'DISPLAY=:0', '/home/suzanne/perso/dotfiles/nix/result/bin/gimp', '--new-instance'],
xwininfo_filter_re = r'gimp',
extra_xprop_filter = lambda processId, windowId, i: x11prop(windowId, 'WM_STATE', 'WM_STATE') is not None))
class EmbeddedWindow(QtCore.QObject):
def __init__(self, tool, externalAppInstance, processId, windowId):
super(EmbeddedWindow, self).__init__()
self.tool = tool
self.externalAppInstance = externalAppInstance
self.processId = processId
self.windowId = windowId
self.mdi = Gui.getMainWindow().findChild(QtGui.QMdiArea)
self.xw = QtGui.QWindow.fromWinId(self.windowId)
self.xw.setFlags(QtGui.Qt.FramelessWindowHint)
self.xwd = QtGui.QWidget.createWindowContainer(self.xw)
self.mwx = QtGui.QMainWindow()
self.mwx.layout().addWidget(self.xwd)
self.mdiSub = self.mdi.addSubWindow(self.xwd)
self.xwd.setBaseSize(640,480)
self.mwx.setBaseSize(640,480)
self.mdiSub.setBaseSize(640,480)
self.mdiSub.setWindowTitle(tool.name)
self.mdiSub.show()
#self.xw.installEventFilter(self)
def eventFilter(self, obj, event):
# This doesn't seem to work, some events occur but no the close one.
if event.type() == QtCore.QEvent.Close:
mdiSub.close()
return False
# <optional spaces> <digits (captured in group 1)> <optional spaces> "<quoted string>" <optional spaces> : <anything>
xwininfo_re = re.compile(r'^\s*([0-9]+)\s*"[^"]*"\s*:.*$')
def x11stillAlive(windowId):
try:
subprocess.check_output(['xprop', '-id', str(windowId), '_NET_WM_PID'])
return True
except:
return False
def x11prop(windowId, prop, type):
try:
output = subprocess.check_output(['xprop', '-id', str(windowId), prop]).decode('utf-8', 'ignore').split('\n')
except subprocess.CalledProcessError as e:
output = []
xprop_re = re.compile(r'^' + re.escape(prop) + r'\(' + re.escape(type) + r'\)((:)| =(.*))$')
for line in output:
trymatch = xprop_re.match(line)
if trymatch:
return trymatch.group(2) or trymatch.group(3)
return None
def try_pipe_lines(commandAndArguments):
try:
return subprocess.check_output(commandAndArguments).decode('utf-8', 'ignore').split('\n')
except:
return []
class ExternalApps():
def __init__(self):
setattr(FreeCAD, 'ExternalApps', self)
def deleted(widget):
"""Detect RuntimeError: Internal C++ object (PySide2.QtGui.QWindow) already deleted."""
try:
str(widget) # str fails on already-deleted Qt wrappers.
return False
except:
return True
class ExternalAppInstance(QtCore.QObject):
def __init__(self, toolName):
super(ExternalAppInstance, self).__init__()
self.tool = tools[toolName]
# Start the application
# TODO: popen_process shouldn't be exposed to in-document scripts, it would allow them to redirect output etc.
print('Starting ' + ' '.join(self.tool.start_command_and_args))
self.popen_process = subprocess.Popen(self.tool.start_command_and_args)
self.toolProcessIds = [self.popen_process.pid]
self.initWaitForWindow()
self.foundWindows = dict()
setattr(FreeCAD.ExternalApps, self.tool.name, self)
def initWaitForWindow(self):
self.TimeoutHasOccurred = False # for other scritps to know the status
self.startupTimeout = 10000
self.elapsed = QtCore.QElapsedTimer()
self.elapsed.start()
self.timer = QtCore.QTimer(self)
self.timer.timeout.connect(self.attemptToFindWindow)
def waitForWindow(self):
self.timer.start(50)
@QtCore.Slot()
def attemptToFindWindow(self):
try:
self.attemptToFindWindowWrapped()
except:
self.timer.stop()
raise
def attemptToFindWindowWrapped(self):
# use decode('utf-8', 'ignore') to use strings instead of byte strings and discard ill-formed unicode in case these tool doesn't sanitize their output
for line in try_pipe_lines(['xwininfo', '-root', '-tree', '-int']):
if self.tool.xwininfo_filter_re.search(line):
windowId = int(xwininfo_re.match(line).group(1))
# use decode('utf-8', 'ignore') to use strings instead of byte strings and discard ill-formed unicode in case this tool doesn't sanitize their output
xprop_try_process_id = x11prop(windowId, '_NET_WM_PID', 'CARDINAL')
if xprop_try_process_id:
processId = int(xprop_try_process_id) # TODO try parse int and catch failure
if processId in self.toolProcessIds:
if self.tool.extra_xprop_filter(processId, windowId, len(self.foundWindows)):
self.foundWindow(processId, windowId)
if self.elapsed.elapsed() > self.startupTimeout:
self.timer.stop()
self.TimeoutHasOccurred = True
def foundWindow(self, processId, windowId):
if windowId not in self.foundWindows.keys():
self.foundWindows[windowId] = EmbeddedWindow(self.tool, self, processId, windowId)
# TODO: find an event instead of polling
for w in self.foundWindows.values():
#if not deleted(xw) and not xw.isActive():
if not x11stillAlive(w.windowId):
w.mdiSub.close()
# prevent_garbage_collect by binding to a variable???
#p = ExternalAppInstance('Mousepad')
#p = ExternalAppInstance('Inkscape')
ExternalApps()
class GIMPCommand():
def GetResources(self):
return {
'Pixmap': ':/icons/GIMP.svg',
'Accel': "Shit+G",
'MenuText': "Menu text",
'ToolTip': "Tooltip",
}
def Activated(self):
print("Command activated")
p = ExternalAppInstance('GIMP')
p.waitForWindow()
def IsActive(self):
# return false to grey out the command in the menus, toolbars etc.
return True
Gui.addCommand('GIMPCommand', GIMPCommand())

0
Init.py Normal file
View File

72
InitGui.py Normal file
View File

@ -0,0 +1,72 @@
import sys
class XternalAppsWorkbench(Workbench):
MenuText = "XternalApps"
ToolTip = "Embeds external Applications in FreeCAD"
Icon = """
/* XPM */
static char * icon_xpm[] = {
"16 16 15 1",
" c None",
". c #FFFFFF",
"+ c #E8E5E5",
"@ c #897578",
"# c #9B8B8D",
"$ c #75575C",
"% c #C9C3C4",
"& c #FF89DA",
"* c #FF96DA",
"= c #FFA2DA",
"- c #FFACDA",
"; c #FFB2DA",
"> c #FFEAF3",
", c #FFB9DA",
"' c #FF9DDA",
"................",
"..........+@....",
".........#$%....",
"........$$$.....",
".......%$$%.....",
".......&%.......",
"......*&........",
".....=&.........",
"....-&.....&....",
"...;&>....&&....",
"..,'&.....&&....",
"..&&.....&..&...",
".........&&&&...",
"........&...&...",
".......&.....&..",
"................"};
"""
def __init__(self):
super(self.__class__, self).__init__()
def Initialize(self):
print('Initialize')
if sys.version_info[0] == 2:
import Resources2
else:
import Resources3
import GIMPCommand
# import commands
self.list = ['GIMPCommand']
self.appendMenu("ExternalApplications", self.list)
self.appendToolbar("ExternalApplications", self.list)
def Activated(self):
print('Activated')
pass
def Deactivated(self):
print('Deactivated')
pass
def ContextMenu(self):
pass
def GetClassName(self):
return "Gui::PythonWorkbench"
Gui.addWorkbench(XternalAppsWorkbench())

1
LICENSE Normal file
View File

@ -0,0 +1 @@
The contents of this repository are released under the CC0, with the exception of the GIMP logo which comes from the GIMP project and is therefore under the GPL license.

1406
Resources2.py Normal file

File diff suppressed because it is too large Load Diff

1406
Resources3.py Normal file

File diff suppressed because it is too large Load Diff

BIN
icon.xcf Normal file

Binary file not shown.

384
icons/GIMP.svg Normal file
View File

@ -0,0 +1,384 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.0"
width="48"
height="48"
id="svg11300">
<defs
id="defs3">
<linearGradient
id="linearGradient8542">
<stop
style="stop-color:#5b676b;stop-opacity:1"
offset="0"
id="stop8544" />
<stop
style="stop-color:#141718;stop-opacity:1"
offset="1"
id="stop8546" />
</linearGradient>
<linearGradient
id="linearGradient8534">
<stop
style="stop-color:black;stop-opacity:1"
offset="0"
id="stop8536" />
<stop
style="stop-color:black;stop-opacity:0"
offset="1"
id="stop8538" />
</linearGradient>
<linearGradient
id="linearGradient8524">
<stop
style="stop-color:white;stop-opacity:1"
offset="0"
id="stop8526" />
<stop
style="stop-color:white;stop-opacity:0"
offset="1"
id="stop8528" />
</linearGradient>
<linearGradient
id="linearGradient2446">
<stop
style="stop-color:white;stop-opacity:1"
offset="0"
id="stop2448" />
<stop
style="stop-color:white;stop-opacity:0"
offset="1"
id="stop2450" />
</linearGradient>
<linearGradient
x1="13.236155"
y1="37.752247"
x2="7.7521091"
y2="42.282146"
id="linearGradient2452"
xlink:href="#linearGradient2446"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.755165,0.395143,-0.395143,0.755165,-25.91245,6.532586)" />
<linearGradient
id="linearGradient6963">
<stop
style="stop-color:#696969;stop-opacity:1"
offset="0"
id="stop6965" />
<stop
style="stop-color:black;stop-opacity:1"
offset="1"
id="stop6967" />
</linearGradient>
<radialGradient
cx="15.415101"
cy="35.356506"
r="7.5791559"
fx="15.415101"
fy="35.356506"
id="radialGradient6969"
xlink:href="#linearGradient6963"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.572694,5.424952e-17,1.037922e-12,1.532639,-55.36682,-21.35823)" />
<linearGradient
id="linearGradient6939">
<stop
style="stop-color:#bdbdbd;stop-opacity:1"
offset="0"
id="stop6941" />
<stop
style="stop-color:#e2e2e2;stop-opacity:1"
offset="0.33333334"
id="stop6947" />
<stop
style="stop-color:#a3a3a3;stop-opacity:1"
offset="0.66666669"
id="stop6949" />
<stop
style="stop-color:#ddd;stop-opacity:1"
offset="1"
id="stop6943" />
</linearGradient>
<linearGradient
x1="19.394735"
y1="30.001331"
x2="23.109331"
y2="33.438831"
id="linearGradient6945"
xlink:href="#linearGradient6939"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-46.40695,-1.802856)" />
<linearGradient
id="linearGradient6951">
<stop
style="stop-color:#6e3d09;stop-opacity:1"
offset="0"
id="stop6953" />
<stop
style="stop-color:#ea8113;stop-opacity:1"
offset="0.24242425"
id="stop6959" />
<stop
style="stop-color:#5c3307;stop-opacity:1"
offset="0.62121212"
id="stop6961" />
<stop
style="stop-color:#e07c12;stop-opacity:1"
offset="1"
id="stop6955" />
</linearGradient>
<linearGradient
x1="37.017639"
y1="19.239889"
x2="27.753893"
y2="11.182488"
id="linearGradient6957"
xlink:href="#linearGradient6951"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-49.30496,1.877723)" />
<linearGradient
id="linearGradient6500">
<stop
style="stop-color:#857c63;stop-opacity:1"
offset="0"
id="stop6502" />
<stop
style="stop-color:#221f19;stop-opacity:1"
offset="1"
id="stop6504" />
</linearGradient>
<linearGradient
id="linearGradient6492">
<stop
style="stop-color:black;stop-opacity:1"
offset="0"
id="stop6494" />
<stop
style="stop-color:black;stop-opacity:0"
offset="1"
id="stop6496" />
</linearGradient>
<linearGradient
id="linearGradient6482">
<stop
style="stop-color:black;stop-opacity:1"
offset="0"
id="stop6484" />
<stop
style="stop-color:black;stop-opacity:0"
offset="1"
id="stop6486" />
</linearGradient>
<linearGradient
id="linearGradient6468">
<stop
style="stop-color:white;stop-opacity:1"
offset="0"
id="stop6470" />
<stop
style="stop-color:#b9b9b0;stop-opacity:1"
offset="1"
id="stop6472" />
</linearGradient>
<linearGradient
id="linearGradient6452">
<stop
style="stop-color:white;stop-opacity:1"
offset="0"
id="stop6454" />
<stop
style="stop-color:white;stop-opacity:0"
offset="1"
id="stop6456" />
</linearGradient>
<linearGradient
x1="6.3051529"
y1="23.362427"
x2="5.9846287"
y2="31.57"
id="linearGradient6458"
xlink:href="#linearGradient6452"
gradientUnits="userSpaceOnUse" />
<radialGradient
cx="69.473244"
cy="19.597878"
r="3.5153139"
fx="69.473244"
fy="19.597878"
id="radialGradient6474"
xlink:href="#linearGradient6468"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.318488,1.207574e-15,-1.207574e-15,1.318488,-22.1264,-6.241691)" />
<radialGradient
cx="23"
cy="33.9375"
r="18.25"
fx="23"
fy="33.9375"
id="radialGradient6498"
xlink:href="#linearGradient6492"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.284247,0,24.29088)" />
<linearGradient
x1="14.96875"
y1="19.110678"
x2="39.524544"
y2="46.98568"
id="linearGradient8530"
xlink:href="#linearGradient8524"
gradientUnits="userSpaceOnUse" />
<radialGradient
cx="6.0242186"
cy="25.271027"
r="4.8310289"
fx="6.0242186"
fy="25.271027"
id="radialGradient8548"
xlink:href="#linearGradient8542"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.916159,9.318684e-2,-0.108765,1.069309,3.253668,-3.029272)" />
<linearGradient
x1="26.162951"
y1="30.543303"
x2="24.328892"
y2="30.985245"
id="linearGradient4330"
xlink:href="#linearGradient8534"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="32.350136"
y1="28.083355"
x2="21.213203"
y2="30.293064"
id="linearGradient4351"
xlink:href="#linearGradient6482"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-3.836549,0.345971)" />
<radialGradient
cx="18.557627"
cy="22.300018"
r="19.2292"
fx="18.557627"
fy="22.300018"
id="radialGradient4354"
xlink:href="#linearGradient6500"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.77275,-1.847562e-16,1.351402e-16,1.29668,-16.3404,-6.615959)" />
<radialGradient
cx="69.473244"
cy="19.597878"
r="3.5153139"
fx="69.473244"
fy="19.597878"
id="radialGradient4363"
xlink:href="#linearGradient6468"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.318488,1.207574e-15,-1.207574e-15,1.318488,-22.1264,-6.241691)" />
</defs>
<g
id="layer1">
<path
d="M 41.25 33.9375 A 18.25 5.1875 0 1 1 4.75,33.9375 A 18.25 5.1875 0 1 1 41.25 33.9375 z"
transform="matrix(1,0,0,1.53012,0.125,-19.99096)"
style="color:black;fill:url(#radialGradient6498);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999997;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path6490" />
<path
d="M 10.374369,12.467884 C 10.374369,12.467884 13.248878,18.395518 19.973611,18.228291 C 34.066126,17.874738 36.53732,10.523341 36.890873,9.4626804 C 37.244427,8.4020202 37.785407,8.5626825 37.91048,9.542947 C 42.506674,51.262247 6.0135488,33.362123 4.7175144,26.256467 C 11.965359,24.135147 10.197592,20.069282 10.197592,20.069282 L 10.374369,12.467884 z "
style="color:black;fill:url(#radialGradient4354);fill-opacity:1;fill-rule:evenodd;stroke:#2e3436;stroke-width:0.9999997;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path4323" />
<path
d="M 15.73779,30.066049 C 22.47669,31.413886 25.908481,30.164142 27.916965,28.613273 C 27.386635,27.928263 26.480655,27.176962 26.480655,27.176962 C 26.480655,27.176962 28.833972,27.830904 29.662635,28.900535 C 30.488925,29.967103 29.969443,30.624242 29.753196,31.988905 C 29.271785,30.790306 28.373215,30.340813 28.251562,29.864573 C 26.445294,32.3615 21.94512,32.257773 15.73779,30.066049 z "
style="color:black;fill:url(#linearGradient4351);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999997;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path6480" />
<path
d="M 36.96875,11.84375 C 36.406772,12.770645 35.562258,13.876916 34.28125,14.9375 C 31.649332,17.116542 27.230687,19.099847 20,19.28125 C 15.775627,19.386299 13.047259,17.347101 11.375,15.53125 L 11.25,20 C 11.386107,20.418802 11.665455,21.390498 11.1875,22.71875 C 10.673186,24.148046 9.032986,25.610113 6.21875,26.71875 C 6.4690804,27.240783 6.7142345,27.76237 7.46875,28.5 C 8.4967003,29.504945 9.9257833,30.588049 11.625,31.5625 C 15.023433,33.511402 19.426583,35.055712 23.53125,35.125 C 27.635917,35.194288 31.388376,33.89045 33.96875,30.125 C 36.347494,26.653782 37.651223,20.777057 36.96875,11.84375 z "
style="opacity:0.18539327;color:black;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient8530);stroke-width:0.9999997;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path8520" />
<path
d="M 72.655224 21.837049 A 3.1819806 3.1819806 0 1 1 66.291263,21.837049 A 3.1819806 3.1819806 0 1 1 72.655224 21.837049 z"
transform="matrix(1.277778,0,0,1.277778,-75.12661,-6.507784)"
style="color:black;fill:url(#radialGradient4363);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:0.78260845;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path4357" />
<path
d="M 10.429825 27.228739 A 4.3310289 6.0987959 0 1 1 1.767767,27.228739 A 4.3310289 6.0987959 0 1 1 10.429825 27.228739 z"
transform="matrix(0.810984,-0.585069,0.585069,0.810984,-14.77791,6.947121)"
style="color:black;fill:url(#radialGradient8548);fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:0.9999997;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path5198" />
<path
d="M 24.041631 21.837049 A 2.2980971 2.2980971 0 1 1 19.445437,21.837049 A 2.2980971 2.2980971 0 1 1 24.041631 21.837049 z"
transform="matrix(0.851852,0,0,0.851852,-3.926759,3.395528)"
style="color:black;fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:1.17391276;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path4359" />
<path
d="M 6.09375,22.15625 C 5.2955008,22.15625 4.5406196,22.602421 3.90625,23.5 C 3.2718804,24.397579 2.8125,25.734204 2.8125,27.21875 C 2.8125,28.703296 3.2718804,30.039921 3.90625,30.9375 C 4.5406196,31.835079 5.2955011,32.28125 6.09375,32.28125 C 6.8919992,32.28125 7.6710339,31.804861 8.3125,30.90625 C 8.9539661,30.007639 9.40625,28.700064 9.40625,27.21875 C 9.40625,25.737436 8.9539662,24.429861 8.3125,23.53125 C 7.6710338,22.632639 6.8919989,22.15625 6.09375,22.15625 z "
transform="matrix(0.800389,-0.599481,0.599481,0.800389,-15.2744,7.32784)"
style="opacity:0.28089887;color:black;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient6458);stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path6450" />
<path
d="M 5.833631 23.251263 A 1.767767 2.1213202 0 1 1 2.2980971,23.251263 A 1.767767 2.1213202 0 1 1 5.833631 23.251263 z"
style="color:black;fill:white;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999997;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path6446" />
<path
d="M 23.157747 20.953165 A 1.767767 1.767767 0 1 1 19.622213,20.953165 A 1.767767 1.767767 0 1 1 23.157747 20.953165 z"
transform="matrix(0.766666,0,0,0.766666,-2.556414,5.029841)"
style="color:black;fill:white;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999997;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path4361" />
<path
d="M 72.655224 21.837049 A 3.1819806 3.1819806 0 1 1 66.291263,21.837049 A 3.1819806 3.1819806 0 1 1 72.655224 21.837049 z"
transform="matrix(1.5,0,0,1.5,-82.16821,-10.91852)"
style="color:black;fill:url(#radialGradient6474);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:0.66666645;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path6462" />
<path
d="M 24.041631 21.837049 A 2.2980971 2.2980971 0 1 1 19.445437,21.837049 A 2.2980971 2.2980971 0 1 1 24.041631 21.837049 z"
transform="translate(1.414216,0.707108)"
style="color:black;fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:0.9999997;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path6464" />
<path
d="M 23.157747 20.953165 A 1.767767 1.767767 0 1 1 19.622213,20.953165 A 1.767767 1.767767 0 1 1 23.157747 20.953165 z"
transform="matrix(0.9,0,0,0.9,3.022883,2.625648)"
style="color:black;fill:white;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999997;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path6466" />
<g
transform="matrix(-0.114852,-0.389864,0.389864,-0.114852,24.71507,29.68942)"
id="g8463">
<path
d="M -23.364209,23.568336 L -19.654111,27.037511 C -11.307128,20.656664 -2.5600338,6.9381374 -2.5600338,6.9381374 C -0.58371893,4.6957251 -2.6769537,3.1876548 -4.7249404,4.5402186 C -4.7249404,4.5402186 -17.695303,14.655085 -23.364209,23.568336 z "
style="opacity:1;color:black;fill:url(#linearGradient6957);fill-opacity:1;fill-rule:nonzero;stroke:#673907;stroke-width:2.46045303;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path6937" />
<path
d="M -30.449715,32.813894 L -28.203395,34.747714 L -19.710629,27.380683 L -19.435568,26.674855 L -18.341163,26.65704 C -18.778663,25.09454 -21.282677,22.273585 -23.157677,22.273585 L -23.075658,23.36366 L -23.745649,23.743687 L -30.449715,32.813894 z "
style="opacity:1;color:black;fill:url(#linearGradient6945);fill-opacity:1;fill-rule:nonzero;stroke:#888a85;stroke-width:2.46045303;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path6935" />
<path
d="M -23.801371,28.376767 L -28.166304,33.643238"
style="opacity:1;color:black;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:white;stroke-width:2.46045327;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path6985" />
<path
d="M -45.341208,42.769835 C -34.89725,42.769835 -26.971169,44.013565 -25.470603,36.415097 C -24.261354,30.291783 -32.681137,27.357729 -36.853473,32.824236 C -40.87275,38.090207 -45.341208,42.769835 -45.341208,42.769835 z "
style="opacity:1;color:black;fill:url(#radialGradient6969);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path6933" />
<path
d="M 8.8749989 37.75 A 1.2499999 1.2499999 0 1 1 6.3749992,37.75 A 1.2499999 1.2499999 0 1 1 8.8749989 37.75 z"
transform="matrix(2.069903,-2.005828e-15,-1.697698e-15,2.069903,-44.75012,-41.50978)"
style="opacity:0.52777782;color:black;fill:white;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path6971" />
<path
d="M 8.8749989 37.75 A 1.2499999 1.2499999 0 1 1 6.3749992,37.75 A 1.2499999 1.2499999 0 1 1 8.8749989 37.75 z"
transform="matrix(1.396669,6.090506e-16,8.67172e-16,1.396669,-32.05526,-25.87664)"
style="opacity:1;color:black;fill:white;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path6983" />
<path
d="M -38.543723,40.909242 C -38.543723,40.909242 -34.822203,41.003542 -32.427185,39.497247 C -31.579834,38.964324 -30.911411,40.147232 -31.933366,40.584614 C -34.14076,41.529346 -38.543723,40.909242 -38.543723,40.909242 z "
style="opacity:0.42777776;color:black;fill:url(#linearGradient2452);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path1571" />
</g>
<path
d="M 23.003067,31.736544 C 24.500439,31.879636 25.852696,31.464331 26.41496,31.262497 C 26.513185,30.707111 26.951512,29.64124 28.461048,29.571029 L 27.930718,28.642952 C 27.930718,28.642952 25.964077,29.990873 23.864854,30.388621 L 23.003067,31.736544 z "
style="color:black;fill:url(#linearGradient4330);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999997;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path8532" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 21 KiB