Finish up adding the brestpump measurement

This commit is contained in:
bugbountyguy 2022-03-02 21:00:56 -06:00 committed by Christopher Charbonneau Wells
parent 3474185b00
commit 5c45b037f0
27 changed files with 459 additions and 9952 deletions

View File

@ -63,6 +63,11 @@ class StartEndFieldFilter(ChildFieldFilter):
)
class BreastpumpFilter(TimeFieldFilter):
class Meta(TimeFieldFilter.Meta):
model = models.Breastpump
class DiaperChangeFilter(TimeFieldFilter, TagsFieldFilter):
class Meta(TimeFieldFilter.Meta):
model = models.DiaperChange

View File

@ -102,6 +102,12 @@ class UserSerializer(serializers.ModelSerializer):
fields = ("id", "username")
class BreastpumpSerializer(CoreModelSerializer):
class Meta:
model = models.Breastpump
fields = ("id", "child", "amount", "time", "notes")
class ChildSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = models.Child

View File

@ -11,7 +11,7 @@ router.register(r"changes", views.DiaperChangeViewSet)
router.register(r"feedings", views.FeedingViewSet)
router.register(r"notes", views.NoteViewSet)
router.register(r"sleep", views.SleepViewSet)
router.register(r"temperature", views.TemperatureViewSet)
router.register(r"breastpump", views.BreastpumpViewSet)
router.register(r"timers", views.TimerViewSet)
router.register(r"tummy-times", views.TummyTimeViewSet)
router.register(r"weight", views.WeightViewSet)

View File

@ -16,6 +16,12 @@ class ChildViewSet(viewsets.ModelViewSet):
filterset_fields = ("first_name", "last_name", "slug", "birth_date")
class BreastpumpViewSet(viewsets.ModelViewSet):
queryset = models.Breastpump.objects.all()
serializer_class = serializers.BreastpumpSerializer
filterset_class = filters.BreastpumpFilter
class DiaperChangeViewSet(viewsets.ModelViewSet):
queryset = models.DiaperChange.objects.all()
serializer_class = serializers.DiaperChangeSerializer

View File

