From 8f3246bf152d10895a37cf10f1077fd19a295ef5 Mon Sep 17 00:00:00 2001 From: pierreporte Date: Sun, 8 Mar 2026 23:16:15 +0100 Subject: [PATCH 1/2] Hems: MVP --- InitGui.py | 1 + Resources/SheetMetal.qrc | 1 + Resources/icons/SheetMetal_AddHem.svg | 387 +++++++++++++++++++++++ SheetMetalCmd.py | 426 ++++++++++++++++++++++++++ 4 files changed, 815 insertions(+) create mode 100644 Resources/icons/SheetMetal_AddHem.svg diff --git a/InitGui.py b/InitGui.py index a208b70..c3961c4 100644 --- a/InitGui.py +++ b/InitGui.py @@ -78,6 +78,7 @@ def Initialize(self): "SheetMetal_NewSketch", "SheetMetal_AddBase", "SheetMetal_AddWall", + "SheetMetal_AddHem", "SheetMetal_Extrude", "SheetMetal_ExtendBySketch", "SheetMetal_AddFoldWall", diff --git a/Resources/SheetMetal.qrc b/Resources/SheetMetal.qrc index 1b20b46..e619021 100644 --- a/Resources/SheetMetal.qrc +++ b/Resources/SheetMetal.qrc @@ -7,6 +7,7 @@ icons/SheetMetal_AddJunction.svg icons/SheetMetal_AddRelief.svg icons/SheetMetal_AddWall.svg + icons/SheetMetal_AddHem.svg icons/SheetMetal_Extrude.svg icons/SheetMetal_Forming.svg icons/SheetMetal_SketchOnSheet.svg diff --git a/Resources/icons/SheetMetal_AddHem.svg b/Resources/icons/SheetMetal_AddHem.svg new file mode 100644 index 0000000..19e62bd --- /dev/null +++ b/Resources/icons/SheetMetal_AddHem.svg @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + [maxwxyz] + + + https://www.freecad.org/wiki/index.php?title=Artwork + + + FreeCAD + + + FreeCAD/src/Mod/Sketcher/Gui/Resources/icons/Sketcher_CreateArc.svg + + + FreeCAD LGPL2+ + + + 2023-12-19 + + + + + + + + + + + + + + + + + + + diff --git a/SheetMetalCmd.py b/SheetMetalCmd.py index e9d05c5..d785c7b 100644 --- a/SheetMetalCmd.py +++ b/SheetMetalCmd.py @@ -40,6 +40,8 @@ # List of properties to be saved as defaults. smAddWallDefaultVars = ["BendType", "LengthSpec", ("angle", "defaultAngle"), ("radius", "defaultRadius"), "AutoMiter", ("kfactor", "defaultKFactor")] +smAddHemDefaultVars = ["HemType", ("width", "defaultWidth"), + ("radius", "defaultRadius"), "AutoMiter", ("kfactor", "defaultKFactor")] translate = FreeCAD.Qt.translate @@ -2055,6 +2057,299 @@ def execute(self, fp): fp.Shape = s +class SMHem: + def __init__(self, obj, selobj, sel_items, refAngOffset=None, checkRefFace=False): + """Add Hem on an edge.""" + self.addVerifyProperties(obj, refAngOffset, checkRefFace) + + _tip_ = translate("App::Property", "Base Object") + obj.addProperty("App::PropertyLinkSub", "baseObject", "Parameters", _tip_ + ).baseObject = (selobj, sel_items) + obj.Proxy = self + SheetMetalTools.taskRestoreDefaults(obj, smAddHemDefaultVars) + + def addVerifyProperties(self, obj, refAngOffset=None, checkRefFace=False): + SheetMetalTools.smAddEnumProperty(obj, + "HemType", + translate("App::Property", "Hem Type"), + ["Flat", "Teardrop", "Rolled"]) + SheetMetalTools.smAddLengthProperty(obj, + "radius", + translate("App::Property", "Bend Radius"), + 1.0) + SheetMetalTools.smAddLengthProperty(obj, + "width", + translate("App::Property", "Width of Hem"), + 10.0) + SheetMetalTools.smAddLengthProperty(obj, + "clearance", + translate("App::Property", "Clearance of Hem"), + 0.0) + SheetMetalTools.smAddDistanceProperty(obj, + "gap1", + translate("App::Property", "Gap from Left Side"), + 0.0) + SheetMetalTools.smAddDistanceProperty(obj, + "gap2", + translate("App::Property", "Gap from Right Side"), + 0.0) + SheetMetalTools.smAddBoolProperty(obj, + "invert", + translate("App::Property", "Invert Bend Direction"), + False) + SheetMetalTools.smAddDistanceProperty(obj, + "extend1", + translate("App::Property", "Extend from Left Side"), + 0.0) + SheetMetalTools.smAddDistanceProperty(obj, + "extend2", + translate("App::Property", "Extend from Right Side"), + 0.0) + SheetMetalTools.smAddEnumProperty(obj, + "BendType", + translate("App::Property", "Bend Type"), + ["Material Outside", "Material Inside", "Thickness Outside", "Offset"]) + SheetMetalTools.smAddLengthProperty(obj, + "reliefw", + translate("App::Property", "Relief Width"), + 0.8, + "ParametersRelief") + SheetMetalTools.smAddLengthProperty(obj, + "reliefd", + translate("App::Property", "Relief Depth"), + 1.0, + "ParametersRelief") + SheetMetalTools.smAddBoolProperty(obj, + "UseReliefFactor", + translate("App::Property", "Use Relief Factor"), + False, + "ParametersRelief") + SheetMetalTools.smAddEnumProperty(obj, + "reliefType", + translate("App::Property", "Relief Type"), + ["Rectangle", "Round"], + None, + "ParametersRelief") + SheetMetalTools.smAddFloatProperty(obj, + "ReliefFactor", + translate("App::Property", "Relief Factor"), + 0.7, + "ParametersRelief") + SheetMetalTools.smAddAngleProperty(obj, + "miterangle1", + translate("App::Property", "Bend Miter Angle from Left Side"), + 0.0, + "ParametersMiterangle") + SheetMetalTools.smAddAngleProperty(obj, + "miterangle2", + translate("App::Property", "Bend Miter Angle from Right Side"), + 0.0, + "ParametersMiterangle") + SheetMetalTools.smAddLengthProperty(obj, + "minGap", + translate("App::Property", "Auto Miter Minimum Gap"), + 0.2, + "ParametersEx") + SheetMetalTools.smAddLengthProperty(obj, + "maxExtendDist", + translate("App::Property", "Auto Miter maximum Extend Distance"), + 5.0, + "ParametersEx") + SheetMetalTools.smAddLengthProperty(obj, + "minReliefGap", + translate("App::Property", "Minimum Gap to Relief Cut"), + 1.0, + "ParametersEx") + SheetMetalTools.smAddBoolProperty(obj, + "AutoMiter", + translate("App::Property", "Enable Auto Miter"), + True, + "ParametersEx") + SheetMetalTools.smAddBoolProperty(obj, + "unfold", + translate("App::Property", "Shows Unfold View of Current Bend"), + False, + "ParametersEx") + SheetMetalTools.smAddProperty(obj, + "App::PropertyFloatConstraint", + "kfactor", + translate("App::Property", + "Location of Neutral Line. Caution: Using ANSI standards, not DIN."), + (0.5, 0.0, 1.0, 0.01), + "ParametersEx") + SheetMetalTools.smAddBoolProperty(obj, + "sketchflip", + translate("App::Property", "Flip Sketch Direction"), + False, + "ParametersEx2") + SheetMetalTools.smAddBoolProperty(obj, + "sketchinvert", + translate("App::Property", "Invert Sketch Start"), + False, + "ParametersEx2") + SheetMetalTools.smAddProperty(obj, + "App::PropertyFloatList", + "LegLengthList", + translate("App::Property", "Leg Lenghts List"), + None, + "ParametersEx3") + SheetMetalTools.smAddBoolProperty(obj, + "Perforate", + FreeCAD.Qt.translate("App::Property", "Enable Perforation"), + False, + "ParametersPerforation") + SheetMetalTools.smAddAngleProperty(obj, + "PerforationAngle", + FreeCAD.Qt.translate("App::Property", "Perforation Angle"), + 0.0, + "ParametersPerforation") + SheetMetalTools.smAddLengthProperty(obj, + "PerforationInitialLength", + FreeCAD.Qt.translate("App::Property", "Initial Perforation Length"), + 5.0, + "ParametersPerforation") + SheetMetalTools.smAddLengthProperty(obj, + "PerforationMaxLength", + FreeCAD.Qt.translate("App::Property", "Perforation Max Length"), + 5.0, + "ParametersPerforation") + SheetMetalTools.smAddLengthProperty(obj, + "NonperforationMaxLength", + FreeCAD.Qt.translate("App::Property", "Non-Perforation Max Length"), + 5.0, + "ParametersPerforation") + SheetMetalTools.smAddProperty(obj, + "App::PropertyLinkSub", + "OffsetFaceReference", + "Face reference for offset", + refAngOffset, + "ParametersEx") + SheetMetalTools.smAddEnumProperty(obj, + "OffsetType", + "Offset Type", + ["Material Outside", "Material Inside", "Thickness Outside", "Offset"], + "Material Inside", + "ParametersEx") + SheetMetalTools.smAddDistanceProperty(obj, + "OffsetTypeOffset", + "Works when offset face reference is on. It offsets by " + "a normal distance from the offsets reference face.", + 0.0, + "ParametersEx") + SheetMetalTools.smAddBoolProperty(obj, + "SupplAngleRef", + "Supplementary angle reference", + False, + "ParametersEx") + + def getElementMapVersion(self, _fp, ver, _prop, restored): + if not restored: + return smElementMapVersion + ver + return None + + def execute(self, fp): + """Print a short message when doing a recomputation. + + Note: + This method is mandatory. + + """ + self.addVerifyProperties(fp) + + bendAList = [fp.width.Value] + LegLengthList = [fp.width.Value] + bendR = fp.radius.Value + allowedAutoMiter = fp.AutoMiter + + # Restrict some params. + fp.miterangle1.Value = smRestrict(fp.miterangle1.Value, -80.0, 80.0) + fp.miterangle2.Value = smRestrict(fp.miterangle2.Value, -80.0, 80.0) + + # Pass selected object shape. + Main_Object = fp.baseObject[0].Shape.copy() + face = fp.baseObject[1] + thk, thkDir = sheet_thk(Main_Object, face[0]) + + fp.LegLengthList = LegLengthList + # print(LegLengthList) + + # Extend value needed for first bend set only. + extend1_list = [0.0 for n in LegLengthList] + extend2_list = [0.0 for n in LegLengthList] + extend1_list[0] = fp.extend1.Value + extend2_list[0] = fp.extend2.Value + # print(extend1_list, extend2_list) + + # Gap value needed for first bend set only. + gap1_list = [0.0 for n in LegLengthList] + gap2_list = [0.0 for n in LegLengthList] + gap1_list[0] = fp.gap1.Value + gap2_list[0] = fp.gap2.Value + # print(gap1_list, gap2_list) + + # Compute geometrical parameters for selected hem type + for i, _ in enumerate(LegLengthList): + if fp.HemType == "Flat": # has a width and clearance, and bend radius (if clearance) + bendAList[i] = 180.0 + bendR = fp.clearance.Value/2.0 # still 0 if no clearance + elif fp.HemType == "Teardrop": # has a width, clearance, and bend radius + if fp.clearance.Value == 0.0: + theta = math.atan(fp.radius.Value/fp.width.Value) + bendAList[i] = 180.0 + 2*math.degrees(theta) + LegLengthList[i] = fp.width.Value + else: + w = fp.width.Value + c = fp.clearance.Value + theta = math.atan((w-math.sqrt(w**2-2.0*bendR*c+c**2))/c) + bendAList[i] = 180.0 + math.degrees(2*theta) + LegLengthList[i] = c*(math.cos(2*theta)-1)/math.sin(2*theta)+w + elif fp.HemType == "Rolled": # has bend radius, no clearance, and no width + bendAList[i] = 270.0 + math.degrees(math.asin(bendR/(bendR+thk))) + LegLengthList[i] = 0.0 + allowedAutoMiter = False + + for i, LegLength in enumerate(LegLengthList): + s, f = smBend( + thk, + bendR=bendR, + bendA=bendAList[i], + miterA1=fp.miterangle1.Value, + miterA2=fp.miterangle2.Value, + BendType=fp.BendType, + flipped=fp.invert, + unfold=fp.unfold, + extLen=LegLength, + reliefType=fp.reliefType, + gap1=gap1_list[i], + gap2=gap2_list[i], + reliefW=fp.reliefw.Value, + reliefD=fp.reliefd.Value, + minReliefgap=fp.minReliefGap.Value, + extend1=extend1_list[i], + extend2=extend2_list[i], + kfactor=fp.kfactor, + #offset=offsetValue, + ReliefFactor=fp.ReliefFactor, + UseReliefFactor=fp.UseReliefFactor, + automiter=allowedAutoMiter, + selFaceNames=face, + MainObject=Main_Object, + #sketch=fp.Sketch, + mingap=fp.minGap.Value, + maxExtendGap=fp.maxExtendDist.Value, + #LengthSpec=fp.LengthSpec, + Perforate=fp.Perforate, + PerforationAngle=fp.PerforationAngle.Value, + PerforationInitialLength=fp.PerforationInitialLength.Value, + PerforationMaxLength=fp.PerforationMaxLength.Value, + NonperforationMaxLength=fp.NonperforationMaxLength.Value) + faces = smGetFace(f, s) + face = faces + Main_Object = s + + fp.Shape = s + + ################################################################################################### # Gui code ################################################################################################### @@ -2365,6 +2660,137 @@ def IsActive(self): if not False in geomTest and geomTest is not None: return True return None + + + class AddHemCommandClass: + """Add Hem command.""" + + def GetResources(self): + return { + # The name of a svg file available in the resources. + "Pixmap": os.path.join(icons_path, "SheetMetal_AddHem.svg"), + "MenuText": FreeCAD.Qt.translate("SheetMetal", "Make Hem"), + "Accel": "Z", + "ToolTip": FreeCAD.Qt.translate( + "SheetMetal", + "Creat hems on edges.\n" + "1. Select edges to create bends with walls.\n" + "2. Use Property editor to modify other parameters", + ), + } + + def Activated(self): + doc = FreeCAD.ActiveDocument + view = Gui.ActiveDocument.ActiveView + activeBody = None + + # Get the sheet metal object. + try: + for obj in Gui.Selection.getSelectionEx(): + if not "Plane" in obj.Object.TypeId: + for subElem in obj.SubElementNames: + if type(obj.Object.Shape.getElement(subElem)) == Part.Edge: + sel = obj + break + selobj = sel.Object + except: + raise Exception("At least one edge must be selected to create a hem.") + + selSubNames = list(sel.SubElementNames) + selSubObjs = sel.SubObjects + + # Remove faces for wall creation reference because only + # edges should be used as reference to create hems. + for subObjName in selSubNames: + if type(selobj.Shape.getElement(subObjName)) == Part.Face: + selSubNames.remove(subObjName) + if len(selSubNames) < 1: + raise Exception("At least one edge must be selected to create a hem.") + + # Get only one selected face to use for reference to angle + # and offset. + faceCount = 0 + refAngOffset = None + checkRefFace = False + for obj in Gui.Selection.getSelectionEx(): + for subObj in obj.SubObjects: + if type(subObj) == Part.Face and not "Plane" in obj.Object.TypeId: + faceCount += 1 + if faceCount == 1: + for subObjName in obj.SubElementNames: + if obj.Object.Shape.getElement(subObjName).isEqual(subObj): + refAngOffset = [obj.Object, subObjName] + checkRefFace = True + else: + print("If more than one face is selected, " + "only the first is used for " + "reference to angle and offset.") + if "Plane" in obj.Object.TypeId and faceCount == 0: + if obj.Object.TypeId == "App::Plane": + refAngOffset = [obj.Object, ""] + else: + refAngOffset = [obj.Object, obj.SubElementNames[0]] + checkRefFace = True + + viewConf = SheetMetalTools.GetViewConfig(selobj) + if hasattr(view, "getActiveObject"): + activeBody = view.getActiveObject("pdbody") + if not SheetMetalTools.smIsOperationLegal(activeBody, selobj): + return + doc.openTransaction("Hem") + if activeBody is None or not SheetMetalTools.smIsPartDesign(selobj): + newObj = doc.addObject("Part::FeaturePython", "Hem") + SMHem(newObj, selobj, selSubNames, refAngOffset, checkRefFace) + SMViewProviderTree(newObj.ViewObject) + else: + # FreeCAD.Console.PrintLog("found active body: " + activeBody.Name) + newObj = doc.addObject("PartDesign::FeaturePython", "Hem") + SMHem(newObj, selobj, selSubNames, refAngOffset, checkRefFace) + SMViewProviderFlat(newObj.ViewObject) + activeBody.addObject(newObj) + SheetMetalTools.SetViewConfig(newObj, viewConf) + Gui.Selection.clearSelection() + if SheetMetalTools.is_autolink_enabled(): + root = SheetMetalTools.getOriginalBendObject(newObj) + if root: + if hasattr(root, "Radius"): + newObj.setExpression("radius", root.Label + ".Radius") + elif hasattr(root, "radius"): + newObj.setExpression("radius", root.Label + ".radius") + newObj.baseObject[0].ViewObject.Visibility = False + doc.recompute() + # 'checkRefFace' turn bendtype to 'Offset' when face + # reference is before the command. + #dialog = SMHemTaskPanel(newObj, checkRefFace) + #SheetMetalTools.updateTaskTitleIcon(dialog) + #Gui.Control.showDialog(dialog) + return + + def IsActive(self): + selobj = Gui.Selection.getSelectionEx() + objSM = None + # In this iteration, we will find which selected object is + # the sheet metal part, 'cause the user can select a face + # for reference (this object will not be the sheet metal + # part). + for obj in selobj: + for subObj in obj.SubObjects: + if type(subObj) == Part.Edge: + objSM = obj + + # Test if any selected subObject in the sheet metal + # isn't edge. + geomTest = [] + for subObj in objSM.SubObjects: + if type(subObj) == Part.Edge: + geomTest.append(True) + else: + geomTest.append(False) + + if not False in geomTest and geomTest is not None: + return True + return None Gui.addCommand("SheetMetal_AddWall", AddWallCommandClass()) + Gui.addCommand("SheetMetal_AddHem", AddHemCommandClass()) From 1528d28fe490215853859fe837fd0d2756cfcb42 Mon Sep 17 00:00:00 2001 From: pierreporte Date: Tue, 10 Mar 2026 20:29:15 +0100 Subject: [PATCH 2/2] Hems: Added specific icon by maxwxyz --- Resources/icons/SheetMetal_AddHem.svg | 350 ++++---------------------- 1 file changed, 47 insertions(+), 303 deletions(-) diff --git a/Resources/icons/SheetMetal_AddHem.svg b/Resources/icons/SheetMetal_AddHem.svg index 19e62bd..16f71bb 100644 --- a/Resources/icons/SheetMetal_AddHem.svg +++ b/Resources/icons/SheetMetal_AddHem.svg @@ -7,205 +7,14 @@ id="svg2869" version="1.1" viewBox="0 0 64 64" - sodipodi:docname="SheetMetal_AddHem.svg" - inkscape:version="1.2.2 (1:1.2.2+202305151914+b0a8486541)" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + id="linearGradient46" + gradientUnits="userSpaceOnUse" + x1="-219.38676" + y1="-112.62828" + x2="-123.00488" + y2="-103.29395" /> + @@ -331,57 +84,48 @@ - + id="g44" + transform="matrix(0.19046319,0,0,0.18947786,71.960813,62.535362)" + style="stroke-width:5.26399"> + d="m -208.58984,-286.18945 c -3.46991,0.11925 -6.70256,0.98654 -9.57422,2.64453 l -133.62696,77.14844 c 11.48637,-6.63156 28.76878,-0.60046 43.76368,15.27148 l 61.67382,65.2793 133.62696,-77.14844 -61.67383,-65.28125 c -11.24626,-11.90381 -23.77972,-18.27181 -34.18945,-17.91406 z" + style="fill:#73d216;fill-rule:evenodd;stroke:#17220b;stroke-width:10.52798441;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1" + id="path43" /> + d="m -256.63086,-103.29492 -47.16211,-49.91992 -19.65234,11.3457 z" + style="fill:#3465a4;fill-rule:evenodd;stroke:#0c1522;stroke-width:10.52799999;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1" + id="path41" /> + d="m -56.191406,-141.86914 -133.626954,77.15039 v 30.859375 l 133.626954,-77.148435 z" + style="fill:#729fcf;fill-rule:evenodd;stroke:#0c1522;stroke-width:10.52798441;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1" + id="path40" /> + d="M -189.81836,-33.859375 V -64.71875 l -66.8125,-38.57617 -66.81445,-38.57422 v 30.86133 z" + style="fill:#3465a4;fill-rule:evenodd;stroke:#0c1522;stroke-width:10.52798441;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1" + id="path39" /> + d="m -123.00586,-180.44336 -133.625,77.14844 66.8125,38.57617 133.626954,-77.15039 z" + style="fill:#3465a4;fill-rule:evenodd;stroke:#0c1522;stroke-width:10.528;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1" + id="path38" /> + d="m -112.72656,-202.99414 -133.62696,77.14844 -10.27734,22.55078 133.625,-77.14844 z" + style="fill:#8ae234;fill-rule:evenodd;stroke:#17220b;stroke-width:10.52798441;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1" + id="path37" /> + d="m -123.00586,-168.27344 -112.54687,64.97852 45.73437,26.406248 112.548829,-64.980468 z" + style="fill:url(#linearGradient46);fill-rule:evenodd;stroke:#729fcf;stroke-width:10.52798441;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1" + id="path45" /> + d="m -342.21484,-209.03906 c -3.46979,0.11915 -6.70459,0.98469 -9.57618,2.64258 -0.69897,0.40355 -1.36502,0.85215 -2.0039,1.33789 -0.21845,0.16607 -0.41559,0.35977 -0.62695,0.53515 -0.40857,0.33903 -0.82119,0.6739 -1.20313,1.04688 -0.23085,0.22544 -0.43909,0.47927 -0.66016,0.71679 -0.33206,0.3568 -0.66866,0.70842 -0.97851,1.0918 -0.21986,0.27202 -0.41835,0.56847 -0.62695,0.85352 -0.28398,0.38807 -0.57099,0.772 -0.83399,1.18359 -0.19312,0.3022 -0.36708,0.62493 -0.54883,0.93945 -0.24476,0.42365 -0.49083,0.84563 -0.71484,1.29102 -0.17627,0.35042 -0.3347,0.71854 -0.49805,1.08203 -0.19823,0.44116 -0.39708,0.88196 -0.57617,1.3418 -0.15082,0.38724 -0.2847,0.78937 -0.42187,1.18945 -0.16016,0.46716 -0.3195,0.93581 -0.46094,1.41992 -0.12179,0.41687 -0.23006,0.84636 -0.33789,1.27539 -0.10253,0.40798 -0.19726,0.82159 -0.28711,1.24024 -0.26481,1.23391 -0.39135,2.57544 -0.54492,3.89648 -0.1044,0.89825 -0.2582,1.76002 -0.31055,2.69531 -0.0755,1.34922 -0.0204,2.7815 0.0137,4.20118 0.0223,0.92747 -0.0168,1.8167 0.0527,2.77148 0.11743,1.6108 0.3831,3.29834 0.63671,4.97852 0.12565,0.83236 0.17846,1.6291 0.33789,2.47656 0.48218,2.56278 1.10864,5.18781 1.9043,7.86523 6.20485,20.87959 20.82098,40.59748 37.03516,49.95899 v -30.86133 c -5.40473,-3.12038 -10.27755,-9.69248 -12.34571,-16.65234 -0.25916,-0.87199 -0.45976,-1.72491 -0.61914,-2.56055 -0.0523,-0.27418 -0.0755,-0.53325 -0.11718,-0.80274 -0.0864,-0.55813 -0.16755,-1.113 -0.20899,-1.64843 -0.0229,-0.29594 -0.0199,-0.5751 -0.0293,-0.86328 -0.0155,-0.4779 -0.0273,-0.95178 -0.006,-1.40625 0.0143,-0.30507 0.0493,-0.59321 0.0801,-0.88672 0.0562,-0.53615 0.11036,-1.07452 0.22071,-1.56836 0.0103,-0.0462 0.0244,-0.089 0.0352,-0.13477 0.0306,-0.12976 0.0673,-0.25432 0.10157,-0.38086 0.051,-0.18787 0.10292,-0.37416 0.16211,-0.55468 0.0429,-0.13091 0.0895,-0.25786 0.13671,-0.38477 0.0593,-0.15933 0.12148,-0.31592 0.1875,-0.46875 0.0547,-0.12658 0.11065,-0.25107 0.16993,-0.37305 0.0761,-0.15657 0.15662,-0.30828 0.24023,-0.45703 0.0606,-0.10774 0.12105,-0.21484 0.18555,-0.31836 0.0866,-0.13901 0.1798,-0.27116 0.27343,-0.40234 0.0739,-0.10347 0.1464,-0.20819 0.22461,-0.30664 0.10164,-0.12797 0.20942,-0.24793 0.31836,-0.36719 0.0784,-0.0858 0.15422,-0.17471 0.23633,-0.25586 0.12606,-0.12458 0.26162,-0.23621 0.39649,-0.34961 0.0766,-0.0644 0.14907,-0.13456 0.22851,-0.19531 0.21681,-0.16569 0.44399,-0.31983 0.68164,-0.45703 3.82866,-2.21061 9.58947,-0.20074 14.58789,5.08984 l 61.67383,65.2793 10.27734,-22.55078 -61.67382,-65.2793 c -11.24618,-11.90395 -23.77813,-18.27151 -34.1875,-17.91406 z" + style="fill:#73d216;fill-rule:evenodd;stroke:#17220b;stroke-width:10.52798441;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1" + id="path44" /> + d="m -208.22852,-275.6582 c -1.94159,0.0667 -3.38193,0.49885 -4.66601,1.24023 l -106.125,61.26953 c 6.61944,3.69382 12.98053,8.78356 18.65234,14.78711 l 55.95508,59.22656 114.86524,-66.31835 -52.51368,-55.58594 c -4.92521,-5.21318 -10.00943,-9.05182 -14.60742,-11.44141 -4.59799,-2.38959 -8.64579,-3.2779 -11.56055,-3.17773 z" + style="fill:#73d216;fill-rule:evenodd;stroke:url(#linearGradient47);stroke-width:10.52798441;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1" + id="path46" /> + d="m -323.44531,-141.86914 19.65234,-11.3457 -14.51172,-15.35938 c -4.99842,-5.29058 -10.75923,-7.30045 -14.58789,-5.08984 -0.23825,0.13755 -0.46433,0.29085 -0.68164,0.45703 -0.0796,0.0608 -0.15175,0.13076 -0.22851,0.19531 -0.1345,0.11314 -0.27075,0.22534 -0.39649,0.34961 -0.0822,0.0812 -0.15791,0.17002 -0.23633,0.25586 -0.10886,0.11916 -0.21679,0.23934 -0.31836,0.36719 -0.0781,0.0984 -0.1508,0.20324 -0.22461,0.30664 -0.0936,0.13111 -0.18687,0.2634 -0.27343,0.40234 -0.0644,0.10345 -0.12503,0.21069 -0.18555,0.31836 -0.0836,0.14881 -0.16412,0.3004 -0.24023,0.45703 -0.0593,0.12191 -0.11528,0.24654 -0.16993,0.37305 -0.0659,0.15264 -0.12828,0.30962 -0.1875,0.46875 -0.0472,0.12688 -0.0938,0.25389 -0.13671,0.38477 -0.0592,0.18067 -0.11112,0.36665 -0.16211,0.55468 -0.0343,0.12641 -0.071,0.25124 -0.10157,0.38086 -0.0207,0.0877 -0.0358,0.1804 -0.0547,0.26953 -0.0966,0.45465 -0.1498,0.94381 -0.20118,1.4336 -0.0307,0.29284 -0.0657,0.58238 -0.0801,0.88672 -0.0213,0.45402 -0.01,0.92885 0.006,1.40625 0.009,0.28763 0.006,0.56792 0.0293,0.86328 0.0414,0.53485 0.12271,1.09094 0.20899,1.64843 0.0417,0.26926 0.0649,0.52879 0.11718,0.80274 0.15937,0.83551 0.36002,1.6887 0.61914,2.56055 2.06816,6.95986 6.94098,13.53196 12.34571,16.65234 z" + style="fill:#4e9a06;fill-rule:evenodd;stroke:#17220b;stroke-width:10.52799999;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1" + id="path42" /> - -