@ -20,6 +20,17 @@
"slug": "fake-child",
"picture": ""
}
},
{
"model": "core.breastpump",
"pk": 1,
"fields":
{
"child": 1,
"amount": 50.0,
"time": "2017-11-17T17:52:00Z",
"notes": "new device"
}
},
{
"model": "core.diaperchange",

View File

@ -75,6 +75,9 @@ class Command(BaseCommand):
"""
self.time = self.child.birth_date
self.breastpump = round(uniform(95.0, 102.0), 2)
self._add_breastpump_entry()
self.temperature = round(uniform(95.0, 102.0), 2)
self._add_temperature_entry()
@ -103,6 +106,7 @@ class Command(BaseCommand):
self._add_diaperchange_entry()
self._add_feeding_entry()
self._add_diaperchange_entry()
self._add_breastpump_entry()
if choice([True, False]):
self._add_tummytime_entry()
if choice([True, False]):
@ -110,6 +114,8 @@ class Command(BaseCommand):
self._add_tummytime_entry()
if choice([True, False]):
self._add_temperature_entry()
if choice([True, False]):
self._add_breastpump_entry()
if (self.time - last_note_entry_time).days > 1 and choice([True, False]):
self._add_note_entry()
last_note_entry_time = self.time
@ -126,6 +132,24 @@ class Command(BaseCommand):
self._add_bmi_entry()
last_bmi_entry_time = self.time
@transaction.atomic
def _add_breastpump_entry(self):
"""
Add a Breastpump entry. This assumes a weekly interval.
:returns:
"""
self.amount = round(uniform(95.0, 102.0), 2)
notes = ""
if choice([True, False, False, False]):
notes = " ".join(self.faker.sentences(randint(1, 5)))
models.Breastpump.objects.create(
child=self.child, amount=self.amount, time=self.time, notes=notes
).save()
@transaction.atomic
def _add_diaperchange_entry(self):
"""

View File

@ -87,6 +87,12 @@
{% trans "Weight" %}
</a>
{% endif %}
{% if perms.core.add_breastpump %}
<a class="dropdown-item p-2" href="{% url 'core:breastpump-add' %}">
<i class="icon-breastpump" aria-hidden="true"></i>
{% trans "Breastpump" %}
</a>
{% endif %}
</div>
</div>
</div>
@ -235,6 +241,20 @@
</a>
{% endif %}
{% if perms.core.view_breastpump %}
<a class="dropdown-item{% if request.path == '/breastpump/' %} active{% endif %}"
href="{% url 'core:breastpump-list' %}">
<i class="icon-breastpump" aria-hidden="true"></i>
{% trans "Breastpump" %}
</a>
{% endif %}
{% if perms.core.add_breastpump %}
<a class="dropdown-item pl-5{% if request.path == '/breastpump/add/' %} active{% endif %}"
href="{% url 'core:breastpump-add' %}"><i class="icon-add" aria-hidden="true"></i>
{% trans "Breastpump entry" %}
</a>
{% endif %}
</div>
</li>

View File

@ -58,6 +58,27 @@ class ChildAdmin(ImportExportMixin, ExportActionMixin, admin.ModelAdmin):
resource_class = ChildImportExportResource
class BreastpumpImportExportResource(ImportExportResourceBase):
class Meta:
model = models.Breastpump
@admin.register(models.Breastpump)
class BreastpumpAdmin(ImportExportMixin, ExportActionMixin, admin.ModelAdmin):
list_display = (
"child",
"amount",
"time",
)
list_filter = ("child",)
search_fields = (
"child__first_name",
"child__last_name",
"amount",
)
resource_class = BreastpumpImportExportResource
class DiaperChangeImportExportResource(ImportExportResourceBase):
class Meta:
model = models.DiaperChange

View File

@ -124,6 +124,21 @@ class ChildDeleteForm(forms.ModelForm):
return instance
class BreastpumpForm(CoreModelForm):
class Meta:
model = models.Breastpump
fields = ["child", "amount", "time", "notes"]
widgets = {
"time": forms.DateTimeInput(
attrs={
"autocomplete": "off",
"data-target": "#datetimepicker_time",
}
),
"notes": forms.Textarea(attrs={"rows": 5}),
}
class DiaperChangeForm(CoreModelForm):
class Meta:
model = models.DiaperChange

View File

@ -0,0 +1,49 @@
# Generated by Django 4.0.3 on 2022-03-02 23:17
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('core', '0018_bmi_headcircumference_height'),
]
operations = [
migrations.CreateModel(
name="Breastpump",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("amount", models.FloatField(verbose_name="Amount")),
("time", models.DateTimeField(verbose_name="Time")),
(
"child",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="breastpump",
to="core.Child",
verbose_name="Child",
),
),
],
options={
"verbose_name": "Breastpump",
"verbose_name_plural": "Breastpump",
"ordering": ["-time"],
"default_permissions": ("view", "add", "change", "delete"),
},
),
migrations.AddField(
model_name="breastpump",
name="notes",
field=models.TextField(blank=True, null=True, verbose_name="Notes"),
),
]

View File

@ -173,6 +173,35 @@ class TaggableManager(TaggitTaggableManager):
return super().formfield(*args, **kwargs)
class Breastpump(models.Model):
model_name = "breastpump"
child = models.ForeignKey(
"Child",
on_delete=models.CASCADE,
related_name="breastpump",
verbose_name=_("Child"),
)
amount = models.FloatField(
blank=False, null=False, verbose_name=_("Amount")
)
time = models.DateTimeField(blank=False, null=False, verbose_name=_("Time"))
notes = models.TextField(blank=True, null=True, verbose_name=_("Notes"))
objects = models.Manager()
class Meta:
default_permissions = ("view", "add", "change", "delete")
ordering = ["-time"]
verbose_name = _("Breastpump")
verbose_name_plural = _("Breastpump")
def __str__(self):
return str(_("Breastpump"))
def clean(self):
validate_time(self.time, "time")
class Child(models.Model):
model_name = "child"
first_name = models.CharField(max_length=255, verbose_name=_("First name"))

View File

@ -0,0 +1,20 @@
{% extends 'babybuddy/page.html' %}
{% load i18n widget_tweaks %}
{% block title %}{% trans "Delete a Breastpump Reading" %}{% endblock %}
{% block breadcrumbs %}
<li class="breadcrumb-item"><a href="{% url 'core:breastpump-list' %}">{% trans "Breastpump" %}</a></li>
<li class="breadcrumb-item active" aria-current="page">{% trans "Delete" %}</li>
{% endblock %}
{% block content %}
<form role="form" method="post">
{% csrf_token %}
{% blocktrans trimmed %}
<h1>Are you sure you want to delete <span class="text-info">{{ object }}</span>?</h1>
{% endblocktrans %}
<input type="submit" value="{% trans "Delete" %}" class="btn btn-danger" />
<a href="{% url 'core:breastpump-list' %}" class="btn btn-default">{% trans "Cancel" %}</a>
</form>
{% endblock %}

View File

@ -0,0 +1,38 @@
{% extends 'babybuddy/page.html' %}
{% load datetime i18n %}
{% block title %}
{% if object %}
{{ object }}
{% else %}
{% trans "Add a Breastpump Reading" %}
{% endif %}
{% endblock %}
{% block breadcrumbs %}
<li class="breadcrumb-item"><a href="{% url 'core:breastpump-list' %}">{% trans "Breastpump" %}</a></li>
{% if object %}
<li class="breadcrumb-item active" aria-current="page">{% trans "Update" %}</li>
{% else %}
<li class="breadcrumb-item active" aria-current="page">{% trans "Add a Breastpump Reading" %}</li>
{% endif %}
{% endblock %}
{% block content %}
{% if object %}
{% blocktrans trimmed %}
<h1>Update <span class="text-info">{{ object }}</span></h1>
{% endblocktrans %}
{% else %}
<h1>{% trans "Add a Breastpump Entry" %}</h1>
{% endif %}
{% include 'babybuddy/form.html' %}
{% endblock %}
{% block javascript %}
<script type="text/javascript">
BabyBuddy.DatetimePicker.init($('#datetimepicker_time'), {
format: '{% datetimepicker_format %}'
});
</script>
{% endblock %}

View File

@ -0,0 +1,73 @@
{% extends 'babybuddy/page.html' %}
{% load datetime i18n widget_tweaks %}
{% block title %}{% trans "Breastpump" %}{% endblock %}
{% block breadcrumbs %}
<li class="breadcrumb-item active" aria-current="page">{% trans "Breastpump" %}</li>
{% endblock %}
{% block content %}
<h1>
{% trans "Breastpump" %}
{% if perms.core.add_breastpump %}
<a href="{% url 'core:breastpump-add' %}" class="btn btn-sm btn-success">
<i class="icon-breastpump" aria-hidden="true"></i> {% trans "Add Breastpump Entry" %}
</a>
{% endif %}
</h1>
{% include 'babybuddy/filter.html' %}
<div class="table-responsive">
<table class="table table-instances">
<thead class="thead-inverse">
<tr>
<th>{% trans "Actions" %}</th>
<th>{% trans "Time" %}</th>
{% if not unique_child %}
<th>{% trans "Child" %}</th>
{% endif %}
<th>{% trans "Amount" %}</th>
</tr>
</thead>
<tbody>
{% for breastpump in object_list %}
{% cycle "odd" "even" as row_class silent %}
<tr class="{{ row_class }}">
<td>
<div class="btn-group btn-group-sm" role="group" aria-label="{% trans "Actions" %}">
{% if perms.core.change_breastpump %}
<a href="{% url 'core:breastpump-update' breastpump.id %}" class="btn btn-primary">
<i class="icon-update" aria-hidden="true"></i>
</a>
{% endif %}
{% if perms.core.delete_breastpump %}
<a href="{% url 'core:breastpump-delete' breastpump.id %}" class="btn btn-danger">
<i class="icon-delete" aria-hidden="true"></i>
</a>
{% endif %}
</div>
</td>
<th scope="row">{{ breastpump.time|datetime_short }}</th>
{% if not unique_child %}
<td><a href="{% url 'core:child' breastpump.child.slug %}">{{ breastpump.child }}</a></td>
{% endif %}
<td>{{ breastpump.amount }}</td>
</tr>
{% if breastpump.notes %}
<tr class="{{ row_class }} row-details">
<td colspan="4"><i class="icon-note mr-2" aria-hidden="true"></i>{{ breastpump.notes }}</td>
</tr>
{% endif %}
{% empty %}
<tr>
<th colspan="4">{% trans "No breastpump entries found." %}</th>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% include 'babybuddy/paginator.html' %}
{% endblock %}

View File

@ -6,6 +6,18 @@ from . import views
app_name = "core"
urlpatterns = [
path("breastpump/", views.BreastpumpList.as_view(), name="breastpump-list"),
path("breastpump/add/", views.BreastpumpAdd.as_view(), name="breastpump-add"),
path(
"breastpump/<int:pk>/",
views.BreastpumpUpdate.as_view(),
name="breastpump-update",
),
path(
"breastpump/<int:pk>/delete/",
views.BreastpumpDelete.as_view(),
name="breastpump-delete",
),
path("children/", views.ChildList.as_view(), name="child-list"),
path("children/add/", views.ChildAdd.as_view(), name="child-add"),
path("children/<str:slug>/", views.ChildDetail.as_view(), name="child"),

View File

@ -121,6 +121,36 @@ class ChildDelete(CoreUpdateView):
return success_message % cleaned_data
class BreastpumpList(PermissionRequiredMixin, BabyBuddyFilterView):
model = models.Breastpump
template_name = "core/breastpump_list.html"
permission_required = ("core.view_breastpump",)
paginate_by = 10
filterset_fields = ("child",)
class BreastpumpAdd(CoreAddView):
model = models.Breastpump
permission_required = ("core.add_breastpump",)
form_class = forms.BreastpumpForm
success_url = reverse_lazy("core:breastpump-list")
success_message = _("%(model)s reading added!")
class BreastpumpUpdate(CoreUpdateView):
model = models.Breastpump
permission_required = ("core.change_breastpump",)
form_class = forms.BreastpumpForm
success_url = reverse_lazy("core:breastpump-list")
success_message = _("%(model)s reading for %(child)s updated.")
class BreastpumpDelete(CoreDeleteView):
model = models.Breastpump
permission_required = ("core.delete_breastpump",)
success_url = reverse_lazy("core:breastpump-list")
class DiaperChangeList(PermissionRequiredMixin, BabyBuddyFilterView):
model = models.DiaperChange
template_name = "core/diaperchange_list.html"

View File

@ -11,6 +11,7 @@ authorization.
Currently, the following endpoints are available for `GET`, `OPTIONS`, and
`POST` requests:
- `/api/breastpump/`
- `/api/children/`
- `/api/changes/` (Diaper Changes)
- `/api/feedings/`

View File

@ -45,6 +45,7 @@ ability to edit any entry.
The Measurements menu provides the option to view and track your baby's
measurements of temperature, weight, height, head circumference and BMI.
This section also includes the mother's measurements for breastpump pumped.
Selecting any of the measurements will open that specific page with all related
measurements listed.

9975
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,4 @@
from .breastpump_amounts import breastpump_amounts # NOQA
from .diaperchange_amounts import diaperchange_amounts # NOQA
from .diaperchange_lifetimes import diaperchange_lifetimes # NOQA
from .diaperchange_types import diaperchange_types # NOQA

View File

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
from django.utils import timezone
from django.utils.translation import gettext as _
import plotly.offline as plotly
import plotly.graph_objs as go
from reports import utils
def breastpump_amounts(objects):
"""
Create a graph showing breastpump amounts over time.
:param instances: a QuerySet of Breastpump instances.
:returns: a tuple of the the graph's html and javascript.
"""
objects = objects.order_by("-time")
trace = go.Scatter(
name=_("Breastpump"),
x=list(objects.values_list("time", flat=True)),
y=list(objects.values_list("amount", flat=True)),
fill="tozeroy",
)
layout_args = utils.default_graph_layout_options()
layout_args["barmode"] = "stack"
layout_args["title"] = _("<b>Breastpump</b>")
layout_args["xaxis"]["title"] = _("Date")
layout_args["xaxis"]["rangeselector"] = utils.rangeselector_date()
layout_args["yaxis"]["title"] = _("Breastpump")
fig = go.Figure({"data": [trace], "layout": go.Layout(**layout_args)})
output = plotly.plot(fig, output_type="div", include_plotlyjs=False)
return utils.split_graph_output(output)

View File

@ -0,0 +1,9 @@
{% extends 'reports/report_base.html' %}
{% load i18n %}
{% block title %}{% trans "Breastpump" %} - {{ object }}{% endblock %}
{% block breadcrumbs %}
{{ block.super }}
<li class="breadcrumb-item active" aria-current="page">{% trans "Breastpump" %}</li>
{% endblock %}

View File

@ -8,6 +8,7 @@
<h1>Reports</h1>
<div class="list-group">
<a href="{% url 'reports:report-bmi-bmi-child' object.slug %}" class="list-group-item list-group-item-action">{% trans "Body Mass Index (BMI)" %}</a>
<a href="{% url 'reports:report-breastpump-amounts-child' object.slug %}" class="list-group-item list-group-item-action">{% trans "Breastpump Amounts" %}</a>
<a href="{% url 'reports:report-diaperchange-amounts-child' object.slug %}" class="list-group-item list-group-item-action">{% trans "Diaper Change Amounts" %}</a>
<a href="{% url 'reports:report-diaperchange-types-child' object.slug %}" class="list-group-item list-group-item-action">{% trans "Diaper Change Types" %}</a>
<a href="{% url 'reports:report-diaperchange-lifetimes-child' object.slug %}" class="list-group-item list-group-item-action">{% trans "Diaper Lifetimes" %}</a>

View File

@ -11,6 +11,11 @@ urlpatterns = [
views.ChildReportList.as_view(),
name="report-list",
),
path(
"children/<str:slug>/reports/breastpump/amounts/",
views.BreastpumpAmounts.as_view(),
name="report-breastpump-amounts-child",
),
path(
"children/<str:slug>/reports/changes/amounts/",
views.DiaperChangeAmounts.as_view(),

View File

@ -17,6 +17,24 @@ class ChildReportList(PermissionRequiredMixin, DetailView):
template_name = "reports/report_list.html"
class BreastpumpAmounts(PermissionRequiredMixin, DetailView):
"""
Graph of breastpump milk amounts collected.
"""
model = models.Child
permission_required = ("core.view_child",)
template_name = "reports/breastpump_amounts.html"
def get_context_data(self, **kwargs):
context = super(BreastpumpAmounts, self).get_context_data(**kwargs)
child = context["object"]
changes = models.Breastpump.objects.filter(child=child)
if changes and changes.count() > 0:
context["html"], context["js"] = graphs.breastpump_amounts(changes)
return context
class DiaperChangeAmounts(PermissionRequiredMixin, DetailView):
"""
Graph of diaper "amounts" - measurements of urine output.

View File

@ -85,6 +85,8 @@
<glyph glyph-name="bmi" unicode="&#xf295;" d="M714 136q0 29-21 50t-50 21-50-21-22-50 22-50 50-22 50 22 21 50z m-428 428q0 29-21 51t-51 21-50-21-21-51 21-50 50-21 51 21 21 50z m571-428q0-89-63-152t-151-63-152 63-62 152 62 151 152 63 151-63 63-151z m-53 607q0-11-8-21l-589-786q-11-15-28-15h-90q-14 0-25 11t-10 25q0 11 7 21l589 786q11 15 29 15h89q14 0 25-11t11-25z m-375-179q0-88-63-151t-152-63-151 63-63 151 63 152 151 63 152-63 63-152z" horiz-adv-x="857.1" />
<glyph glyph-name="temperature" unicode="&#xf2c8;" d="M357 100q0-45-31-76t-76-31-76 31-31 76q0 34 19 61t52 40v363h72v-363q32-12 52-40t19-61z m72 0q0 43-19 80t-53 63v428q0 45-31 76t-76 32-76-32-31-76v-428q-34-25-53-63t-19-80q0-74 53-126t126-53 126 53 53 126z m71 0q0-103-73-177t-177-73-177 73-73 177q0 102 71 175v396q0 75 53 127t126 52 126-52 53-127v-396q71-73 71-175z m71 321v-71h-107v71h107z m0 143v-71h-107v71h107z m0 143v-71h-107v71h107z" horiz-adv-x="571.4" />
<glyph glyph-name="breastpump" unicode="&#xf392;" d="M290 28c9.333 78.667 29.333 151.667 60 219c30.667 67.333 61.333 120.333 92 159c30.667 38.667 58 84 82 136c24 52 36 105.333 36 160c0 76 -27.667 141.333 -83 196c-55.333 54.667 -121 82 -197 82c-76 0 -141.667 -27.333 -197 -82c-55.333 -54.667 -83 -120 -83 -196c0 -54.667 12 -108 36 -160c24 -52 51.333 -97.333 82 -136c30.667 -38.667 61.333 -91.667 92 -159c30.667 -67.333 50.667 -140.333 60 -219c1.333 -5.333 5 -8 11 -8c6 0 9 2.667 9 8c0 0 0 0 0 0m-42 392c1.333 -2.667 0.667 -7.333 -2 -14c-4 -4 -8.667 -6 -14 -6c-5.333 0 -9.333 2 -12 6c0 0 -40 58 -40 58c-21.333 30.667 -37.333 54 -48 70c-10.667 16 -22 41 -34 75c-12 34 -18 67.667 -18 101c0 16 5.667 29.667 17 41c11.333 11.333 25 17 41 17c38.667 0 58 -22.667 58 -68c0 -62.667 14 -144.667 42 -246c1.333 -4 3 -9.667 5 -17c2 -7.333 3.667 -13 5 -17c0 0 0 0 0 0" horiz-adv-x="571.4" />
</font>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -85,6 +85,8 @@
<glyph glyph-name="bmi" unicode="&#xf295;" d="M714 136q0 29-21 50t-50 21-50-21-22-50 22-50 50-22 50 22 21 50z m-428 428q0 29-21 51t-51 21-50-21-21-51 21-50 50-21 51 21 21 50z m571-428q0-89-63-152t-151-63-152 63-62 152 62 151 152 63 151-63 63-151z m-53 607q0-11-8-21l-589-786q-11-15-28-15h-90q-14 0-25 11t-10 25q0 11 7 21l589 786q11 15 29 15h89q14 0 25-11t11-25z m-375-179q0-88-63-151t-152-63-151 63-63 151 63 152 151 63 152-63 63-152z" horiz-adv-x="857.1" />
<glyph glyph-name="temperature" unicode="&#xf2c8;" d="M357 100q0-45-31-76t-76-31-76 31-31 76q0 34 19 61t52 40v363h72v-363q32-12 52-40t19-61z m72 0q0 43-19 80t-53 63v428q0 45-31 76t-76 32-76-32-31-76v-428q-34-25-53-63t-19-80q0-74 53-126t126-53 126 53 53 126z m71 0q0-103-73-177t-177-73-177 73-73 177q0 102 71 175v396q0 75 53 127t126 52 126-52 53-127v-396q71-73 71-175z m71 321v-71h-107v71h107z m0 143v-71h-107v71h107z m0 143v-71h-107v71h107z" horiz-adv-x="571.4" />
<glyph glyph-name="breastpump" unicode="&#xf392;" d="M290 28c9.333 78.667 29.333 151.667 60 219c30.667 67.333 61.333 120.333 92 159c30.667 38.667 58 84 82 136c24 52 36 105.333 36 160c0 76 -27.667 141.333 -83 196c-55.333 54.667 -121 82 -197 82c-76 0 -141.667 -27.333 -197 -82c-55.333 -54.667 -83 -120 -83 -196c0 -54.667 12 -108 36 -160c24 -52 51.333 -97.333 82 -136c30.667 -38.667 61.333 -91.667 92 -159c30.667 -67.333 50.667 -140.333 60 -219c1.333 -5.333 5 -8 11 -8c6 0 9 2.667 9 8c0 0 0 0 0 0m-42 392c1.333 -2.667 0.667 -7.333 -2 -14c-4 -4 -8.667 -6 -14 -6c-5.333 0 -9.333 2 -12 6c0 0 -40 58 -40 58c-21.333 30.667 -37.333 54 -48 70c-10.667 16 -22 41 -34 75c-12 34 -18 67.667 -18 101c0 16 5.667 29.667 17 41c11.333 11.333 25 17 41 17c38.667 0 58 -22.667 58 -68c0 -62.667 14 -144.667 42 -246c1.333 -4 3 -9.667 5 -17c2 -7.333 3.667 -13 5 -17c0 0 0 0 0 0" horiz-adv-x="571.4" />
</font>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB