diff --git a/apps/api/urls.py b/apps/api/urls.py
index ef631004..ad2daf5f 100644
--- a/apps/api/urls.py
+++ b/apps/api/urls.py
@@ -47,6 +47,10 @@ if "wei" in settings.INSTALLED_APPS:
     from wei.api.urls import register_wei_urls
     register_wei_urls(router, 'wei')
 
+if "wrapped" in settings.INSTALLED_APPS:
+    from wrapped.api.urls import register_wrapped_urls
+    register_wrapped_urls(router, 'wrapped')
+
 app_name = 'api'
 
 # Wire up our API using automatic URL routing.
diff --git a/apps/permission/fixtures/initial.json b/apps/permission/fixtures/initial.json
index 8589bb37..bf9171fc 100644
--- a/apps/permission/fixtures/initial.json
+++ b/apps/permission/fixtures/initial.json
@@ -3829,7 +3829,7 @@
             "mask": 3,
             "field": "",
             "permanent": false,
-            "description": "Voir les profils des membres du club"
+	    "description": "Voir les profils des membres du club"
         }
     },
     {
@@ -4008,6 +4008,86 @@
             "description": "Voir le tableau des ouvreur⋅ses pour les activités organisées par son club"
         }
     },
+    {
+	"model": "permission.permission",
+	"pk": 255,
+	"fields": {
+	    "model": [
+		"wrapped",
+		"wrapped"
+	    ],
+	    "query": "{\"public\": true}",
+	    "type": "view",
+	    "mask": 1,
+	    "field": "",
+	    "permanent": false,
+	    "description": "Voir les wrapped public"
+	}
+    },
+    {
+	"model": "permission.permission",
+	"pk": 256,
+	"fields": {
+	    "model": [
+		"wrapped",
+		"wrapped"
+	    ],
+	    "query": "{\"note__noteuser__user\": [\"user\"]}",
+	    "type": "view",
+	    "mask": 1,
+	    "field": "",
+	    "permanent": true,
+	    "description": "Voir ses propres wrapped, pour toujours"
+	}
+    },
+    {
+	"model": "permission.permission",
+	"pk": 257,
+	"fields": {
+	    "model": [
+		"wrapped",
+		"wrapped"
+	    ],
+	    "query": "{\"note__noteuser__user\": [\"user\"]}",
+	    "type": "change",
+	    "mask": 1,
+	    "field": "public",
+	    "permanent": true,
+	    "description": "Modifier la visibilité de ses wrapped, pour toujours"
+	}
+    },
+    {
+	"model": "permission.permission",
+	"pk": 258,
+	"fields": {
+	    "model": [
+		"wrapped",
+		"wrapped"
+	    ],
+	    "query": "{\"note__noteclub__club\": [\"club\"]}",
+	    "type": "view",
+	    "mask": 1,
+	    "field": "",
+	    "permanent": false,
+	    "description": "Voir les wrapped de son club"
+	}
+    },
+    {
+	"model": "permission.permission",
+	"pk": 259,
+	"fields": {
+	    "model": [
+		"wrapped",
+		"wrapped"
+	    ],
+	    "query": "{\"note__noteclub__club\": [\"club\"]}",
+	    "type": "change",
+	    "mask": 1,
+	    "field": "public",
+	    "permanent": false,
+	    "description": "Modifier la visibilité des wrapped de son club"
+	}
+    },
     {
         "model": "permission.role",
         "pk": 1,
@@ -4059,7 +4139,10 @@
                 205,
                 206,
                 248,
-                249
+                249,
+		255,
+		256,
+		257
             ]
         }
     },
@@ -4148,7 +4231,10 @@
                 227,
                 233,
                 234,
-                237
+                237,
+		247,
+		258,
+		259
             ]
         }
     },
diff --git a/apps/wrapped/__init__.py b/apps/wrapped/__init__.py
new file mode 100644
index 00000000..e9c45ef0
--- /dev/null
+++ b/apps/wrapped/__init__.py
@@ -0,0 +1,4 @@
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+default_app_config = 'activity.apps.WrappedConfig'
diff --git a/apps/wrapped/admin.py b/apps/wrapped/admin.py
new file mode 100644
index 00000000..a50ec0ad
--- /dev/null
+++ b/apps/wrapped/admin.py
@@ -0,0 +1,17 @@
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from django.contrib import admin
+from note_kfet.admin import admin_site
+
+from .models import Bde, Wrapped
+
+
+@admin.register(Bde, site=admin_site)
+class BdeAdmin(admin.ModelAdmin):
+    pass
+
+
+@admin.register(Wrapped, site=admin_site)
+class WrappedAdmin(admin.ModelAdmin):
+    pass
diff --git a/apps/wrapped/api/__init__.py b/apps/wrapped/api/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/apps/wrapped/api/serializers.py b/apps/wrapped/api/serializers.py
new file mode 100644
index 00000000..d156ae75
--- /dev/null
+++ b/apps/wrapped/api/serializers.py
@@ -0,0 +1,28 @@
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from rest_framework import serializers
+
+from ..models import Wrapped, Bde
+
+
+class WrappedSerializer(serializers.ModelSerializer):
+    """
+    REST API Serializer for Wrapped.
+    The djangorestframework plugin will analyse the model `Wrapped` and parse all fields in the API.
+    """
+
+    class Meta:
+        model = Wrapped
+        fields = '__all__'
+
+
+class BdeSerializer(serializers.ModelSerializer):
+    """
+    REST API Serializer for Bde.
+    The djangorestframework plugin will analyse the model `Bde` and parse all fields in the API.
+    """
+
+    class Meta:
+        model = Bde
+        fields = '__all__'
diff --git a/apps/wrapped/api/urls.py b/apps/wrapped/api/urls.py
new file mode 100644
index 00000000..b06cddb9
--- /dev/null
+++ b/apps/wrapped/api/urls.py
@@ -0,0 +1,12 @@
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from .views import WrappedViewSet, BdeViewSet
+
+
+def register_wrapped_urls(router, path):
+    """
+    Configure router for Wrapped REST API.
+    """
+    router.register(path + '/wrapped', WrappedViewSet)
+    router.register(path + '/bde', BdeViewSet)
diff --git a/apps/wrapped/api/views.py b/apps/wrapped/api/views.py
new file mode 100644
index 00000000..72294230
--- /dev/null
+++ b/apps/wrapped/api/views.py
@@ -0,0 +1,35 @@
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from api.viewsets import ReadProtectedModelViewSet
+from django_filters.rest_framework import DjangoFilterBackend
+from rest_framework.filters import SearchFilter
+
+from .serializers import WrappedSerializer, BdeSerializer
+from ..models import Wrapped, Bde
+
+
+class WrappedViewSet(ReadProtectedModelViewSet):
+    """
+    REST API View set.
+    The djangorestframework plugin will get all `Wrapped` objects, serialize it to JSON with the given
+    serializer, then render it on /api/wrapped/wrapped/
+    """
+    queryset = Wrapped.objects.order_by('id')
+    serializer_class = WrappedSerializer
+    filter_backends = [DjangoFilterBackend, SearchFilter]
+    filterset_fields = ['note', 'bde', ]
+    search_fields = ['$note', ]
+
+
+class BdeViewSet(ReadProtectedModelViewSet):
+    """
+    REST API View set.
+    The djangorestframework plugin will get all `Bde` objects, serialize it to JSON with the given
+    serializer, then render it on /api/wrapped/bde/
+    """
+    queryset = Bde.objects.order_by('id')
+    serializer_class = BdeSerializer
+    filter_backends = [DjangoFilterBackend, SearchFilter]
+    filterset_fields = ['name', ]
+    search_fields = ['$name', ]
diff --git a/apps/wrapped/apps.py b/apps/wrapped/apps.py
new file mode 100644
index 00000000..83630287
--- /dev/null
+++ b/apps/wrapped/apps.py
@@ -0,0 +1,10 @@
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from django.apps import AppConfig
+from django.utils.translation import gettext_lazy as _
+
+
+class WrappedConfig(AppConfig):
+    name = 'wrapped'
+    verbose_name = _('wrapped')
diff --git a/apps/wrapped/management/commands/generate_wrapped.py b/apps/wrapped/management/commands/generate_wrapped.py
new file mode 100644
index 00000000..9e5c19d2
--- /dev/null
+++ b/apps/wrapped/management/commands/generate_wrapped.py
@@ -0,0 +1,592 @@
+# Copyright (C) 2028-2024 by BDE ENS Paris-Saclay
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+import json
+from argparse import ArgumentParser
+
+from django.core.management import BaseCommand
+from django.db.models import Q
+from note.models import Note, Transaction
+from member.models import User, Club, Membership
+from activity.models import Activity, Entry
+from wei.models import WEIClub
+
+from ...models import Bde, Wrapped
+
+
+class Command(BaseCommand):
+    help = "Generate wrapper for the annual BDE change"
+
+    def add_arguments(self, parser: ArgumentParser):
+        parser.add_argument(
+            '-b', '--bde',
+            type=str,
+            required=False,
+            help="A list of BDE name,  BDE1,BDE2,... (a BDE name cannot have ',')",
+            dest='bde',
+        )
+        parser.add_argument(
+            '-i', '--id',
+            type=str,
+            required=False,
+            help="A list of BDE id, id1,id2,...",
+            dest='bde_id',
+        )
+        parser.add_argument(
+            '-u', '--users',
+            type=str,
+            required=False,
+            help="""User will have their(s) wrapped generated,
+            all = all users
+            adh = all users who have a valid memberships to BDE during the BDE considered
+            supersuser = all superusers
+            custom user1,user2,... = a list of username,
+            custom_id id1,id2,... = a list of user id""",
+            dest='user',
+        )
+        parser.add_argument(
+            '-c', '--club',
+            type=str,
+            required=False,
+            help="""Club will have their(s) wrapped generated,
+            all = all clubs,
+            active = all clubs with at least one transaction during the BDE mandate considered,
+            custom club1,club2,... = a list of club name,
+            custom_id id1,id2,... = a list of club id""",
+            dest='club',
+        )
+        parser.add_argument(
+            '-f', '--force-change',
+            required=False,
+            action='store_true',
+            help="if wrapped already exist change data_json",
+            dest='change',
+        )
+        parser.add_argument(
+            '-n', '--no-creation',
+            required=False,
+            action='store_false',
+            help="if wrapped don't already exist, don't generate it",
+            dest='create',
+        )
+
+    def handle(self, *args, **options):
+        # useful string for output
+        red = '\033[31;1m'
+        yellow = '\033[33;1m'
+        green = '\033[32;1m'
+        abort = red + 'ABORT'
+        warning = yellow + 'WARNING'
+        success = green + 'SUCCESS'
+
+        # Traitement des paramètres
+        verb = options['verbosity']
+        bde = []
+        if options['bde']:
+            bde_list = options['bde'].split(',')
+            bde = [Bde.objects.get(name=bde_name) for bde_name in bde_list]
+
+        if options['bde_id']:
+            if bde:
+                if verb >= 1:
+                    print(warning)
+                    print(yellow + 'You already defined bde with their name !')
+                if verb >= 0:
+                    print(abort)
+                return
+            bde_id = options['bde_id'].split(',')
+            bde = [Bde.objects.get(pk=i) for i in bde_id]
+
+        user = []
+        if options['user']:
+            if options['user'] == 'all':
+                user = ['all', None]
+            elif options['user'] == 'adh':
+                user = ['adh', None]
+            elif options['user'] == 'superuser':
+                user = ['superuser', None]
+            elif options['user'].split(' ')[0] == 'custom':
+                user_list = options['user'].split(' ')[1].split(',')
+                user = ['custom', [User.objects.get(username=u) for u in user_list]]
+            elif options['user'].split(' ')[0] == 'custom_id':
+                user_id = options['user'].split(' ')[1].split(',')
+                user = ['custom_id', [User.objects.get(pk=u) for u in user_id]]
+            else:
+                if verb >= 1:
+                    print(warning)
+                    print(yellow + 'You user option is not recognized')
+                if verb >= 0:
+                    print(abort)
+                return
+
+        club = []
+        if options['club']:
+            if options['club'] == 'all':
+                club = ['all', None]
+            elif options['club'] == 'active':
+                club = ['active', None]
+            elif options['club'].split(' ')[0] == 'custom':
+                club_list = options['club'].split(' ')[1].split(',')
+                club = ['custom', [Club.objects.get(name=club_name) for club_name in club_list]]
+            elif options['club'].split(' ')[0] == 'custom_id':
+                club_id = options['club'].split(' ')[1].split(',')
+                club = ['custom_id', [Club.objects.get(pk=c) for c in club_id]]
+            else:
+                if verb >= 1:
+                    print(warning)
+                    print(yellow + 'You club option is not recognized')
+                if verb >= 0:
+                    print(abort)
+                return
+
+        change = options['change']
+        create = options['create']
+
+        # check if parameters are sufficient for generate wrapped with the desired option
+        if not bde:
+            if verb >= 1:
+                print(warning)
+                print(yellow + 'You have not selectionned a BDE !')
+            if verb >= 0:
+                print(abort)
+            return
+        if not (user or club):
+            if verb >= 1:
+                print(warning)
+                print(yellow + 'No club or user selected !')
+            if verb >= 0:
+                print(abort)
+            return
+
+        if verb >= 3:
+            print('\033[1mOptions:\033[m')
+            bde_str = ''
+            for b in bde:
+                bde_str += str(b)
+            print('BDE: ' + bde_str)
+            if user:
+                print('User: ' + user[0])
+            if club:
+                print('Club: ' + club[0])
+            print('change: ' + str(change))
+            print('create: ' + str(create))
+            print('')
+        if not (change or create):
+            if verb >= 1:
+                print(warning)
+                print(yellow + 'change and create is set to false, none wrapped will be created')
+            if verb >= 0:
+                print(abort)
+            return
+        if verb >= 1 and change:
+            print(warning)
+            print(yellow + 'change is set to true, some wrapped may be replaced !')
+        if verb >= 1 and not create:
+            print(warning)
+            print(yellow + 'create is set to false, wrapped will not be created !')
+        if verb >= 3 or change or not create:
+            a = str(input('\033[mContinue ? (y/n) ')).lower()
+            if a in ['n', 'no', 'non', '0']:
+                if verb >= 0:
+                    print(abort)
+                return
+
+        note = self.convert_to_note(change, create, bde=bde, user=user, club=club, verb=verb)
+        if verb >= 1:
+            print("\033[32mUser and/or Club given has successfully convert in their note\033[m")
+        global_data = self.global_data(bde, verb=verb)
+        if verb >= 1:
+            print("\033[32mGlobal data has been successfully generated\033[m")
+
+        unique_data = self.unique_data(bde, note, global_data=global_data, verb=verb)
+        if verb >= 1:
+            print("\033[32mUnique data has been successfully generated\033[m")
+
+        self.make_wrapped(unique_data, note, bde, change, create, verb=verb)
+        if verb >= 1:
+            print(green + "The wrapped has been generated !")
+        if verb >= 0:
+            print(success)
+
+        return
+
+    def convert_to_note(self, change, create, bde=None, user=None, club=None, verb=1):
+        notes = []
+        for b in bde:
+            note_for_bde = Note.objects.filter(pk__lte=-1)
+            if user:
+                if 'custom' in user[0]:
+                    for u in user[1]:
+                        query = Q(noteuser__user=u)
+                        note_for_bde |= Note.objects.filter(query)
+                elif user[0] == 'all':
+                    query = Q(noteuser__user__pk__gte=-1)
+                    note_for_bde |= Note.objects.filter(query)
+                elif user[0] == 'adh':
+                    m = Membership.objects.filter(club=1,
+                                                  date_start__lt=b.date_end,
+                                                  date_end__gt=b.date_start,
+                                                  ).distinct('user')
+                    for membership in m:
+                        note_for_bde |= Note.objects.filter(noteuser__user=membership.user)
+
+                elif user[0] == 'superuser':
+                    query |= Q(noteuser__user__is_superuser=True)
+                    note_for_bde |= Note.objects.filter(query)
+
+            if club:
+                if 'custom' in club[0]:
+                    for c in club[1]:
+                        query = Q(noteclub__club=c)
+                        note_for_bde |= Note.objects.filter(query)
+                elif club[0] == 'all':
+                    query = Q(noteclub__club__pk__gte=-1)
+                    note_for_bde |= Note.objects.filter(query)
+                elif club[0] == 'active':
+                    nc = Note.objects.filter(noteclub__club__pk__gte=-1)
+                    for noteclub in nc:
+                        if Transaction.objects.filter(
+                                Q(created_at__gte=b.date_start,
+                                  created_at__lte=b.date_end) & (Q(source=noteclub) | Q(destination=noteclub))):
+                            note_for_bde |= Note.objects.filter(pk=noteclub.pk)
+
+            note_for_bde = self.filter_note(b, note_for_bde, change, create, verb=verb)
+            notes.append(note_for_bde)
+            if verb >= 2:
+                print("\033[m{nb} note selectionned for bde {bde}".format(nb=len(note_for_bde), bde=b.name))
+        return notes
+
+    def global_data(self, bde, verb=1):
+        data = {}
+        for b in bde:
+            if b.name == 'Rave Part[list]':
+                if verb >= 2:
+                    print("Begin to make global data")
+                if verb >= 3:
+                    print('nb_transaction')
+                # nb total de transactions
+                data['nb_transaction'] = Transaction.objects.filter(
+                    created_at__gte=b.date_start,
+                    created_at__lte=b.date_end,
+                    valid=True).count()
+
+                if verb >= 3:
+                    print('nb_vieux_con')
+                # nb total de vielleux con·ne·s derrière le bar
+                button_id = [2884, 2585]
+                transactions = Transaction.objects.filter(
+                    created_at__gte=b.date_start,
+                    created_at__lte=b.date_end,
+                    valid=True,
+                    recurrenttransaction__template__pk__in=button_id)
+
+                q = 0
+                for t in transactions:
+                    q += t.quantity
+                data['nb_vieux_con'] = q
+
+                if verb >= 3:
+                    print('nb_soiree')
+                # nb total de soirée
+                a_type_id = [1, 2, 4, 5, 7, 10]
+                data['nb_soiree'] = Activity.objects.filter(
+                    date_end__gte=b.date_start,
+                    date_start__lte=b.date_end,
+                    valid=True,
+                    activity_type__pk__in=a_type_id).count()
+
+                if verb >= 3:
+                    print('pots, nb_entree_pot')
+                # nb d'entrée totale aux pots
+                pot_id = [1, 4, 10]
+                pots = Activity.objects.filter(
+                    date_end__gte=b.date_start,
+                    date_start__lte=b.date_end,
+                    valid=True,
+                    activity_type__pk__in=pot_id)
+                data['pots'] = pots  # utile dans unique_data
+                data['nb_entree_pot'] = 0
+                for pot in pots:
+                    data['nb_entree_pot'] += Entry.objects.filter(activity=pot).count()
+
+                if verb >= 3:
+                    print('top3_buttons')
+                # top 3 des boutons les plus cliqués
+                transactions = Transaction.objects.filter(
+                    created_at__gte=b.date_start,
+                    created_at__lte=b.date_end,
+                    valid=True,
+                    amount__gt=0,
+                    recurrenttransaction__template__pk__gte=-1)
+
+                d = {}
+                for t in transactions:
+                    if t.recurrenttransaction.template.name in d:
+                        d[t.recurrenttransaction.template.name] += t.quantity
+                    else:
+                        d[t.recurrenttransaction.template.name] = t.quantity
+
+                data['top3_buttons'] = list(sorted(d.items(), key=lambda item: item[1], reverse=True))[:3]
+
+                if verb >= 3:
+                    print('class_conso_all')
+                # le classement des plus gros consommateurs (BDE + club)
+                transactions = Transaction.objects.filter(
+                    created_at__gte=b.date_start,
+                    created_at__lte=b.date_end,
+                    valid=True,
+                    source__noteuser__user__pk__gte=-1,
+                    destination__noteclub__club__pk__gte=-1)
+
+                d = {}
+                for t in transactions:
+                    if t.source in d:
+                        d[t.source] += t.total
+                    else:
+                        d[t.source] = t.total
+
+                data['class_conso_all'] = dict(sorted(d.items(), key=lambda item: item[1], reverse=True))
+
+                if verb >= 3:
+                    print('class_conso_bde')
+                # le classement des plus gros consommateurs BDE
+                transactions = Transaction.objects.filter(
+                    created_at__gte=b.date_start,
+                    created_at__lte=b.date_end,
+                    valid=True,
+                    source__noteuser__user__pk__gte=-1,
+                    destination=5)
+
+                d = {}
+                for t in transactions:
+                    if t.source in d:
+                        d[t.source] += t.total
+                    else:
+                        d[t.source] = t.total
+
+                data['class_conso_bde'] = dict(sorted(d.items(), key=lambda item: item[1], reverse=True))
+
+            else:
+                # make your wrapped or reuse previous wrapped
+                raise NotImplementedError("The BDE: {bde_name} has not personalized wrapped, make it !"
+                                          .format(bde_name=b.name))
+        return data
+
+    def unique_data(self, bde, note, global_data=None, verb=1):
+        data = []
+        for i in range(len(bde)):
+            data_bde = []
+            if bde[i].name == 'Rave Part[list]':
+                if verb >= 3:
+                    total = len(note[i])
+                    current = 0
+                    print('Make {nb} data for wrapped sponsored by {bde}'
+                          .format(nb=total, bde=bde[i].name))
+                for n in note[i]:
+                    d = {}
+                    if 'user' in n.__dir__():
+                        # première conso du mandat
+                        transactions = Transaction.objects.filter(
+                            valid=True,
+                            recurrenttransaction__template__id__gte=-1,
+                            created_at__gte=bde[i].date_start,
+                            created_at__lte=bde[i].date_end,
+                            source=n,
+                            destination=5).order_by('created_at')
+                        if transactions:
+                            d['first_conso'] = transactions[0].template.name
+                        else:
+                            d['first_conso'] = ''
+                        # Wei + bus
+                        wei = WEIClub.objects.filter(
+                            date_start__lte=bde[i].date_end,
+                            date_end__gte=bde[i].date_start)
+                        if not wei:
+                            d['wei'] = ''
+                            d['bus'] = ''
+                        else:
+                            w = wei[0]
+                            memberships = Membership.objects.filter(club=w, user=n.user)
+                            if not memberships:
+                                d['wei'] = ''
+                                d['bus'] = ''
+                            else:
+                                alias = []
+                                for a in w.note.alias.iterator():
+                                    alias.append(str(a))
+                                d['wei'] = alias[-1]
+                                d['bus'] = memberships[0].weimembership.bus.name
+                        # top3 conso
+                        transactions = Transaction.objects.filter(
+                            valid=True,
+                            created_at__gte=bde[i].date_start,
+                            created_at__lte=bde[i].date_end,
+                            source=n,
+                            amount__gt=0,
+                            recurrenttransaction__template__id__gte=-1)
+                        dt = {}
+                        dc = {}
+                        for t in transactions:
+                            if t.template.name in dt:
+                                dt[t.template.name] += t.quantity
+                            else:
+                                dt[t.template.name] = t.quantity
+                            if t.template.category.name in dc:
+                                dc[t.template.category.name] += t.quantity
+                            else:
+                                dc[t.template.category.name] = t.quantity
+
+                        d['top3_conso'] = list(sorted(dt.items(), key=lambda item: item[1], reverse=True))[:3]
+                        # catégorie de bouton préférée
+                        if dc:
+                            d['top_category'] = list(sorted(dc.items(), key=lambda item: item[1], reverse=True))[0][0]
+                        else:
+                            d['top_category'] = ''
+                        # nombre de pot, et nombre d'entrée pot
+                        pots = global_data['pots']
+                        d['nb_pots'] = pots.count()
+
+                        p = 0
+                        for pot in pots:
+                            if Entry.objects.filter(activity=pot, note=n):
+                                p += 1
+                        d['nb_pot_entry'] = p
+                        # ton nombre de rechargement
+                        d['nb_rechargement'] = Transaction.objects.filter(
+                            valid=True,
+                            created_at__gte=bde[i].date_start,
+                            created_at__lte=bde[i].date_end,
+                            destination=n,
+                            source__pk__in=[1, 2, 3, 4]).count()
+                        # ajout info globale spécifique user
+                        # classement et montant conso all
+                        d['class_part_all'] = len(global_data['class_conso_all'])
+                        if n in global_data['class_conso_all']:
+                            d['class_conso_all'] = list(global_data['class_conso_all']).index(n) + 1
+                            d['amount_conso_all'] = global_data['class_conso_all'][n] / 100
+                        else:
+                            d['class_conso_all'] = 0
+                            d['amount_conso_all'] = 0
+                        # classement et montant conso bde
+                        d['class_part_bde'] = len(global_data['class_conso_bde'])
+                        if n in global_data['class_conso_bde']:
+                            d['class_conso_bde'] = list(global_data['class_conso_bde']).index(n) + 1
+                            d['amount_conso_bde'] = global_data['class_conso_bde'][n] / 100
+                        else:
+                            d['class_conso_bde'] = 0
+                            d['amount_conso_bde'] = 0
+
+                    if 'club' in n.__dir__():
+                        # plus gros consommateur
+                        transactions = Transaction.objects.filter(
+                            valid=True,
+                            created_at__lte=bde[i].date_end,
+                            created_at__gte=bde[i].date_start,
+                            destination=n,
+                            source__noteuser__user__pk__gte=-1)
+                        dt = {}
+
+                        for t in transactions:
+                            if t.source.user.username in dt:
+                                dt[t.source.user.username] += t.total
+                            else:
+                                dt[t.source.user.username] = t.total
+                        if dt:
+                            d['big_consumer'] = list(sorted(dt.items(), key=lambda item: item[1], reverse=True))[0]
+                            d['big_consumer'] = (d['big_consumer'][0], d['big_consumer'][1] / 100)
+                        else:
+                            d['big_consumer'] = ''
+                        # plus gros créancier
+                        transactions = Transaction.objects.filter(
+                            valid=True,
+                            created_at__lte=bde[i].date_end,
+                            created_at__gte=bde[i].date_start,
+                            source=n,
+                            destination__noteuser__user__pk__gte=-1)
+                        dt = {}
+
+                        for t in transactions:
+                            if t.destination.user.username in dt:
+                                dt[t.destination.user.username] += t.total
+                            else:
+                                dt[t.destination.user.username] = t.total
+                        if dt:
+                            d['big_creancier'] = list(sorted(dt.items(), key=lambda item: item[1], reverse=True))[0]
+                            d['big_creancier'] = (d['big_creancier'][0], d['big_creancier'][1] / 100)
+                        else:
+                            d['big_creancier'] = ''
+                        # nb de soirée organisée
+                        d['nb_soiree_orga'] = Activity.objects.filter(
+                            valid=True,
+                            date_start__lte=bde[i].date_end,
+                            date_end__gte=bde[i].date_start,
+                            organizer=n.club).count()
+                        # nb de membres cumulé
+                        d['nb_member'] = Membership.objects.filter(
+                            date_start__lte=bde[i].date_end,
+                            date_end__gte=bde[i].date_start,
+                            club=n.club).distinct('user').count()
+
+                    # ajout info globale
+                    # top3 button
+                    d['glob_top3_conso'] = global_data['top3_buttons']
+                    # nb entree pot
+                    d['glob_nb_entree_pot'] = global_data['nb_entree_pot']
+                    # nb soiree
+                    d['glob_nb_soiree'] = global_data['nb_soiree']
+                    # nb vieux con
+                    d['glob_nb_vieux_con'] = global_data['nb_vieux_con']
+                    # nb transaction
+                    d['glob_nb_transaction'] = global_data['nb_transaction']
+
+                    data_bde.append(json.dumps(d))
+                    if verb >= 3:
+                        current += 1
+                        print('\033[2K' + '({c}/{t})'.format(c=current, t=total) + '\033[1A')
+
+            else:
+                # make your wrapped or reuse previous wrapped
+                raise NotImplementedError("The BDE: {bde_name} has not personalized wrapped, make it !"
+                                          .format(bde_name=bde[i].name))
+            data.append(data_bde)
+        return data
+
+    def make_wrapped(self, unique_data, note, bde, change, create, verb=1):
+        if verb >= 3:
+            current = 0
+            total = 0
+            for n in note:
+                total += len(n)
+            print('\033[mMake {nb} wrapped'.format(nb=total))
+        for i in range(len(bde)):
+            for j in range(len(note[i])):
+                if create and not Wrapped.objects.filter(bde=bde[i], note=note[i][j]):
+                    Wrapped(bde=bde[i],
+                            note=note[i][j],
+                            data_json=unique_data[i][j],
+                            public=False,
+                            generated=True).save()
+                elif change:
+                    w = Wrapped.objects.get(bde=bde[i], note=note[i][j])
+                    w.data_json = unique_data[i][j]
+                    w.save()
+                if verb >= 3:
+                    current += 1
+                    print('\033[2K' + '({c}/{t})'.format(c=current, t=total) + '\033[1A')
+        return
+
+    def filter_note(self, bde, note, change, create, verb=1):
+        if change and create:
+            return list(note)
+        if change and not create:
+            note_new = []
+            for n in note:
+                if Wrapped.objects.filter(bde=bde, note=n):
+                    note_new.append(n)
+            return note_new
+        if not change and create:
+            note_new = []
+            for n in note:
+                if not Wrapped.objects.filter(bde=bde, note=n):
+                    note_new.append(n)
+            return note_new
diff --git a/apps/wrapped/migrations/0001_initial.py b/apps/wrapped/migrations/0001_initial.py
new file mode 100644
index 00000000..865112db
--- /dev/null
+++ b/apps/wrapped/migrations/0001_initial.py
@@ -0,0 +1,86 @@
+# Generated by Django 4.2.15 on 2025-02-13 01:38
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+    initial = True
+
+    dependencies = [
+        ("note", "0007_alter_note_polymorphic_ctype_and_more"),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="Bde",
+            fields=[
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("name", models.CharField(max_length=255, verbose_name="name")),
+                ("date_start", models.DateTimeField(verbose_name="date start")),
+                ("date_end", models.DateTimeField(verbose_name="date end")),
+            ],
+            options={
+                "verbose_name": "BDE",
+                "verbose_name_plural": "BDE",
+            },
+        ),
+        migrations.CreateModel(
+            name="Wrapped",
+            fields=[
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                (
+                    "generated",
+                    models.BooleanField(default=False, verbose_name="generated"),
+                ),
+                ("public", models.BooleanField(default=False, verbose_name="public")),
+                (
+                    "data_json",
+                    models.TextField(
+                        default="{}",
+                        help_text="data in the wrapped and generated by the script generate_wrapped",
+                        verbose_name="data json",
+                    ),
+                ),
+                (
+                    "bde",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.PROTECT,
+                        related_name="+",
+                        to="wrapped.bde",
+                        verbose_name="bde",
+                    ),
+                ),
+                (
+                    "note",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.PROTECT,
+                        related_name="+",
+                        to="note.note",
+                        verbose_name="note",
+                    ),
+                ),
+            ],
+            options={
+                "verbose_name": "Wrapped",
+                "verbose_name_plural": "Wrappeds",
+                "unique_together": {("note", "bde")},
+            },
+        ),
+    ]
diff --git a/apps/wrapped/migrations/__init__.py b/apps/wrapped/migrations/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/apps/wrapped/models.py b/apps/wrapped/models.py
new file mode 100644
index 00000000..b9ebc0e2
--- /dev/null
+++ b/apps/wrapped/models.py
@@ -0,0 +1,80 @@
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from django.db import models
+from django.utils.translation import gettext_lazy as _
+from note.models import Note
+
+
+class Bde(models.Model):
+    """
+    describe a BDE
+    """
+
+    name = models.CharField(
+        max_length=255,
+        verbose_name=_('name'),
+    )
+
+    date_start = models.DateTimeField(
+        verbose_name=_('date start'),
+    )
+
+    date_end = models.DateTimeField(
+        verbose_name=_('date end'),
+    )
+
+    class Meta:
+        verbose_name = _('BDE')
+        verbose_name_plural = _('BDE')
+
+    def __str__(self):
+        return self.name
+
+
+class Wrapped(models.Model):
+    """
+    A Wrapped is associated to a note, a BDE year,
+    """
+    generated = models.BooleanField(
+        verbose_name=_('generated'),
+        default=False,
+    )
+
+    public = models.BooleanField(
+        verbose_name=_('public'),
+        default=False,
+    )
+
+    bde = models.ForeignKey(
+        Bde,
+        on_delete=models.PROTECT,
+        related_name='+',
+        verbose_name=_('bde'),
+    )
+
+    note = models.ForeignKey(
+        Note,
+        on_delete=models.PROTECT,
+        related_name='+',
+        verbose_name=_('note'),
+    )
+
+    data_json = models.TextField(
+        default='{}',
+        verbose_name=_('data json'),
+        help_text=_('data in the wrapped and generated by the script generate_wrapped'),
+    )
+
+    class Meta:
+        verbose_name = _('Wrapped')
+        verbose_name_plural = _('Wrappeds')
+        unique_together = ('note', 'bde')
+
+    def __str__(self):
+        return 'NoteKfet Wrapped of {note} sponsored by {bde}'.format(bde=str(self.bde), note=str(self.note))
+
+    def makepublic(self):
+        self.public = not self.public
+        self.save()
+        return
diff --git a/apps/wrapped/static/wrapped/css/1/custom.css b/apps/wrapped/static/wrapped/css/1/custom.css
new file mode 100644
index 00000000..39a2d2c3
--- /dev/null
+++ b/apps/wrapped/static/wrapped/css/1/custom.css
@@ -0,0 +1,73 @@
+:root {
+	--accent-primary: #FF0065;
+	--accent-secondary: #FFCB20;
+}
+@font-face {
+	font-family: "JEMROKtrial-Regular";
+	src: url("/static/wrapped/fonts/1/JEMROKtrial-Regular.ttf");
+}
+body {
+	font-family: "JEMROKtrial-Regular", sans-serif;
+	background: url("/static/wrapped/img/1/bg.png");
+	color: white;
+	text-align: center;
+	padding: 50px;
+}
+#name {
+	font-size: 2em;
+	font-weight: bold;
+	text-shadow: 2px 2px 15px var(--accent-secondary);
+}
+.wrap-container {
+	max-width: 500px;
+	margin: auto;
+	padding: 20px;
+	background: rgba(0, 0, 0, 0.8);
+	border-radius: 10px;
+	box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
+}
+.category {
+	display: flex;
+	justify-content: space-between;
+	padding: 10px;
+	background: rgba(255, 255, 255, 0.2);
+	border-radius: 5px;
+	margin: 10px 0;
+	padding: 10px;
+}
+h1 {
+	font-size: 2.5em;
+	font-weight: bold;
+	text-transform: uppercase;
+	letter-spacing: 2px;
+	background: linear-gradient(90deg, var(--accent-primary), var(--accent-secondary));
+	-webkit-background-clip: text;
+}
+.list {
+	list-style: none;
+	padding: 0;
+}
+.list li {
+	display: flex;
+	justify-content: space-between;
+	background: linear-gradient(90deg, var(--accent-primary), var(--accent-secondary));
+	margin: 10px 0;
+	padding: 10px;
+	border-radius: 5px;
+	font-weight: normal;
+}
+.ranking-bar {
+	width: 100%;
+	height: 20px;
+	background: rgba(255, 255, 255, 0.2);
+	border-radius: 10px;
+	overflow: hidden;
+	margin-top: 10px;
+	position: relative;
+}
+.ranking-progress {
+	height: 100%;
+	width: 0%;
+	background: linear-gradient(90deg, var(--accent-primary), var(--accent-secondary));
+	border-radius: 10px;
+}
diff --git a/apps/wrapped/static/wrapped/favicon/1/android-chrome-192x192.png b/apps/wrapped/static/wrapped/favicon/1/android-chrome-192x192.png
new file mode 100644
index 00000000..40f01b34
Binary files /dev/null and b/apps/wrapped/static/wrapped/favicon/1/android-chrome-192x192.png differ
diff --git a/apps/wrapped/static/wrapped/favicon/1/android-chrome-512x512.png b/apps/wrapped/static/wrapped/favicon/1/android-chrome-512x512.png
new file mode 100644
index 00000000..6bd8616e
Binary files /dev/null and b/apps/wrapped/static/wrapped/favicon/1/android-chrome-512x512.png differ
diff --git a/apps/wrapped/static/wrapped/favicon/1/apple-touch-icon.png b/apps/wrapped/static/wrapped/favicon/1/apple-touch-icon.png
new file mode 100644
index 00000000..ccd657d9
Binary files /dev/null and b/apps/wrapped/static/wrapped/favicon/1/apple-touch-icon.png differ
diff --git a/apps/wrapped/static/wrapped/favicon/1/browserconfig.xml b/apps/wrapped/static/wrapped/favicon/1/browserconfig.xml
new file mode 100644
index 00000000..eb5c9b5e
--- /dev/null
+++ b/apps/wrapped/static/wrapped/favicon/1/browserconfig.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<browserconfig>
+    <msapplication>
+        <tile>
+            <square150x150logo src="/static/favicon/1/mstile-150x150.png"/>
+            <TileColor>#00a300</TileColor>
+        </tile>
+    </msapplication>
+</browserconfig>
diff --git a/apps/wrapped/static/wrapped/favicon/1/favicon-16x16.png b/apps/wrapped/static/wrapped/favicon/1/favicon-16x16.png
new file mode 100644
index 00000000..b7a7c124
Binary files /dev/null and b/apps/wrapped/static/wrapped/favicon/1/favicon-16x16.png differ
diff --git a/apps/wrapped/static/wrapped/favicon/1/favicon-32x32.png b/apps/wrapped/static/wrapped/favicon/1/favicon-32x32.png
new file mode 100644
index 00000000..4f3f95f0
Binary files /dev/null and b/apps/wrapped/static/wrapped/favicon/1/favicon-32x32.png differ
diff --git a/apps/wrapped/static/wrapped/favicon/1/favicon.ico b/apps/wrapped/static/wrapped/favicon/1/favicon.ico
new file mode 100644
index 00000000..cbc82dde
Binary files /dev/null and b/apps/wrapped/static/wrapped/favicon/1/favicon.ico differ
diff --git a/apps/wrapped/static/wrapped/favicon/1/mstile-150x150.png b/apps/wrapped/static/wrapped/favicon/1/mstile-150x150.png
new file mode 100644
index 00000000..7cdfc755
Binary files /dev/null and b/apps/wrapped/static/wrapped/favicon/1/mstile-150x150.png differ
diff --git a/apps/wrapped/static/wrapped/favicon/1/safari-pinned-tab.svg b/apps/wrapped/static/wrapped/favicon/1/safari-pinned-tab.svg
new file mode 100644
index 00000000..43a9370f
--- /dev/null
+++ b/apps/wrapped/static/wrapped/favicon/1/safari-pinned-tab.svg
@@ -0,0 +1,503 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+ "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
+ width="933.000000pt" height="933.000000pt" viewBox="0 0 933.000000 933.000000"
+ preserveAspectRatio="xMidYMid meet">
+
+<g transform="translate(0.000000,933.000000) scale(0.100000,-0.100000)"
+fill="#000000" stroke="none">
+<path d="M4285 8909 c-1611 -113 -3013 -1115 -3640 -2600 -322 -763 -413
+-1617 -259 -2439 160 -853 598 -1670 1217 -2266 689 -665 1526 -1060 2497
+-1181 206 -25 734 -25 940 0 539 67 996 204 1455 436 609 308 1121 746 1528
+1304 368 504 642 1152 745 1762 47 277 57 397 57 730 0 335 -6 419 -51 695
+-189 1175 -882 2234 -1884 2882 -772 499 -1702 741 -2605 677z m336 -175 c88
+-16 130 -33 167 -67 29 -27 30 -110 2 -192 -30 -87 -35 -175 -16 -283 19 -107
+45 -165 141 -312 97 -148 117 -198 123 -301 4 -84 3 -87 -24 -118 -39 -44
+-100 -51 -336 -40 -255 12 -305 25 -371 98 -47 52 -68 124 -66 226 1 63 -1 80
+-12 78 -8 -1 -51 -7 -97 -13 l-82 -12 2 -142 c3 -126 1 -146 -18 -187 -42 -91
+-145 -159 -314 -210 -197 -58 -280 -8 -267 162 7 87 32 158 127 357 127 270
+164 434 141 631 -15 123 -9 188 20 225 44 56 188 100 384 116 145 11 393 4
+496 -16z m849 -107 c172 -44 281 -89 332 -138 39 -37 41 -40 34 -85 -3 -27
+-27 -85 -56 -138 -59 -110 -74 -171 -90 -372 -15 -181 -9 -236 30 -276 32 -31
+58 -35 98 -14 35 19 62 54 154 202 100 158 123 205 153 311 51 175 80 209 168
+200 104 -10 335 -126 424 -213 67 -63 71 -96 17 -148 -44 -43 -81 -61 -192
+-93 -114 -32 -167 -62 -235 -131 -78 -79 -120 -155 -168 -301 -47 -144 -74
+-195 -129 -245 -89 -80 -176 -70 -506 57 -253 98 -339 173 -351 305 -7 74 14
+158 66 260 61 122 75 180 68 292 -8 140 -32 201 -128 325 -63 81 -79 116 -79
+169 0 35 5 48 23 61 36 27 202 15 367 -28z m-2409 -257 c92 -26 148 -98 156
+-204 11 -135 -61 -297 -205 -459 -24 -27 -42 -50 -40 -52 2 -2 29 2 61 7 63
+11 129 0 174 -29 29 -19 55 -68 78 -148 13 -49 26 -69 70 -110 154 -146 134
+-194 -155 -372 -214 -132 -295 -164 -353 -140 -55 24 -71 70 -64 193 7 131 -9
+207 -52 246 -17 16 -40 28 -51 28 -56 0 -183 -72 -280 -159 l-45 -40 25 -21
+c14 -12 71 -44 127 -72 155 -78 243 -175 243 -268 0 -62 -43 -124 -191 -272
+-175 -174 -263 -225 -347 -197 -59 19 -91 49 -122 114 -25 49 -33 85 -45 200
+-18 164 -34 225 -83 318 -56 109 -110 161 -217 212 -101 48 -169 104 -180 148
+-18 71 74 200 269 379 386 355 806 642 1012 692 71 17 165 20 215 6z m3941
+-474 c91 -39 319 -242 542 -483 78 -84 151 -172 164 -195 46 -86 22 -175 -85
+-308 -146 -180 -264 -199 -360 -57 -79 117 -56 264 48 313 24 12 63 42 87 68
+52 57 55 91 12 134 -69 69 -185 48 -316 -57 -82 -65 -104 -135 -64 -209 33
+-62 45 -72 91 -76 47 -4 69 -25 69 -64 0 -41 -49 -112 -77 -112 -8 0 -41 23
+-75 51 -64 53 -104 76 -114 66 -3 -3 -10 -22 -14 -43 -21 -93 41 -237 127
+-297 53 -36 91 -35 129 4 44 46 61 53 89 35 60 -40 72 -184 22 -282 -50 -98
+-113 -130 -239 -121 -114 8 -195 49 -328 168 -58 52 -171 149 -252 216 -227
+191 -260 238 -222 320 29 62 129 153 223 203 46 25 105 64 131 87 81 73 161
+250 195 430 20 107 37 149 77 191 36 36 81 42 140 18z m-2454 -617 c3 -19 -23
+-49 -43 -49 -18 0 -45 27 -45 45 0 27 83 31 88 4z m382 -79 c8 -14 8 -26 0
+-40 -19 -35 -80 -20 -80 20 0 40 61 55 80 20z m409 -11 c42 -12 134 -44 205
+-71 501 -195 938 -549 1235 -1002 83 -126 202 -359 252 -493 19 -51 37 -93 40
+-93 12 0 58 98 90 193 18 53 37 97 43 97 6 0 47 -7 90 -15 117 -23 322 -29
+463 -16 171 17 327 62 452 132 29 17 59 28 66 26 22 -9 107 -131 150 -217 142
+-286 151 -529 30 -887 -19 -56 -40 -142 -46 -191 -11 -79 -10 -95 5 -142 25
+-77 65 -130 140 -186 80 -59 80 -49 -7 -247 -147 -334 -310 -554 -479 -650
+-131 -75 -197 -91 -363 -92 -164 0 -130 -18 -340 175 -200 183 -319 290 -325
+290 -3 0 -13 -24 -23 -52 -34 -98 -165 -352 -244 -473 -416 -633 -1062 -1051
+-1804 -1170 -151 -24 -382 -34 -554 -24 -465 28 -886 169 -1280 430 -92 61
+-143 102 -161 129 -62 94 -135 369 -137 516 -1 68 3 89 24 129 32 64 69 90
+124 89 61 -1 115 -37 221 -146 49 -52 119 -113 153 -136 107 -71 157 -53 182
+66 14 69 4 119 -45 231 -33 75 -66 209 -66 269 0 22 -14 47 -49 89 -138 166
+-233 361 -283 584 -31 138 -33 407 -4 538 104 479 427 851 879 1011 43 15 80
+30 82 32 5 4 -17 96 -30 131 -9 23 10 22 43 -2 15 -10 54 -34 87 -52 l60 -33
+202 -1 c164 0 204 2 208 13 3 8 2 63 -1 122 -8 128 -2 169 32 210 33 39 44 38
+44 -5 0 -50 29 -118 88 -209 50 -75 52 -81 52 -148 0 -39 -7 -84 -15 -106 -25
+-58 -34 -113 -28 -159 l5 -41 41 46 c69 80 87 131 87 250 0 56 3 102 8 102 17
+0 114 -95 132 -130 26 -51 34 -127 21 -190 -6 -29 -10 -55 -7 -57 7 -7 125 87
+150 120 25 33 49 104 40 119 -3 4 -23 8 -44 8 -98 0 -136 17 -217 98 -71 70
+-77 74 -89 57 -8 -10 -14 -25 -14 -32 0 -24 -18 -14 -63 37 -62 69 -82 154
+-53 224 27 65 76 106 191 162 122 58 230 131 240 163 9 28 -11 60 -41 67 -35
+9 -119 -1 -179 -21 -27 -9 -117 -49 -200 -88 -175 -82 -220 -91 -289 -57 -152
+73 -93 290 102 377 53 23 61 24 191 17 136 -7 136 -7 167 19 18 16 41 52 57
+94 15 37 37 80 49 95 28 33 134 98 162 98 11 0 54 -10 95 -21z m-901 -195 c37
+-26 23 -74 -23 -74 -43 0 -63 58 -27 79 23 14 24 14 50 -5z m-3516 -1078 c80
+-44 254 -103 344 -116 99 -14 316 -12 479 5 197 20 182 23 199 -32 30 -102 67
+-186 110 -253 27 -42 43 -76 39 -86 -14 -38 -131 125 -173 243 -13 35 -27 60
+-32 57 -30 -19 -116 -190 -151 -300 -48 -152 -60 -243 -54 -419 5 -169 15
+-238 74 -505 34 -156 36 -175 36 -355 1 -135 -4 -218 -16 -285 -22 -130 -61
+-277 -91 -344 -14 -31 -22 -56 -18 -56 4 1 104 93 222 205 197 188 229 212
+230 174 0 -6 -326 -312 -452 -422 -47 -42 -98 -81 -113 -87 -39 -15 -219 -12
+-300 5 -38 8 -112 35 -164 61 -121 59 -227 159 -320 299 -77 117 -216 389
+-251 493 l-25 73 35 27 c203 157 227 254 135 542 -103 320 -111 513 -33 745
+43 126 185 365 218 365 5 0 38 -16 72 -34z m1564 -2071 c26 -39 -31 -86 -64
+-53 -18 18 -15 55 6 67 23 14 42 10 58 -14z m434 -265 c8 -14 8 -26 0 -40 -19
+-35 -80 -20 -80 20 0 40 61 55 80 20z m-392 -162 c4 -34 -27 -54 -58 -38 -21
+11 -25 27 -14 55 5 11 16 15 38 13 25 -2 32 -8 34 -30z m168 -223 c11 -43 -34
+-73 -64 -43 -13 13 -16 50 -5 61 3 4 19 7 34 7 22 0 30 -6 35 -25z m4258 -79
+c42 -57 100 -125 128 -152 99 -89 238 -168 428 -244 190 -76 276 -126 364
+-215 92 -92 128 -197 88 -256 -34 -50 -96 -119 -108 -119 -7 0 -28 22 -47 48
+-55 77 -61 91 -48 119 16 35 -13 95 -80 162 -68 68 -126 106 -319 216 -192
+109 -304 185 -398 271 -59 54 -77 65 -97 60 -18 -5 -28 0 -44 20 -36 46 -37
+85 -1 142 17 29 37 52 44 52 8 0 48 -47 90 -104z m-4627 -91 c88 -132 97 -158
+91 -246 -7 -87 -45 -167 -112 -234 -72 -72 -133 -98 -216 -93 -75 4 -100 19
+-156 93 -19 25 -38 45 -42 45 -4 0 -33 -33 -66 -74 -83 -107 -238 -253 -292
+-278 -39 -17 -50 -18 -75 -7 -38 15 -95 81 -110 127 -37 111 96 236 358 335
+209 80 308 154 413 309 77 114 100 140 119 136 9 -2 48 -53 88 -113z m4568
+-154 c89 -67 204 -184 220 -223 14 -35 14 -39 -5 -58 -24 -24 -69 -26 -113 -4
+-40 21 -77 54 -77 70 0 13 -46 54 -61 54 -17 0 -8 -37 19 -81 64 -101 201
+-197 362 -255 167 -59 279 -144 315 -237 24 -63 11 -107 -51 -176 -79 -88
+-133 -102 -200 -53 -50 36 -133 139 -219 271 -77 117 -131 174 -257 269 -48
+36 -85 68 -82 71 6 7 132 -81 195 -138 30 -27 98 -109 149 -181 52 -73 125
+-166 163 -206 89 -96 129 -108 193 -59 43 33 39 40 -9 20 -20 -8 -45 -15 -56
+-15 -33 0 -138 107 -229 233 -96 133 -213 253 -300 308 -63 39 -127 66 -116
+47 5 -7 -1 -9 -20 -4 -22 5 -26 3 -26 -16 0 -24 26 -58 46 -58 16 0 73 -65 85
+-98 20 -52 -11 -102 -64 -102 -98 0 -220 130 -241 255 -10 58 4 87 85 174 39
+42 99 111 132 153 73 92 87 96 162 39z m-4283 -208 c64 -61 108 -124 115 -168
+7 -46 -17 -113 -76 -204 -84 -131 -140 -252 -162 -347 -61 -265 -99 -371 -154
+-429 -26 -28 -40 -35 -72 -35 -70 0 -179 86 -216 169 -38 87 5 218 110 332
+l56 60 -23 24 c-13 14 -29 25 -35 25 -6 0 -55 -47 -109 -105 -54 -58 -115
+-115 -137 -125 -81 -42 -154 -16 -185 65 -16 43 -16 47 1 92 37 96 120 161
+345 271 193 93 259 148 363 305 93 139 101 142 179 70z m3835 -224 c72 -35
+133 -128 133 -203 0 -36 -5 -48 -26 -65 -32 -25 -55 -26 -94 -6 -34 18 -45 35
+-54 90 -8 44 -40 85 -67 85 -27 0 -59 -48 -59 -89 0 -48 42 -132 86 -171 45
+-39 92 -40 189 -1 140 57 189 52 298 -30 77 -58 139 -132 176 -209 21 -46 26
+-69 25 -135 0 -68 -4 -89 -29 -138 -36 -72 -131 -164 -210 -203 -160 -78 -292
+-16 -437 205 -27 41 -47 82 -46 90 2 12 21 18 76 22 130 12 237 89 212 153
+-18 49 -49 52 -136 13 -102 -45 -134 -51 -194 -37 -69 17 -130 73 -175 162
+-62 125 -45 241 51 347 43 48 128 108 180 126 51 18 51 18 101 -6z m-3403
+-138 c50 -32 129 -80 176 -106 153 -85 210 -162 210 -285 0 -117 -76 -226
+-174 -251 l-45 -11 27 -40 c36 -56 42 -149 13 -232 -12 -33 -21 -82 -21 -110
+0 -75 -19 -177 -39 -211 -34 -58 -115 -62 -230 -10 -79 37 -121 72 -142 120
+-33 74 -6 145 96 253 65 70 115 152 115 192 0 40 -32 90 -76 120 -38 27 -64
+37 -64 26 0 -46 -46 -282 -65 -332 -71 -188 -137 -228 -272 -165 -80 38 -147
+101 -169 157 -40 105 44 246 222 375 159 114 218 207 259 405 25 121 44 164
+72 164 9 0 57 -26 107 -59z m2891 -157 c26 -10 44 -56 61 -156 18 -106 63
+-210 119 -275 20 -23 73 -69 119 -102 141 -102 212 -199 223 -305 10 -94 -39
+-155 -174 -218 -81 -38 -156 -47 -201 -24 -72 37 -123 186 -139 404 -10 126
+-12 137 -51 215 -22 45 -70 120 -105 167 -36 47 -70 102 -77 124 -11 34 -10
+41 7 65 20 27 115 84 168 100 17 5 31 10 32 10 1 1 9 -2 18 -5z m-2249 -154
+c107 -37 231 -70 384 -100 83 -16 161 -37 173 -45 45 -29 71 -93 75 -186 3
+-51 0 -101 -7 -122 -17 -50 -73 -97 -115 -97 -68 0 -136 74 -136 148 0 19 6
+35 14 38 21 8 27 31 16 60 -7 18 -16 25 -32 22 -48 -7 -99 -156 -99 -289 0
+-47 9 -103 32 -181 61 -212 35 -383 -64 -435 -41 -21 -140 -21 -226 2 -160 41
+-212 104 -198 238 9 89 44 163 133 279 105 139 119 177 119 325 0 104 -2 114
+-23 135 -23 23 -23 23 -38 4 -17 -23 -18 -58 -3 -73 14 -14 -17 -88 -49 -113
+-13 -11 -40 -20 -59 -20 -104 0 -147 101 -107 253 20 78 47 130 80 156 33 26
+56 26 130 1z m1218 -43 c14 -54 -1 -87 -44 -101 -54 -17 -62 -43 -55 -176 9
+-168 53 -559 76 -675 32 -159 70 -225 128 -225 45 0 61 -31 61 -116 0 -98 -6
+-102 -163 -119 -185 -19 -230 -5 -268 81 -43 96 -45 360 -3 544 36 161 29 358
+-22 565 -27 112 -31 202 -10 230 17 23 80 33 201 31 l90 -1 9 -38z m406 -57
+c22 -22 22 -22 24 -200 2 -100 6 -136 23 -182 61 -163 189 -247 293 -193 35
+18 41 38 38 120 l-3 60 36 3 c73 6 177 -107 220 -241 27 -84 21 -166 -17 -244
+-35 -72 -70 -98 -182 -132 -231 -72 -428 -110 -497 -97 -52 10 -100 58 -122
+119 -26 75 -23 227 5 334 41 151 24 263 -65 434 -36 70 -44 94 -41 130 4 53
+29 70 133 92 98 21 131 21 155 -3z"/>
+<path d="M4450 8721 c14 -4 54 -14 90 -20 36 -7 88 -23 116 -35 41 -19 54 -32
+72 -70 12 -25 22 -57 22 -71 0 -40 16 -29 30 19 31 111 -57 174 -255 182 -65
+3 -91 1 -75 -5z"/>
+<path d="M3914 8686 c-144 -47 -171 -81 -160 -206 3 -42 12 -96 19 -121 l13
+-44 12 108 c7 65 19 122 31 145 21 41 103 103 164 122 20 6 37 13 37 16 0 10
+-50 1 -116 -20z"/>
+<path d="M4157 8572 c-26 -28 -45 -82 -67 -191 -48 -235 -66 -471 -37 -471 8
+0 58 7 113 15 54 8 104 15 111 15 17 0 53 115 60 190 9 109 -44 368 -89 433
+-23 32 -66 37 -91 9z"/>
+<path d="M4336 8308 c32 -150 3 -361 -53 -382 -9 -4 -58 -12 -109 -18 -127
+-16 -122 -33 7 -23 l102 7 -9 -39 c-5 -21 -9 -72 -8 -114 0 -62 6 -87 28 -132
+46 -95 129 -148 228 -147 33 1 33 1 -12 17 -69 24 -107 59 -142 131 -30 60
+-33 75 -32 152 0 58 9 118 27 187 37 139 35 214 -10 358 -23 74 -33 76 -17 3z"/>
+<path d="M3566 7668 c-31 -47 -78 -184 -83 -239 -7 -68 10 -124 42 -145 32
+-21 104 -20 162 2 68 25 74 34 17 28 -66 -8 -130 10 -151 43 -27 41 -22 150
+10 248 28 83 29 102 3 63z"/>
+<path d="M5163 8646 c-17 -8 -36 -23 -42 -35 -25 -46 -9 -84 95 -216 57 -73
+51 -41 -11 60 -48 78 -52 90 -42 121 9 26 48 44 119 53 l53 7 -50 8 c-27 4
+-59 9 -70 12 -11 2 -34 -3 -52 -10z"/>
+<path d="M6211 8246 c-12 -13 -37 -71 -55 -128 -41 -130 -64 -175 -176 -342
+-88 -132 -136 -184 -182 -198 -20 -5 -19 -6 8 -7 81 -3 211 152 331 394 22 44
+46 96 53 115 21 55 59 101 98 117 31 13 46 13 128 -1 101 -17 183 -46 229 -80
+39 -29 55 -38 55 -32 0 8 -111 81 -167 110 -79 39 -200 76 -253 76 -36 0 -51
+-5 -69 -24z"/>
+<path d="M5263 7797 c-63 -150 -77 -200 -69 -250 15 -92 64 -145 196 -212 91
+-45 126 -54 68 -16 -68 43 -168 149 -191 200 -25 56 -17 148 23 293 16 57 28
+104 26 105 -1 1 -25 -53 -53 -120z"/>
+<path d="M2820 8326 c-74 -26 -126 -52 -223 -109 -77 -45 -97 -66 -40 -41 193
+83 294 114 373 114 74 0 145 -26 174 -63 l26 -32 0 35 c0 52 -32 97 -77 109
+-62 18 -161 12 -233 -13z"/>
+<path d="M2400 7949 c-100 -41 -150 -172 -150 -395 0 -121 22 -279 41 -299 7
+-7 40 20 97 80 133 138 189 270 180 430 -5 87 -27 147 -63 171 -30 19 -76 25
+-105 13z"/>
+<path d="M2562 7933 c33 -64 42 -98 46 -164 7 -135 -36 -256 -135 -379 -34
+-41 -59 -77 -57 -79 2 -2 18 8 37 22 139 106 207 240 207 410 0 87 -15 134
+-56 172 -25 24 -50 34 -42 18z"/>
+<path d="M1698 7492 c-106 -109 -113 -211 -20 -276 20 -14 74 -39 119 -56 46
+-17 99 -43 119 -56 20 -14 38 -23 40 -21 6 6 -91 98 -166 157 -36 28 -73 66
+-83 83 -26 45 -18 115 18 167 15 22 26 42 23 45 -2 2 -25 -17 -50 -43z"/>
+<path d="M2710 7365 c0 -3 15 -19 34 -36 51 -44 66 -100 66 -243 0 -102 3
+-126 19 -153 35 -57 90 -56 184 3 32 20 57 38 55 40 -2 2 -32 -4 -66 -14 -112
+-30 -146 3 -136 129 11 127 -29 224 -108 265 -28 14 -48 18 -48 9z"/>
+<path d="M2086 6674 c10 -194 22 -236 83 -287 76 -64 161 -39 279 81 99 102
+110 125 32 72 -130 -88 -213 -109 -277 -70 -41 24 -45 33 -81 169 -17 62 -33
+116 -36 118 -3 3 -3 -34 0 -83z"/>
+<path d="M6902 7869 c-19 -6 -40 -22 -51 -39 -18 -31 -57 -208 -47 -217 3 -4
+19 25 36 63 62 143 59 139 117 142 64 4 123 -24 209 -97 63 -54 93 -68 53 -25
+-32 36 -164 141 -197 158 -40 20 -83 26 -120 15z"/>
+<path d="M7470 7455 c0 -3 31 -42 70 -88 38 -45 80 -102 92 -127 28 -56 33
+-139 14 -210 -8 -30 -13 -56 -11 -58 1 -1 17 19 34 47 20 30 34 67 37 97 7 58
+-1 72 -138 237 -84 100 -98 115 -98 102z"/>
+<path d="M6560 7189 c-14 -11 -56 -36 -95 -56 -77 -40 -190 -144 -201 -187 -3
+-14 -3 -38 1 -53 8 -33 85 -108 146 -142 l43 -25 -22 30 c-105 136 -98 179 52
+334 107 111 135 147 76 99z"/>
+<path d="M6980 7095 c0 -28 6 -60 15 -71 19 -28 75 -54 114 -54 27 0 32 -4 38
+-31 7 -38 23 -19 23 29 0 31 -1 32 -43 32 -49 0 -78 23 -121 100 l-26 45 0
+-50z"/>
+<path d="M6850 6833 c0 -194 171 -375 302 -320 19 8 44 27 56 42 28 35 54 29
+69 -15 l12 -35 0 40 c1 88 -47 120 -96 64 -15 -17 -39 -35 -51 -40 -34 -13
+-96 6 -137 43 -40 34 -97 132 -122 204 -23 71 -33 76 -33 17z"/>
+<path d="M4656 6262 c-14 -28 -16 -56 -14 -177 l3 -145 32 -6 c36 -7 50 -31
+30 -51 -7 -7 -33 -19 -57 -26 -42 -11 -47 -17 -80 -81 -30 -60 -34 -79 -34
+-140 1 -44 8 -93 21 -129 22 -64 14 -89 -10 -29 -29 74 -40 153 -27 212 6 30
+14 67 17 82 7 39 -15 44 -76 17 -48 -20 -51 -24 -52 -58 0 -20 -4 -44 -8 -54
+-4 -12 7 -45 31 -95 21 -42 41 -99 44 -127 8 -63 -8 -51 -25 19 -17 68 -67
+165 -106 203 l-33 32 -39 -29 c-39 -29 -40 -32 -47 -103 -7 -81 1 -115 47
+-189 16 -27 27 -54 25 -60 -3 -7 -17 6 -32 30 -25 40 -38 68 -65 135 -12 31
+-58 54 -81 39 -8 -5 -19 -38 -25 -76 -9 -55 -9 -72 4 -98 13 -27 73 -80 104
+-91 7 -2 9 -8 5 -12 -12 -12 -98 44 -119 78 -10 18 -24 50 -30 72 l-11 40 -22
+-27 c-11 -15 -33 -49 -48 -76 l-28 -49 28 -54 c20 -40 38 -60 70 -77 38 -21
+55 -42 34 -42 -22 0 -101 64 -118 95 -22 42 -31 44 -40 8 -10 -40 41 -133 83
+-153 40 -18 43 -35 6 -25 -38 9 -50 21 -83 79 l-29 50 -11 -30 c-16 -41 -50
+-185 -50 -211 0 -23 45 -56 93 -67 15 -4 25 -11 22 -16 -6 -10 -58 3 -91 25
+-12 8 -25 11 -27 7 -8 -12 1 -95 12 -124 9 -24 16 -28 51 -28 25 0 39 -4 35
+-10 -3 -5 -19 -10 -36 -10 -17 0 -29 -5 -29 -12 0 -7 20 -44 44 -82 l43 -69 6
+119 c6 142 22 209 81 329 96 194 252 330 461 401 115 39 295 45 415 15 274
+-68 483 -268 570 -546 34 -110 39 -278 11 -398 -66 -287 -275 -508 -558 -589
+-113 -33 -306 -32 -413 1 -100 31 -211 90 -287 152 -66 54 -157 166 -192 237
+l-22 43 -30 -26 c-17 -14 -41 -28 -55 -31 -13 -3 -24 -8 -24 -9 0 -2 9 -24 20
+-49 l19 -46 37 15 c21 8 43 20 50 26 8 7 14 7 18 0 4 -6 -16 -22 -43 -36 l-50
+-25 20 -35 c24 -40 54 -45 122 -21 20 8 37 9 37 4 0 -12 -63 -38 -95 -38 -14
+0 -25 -6 -25 -12 0 -7 24 -44 53 -83 l53 -70 49 3 c35 1 65 11 99 33 27 16 51
+27 55 24 8 -8 -34 -40 -87 -66 -64 -32 -68 -49 -23 -93 37 -36 40 -37 87 -31
+70 11 81 19 96 72 7 25 20 49 27 51 10 3 12 0 6 -14 -4 -11 -13 -41 -21 -69
+-9 -35 -24 -59 -49 -82 l-37 -32 69 -45 c37 -25 73 -46 79 -46 7 0 34 17 61
+38 52 41 97 114 107 175 4 20 11 37 16 37 11 0 4 -48 -15 -105 -7 -22 -16 -60
+-19 -83 -4 -24 -15 -61 -26 -82 l-19 -38 37 -15 c36 -14 38 -14 79 15 50 36
+52 41 63 137 6 53 4 86 -5 118 -15 51 -3 67 16 21 17 -41 14 -149 -6 -234 -24
+-102 -19 -109 83 -128 47 -9 88 -14 90 -11 3 3 0 16 -6 30 -19 41 -14 85 19
+191 30 96 33 149 14 197 -4 9 -3 17 3 17 24 0 35 -70 22 -145 -12 -70 -12 -75
+10 -107 46 -66 99 -113 84 -73 -10 25 17 114 43 145 25 30 25 30 8 86 -9 32
+-27 73 -40 93 -27 39 -25 53 4 27 40 -36 63 -113 67 -225 3 -58 9 -120 14
+-137 13 -40 74 -99 125 -120 44 -18 95 -34 95 -30 0 2 -15 19 -33 38 -33 35
+-57 94 -57 139 0 14 9 57 20 97 37 135 20 239 -56 339 -18 23 -21 33 -11 33
+34 0 107 -148 107 -218 0 -21 7 -48 16 -60 18 -25 74 -56 121 -67 l33 -7 -15
+43 c-9 24 -15 77 -15 127 0 79 -2 89 -31 134 -31 48 -105 98 -144 98 -8 0 -15
+5 -15 10 0 28 105 -13 146 -57 14 -15 45 -63 69 -108 49 -89 88 -136 131 -158
+16 -8 71 -17 126 -20 53 -3 106 -10 117 -16 25 -14 26 -9 7 27 -19 36 -63 76
+-111 100 -76 38 -99 77 -134 227 -33 136 -66 177 -169 204 -55 15 -46 32 10
+18 74 -18 114 -51 145 -117 23 -49 35 -62 66 -75 39 -16 94 -19 146 -9 36 7
+40 20 10 29 -52 17 -116 97 -133 168 -9 37 -62 84 -110 98 -23 6 -63 8 -95 4
+-44 -5 -53 -4 -44 6 13 13 114 18 154 7 15 -4 62 -37 105 -73 121 -100 166
+-105 310 -34 59 29 96 41 133 42 28 1 51 4 51 7 0 9 -70 61 -100 74 -21 8 -47
+10 -87 4 -32 -5 -81 -11 -110 -14 l-52 -6 -58 55 c-32 30 -76 64 -98 75 -44
+21 -129 42 -175 42 -17 0 -30 5 -30 11 0 19 128 0 195 -28 33 -14 70 -25 82
+-25 41 0 153 99 153 135 0 3 -18 0 -40 -5 -55 -14 -95 -4 -170 42 -36 22 -75
+40 -88 40 -12 0 -46 -16 -74 -35 -29 -19 -54 -32 -57 -29 -10 10 50 54 114 85
+54 26 70 29 162 29 144 0 173 14 239 117 18 29 52 66 75 83 66 47 20 36 -92
+-22 -111 -58 -99 -57 -249 -14 -86 25 -196 21 -255 -9 -27 -13 -51 -22 -53
+-20 -11 11 24 35 71 51 29 9 61 25 73 36 12 10 63 30 115 44 52 14 104 31 116
+39 22 15 43 69 43 113 0 26 -2 26 -38 8 -15 -7 -47 -17 -72 -20 -25 -4 -67
+-13 -95 -21 -27 -8 -77 -22 -109 -31 -44 -11 -69 -25 -93 -52 -18 -20 -33 -42
+-33 -49 0 -7 -4 -13 -10 -13 -33 0 21 84 70 109 19 10 71 28 115 40 142 39
+177 74 206 208 19 88 58 184 86 215 15 17 14 18 -8 18 -80 0 -154 -53 -226
+-162 -30 -45 -60 -77 -88 -93 -38 -23 -65 -32 -186 -65 -20 -5 -57 -26 -82
+-45 -54 -41 -64 -32 -14 12 18 16 42 44 54 63 12 20 37 46 55 60 75 55 118
+102 124 137 7 35 -10 114 -24 112 -4 0 -21 -19 -37 -42 -40 -55 -108 -100
+-186 -123 -56 -17 -64 -23 -80 -59 -11 -22 -22 -57 -25 -77 -7 -39 -24 -53
+-24 -20 0 28 37 129 62 171 12 20 52 68 89 107 93 98 104 122 102 216 -1 42
+-9 100 -17 129 -18 60 -20 107 -6 143 12 33 2 33 -47 -3 -47 -34 -73 -90 -73
+-160 0 -59 -20 -130 -50 -171 -12 -17 -53 -54 -91 -81 -92 -67 -137 -122 -157
+-191 -19 -64 -38 -79 -27 -21 6 35 18 60 64 141 11 19 25 65 32 103 18 100 2
+162 -58 229 -24 27 -49 50 -53 50 -4 0 -10 -42 -12 -92 -4 -107 -23 -155 -95
+-239 -48 -56 -49 -61 -28 -139 18 -66 17 -60 5 -60 -13 0 -38 88 -51 185 -10
+78 -9 86 15 157 17 48 26 96 26 134 0 52 -5 69 -36 120 -70 112 -86 145 -98
+192 l-13 47 -17 -33z"/>
+<path d="M4060 6014 c0 -2 5 -25 10 -52 l11 -48 54 11 c29 5 56 13 59 15 2 3
+-27 21 -65 41 -38 20 -69 35 -69 33z"/>
+<path d="M5650 5960 c-19 -5 -70 -14 -112 -21 l-76 -13 1 -97 2 -97 -42 -62
+c-24 -34 -43 -72 -43 -85 0 -29 -24 -49 -50 -42 -13 3 -25 -2 -35 -16 -24 -35
+-18 -37 44 -16 72 25 143 84 175 147 l23 46 16 -25 c9 -13 21 -45 28 -71 19
+-71 2 -116 -68 -175 -113 -95 -138 -127 -82 -104 13 5 57 19 97 31 l72 21 0
+47 c0 67 34 130 90 167 27 18 93 44 160 63 183 52 224 79 237 155 7 45 -30 96
+-92 127 -44 22 -64 25 -180 27 -71 1 -146 -2 -165 -7z"/>
+<path d="M4315 5909 c-520 -53 -966 -396 -1139 -877 -73 -203 -91 -472 -47
+-681 52 -243 173 -471 345 -646 196 -199 467 -342 741 -389 119 -21 353 -21
+474 0 110 19 197 45 194 59 -1 6 -23 13 -48 17 -275 40 -649 307 -843 602 -64
+98 -132 241 -132 281 0 11 10 15 35 15 45 0 92 23 100 49 11 36 -14 98 -75
+183 -33 45 -75 112 -93 148 -31 63 -32 68 -31 185 1 86 7 142 22 197 74 275
+235 506 467 670 67 48 221 129 295 155 21 8 31 16 25 22 -15 15 -189 21 -290
+10z m194 -23 c-2 -2 -38 -22 -79 -43 -405 -209 -664 -603 -665 -1009 0 -96 2
+-104 37 -175 21 -41 64 -112 97 -158 62 -85 83 -143 62 -164 -6 -6 -42 -15
+-79 -20 -37 -4 -86 -10 -109 -13 -52 -7 -66 13 -40 58 21 36 21 48 3 48 -15 0
+-46 -58 -46 -87 0 -37 34 -56 88 -51 l49 5 18 -55 c9 -30 34 -88 55 -128 l38
+-74 -42 0 c-29 0 -65 11 -107 33 -61 31 -64 33 -61 66 5 42 -17 39 -31 -5 -5
+-16 -20 -40 -33 -55 -13 -14 -24 -28 -24 -32 0 -14 24 -7 45 13 l22 20 62 -32
+c46 -24 80 -33 127 -36 l64 -4 45 -63 c164 -231 436 -436 695 -526 l95 -33
+-55 -13 c-343 -76 -732 -3 -1030 193 -460 303 -676 860 -535 1382 142 526 610
+908 1170 955 64 6 169 7 164 3z"/>
+<path d="M3481 5234 c-50 -25 -71 -47 -57 -61 3 -3 23 6 44 20 74 52 151 48
+207 -10 19 -20 38 -33 42 -29 13 13 -22 60 -62 83 -54 30 -108 29 -174 -3z"/>
+<path d="M3630 5144 c0 -3 11 -20 25 -38 24 -32 50 -129 39 -147 -3 -5 -15 -7
+-28 -3 -27 6 -74 -11 -103 -38 l-22 -21 -31 27 c-31 25 -70 35 -70 17 0 -5 15
+-18 34 -29 38 -23 122 -120 162 -188 15 -25 30 -42 35 -37 7 7 22 80 49 243
+12 71 -8 157 -48 203 -14 16 -42 24 -42 11z m48 -222 c19 -13 4 -67 -28 -97
+l-27 -26 -31 37 c-30 36 -31 39 -14 57 28 32 74 45 100 29z"/>
+<path d="M3406 4541 c-4 -7 6 -32 23 -59 82 -128 130 -278 134 -412 3 -107 21
+-109 25 -1 4 107 -23 214 -83 336 -51 103 -88 155 -99 136z"/>
+<path d="M8240 5861 c-66 -35 -213 -81 -304 -96 -109 -18 -448 -20 -579 -4
+-49 6 -91 8 -94 6 -3 -3 8 -25 25 -49 79 -115 152 -309 177 -473 13 -80 16
+-147 12 -269 -4 -142 -9 -179 -41 -316 -21 -85 -45 -186 -53 -225 -24 -101
+-24 -476 -1 -597 30 -154 60 -248 112 -352 l51 -101 85 -3 c103 -4 224 12 298
+40 137 51 324 212 427 368 58 89 139 246 184 359 l32 82 -69 67 c-78 76 -117
+148 -127 232 -7 60 23 208 71 343 108 311 80 633 -77 892 -79 129 -73 125
+-129 96z m76 -75 c64 -64 29 -136 -47 -96 -20 11 -49 60 -49 84 0 19 27 46 47
+46 8 0 30 -15 49 -34z m-855 -115 c41 -41 49 -70 24 -91 -36 -30 -125 33 -125
+88 0 35 6 42 38 42 15 0 39 -15 63 -39z m544 -106 c99 -28 219 -124 263 -212
+72 -141 1 -334 -158 -435 -66 -42 -111 -51 -177 -38 -47 10 -65 21 -108 64
+-84 84 -122 218 -112 398 8 148 43 209 134 234 50 13 75 12 158 -11z m212
+-760 c72 -30 113 -86 113 -153 0 -49 -68 -395 -109 -557 -62 -242 -110 -332
+-220 -408 -42 -29 -53 -32 -121 -32 -64 0 -85 5 -140 32 -134 66 -238 177
+-292 312 -20 49 -23 74 -23 191 1 150 14 201 77 308 100 166 294 300 467 322
+87 11 202 4 248 -15z m271 -557 c17 -17 15 -79 -4 -106 -21 -30 -61 -29 -75 2
+-14 30 -5 70 21 96 23 23 41 25 58 8z m-898 -635 c31 -21 48 -41 61 -73 40
+-97 -89 -92 -136 6 -32 68 14 109 75 67z"/>
+<path d="M7860 5458 c-48 -32 -64 -70 -68 -159 -6 -115 42 -253 110 -316 36
+-33 98 -39 154 -13 97 42 139 92 164 193 34 134 -103 290 -275 312 -43 6 -55
+3 -85 -17z"/>
+<path d="M7980 4739 c-171 -49 -284 -126 -386 -262 -58 -79 -84 -163 -84 -278
+0 -176 81 -321 217 -389 37 -19 64 -24 119 -24 63 0 76 3 123 33 62 40 86 70
+139 176 49 100 95 248 132 425 39 190 26 245 -69 298 -48 27 -137 37 -191 21z
+m45 -203 c27 -12 36 -23 46 -58 31 -115 -67 -339 -172 -394 -79 -40 -166 3
+-194 99 -19 64 -19 81 1 147 12 39 30 69 72 113 92 96 169 125 247 93z"/>
+<path d="M4550 5820 c0 -5 5 -10 10 -10 6 0 10 5 10 10 0 6 -4 10 -10 10 -5 0
+-10 -4 -10 -10z"/>
+<path d="M4358 5736 c-23 -17 -23 -29 1 -50 17 -15 19 -15 25 -1 8 23 8 65 -1
+65 -5 0 -16 -7 -25 -14z"/>
+<path d="M7205 5720 c-9 -45 -65 -166 -98 -215 -24 -35 -25 -40 -12 -76 22
+-61 63 -254 81 -384 12 -84 17 -185 17 -340 0 -292 -33 -521 -111 -772 l-29
+-89 195 -185 c107 -101 198 -185 203 -187 5 -2 -2 20 -15 50 -56 127 -93 312
+-105 533 -11 194 -1 306 42 490 104 438 88 759 -55 1051 -21 45 -54 99 -72
+120 l-33 39 -8 -35z"/>
+<path d="M4170 5590 l-35 -29 28 -10 c43 -17 47 -14 47 29 0 22 -1 40 -2 40
+-2 0 -19 -14 -38 -30z"/>
+<path d="M4065 5470 c-3 -5 -1 -10 4 -10 6 0 11 5 11 10 0 6 -2 10 -4 10 -3 0
+-8 -4 -11 -10z"/>
+<path d="M4610 5384 c-232 -44 -437 -200 -541 -409 -62 -125 -82 -225 -76
+-364 15 -328 211 -584 527 -691 89 -30 275 -38 380 -16 113 23 261 101 348
+181 159 148 241 335 242 551 0 217 -70 387 -224 539 -87 86 -192 149 -310 187
+-60 19 -285 33 -346 22z m319 -45 c119 -30 223 -91 321 -189 144 -143 213
+-309 213 -510 0 -130 -18 -204 -80 -330 -88 -179 -260 -318 -460 -371 -107
+-29 -259 -29 -366 0 -204 54 -376 196 -467 386 -52 109 -70 190 -70 315 0 125
+18 206 70 315 71 148 186 263 335 335 166 80 321 95 504 49z"/>
+<path d="M4320 4910 c-89 -41 -160 -140 -160 -222 0 -34 3 -38 38 -47 20 -6
+119 -11 220 -11 104 0 182 -4 182 -9 0 -5 -7 -37 -16 -71 -30 -119 -1 -163
+113 -174 76 -7 180 7 200 27 31 31 30 128 -2 210 -7 16 6 17 191 17 236 0 250
+4 247 68 -2 57 -49 139 -101 179 -146 111 -345 39 -398 -145 -16 -53 -16 -57
+6 -110 13 -30 25 -77 28 -103 4 -44 1 -51 -27 -80 -31 -30 -34 -31 -103 -27
+-59 3 -73 8 -89 27 -25 31 -25 96 1 161 26 66 25 114 -4 175 -44 96 -118 146
+-221 152 -45 3 -71 -2 -105 -17z"/>
+<path d="M4976 4334 c-3 -9 -6 -26 -6 -39 0 -13 -10 -31 -22 -40 -57 -40 -256
+-77 -307 -58 -14 6 -28 23 -35 43 -18 55 -36 50 -29 -9 4 -38 2 -57 -11 -75
+-20 -31 -20 -46 -2 -46 8 0 20 13 27 28 12 27 14 28 98 28 90 0 187 21 254 53
+36 18 38 18 47 1 11 -20 47 -36 58 -26 3 4 -7 19 -23 36 -24 25 -27 35 -23 74
+4 33 2 46 -7 46 -7 0 -16 -7 -19 -16z"/>
+<path d="M5890 5289 c-24 -16 -49 -29 -56 -29 -6 0 -18 -8 -25 -17 -13 -15
+-11 -16 20 -10 19 4 49 18 66 32 18 13 35 22 37 20 9 -9 -11 -135 -26 -163
+-18 -35 -58 -55 -152 -77 -40 -9 -80 -23 -90 -31 -18 -15 -18 -15 6 -9 14 3
+59 15 101 25 101 25 126 38 149 75 20 33 46 176 36 201 -7 19 -14 17 -66 -17z"/>
+<path d="M5720 4771 c0 -5 33 -29 73 -51 63 -36 78 -40 119 -36 26 3 58 12 72
+21 33 22 39 6 15 -42 -24 -49 -77 -103 -124 -129 -19 -10 -35 -22 -35 -27 0
+-13 58 24 112 72 54 48 73 78 83 133 8 44 -8 58 -38 30 -68 -61 -131 -55 -252
+24 -14 9 -25 12 -25 5z"/>
+<path d="M5780 4285 c0 -3 6 -20 14 -38 19 -47 74 -95 128 -115 27 -9 48 -20
+48 -24 0 -4 -25 -15 -56 -24 -55 -16 -139 -15 -191 1 -13 4 -23 3 -23 -3 0
+-17 88 -35 151 -29 66 6 154 44 154 67 0 9 -14 17 -37 21 -60 9 -129 58 -153
+107 -17 36 -35 55 -35 37z"/>
+<path d="M5537 3858 c-9 -33 8 -129 28 -168 9 -18 14 -35 10 -38 -11 -12 -119
+18 -157 43 -29 19 -38 22 -38 10 0 -21 62 -50 149 -69 81 -19 108 -11 78 22
+-28 31 -47 89 -47 144 0 62 -14 94 -23 56z"/>
+<path d="M4165 3851 c-6 -11 9 -23 19 -14 9 9 7 23 -3 23 -6 0 -12 -4 -16 -9z"/>
+<path d="M4301 3721 c-11 -7 -10 -11 7 -20 16 -9 25 -7 44 9 l23 19 -30 1
+c-16 0 -36 -4 -44 -9z"/>
+<path d="M5135 3640 c-14 -26 -19 -52 -18 -103 l1 -67 -39 31 c-21 17 -53 51
+-71 75 -36 51 -44 46 -54 -30 l-7 -46 51 0 c45 0 59 -5 104 -40 38 -29 54 -36
+56 -26 2 8 -2 24 -7 35 -14 25 -14 64 0 78 5 5 9 37 7 69 l-3 59 -20 -35z"/>
+<path d="M4585 3605 c-29 -66 -31 -83 -11 -65 17 13 51 108 42 117 -3 3 -17
+-20 -31 -52z"/>
+<path d="M4710 3500 c-19 -15 -21 -20 -8 -20 9 0 24 7 32 16 31 30 13 33 -24
+4z"/>
+<path d="M4913 3338 c-29 -11 -53 -25 -53 -30 0 -5 10 -28 22 -51 11 -23 24
+-67 27 -97 l7 -55 31 49 c49 74 69 199 33 202 -8 1 -39 -7 -67 -18z"/>
+<path d="M4080 3287 c0 -6 11 -30 25 -53 34 -57 102 -99 149 -90 50 10 86 42
+86 77 l0 29 -63 -35 c-85 -47 -118 -47 -82 1 28 37 19 49 -50 66 -41 10 -65
+11 -65 5z"/>
+<path d="M4229 3243 c-5 -13 -9 -26 -9 -28 0 -8 37 7 59 24 l24 18 -32 5 c-28
+4 -34 1 -42 -19z"/>
+<path d="M796 5833 c-45 -62 -118 -210 -144 -293 -31 -98 -42 -172 -42 -291 0
+-129 18 -227 70 -390 54 -168 74 -267 65 -335 -10 -82 -56 -164 -131 -232
+l-64 -59 15 -44 c32 -90 135 -289 203 -390 198 -295 449 -437 729 -414 l82 7
+39 81 c52 106 97 242 119 359 13 72 17 143 17 313 0 236 3 214 -70 515 -37
+152 -38 159 -38 355 -1 224 7 284 61 439 38 110 80 198 125 264 17 24 28 46
+25 48 -3 3 -49 0 -104 -6 -54 -7 -188 -12 -298 -13 -168 0 -216 3 -301 21
+-102 22 -203 56 -274 92 -22 11 -42 20 -45 20 -2 0 -20 -21 -39 -47z m88 -29
+c9 -8 16 -22 16 -30 0 -24 -29 -73 -49 -84 -76 -40 -111 32 -47 96 38 38 57
+42 80 18z m874 -132 c3 -25 -3 -39 -26 -62 -35 -35 -76 -47 -97 -30 -25 21
+-17 50 25 92 30 30 45 39 67 36 23 -2 29 -8 31 -36z m-482 -97 c54 -16 80 -39
+110 -95 16 -29 19 -57 19 -175 0 -196 -30 -291 -118 -372 -98 -90 -233 -74
+-350 44 -80 79 -123 192 -111 288 16 133 151 264 314 307 81 21 76 21 136 3z
+m-23 -780 c103 -35 173 -81 263 -171 97 -96 155 -202 181 -329 19 -94 9 -201
+-27 -297 -88 -235 -361 -407 -523 -329 -95 46 -176 167 -226 336 -50 170 -131
+571 -131 648 0 84 60 145 162 167 69 15 224 2 301 -25z m-563 -555 c39 -39 35
+-111 -6 -127 -27 -10 -64 40 -64 86 0 59 32 79 70 41z m920 -625 c26 -31 -19
+-117 -73 -140 -65 -27 -95 16 -57 83 35 62 101 91 130 57z"/>
+<path d="M1145 5471 c-97 -24 -189 -91 -225 -166 -72 -149 54 -350 219 -347
+55 2 84 20 121 80 94 149 93 364 -2 422 -34 21 -61 23 -113 11z"/>
+<path d="M986 4736 c-86 -32 -126 -86 -126 -169 0 -120 89 -445 161 -589 44
+-88 70 -120 130 -159 45 -29 60 -33 118 -33 51 -1 77 5 115 24 62 32 147 126
+189 210 28 57 32 76 35 162 3 78 0 112 -17 167 -25 81 -91 176 -172 247 -128
+111 -333 177 -433 140z m251 -205 c64 -30 132 -98 164 -166 81 -170 -23 -348
+-169 -290 -97 39 -192 218 -192 362 0 47 4 59 29 84 25 24 38 29 78 29 26 0
+67 -9 90 -19z"/>
+<path d="M6831 3169 c-27 -43 -27 -100 -1 -130 22 -27 24 -20 10 32 -8 27 -6
+46 5 79 19 54 12 63 -14 19z"/>
+<path d="M7575 2578 c70 -52 169 -156 191 -201 19 -36 23 -56 18 -82 -5 -29
+-1 -42 20 -70 15 -19 36 -40 47 -45 20 -11 20 -11 0 29 -12 22 -21 53 -21 69
+0 62 -32 124 -103 198 -71 75 -112 107 -157 118 -24 7 -24 6 5 -16z"/>
+<path d="M2191 3077 c-26 -43 -43 -87 -32 -87 5 0 24 20 42 45 36 47 47 53 67
+33 15 -15 16 -3 2 23 -17 31 -55 24 -79 -14z"/>
+<path d="M2141 2810 c-68 -54 -126 -101 -129 -104 -11 -11 32 -46 56 -46 87 0
+232 144 232 230 0 37 -34 21 -159 -80z"/>
+<path d="M2295 2825 c-27 -56 -126 -154 -164 -161 -17 -4 -31 -11 -31 -16 0
+-13 64 -1 100 17 44 23 108 100 115 139 11 54 0 65 -20 21z"/>
+<path d="M1629 2646 c-78 -32 -125 -62 -187 -120 -81 -76 -100 -128 -68 -185
+13 -24 14 -24 21 17 15 93 134 225 248 278 53 23 68 34 50 34 -5 0 -33 -11
+-64 -24z"/>
+<path d="M6770 2840 c-36 -46 -32 -51 12 -15 35 30 40 30 98 4 l45 -20 -34 35
+c-48 49 -80 48 -121 -4z"/>
+<path d="M6898 2704 c12 -8 28 -30 36 -48 10 -23 28 -40 60 -55 25 -13 51 -21
+58 -19 7 3 -6 13 -27 24 -24 11 -46 31 -54 49 -21 46 -42 65 -70 65 l-25 0 22
+-16z"/>
+<path d="M6581 2625 c-45 -49 -50 -76 -28 -148 11 -34 74 -126 88 -127 3 0
+-13 36 -34 79 -39 78 -39 80 -27 130 6 28 21 62 32 76 35 45 13 37 -31 -10z"/>
+<path d="M2500 2650 c-24 -46 -19 -50 22 -15 23 19 34 23 48 15 35 -19 45 -9
+17 15 -41 36 -63 32 -87 -15z"/>
+<path d="M2494 2468 c-32 -40 -108 -124 -168 -186 l-110 -113 35 -35 36 -35
+51 43 c69 58 122 130 182 250 47 93 62 148 41 148 -5 0 -35 -33 -67 -72z"/>
+<path d="M2455 2253 c-35 -56 -142 -163 -163 -163 -8 0 -32 14 -54 32 -29 23
+-38 26 -30 12 5 -10 20 -28 31 -38 12 -11 21 -24 21 -30 0 -6 -29 -40 -65 -76
+-85 -86 -135 -181 -135 -257 0 -65 18 -108 66 -154 l35 -34 -30 59 c-24 45
+-31 71 -31 115 0 78 33 131 176 282 111 117 193 226 208 277 11 33 4 27 -29
+-25z"/>
+<path d="M2000 2226 c-126 -63 -217 -133 -246 -187 -31 -61 -10 -135 47 -165
+34 -17 36 -11 9 23 -25 32 -25 66 -1 119 28 61 72 105 171 174 117 80 121 87
+20 36z"/>
+<path d="M6239 2366 c-80 -59 -139 -174 -139 -270 0 -58 36 -144 78 -189 65
+-69 163 -91 256 -58 80 28 90 40 24 30 -144 -24 -273 56 -308 191 -24 89 8
+184 92 276 28 30 48 54 47 54 -2 0 -25 -16 -50 -34z"/>
+<path d="M6380 2342 c0 -4 5 -13 11 -19 6 -6 19 -35 29 -64 10 -32 27 -61 43
+-73 23 -17 30 -18 54 -6 15 7 24 14 18 15 -5 2 -22 6 -37 9 -20 5 -29 15 -38
+43 -7 21 -18 48 -26 60 -15 24 -54 49 -54 35z"/>
+<path d="M6606 1752 c-29 -33 -110 -71 -179 -84 -37 -7 -67 -17 -67 -23 0 -24
+64 -118 114 -170 133 -136 286 -141 426 -15 l45 41 -48 -31 c-143 -94 -298
+-73 -416 56 -69 76 -67 98 11 123 45 15 113 63 128 92 15 28 7 34 -14 11z"/>
+<path d="M2915 2300 c-15 -17 -20 -39 -23 -98 l-3 -77 20 35 c11 19 20 42 21
+51 0 9 8 27 18 40 19 22 19 22 68 5 87 -30 90 -29 32 13 -72 52 -106 60 -133
+31z"/>
+<path d="M3260 2146 c0 -3 18 -22 39 -41 26 -24 50 -61 70 -108 30 -70 30 -71
+31 -34 0 47 -22 95 -58 129 -32 30 -82 63 -82 54z"/>
+<path d="M3105 2099 c-35 -31 -165 -216 -165 -236 0 -15 46 -33 83 -33 63 0
+126 65 153 158 19 63 12 117 -16 132 -15 8 -26 4 -55 -21z"/>
+<path d="M3181 1949 c-30 -66 -84 -126 -121 -134 -15 -3 -47 -1 -70 5 -54 15
+-59 8 -18 -21 42 -30 127 -32 159 -3 32 29 88 154 89 197 0 21 -18 1 -39 -44z"/>
+<path d="M2586 1739 c-140 -108 -169 -147 -174 -234 -5 -76 13 -119 69 -170
+41 -36 75 -49 47 -17 -9 9 -26 37 -38 61 -19 37 -22 56 -18 112 7 89 36 137
+139 230 69 62 110 109 96 109 -2 0 -56 -41 -121 -91z"/>
+<path d="M2948 1426 c-103 -110 -131 -173 -108 -242 12 -34 86 -101 99 -88 3
+3 -1 11 -9 17 -34 26 -50 62 -50 115 0 63 20 106 84 181 95 109 83 122 -16 17z"/>
+<path d="M5835 2098 c-79 -40 -105 -65 -105 -100 0 -36 13 -62 56 -111 19 -20
+34 -42 34 -49 0 -6 2 -9 5 -6 3 3 -8 31 -25 63 -34 65 -36 84 -15 125 15 29
+82 82 127 100 21 8 21 9 3 9 -11 0 -47 -14 -80 -31z"/>
+<path d="M5978 1422 c15 -152 25 -197 54 -258 40 -87 112 -104 226 -54 62 27
+62 36 1 20 -63 -17 -121 -5 -160 34 -40 38 -69 117 -99 266 -11 57 -24 108
+-28 112 -4 4 -2 -50 6 -120z"/>
+<path d="M3591 1977 c-38 -19 -59 -56 -81 -145 -15 -59 -20 -97 -15 -131 10
+-72 20 -76 21 -7 2 80 34 155 85 201 39 35 58 40 132 36 20 -2 37 -1 37 2 0 4
+-94 40 -135 51 -11 3 -31 0 -44 -7z"/>
+<path d="M4040 1861 c8 -5 49 -16 90 -26 65 -15 81 -24 118 -62 45 -47 55 -41
+21 14 -27 44 -63 62 -152 73 -88 12 -96 12 -77 1z"/>
+<path d="M3781 1648 c0 -85 -19 -175 -47 -230 -9 -17 -45 -68 -80 -114 -77
+-101 -88 -122 -113 -211 -13 -49 -17 -82 -12 -109 10 -51 36 -101 61 -114 18
+-10 17 -7 -4 25 -35 51 -40 86 -21 151 27 95 73 179 132 245 73 83 114 170
+121 259 4 66 -11 165 -28 175 -5 3 -8 -32 -9 -77z"/>
+<path d="M4109 1701 c18 -33 13 -78 -10 -94 -19 -14 -19 -18 -8 -57 14 -47 50
+-80 86 -80 24 0 24 0 -6 25 -38 33 -46 59 -27 87 29 42 17 106 -25 129 -19 9
+-19 9 -10 -10z"/>
+<path d="M4665 1958 c-50 -27 -57 -76 -25 -163 l18 -50 1 87 c1 78 3 88 23
+102 12 9 42 16 66 16 26 0 41 4 37 10 -8 13 -95 12 -120 -2z"/>
+<path d="M4650 875 c0 -178 11 -236 52 -270 27 -23 38 -25 118 -25 102 0 128
+15 43 25 -92 10 -110 15 -128 35 -22 24 -41 107 -50 208 -10 130 -17 172 -26
+172 -5 0 -9 -65 -9 -145z"/>
+<path d="M5138 1866 c-98 -21 -119 -61 -78 -151 22 -49 46 -73 30 -30 -6 15
+-10 46 -10 70 0 52 23 73 110 100 30 9 60 18 65 20 28 9 -68 2 -117 -9z"/>
+<path d="M5717 1463 c-4 -3 -7 -33 -7 -65 0 -70 -23 -100 -90 -118 -36 -10
+-50 -9 -85 5 -24 8 -51 25 -60 35 -10 11 -23 20 -29 20 -14 0 54 -69 84 -85
+52 -27 96 -29 145 -5 55 27 68 48 75 125 l5 60 35 -3 35 -2 -25 20 c-24 19
+-70 27 -83 13z"/>
+<path d="M5147 1215 c-46 -206 2 -360 114 -371 l44 -4 -41 19 c-58 27 -80 60
+-94 143 -9 53 -10 92 -1 158 13 104 14 130 3 130 -5 0 -16 -34 -25 -75z"/>
+</g>
+</svg>
diff --git a/apps/wrapped/static/wrapped/favicon/1/site.webmanifest b/apps/wrapped/static/wrapped/favicon/1/site.webmanifest
new file mode 100644
index 00000000..79d235df
--- /dev/null
+++ b/apps/wrapped/static/wrapped/favicon/1/site.webmanifest
@@ -0,0 +1,19 @@
+{
+    "name": "",
+    "short_name": "",
+    "icons": [
+        {
+            "src": "/static/favicon/1/android-chrome-192x192.png",
+            "sizes": "192x192",
+            "type": "image/png"
+        },
+        {
+            "src": "/static/favicon/1/android-chrome-512x512.png",
+            "sizes": "512x512",
+            "type": "image/png"
+        }
+    ],
+    "theme_color": "#ffffff",
+    "background_color": "#ffffff",
+    "display": "standalone"
+}
diff --git a/apps/wrapped/static/wrapped/fonts/1/JEMROKtrial-Regular.ttf b/apps/wrapped/static/wrapped/fonts/1/JEMROKtrial-Regular.ttf
new file mode 100644
index 00000000..ef731e1a
Binary files /dev/null and b/apps/wrapped/static/wrapped/fonts/1/JEMROKtrial-Regular.ttf differ
diff --git a/apps/wrapped/static/wrapped/img/1/bg.png b/apps/wrapped/static/wrapped/img/1/bg.png
new file mode 100644
index 00000000..9e78673c
Binary files /dev/null and b/apps/wrapped/static/wrapped/img/1/bg.png differ
diff --git a/apps/wrapped/tables.py b/apps/wrapped/tables.py
new file mode 100644
index 00000000..6ec37543
--- /dev/null
+++ b/apps/wrapped/tables.py
@@ -0,0 +1,87 @@
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from django.utils.html import format_html
+from django.utils.translation import gettext_lazy as _
+from note_kfet.middlewares import get_current_request
+import django_tables2 as tables
+from django_tables2 import A
+from permission.backends import PermissionBackend
+
+from .models import Wrapped
+
+
+class WrappedTable(tables.Table):
+    """
+    List all wrapped
+    """
+    class Meta:
+        attrs = {
+            'class': 'table table-condensed table-striped table-hover',
+            'id': 'wrapped_table'
+        }
+        row_attrs = {
+            'class': lambda record: 'bg-danger' if not record.generated else '',
+        }
+        model = Wrapped
+        template_name = 'django_tables2/bootstrap4.html'
+        fields = ('note', 'bde', 'public', )
+
+    view = tables.LinkColumn(
+        'wrapped:wrapped_detail',
+        args=[A('pk')],
+        attrs={
+            'td': {'class': 'col-sm-2'},
+            'a': {
+                'class': 'btn btn-sm btn-primary',
+                'data-turbolinks': 'false',
+            }
+        },
+        text=_('view the wrapped'),
+        accessor='pk',
+        verbose_name=_('View'),
+        orderable=False,
+    )
+
+    public = tables.Column(
+        accessor="pk",
+        orderable=False,
+        attrs={
+            "td": {
+                "id": lambda record: "makepublic_" + str(record.pk),
+                "class": 'col-sm-1',
+                "data-toggle": "tooltip",
+                "title": lambda record:
+                (_("Click to make this wrapped private") if record.public else
+                    _("Click to make this wrapped public")) if PermissionBackend.check_perm(
+                    get_current_request(), "wrapped.change_wrapped_public", record) else None,
+                "onclick": lambda record:
+                'makepublic(' + str(record.id) + ', ' + str(not record.public).lower() + ')'
+                if PermissionBackend.check_perm(get_current_request(), "wrapped.change_wrapped_public",
+                                                record) else None
+            }
+        },
+    )
+
+    share = tables.Column(
+        verbose_name=_("Share"),
+        accessor="pk",
+        orderable=False,
+        attrs={
+            "td": {
+                "class": 'col-sm-2',
+                "title": _("Click to copy the link in the press paper"),
+            }
+        },
+    )
+
+    def render_share(self, value, record):
+        val = '<a class="btn btn-sm btn-primary" data-turbolinks="false" '
+        val += 'onclick="copylink(' + str(record.id) + ')">'
+        val += _('Copy link')
+        val += '</a>'
+        return format_html(val)
+
+    def render_public(self, value, record):
+        val = "✔" if record.public else "✖"
+        return val
diff --git a/apps/wrapped/templates/wrapped/1/wrapped_base.html b/apps/wrapped/templates/wrapped/1/wrapped_base.html
new file mode 100644
index 00000000..3cd72a99
--- /dev/null
+++ b/apps/wrapped/templates/wrapped/1/wrapped_base.html
@@ -0,0 +1,82 @@
+{% load static i18n pretty_money getenv %}
+{% comment %}
+Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
+SPDX-License-Identifier: GPL-3.0-or-later
+{% endcomment %}
+<!DOCTYPE html>
+{% get_current_language as LANGUAGE_CODE %}{% get_current_language_bidi as LANGUAGE_BIDI %}
+<html lang="{{ LANGUAGE_CODE|default:"en" }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %} class="postition-relative h-100">
+
+<head>
+	<meta charset="utf-8">
+	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+	<title>
+		{% block title %}{{ title }}{% endblock title %} - {{ request.site.name }}
+	</title>
+	<meta name="description" content="{% trans "The ENS Paris-Saclay BDE note." %}">
+	
+	{# Favicon #}
+	<link rel="apple-touch-icon" sizes="180x180" href="{% static "wrapped/favicon/1/apple-touch-icon.png" %}">
+	<link rel="icon" type="image/png" sizes="32x32" href="{% static "wrapped/favicon/1/favicon-32x32.png" %}">
+	<link rel="icon" type="image/png" sizes="16x16" href="{% static "wrapped/favicon/1/favicon-16x16.png" %}">
+	<link rel="manifest" href="{% static "wrapped/favicon/1/site.webmanifest" %}">
+	<link rel="mask-icon" href="{% static "wrapped/favicon/1/safari-pinned-tab.svg" %}" color="#5bbad5">
+	<link rel="shorcut icon" href="{% static "wrapped/favicon/1/favicon.ico" %}">
+	<meta name="msapplication-TileColor" content="#da532c">
+	<meta name="msapplication-config" content="{% static "wrapped/favicon/1/browserconfig.xml" %}">
+	<meta name="theme-color" content="#ffffff">
+
+	{# Bootstrap, Font Awesome and custom CSS #}
+	<link rel="stylesheet" href="{% static "bootstrap4/css/bootstrap.min.css" %}">
+	<link rel="stylesheet" href="{% static "font-awesome/css/font-awesome.min.css" %}">
+	<link rel="stylesheet" href="{% static "wrapped/css/1/custom.css" %}">
+
+	{# JQuery, Bootstrap and Turbolinks JavaScript #}
+	<script src="{% static "jquery/jquery.min.js" %}"></script>
+	<script src="{% static "popper.js/umd/popper.min.js" %}"></script>
+	<script src="{% static "bootstrap4/js/bootstrap.min.js" %}"></script>
+	<script src="{% static "js/turbolinks.js" %}"></script>
+	<script src="{% static "js/base.js" %}"></script>
+	<script src="{% static "js/konami.js" %}"></script>
+
+	{# Translation in javascript files #}
+	<script src="{% static "js/jsi18n/"|add:LANGUAGE_CODE|add:".js" %}"></script>
+
+	{# If extra ressources are needed for a form, load here #}
+	{% if form.media %}
+		{{ form.media }}
+	{% endif %}
+
+	{% block extracss %}{% endblock %}
+</head>
+<body>
+	{% block content %}
+		<p>Default content...</p>
+	{% endblock %}
+	<br>
+	<div class="wrap-container">
+		<h2>{% trans "The NoteKfet this year it's also" %}</h2>
+		<ul class="list" id="glob_top3_conso">
+			<li>{{ glob_nb_transaction }} {% trans " transactions" %}</li>
+			<li>{{ glob_nb_soiree }} {% trans " parties" %}</li>
+			<li>{{ glob_nb_entree_pot }} {% trans " Pot entries" %}</li>
+		<script>
+			let liste = {{ glob_top3_conso | safe }};
+			let ul = document.getElementById("glob_top3_conso");
+			liste.forEach(item => {
+				let li = document.createElement("li");
+				li.textContent = item[1] + "   " + item[0];
+				ul.appendChild(li);
+			});
+		</script>
+			<li>{{ glob_nb_vieux_con }} {% trans " old dickhead behind the bar" %} </li>
+		</ul>
+	</div>
+<script>
+    CSRF_TOKEN = "{{ csrf_token }}";
+    $(".invalid-feedback").addClass("d-block");
+</script>
+
+{% block extrajavascript %}{% endblock %}
+</body>
+</html>
diff --git a/apps/wrapped/templates/wrapped/1/wrapped_view_club.html b/apps/wrapped/templates/wrapped/1/wrapped_view_club.html
new file mode 100644
index 00000000..57da4a3f
--- /dev/null
+++ b/apps/wrapped/templates/wrapped/1/wrapped_view_club.html
@@ -0,0 +1,31 @@
+{% extends "wrapped/1/wrapped_base.html" %}
+{% comment %}
+COPYRIGHT (C) 2018-2024 BDE ENS Paris-Saclay
+SPDX-License-Identifier: GPL-3.0-or-later
+{% endcomment %}
+{% load i18n pretty_money %}
+{% block content %}
+	<div class="wrap-container">
+		<h2>{% trans "NoteKfet Wrapped" %}</h2>
+		<h1 id="name">{{ wrapped.note.club.name }}</h1>
+		{% trans "Your best consumer:" %}
+		<div class="category" id="consumer"></div>
+		{% trans "Your worst creditor:" %}
+		<div class="category" id="creditor"></div>
+		<ul class="list">
+			<li>{{ nb_soiree_orga }} {% trans "party·ies organised" %}</li>
+			<li>{{ nb_member }} {% trans "distinct members" %}</li>
+		</ul>
+	</div>
+	<script>
+		let con = Boolean({{ big_consumer | safe }});
+		let cre = Boolean({{ big_creancier | safe }});
+		let d1 = document.getElementById("consumer");
+		let d2 = document.getElementById("creditor");
+		if (con) { d1.textContent = {{ big_consumer | safe }}[0] + " " + gettext("with") + " " + {{ big_consumer | safe}}[1] + "€";}
+		else { d1.textContent = gettext("Infortunately, you doesn't have consumer this year");};
+		if (cre) { d2.textContent = {{ big_creancier | safe}}[0] + " " + gettext("with") + " " + {{ big_creancier | safe}}[1] + "€";}
+		else { d2.textContent = gettext("Congratulations you are a real rat !"); };
+
+	</script>
+{% endblock %}
diff --git a/apps/wrapped/templates/wrapped/1/wrapped_view_user.html b/apps/wrapped/templates/wrapped/1/wrapped_view_user.html
new file mode 100644
index 00000000..3e421171
--- /dev/null
+++ b/apps/wrapped/templates/wrapped/1/wrapped_view_user.html
@@ -0,0 +1,69 @@
+{% extends "wrapped/1/wrapped_base.html" %}
+{% comment %}
+COPYRIGHT (C) 2018-2024 BDE ENS Paris-Saclay
+SPDX-License-Identifier: GPL-3.0-or-later
+{% endcomment %}
+{% load i18n pretty_money %}
+{% block content %}
+	<div class="wrap-container">
+		<h2>{% trans "NoteKfet Wrapped" %}</h2>
+		<h1 id="name">{{ wrapped.note.user.username }}</h1>
+	{% if wei %}
+	<div class="category" id="wei">
+		{% trans "You participate to the wei: " %} {{ wei }} {% trans "in the" %} {{ bus }}
+	</div>
+	{% endif %}
+	<div class="ranking-bar">
+		<div class="ranking-progress" id="pot_bar">
+			{{ nb_pot_entry }}/{{ nb_pots }} {% trans "pots !" %}
+		</div>
+		<script>
+			const percentage = ({{ nb_pot_entry }} / {{ nb_pots }}) *100;
+			document.getElementById("pot_bar").style.width = percentage + '%';
+		</script>
+	</div>
+	{% if first_conso %}
+	<ul class="list" id="user_conso">
+		<li>{% trans "Your first conso of the year: " %}   {{ first_conso }}</li>
+		<li>{% trans "Your prefered consumtion category: " %}   {{ top_category }}</li>
+	<script>
+		let top3 = {{ top3_conso | safe }};
+		let l = document.getElementById("user_conso");
+		top3.forEach(item => {
+			let li = document.createElement("li");
+			li.textContent = item[1] + "   " + item[0];
+			l.appendChild(li);
+		});
+	</script>
+	</ul>
+	{% endif %}
+	<div class="category">
+		{{ nb_rechargement }}  {% trans ": it's the number of time your reload your note" %}
+	</div>
+	{% if class_conso_all > 0 %}
+	{% trans "Your overall expenses: " %} 
+	<div class="ranking-bar">
+		<div class="ranking-progress" id="all_bar">
+			{{ class_conso_all }}/{{ class_part_all }} {% trans "with" %} {{ amount_conso_all }}€
+		</div>
+	</div>
+	<script>
+		const p_all = 100 - (({{ class_conso_all }} - 1) / {{ class_part_all }}) * 100;
+		document.getElementById("all_bar").style.width =  p_all + '%';
+	</script>
+	{% endif %}
+	<br>
+	{% if class_conso_bde > 0 %}
+	{% trans "Your expenses to BDE: " %}
+	<div class="ranking-bar">
+		<div class="ranking-progress" id="bde_bar">
+			{{ class_conso_bde }}/{{ class_part_bde }} {% trans "with" %} {{ amount_conso_bde }}€
+		</div>
+	</div>
+	<script>
+		const p_bde = 100 - (({{ class_conso_bde }} - 1) / {{ class_part_all }}) * 100;
+		document.getElementById("bde_bar").style.width = p_bde + '%';
+	</script>
+	{% endif %}
+	</div>
+{% endblock %}
diff --git a/apps/wrapped/templates/wrapped/wrapped_list.html b/apps/wrapped/templates/wrapped/wrapped_list.html
new file mode 100644
index 00000000..28892de5
--- /dev/null
+++ b/apps/wrapped/templates/wrapped/wrapped_list.html
@@ -0,0 +1,69 @@
+{% extends "base.html" %}
+{% comment %}
+SPDX-License-Identifier: GPL-3.0-or-later
+{% endcomment %}
+{% load render_table from django_tables2 %}
+{% load i18n %}
+
+{% block content %}
+<div class="row justify-content-center">   
+    <div class="col-md-10">
+        <div class="card card-border shadow">
+            <div class="card-header text-center">
+		    <h5> {{ title }}</h5>
+            </div>
+            <div class="card-body px-0 py-0" id="wrapped_table">
+                {% render_table table %}
+            </div>
+        </div>
+    </div>
+</div>
+{% endblock %}
+
+{% block extrajavascript %}
+<script type="text/javascript">
+	let club_not_public = {{ club_not_public }};
+	if (club_not_public) { (addMsg("{% trans "Do not forget to ask permission to people who are in your wrapped before to make them public" %}", 'warning'));}
+   function refreshTable() {
+	$("#wrapped_table").load(location.pathname + " #wrapped_table");
+   }
+
+   function copylink(id) {
+	   navigator.clipboard.writeText({{ request.get_full_path }} + id)
+	    .then(() => { addMsg("{% trans "Link copied" %}", 'success', 1000);});
+	}
+
+   function makepublic(id, isprivate) {
+	const makepublic_obj = $('#makepublic_'+id)
+
+	if (makepublic_obj.data('pending'))
+	// The button is already clicked
+	{ return }
+	
+	makepublic_obj.html('<strong style="font-size: 16pt;">⟳</strong>')
+	makepublic_obj.data('pending', true)
+	
+	$.ajax({
+	    url: '/api/wrapped/wrapped/' + id + '/',
+	    type: 'PATCH',
+	    dataType: 'json',
+	    headers: {
+		'X-CSRFTOKEN': CSRF_TOKEN
+	    },
+	    data: {
+		public: isprivate
+	    },
+	    success: function() {
+		if(!isprivate)
+		    addMsg("{% trans "Wrapped is private" %}", 'success', 2000)
+		else addMsg("{% trans "Wrapped is public" %}", 'success', 2000)
+		refreshTable()
+	    },
+	    error: function (err) {
+		addMsg("{% trans "An error occured" %}", 'danger')
+		refreshTable()
+	    }
+	})
+    }
+</script>
+{% endblock %}
diff --git a/apps/wrapped/urls.py b/apps/wrapped/urls.py
new file mode 100644
index 00000000..dde4458b
--- /dev/null
+++ b/apps/wrapped/urls.py
@@ -0,0 +1,13 @@
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from django.urls import path
+
+from . import views
+
+app_name = 'wrapped'
+
+urlpatterns = [
+    path('', views.WrappedListView.as_view(), name='wrapped_list'),
+    path('<int:pk>/', views.WrappedDetailView.as_view(), name='wrapped_detail'),
+]
diff --git a/apps/wrapped/views.py b/apps/wrapped/views.py
new file mode 100644
index 00000000..0a16fd92
--- /dev/null
+++ b/apps/wrapped/views.py
@@ -0,0 +1,62 @@
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+import json
+
+from django.contrib.auth.mixins import LoginRequiredMixin
+from django.utils.translation import gettext_lazy as _
+from django.views.generic import DetailView
+from django_tables2.views import SingleTableView
+from permission.backends import PermissionBackend
+from permission.views import ProtectQuerysetMixin
+
+from .models import Wrapped
+from .tables import WrappedTable
+
+
+class WrappedListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
+    """
+    Display all Wrapped, and classify by year
+    """
+    model = Wrapped
+    table_class = WrappedTable
+    template_name = 'wrapped/wrapped_list.html'
+    extra_context = {'title': _("List of wrapped")}
+
+    def get_queryset(self, **kwargs):
+        return super().get_queryset(**kwargs).distinct()
+
+    def get_table_data(self):
+        return Wrapped.objects.filter(PermissionBackend.filter_queryset(
+            self.request, Wrapped, "change", field='public')).distinct().order_by("-bde__date_start")
+
+    def get_context_data(self, **kwargs):
+        context = super().get_context_data(**kwargs)
+        w = self.object_list.filter(note__noteclub__club__pk__gte=-1, public=False)
+        if w:
+            context['club_not_public'] = 'true'
+        else:
+            context['club_not_public'] = 'false'
+        return context
+
+
+class WrappedDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
+    """
+    View a wrapped
+    """
+    model = Wrapped
+    template_name = 'wrapped/0/wrapped_view.html'  # by default
+
+    def get(self, *args, **kwargs):
+        bde_id = Wrapped.objects.get(pk=kwargs['pk']).bde.id
+        note_type = 'user' if 'user' in Wrapped.objects.get(pk=kwargs['pk']).note.__dir__() else 'club'
+        self.template_name = 'wrapped/' + str(bde_id) + '/wrapped_view_' + note_type + '.html'
+        return super().get(*args, **kwargs)
+
+    def get_context_data(self, **kwargs):
+        context = super().get_context_data(**kwargs)
+        d = json.loads(self.object.data_json)
+        for key in d:
+            context[key] = d[key]
+        context['title'] = str(self.object)
+        return context
diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po
index a95cb766..79814474 100644
--- a/locale/fr/LC_MESSAGES/django.po
+++ b/locale/fr/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: \n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2024-08-17 11:57+0200\n"
+"POT-Creation-Date: 2025-02-25 13:47+0100\n"
 "PO-Revision-Date: 2022-04-11 22:05+0200\n"
 "Last-Translator: bleizi <bleizi@crans.org>\n"
 "Language-Team: French <http://translate.ynerant.fr/projects/nk20/nk20/fr/>\n"
@@ -18,38 +18,43 @@ msgstr ""
 "Plural-Forms: nplurals=2; plural=n > 1;\n"
 "X-Generator: Poedit 3.0\n"
 
-#: apps/activity/apps.py:10 apps/activity/models.py:127
-#: apps/activity/models.py:167
-#: apps/activity/models.py:323
+#: apps/activity/api/serializers.py:77
+#, fuzzy
+#| msgid "This friendship already exists"
+msgid "This opener already exists"
+msgstr "Cette amitié existe déjà"
+
+#: apps/activity/apps.py:10 apps/activity/models.py:129
+#: apps/activity/models.py:169 apps/activity/models.py:323
 msgid "activity"
 msgstr "activité"
 
-#: apps/activity/forms.py:34
+#: apps/activity/forms.py:35
 msgid "The note of this club is inactive."
 msgstr "La note du club est inactive."
 
-#: apps/activity/forms.py:41 apps/activity/models.py:142
+#: apps/activity/forms.py:42 apps/activity/models.py:142
 msgid "The end date must be after the start date."
 msgstr "La date de fin doit être après celle de début."
 
-#: apps/activity/forms.py:82 apps/activity/models.py:271
+#: apps/activity/forms.py:83 apps/activity/models.py:271
 msgid "You can't invite someone once the activity is started."
 msgstr ""
 "Vous ne pouvez pas inviter quelqu'un une fois que l'activité a démarré."
 
-#: apps/activity/forms.py:85 apps/activity/models.py:274
+#: apps/activity/forms.py:86 apps/activity/models.py:274
 msgid "This activity is not validated yet."
 msgstr "Cette activité n'est pas encore validée."
 
-#: apps/activity/forms.py:95 apps/activity/models.py:282
+#: apps/activity/forms.py:96 apps/activity/models.py:282
 msgid "This person has been already invited 5 times this year."
 msgstr "Cette personne a déjà été invitée 5 fois cette année."
 
-#: apps/activity/forms.py:99 apps/activity/models.py:286
+#: apps/activity/forms.py:100 apps/activity/models.py:286
 msgid "This person is already invited."
 msgstr "Cette personne est déjà invitée."
 
-#: apps/activity/forms.py:103 apps/activity/models.py:290
+#: apps/activity/forms.py:104 apps/activity/models.py:290
 msgid "You can't invite more than 3 people to this activity."
 msgstr "Vous ne pouvez pas inviter plus de 3 personnes à cette activité."
 
@@ -63,7 +68,7 @@ msgstr "Vous ne pouvez pas inviter plus de 3 personnes à cette activité."
 #: apps/registration/templates/registration/future_profile_detail.html:16
 #: apps/wei/models.py:67 apps/wei/models.py:131 apps/wei/tables.py:282
 #: apps/wei/templates/wei/base.html:26
-#: apps/wei/templates/wei/weimembership_form.html:14
+#: apps/wei/templates/wei/weimembership_form.html:14 apps/wrapped/models.py:16
 msgid "name"
 msgstr "nom"
 
@@ -115,7 +120,7 @@ msgstr "Lieu où l'activité est organisée, par exemple la Kfet."
 msgid "type"
 msgstr "type"
 
-#: apps/activity/models.py:91 apps/logs/models.py:22 apps/member/models.py:318
+#: apps/activity/models.py:91 apps/logs/models.py:22 apps/member/models.py:325
 #: apps/note/models/notes.py:148 apps/treasury/models.py:293
 #: apps/wei/models.py:171 apps/wei/templates/wei/attribute_bus_1A.html:13
 #: apps/wei/templates/wei/survey.html:15
@@ -172,7 +177,7 @@ msgid "entry time"
 msgstr "heure d'entrée"
 
 #: apps/activity/models.py:180 apps/note/apps.py:14
-#: apps/note/models/notes.py:77
+#: apps/note/models/notes.py:77 apps/wrapped/models.py:60
 msgid "note"
 msgstr "note"
 
@@ -200,7 +205,7 @@ msgstr "Entrée de la note {note} pour l'activité « {activity} »"
 msgid "Already entered on "
 msgstr "Déjà rentré·e le "
 
-#: apps/activity/models.py:204 apps/activity/tables.py:56
+#: apps/activity/models.py:204 apps/activity/tables.py:58
 msgid "{:%Y-%m-%d %H:%M:%S}"
 msgstr "{:%d/%m/%Y %H:%M:%S}"
 
@@ -239,68 +244,96 @@ msgstr "invité·e·s"
 msgid "Invitation"
 msgstr "Invitation"
 
-#: apps/activity/models.py:330
-#: apps/activity/models.py:334
+#: apps/activity/models.py:330 apps/activity/models.py:334
 msgid "Opener"
 msgstr "Ouvreur⋅se"
 
 #: apps/activity/models.py:335
-#: apps/activity/templates/activity_detail.html:16
+#: apps/activity/templates/activity/activity_detail.html:16
 msgid "Openers"
 msgstr "Ouvreur⋅ses"
 
-#: apps/activity/tables.py:27
+#: apps/activity/models.py:339
+#, fuzzy, python-brace-format
+#| msgid "Entry for {note} to the activity {activity}"
+msgid "{opener} is opener of activity {acivity}"
+msgstr "Entrée de la note {note} pour l'activité « {activity} »"
+
+#: apps/activity/tables.py:29
 msgid "The activity is currently open."
 msgstr "Cette activité est actuellement ouverte."
 
-#: apps/activity/tables.py:28
+#: apps/activity/tables.py:30
 msgid "The validation of the activity is pending."
 msgstr "La validation de cette activité est en attente."
 
-#: apps/activity/tables.py:43
+#: apps/activity/tables.py:45
 #: apps/member/templates/member/picture_update.html:18
-#: apps/treasury/tables.py:107
+#: apps/treasury/tables.py:110
 msgid "Remove"
 msgstr "Supprimer"
 
-#: apps/activity/tables.py:56
+#: apps/activity/tables.py:58
 msgid "Entered on "
 msgstr "Entré·e le "
 
-#: apps/activity/tables.py:58
+#: apps/activity/tables.py:60
 msgid "remove"
 msgstr "supprimer"
 
-#: apps/activity/tables.py:82 apps/note/forms.py:68 apps/treasury/models.py:208
+#: apps/activity/tables.py:84 apps/note/forms.py:69 apps/treasury/models.py:208
 msgid "Type"
 msgstr "Type"
 
-#: apps/activity/tables.py:84 apps/member/forms.py:196
+#: apps/activity/tables.py:86 apps/member/forms.py:199
 #: apps/registration/forms.py:91 apps/treasury/forms.py:131
-#: apps/wei/forms/registration.py:104
+#: apps/wei/forms/registration.py:110
 msgid "Last name"
 msgstr "Nom de famille"
 
-#: apps/activity/tables.py:86 apps/member/forms.py:201
+#: apps/activity/tables.py:88 apps/member/forms.py:204
 #: apps/note/templates/note/transaction_form.html:138
 #: apps/registration/forms.py:96 apps/treasury/forms.py:133
-#: apps/wei/forms/registration.py:109
+#: apps/wei/forms/registration.py:115
 msgid "First name"
 msgstr "Prénom"
 
-#: apps/activity/tables.py:88 apps/note/models/notes.py:86
+#: apps/activity/tables.py:90 apps/note/models/notes.py:86
 msgid "Note"
 msgstr "Note"
 
-#: apps/activity/tables.py:90 apps/member/tables.py:50
+#: apps/activity/tables.py:92 apps/member/tables.py:50
 msgid "Balance"
 msgstr "Solde du compte"
 
-#: apps/activity/templates/activity/activity_detail.html:15
+#: apps/activity/tables.py:141 apps/activity/tables.py:148
+#: apps/note/tables.py:166 apps/note/tables.py:173 apps/note/tables.py:234
+#: apps/note/tables.py:281 apps/treasury/tables.py:39
+#: apps/treasury/templates/treasury/invoice_confirm_delete.html:30
+#: apps/treasury/templates/treasury/sogecredit_detail.html:65
+#: apps/wei/tables.py:75 apps/wei/tables.py:118
+#: apps/wei/templates/wei/weiregistration_confirm_delete.html:31
+#: note_kfet/templates/oauth2_provider/application_confirm_delete.html:18
+#: note_kfet/templates/oauth2_provider/application_detail.html:39
+#: note_kfet/templates/oauth2_provider/authorized-token-delete.html:12
+msgid "Delete"
+msgstr "Supprimer"
+
+#: apps/activity/templates/activity/activity_detail.html:24
+#: apps/member/templates/member/club_alias.html:20
+#: apps/member/templates/member/profile_alias.html:19
+#: apps/member/templates/member/profile_trust.html:19
+#: apps/treasury/tables.py:101
+#: apps/treasury/templates/treasury/sogecredit_list.html:34
+#: apps/treasury/templates/treasury/sogecredit_list.html:73
+msgid "Add"
+msgstr "Ajouter"
+
+#: apps/activity/templates/activity/activity_detail.html:35
 msgid "Guests list"
 msgstr "Liste des invité·e·s"
 
-#: apps/activity/templates/activity/activity_detail.html:33
+#: apps/activity/templates/activity/activity_detail.html:55
 msgid "Guest deleted"
 msgstr "Invité·e supprimé·e"
 
@@ -347,7 +380,7 @@ msgstr "Entrée effectuée !"
 #: apps/activity/templates/activity/activity_form.html:16
 #: apps/food/templates/food/add_ingredient_form.html:16
 #: apps/food/templates/food/basicfood_form.html:16
-#: apps/food/templates/food/create_qrcode_form.html:19
+#: apps/food/templates/food/create_qrcode_form.html:20
 #: apps/food/templates/food/transformedfood_form.html:16
 #: apps/member/templates/member/add_members.html:46
 #: apps/member/templates/member/club_form.html:16
@@ -414,41 +447,41 @@ msgstr "modifier"
 msgid "Invite"
 msgstr "Inviter"
 
-#: apps/activity/views.py:37
+#: apps/activity/views.py:38
 msgid "Create new activity"
 msgstr "Créer une nouvelle activité"
 
-#: apps/activity/views.py:67 note_kfet/templates/base.html:96
+#: apps/activity/views.py:71 note_kfet/templates/base.html:96
 msgid "Activities"
 msgstr "Activités"
 
-#: apps/activity/views.py:108
+#: apps/activity/views.py:105
 msgid "Activity detail"
 msgstr "Détails de l'activité"
 
-#: apps/activity/views.py:128
+#: apps/activity/views.py:150
 msgid "Update activity"
 msgstr "Modifier l'activité"
 
-#: apps/activity/views.py:155
+#: apps/activity/views.py:177
 msgid "Invite guest to the activity \"{}\""
 msgstr "Invitation pour l'activité « {} »"
 
-#: apps/activity/views.py:193
+#: apps/activity/views.py:217
 msgid "You are not allowed to display the entry interface for this activity."
 msgstr ""
 "Vous n'êtes pas autorisé·e à afficher l'interface des entrées pour cette "
 "activité."
 
-#: apps/activity/views.py:196
+#: apps/activity/views.py:220
 msgid "This activity does not support activity entries."
 msgstr "Cette activité ne requiert pas d'entrées."
 
-#: apps/activity/views.py:199
+#: apps/activity/views.py:223
 msgid "This activity is closed."
 msgstr "Cette activité est fermée."
 
-#: apps/activity/views.py:295
+#: apps/activity/views.py:328
 msgid "Entry for activity \"{}\""
 msgstr "Entrées pour l'activité « {} »"
 
@@ -468,7 +501,7 @@ msgstr "Entièrement utilisé"
 msgid "Pasta METRO 5kg"
 msgstr "Pâtes METRO 5kg"
 
-#: apps/food/forms.py:96
+#: apps/food/forms.py:100
 msgid "Lasagna"
 msgstr "Lasagnes"
 
@@ -554,7 +587,7 @@ msgstr "ingrédients tranformées"
 msgid "shelf life"
 msgstr "durée de vie"
 
-#: apps/food/models.py:225 apps/food/views.py:365
+#: apps/food/models.py:225 apps/food/views.py:375
 msgid "Transformed food"
 msgstr "Aliment transformé"
 
@@ -562,20 +595,20 @@ msgstr "Aliment transformé"
 msgid "Transformed foods"
 msgstr "Aliments transformés"
 
-#: apps/food/templates/food/create_qrcode_form.html:31
 #: apps/food/templates/food/basicfood_detail.html:14
+#: apps/food/templates/food/create_qrcode_form.html:31
 #: apps/food/templates/food/qrcode_detail.html:15
 #: apps/food/templates/food/transformedfood_detail.html:14
 msgid "Owner"
 msgstr "Propriétaire"
 
-#: apps/food/templates/food/create_qrcode_form.html:34
 #: apps/food/templates/food/basicfood_detail.html:15
+#: apps/food/templates/food/create_qrcode_form.html:34
 msgid "Arrival date"
 msgstr "Date d'arrivée"
 
-#: apps/food/templates/food/create_qrcode_form.html:37
 #: apps/food/templates/food/basicfood_detail.html:16
+#: apps/food/templates/food/create_qrcode_form.html:37
 #: apps/food/templates/food/qrcode_detail.html:16
 #: apps/food/templates/food/transformedfood_detail.html:19
 msgid "Expiry date"
@@ -604,7 +637,7 @@ msgstr "Modifier"
 msgid "Add to a meal"
 msgstr "Ajouter à un plat"
 
-#: apps/food/templates/food/create_qrcode_form.html:14
+#: apps/food/templates/food/create_qrcode_form.html:15
 msgid "New basic food"
 msgstr "Nouvel aliment basique"
 
@@ -612,10 +645,6 @@ msgstr "Nouvel aliment basique"
 msgid "Copy constructor"
 msgstr "Constructeur de copie"
 
-#: apps/food/templates/food/qrcode_detail.html:10
-msgid "number"
-msgstr "numéro"
-
 #: apps/food/templates/food/create_qrcode_form.html:28
 #: apps/food/templates/food/qrcode_detail.html:14
 #: apps/note/templates/note/transaction_form.html:132
@@ -623,6 +652,10 @@ msgstr "numéro"
 msgid "Name"
 msgstr "Nom"
 
+#: apps/food/templates/food/qrcode_detail.html:10
+msgid "number"
+msgstr "numéro"
+
 #: apps/food/templates/food/qrcode_detail.html:29
 msgid "View details"
 msgstr "Voir plus"
@@ -692,19 +725,19 @@ msgstr "Détails de:"
 msgid "Add a new basic food with QRCode"
 msgstr "Ajouter un nouvel ingrédient avec un QR-code"
 
-#: apps/food/views.py:185
+#: apps/food/views.py:194
 msgid "Add a new QRCode"
 msgstr "Ajouter un nouveau QR-code"
 
-#: apps/food/views.py:235
+#: apps/food/views.py:245
 msgid "QRCode"
 msgstr "QR-code"
 
-#: apps/food/views.py:271
+#: apps/food/views.py:281
 msgid "Add a new meal"
 msgstr "Ajouter un nouveau plat"
 
-#: apps/food/views.py:337
+#: apps/food/views.py:347
 msgid "Update a meal"
 msgstr "Modifier le plat"
 
@@ -736,7 +769,7 @@ msgstr "nouvelles données"
 msgid "create"
 msgstr "créer"
 
-#: apps/logs/models.py:65 apps/note/tables.py:230 apps/note/tables.py:277
+#: apps/logs/models.py:65 apps/note/tables.py:230 apps/note/tables.py:279
 #: apps/permission/models.py:126 apps/treasury/tables.py:38
 #: apps/wei/tables.py:74
 msgid "delete"
@@ -777,11 +810,11 @@ msgstr "cotisation pour adhérer (normalien·ne élève)"
 msgid "membership fee (unpaid students)"
 msgstr "cotisation pour adhérer (normalien·ne étudiant·e)"
 
-#: apps/member/admin.py:65 apps/member/models.py:330
+#: apps/member/admin.py:65 apps/member/models.py:337
 msgid "roles"
 msgstr "rôles"
 
-#: apps/member/admin.py:66 apps/member/models.py:344
+#: apps/member/admin.py:66 apps/member/models.py:351
 msgid "fee"
 msgstr "cotisation"
 
@@ -789,24 +822,24 @@ msgstr "cotisation"
 msgid "member"
 msgstr "adhérent·e"
 
-#: apps/member/forms.py:24
+#: apps/member/forms.py:25
 msgid "Permission mask"
 msgstr "Masque de permissions"
 
-#: apps/member/forms.py:46
+#: apps/member/forms.py:48
 msgid "Report frequency"
 msgstr "Fréquence des relevés (en jours)"
 
-#: apps/member/forms.py:48
+#: apps/member/forms.py:50
 msgid "Last report date"
 msgstr "Date de dernier relevé"
 
-#: apps/member/forms.py:52
+#: apps/member/forms.py:54
 msgid ""
 "Anti-VSS (<em>Violences Sexistes et Sexuelles</em>) charter read and approved"
 msgstr "Charte Anti-VSS (Violences Sexistes et Sexuelles) lue et approuvée"
 
-#: apps/member/forms.py:53
+#: apps/member/forms.py:55
 msgid ""
 "Tick after having read and accepted the anti-VSS charter         <a "
 "href=https://perso.crans.org/club-bde/Charte-anti-VSS.pdf target=_blank> "
@@ -816,65 +849,65 @@ msgstr ""
 "crans.org/club-bde/Charte-anti-VSS.pdf target=_blank> disponible en pdf ici</"
 "a>"
 
-#: apps/member/forms.py:60
+#: apps/member/forms.py:62
 msgid "You can't register to the note if you come from the future."
 msgstr "Vous ne pouvez pas vous inscrire à la note si vous venez du futur."
 
-#: apps/member/forms.py:86
+#: apps/member/forms.py:89
 msgid "select an image"
 msgstr "choisissez une image"
 
-#: apps/member/forms.py:87
+#: apps/member/forms.py:90
 msgid "Maximal size: 2MB"
 msgstr "Taille maximale : 2 Mo"
 
-#: apps/member/forms.py:112
+#: apps/member/forms.py:115
 msgid "This image cannot be loaded."
 msgstr "Cette image ne peut pas être chargée."
 
-#: apps/member/forms.py:151 apps/member/views.py:102
-#: apps/registration/forms.py:33 apps/registration/views.py:276
+#: apps/member/forms.py:154 apps/member/views.py:103
+#: apps/registration/forms.py:33 apps/registration/views.py:282
 msgid "An alias with a similar name already exists."
 msgstr "Un alias avec un nom similaire existe déjà."
 
-#: apps/member/forms.py:175
+#: apps/member/forms.py:178
 msgid "Inscription paid by Société Générale"
 msgstr "Inscription payée par la Société générale"
 
-#: apps/member/forms.py:177
+#: apps/member/forms.py:180
 msgid "Check this case if the Société Générale paid the inscription."
 msgstr "Cochez cette case si la Société Générale a payé l'inscription."
 
-#: apps/member/forms.py:182 apps/registration/forms.py:78
-#: apps/wei/forms/registration.py:91
+#: apps/member/forms.py:185 apps/registration/forms.py:78
+#: apps/wei/forms/registration.py:97
 msgid "Credit type"
 msgstr "Type de rechargement"
 
-#: apps/member/forms.py:183 apps/registration/forms.py:79
-#: apps/wei/forms/registration.py:92
+#: apps/member/forms.py:186 apps/registration/forms.py:79
+#: apps/wei/forms/registration.py:98
 msgid "No credit"
 msgstr "Pas de rechargement"
 
-#: apps/member/forms.py:185
+#: apps/member/forms.py:188
 msgid "You can credit the note of the user."
 msgstr "Vous pouvez créditer la note de l'utilisateur⋅rice avant l'adhésion."
 
-#: apps/member/forms.py:189 apps/registration/forms.py:84
-#: apps/wei/forms/registration.py:97
+#: apps/member/forms.py:192 apps/registration/forms.py:84
+#: apps/wei/forms/registration.py:103
 msgid "Credit amount"
 msgstr "Montant à créditer"
 
-#: apps/member/forms.py:206 apps/note/templates/note/transaction_form.html:144
+#: apps/member/forms.py:209 apps/note/templates/note/transaction_form.html:144
 #: apps/registration/forms.py:101 apps/treasury/forms.py:135
-#: apps/wei/forms/registration.py:114
+#: apps/wei/forms/registration.py:120
 msgid "Bank"
 msgstr "Banque"
 
-#: apps/member/forms.py:233
+#: apps/member/forms.py:236
 msgid "User"
 msgstr "Utilisateur⋅rice"
 
-#: apps/member/forms.py:247
+#: apps/member/forms.py:250
 msgid "Roles"
 msgstr "Rôles"
 
@@ -1007,7 +1040,7 @@ msgstr "payé⋅e"
 msgid "Tells if the user receive a salary."
 msgstr "Indique si l'utilisateur⋅rice perçoit un salaire."
 
-#: apps/member/models.py:99 apps/treasury/tables.py:143
+#: apps/member/models.py:99 apps/treasury/tables.py:149
 msgid "No"
 msgstr "Non"
 
@@ -1126,7 +1159,7 @@ msgstr ""
 msgid "add to registration form"
 msgstr "ajouter au formulaire d'inscription"
 
-#: apps/member/models.py:268 apps/member/models.py:324
+#: apps/member/models.py:268 apps/member/models.py:331
 #: apps/note/models/notes.py:176
 msgid "club"
 msgstr "club"
@@ -1135,37 +1168,37 @@ msgstr "club"
 msgid "clubs"
 msgstr "clubs"
 
-#: apps/member/models.py:335
+#: apps/member/models.py:342
 msgid "membership starts on"
 msgstr "l'adhésion commence le"
 
-#: apps/member/models.py:339
+#: apps/member/models.py:346
 msgid "membership ends on"
 msgstr "l'adhésion finit le"
 
-#: apps/member/models.py:348 apps/note/models/transactions.py:385
+#: apps/member/models.py:355 apps/note/models/transactions.py:385
 msgid "membership"
 msgstr "adhésion"
 
-#: apps/member/models.py:349
+#: apps/member/models.py:356
 msgid "memberships"
 msgstr "adhésions"
 
-#: apps/member/models.py:353
+#: apps/member/models.py:360
 #, python-brace-format
 msgid "Membership of {user} for the club {club}"
 msgstr "Adhésion de {user} pour le club {club}"
 
-#: apps/member/models.py:372
+#: apps/member/models.py:379
 #, python-brace-format
 msgid "The role {role} does not apply to the club {club}."
 msgstr "Le rôle {role} ne s'applique pas au club {club}."
 
-#: apps/member/models.py:381 apps/member/views.py:715
+#: apps/member/models.py:388 apps/member/views.py:745
 msgid "User is already a member of the club"
 msgstr "L'utilisateur·rice est déjà membre du club"
 
-#: apps/member/models.py:393 apps/member/views.py:724
+#: apps/member/models.py:400 apps/member/views.py:754
 msgid "User is not a member of the parent club"
 msgstr "L'utilisateur·rice n'est pas membre du club parent"
 
@@ -1180,8 +1213,8 @@ msgid ""
 "%(pretty_fee)s will be charged to renew automatically the membership in this/"
 "these club·s."
 msgstr ""
-"Cet·te utilisateur·rice n'est pas membre du/des club·s parent·s %(clubs)s. Un "
-"montant supplémentaire de %(pretty_fee)s sera débité afin de renouveler "
+"Cet·te utilisateur·rice n'est pas membre du/des club·s parent·s %(clubs)s. "
+"Un montant supplémentaire de %(pretty_fee)s sera débité afin de renouveler "
 "automatiquement l'adhésion dans ce·s club·s."
 
 #: apps/member/templates/member/add_members.html:22
@@ -1208,8 +1241,9 @@ msgid ""
 "This club has parents %(clubs)s. Please make sure that the user is a member "
 "of this or these club·s, otherwise the creation of this membership will fail."
 msgstr ""
-"Ce club a pour parents %(clubs)s. Merci de vous assurer que l'utilisateur⋅rice "
-"est membre de ce·s club·s, sinon la création de cette adhésion va échouer."
+"Ce club a pour parents %(clubs)s. Merci de vous assurer que "
+"l'utilisateur⋅rice est membre de ce·s club·s, sinon la création de cette "
+"adhésion va échouer."
 
 #: apps/member/templates/member/base.html:17
 #: apps/registration/templates/registration/future_profile_detail.html:12
@@ -1217,7 +1251,7 @@ msgid "Account #"
 msgstr "Compte n°"
 
 #: apps/member/templates/member/base.html:48
-#: apps/member/templates/member/base.html:62 apps/member/views.py:59
+#: apps/member/templates/member/base.html:62 apps/member/views.py:60
 #: apps/registration/templates/registration/future_profile_detail.html:48
 #: apps/wei/templates/wei/weimembership_form.html:117
 msgid "Update Profile"
@@ -1278,20 +1312,11 @@ msgstr ""
 "seront à nouveau possible."
 
 #: apps/member/templates/member/club_alias.html:10
-#: apps/member/templates/member/profile_alias.html:10 apps/member/views.py:287
-#: apps/member/views.py:520
+#: apps/member/templates/member/profile_alias.html:10 apps/member/views.py:304
+#: apps/member/views.py:545
 msgid "Note aliases"
 msgstr "Alias de la note"
 
-#: apps/member/templates/member/club_alias.html:20
-#: apps/member/templates/member/profile_alias.html:19
-#: apps/member/templates/member/profile_trust.html:19
-#: apps/treasury/tables.py:99
-#: apps/treasury/templates/treasury/sogecredit_list.html:34
-#: apps/treasury/templates/treasury/sogecredit_list.html:73
-msgid "Add"
-msgstr "Ajouter"
-
 #: apps/member/templates/member/club_detail.html:13
 #: apps/permission/templates/permission/all_rights.html:32
 msgid "Club managers"
@@ -1480,51 +1505,51 @@ msgstr "Sauvegarder les changements"
 msgid "Registrations"
 msgstr "Inscriptions"
 
-#: apps/member/views.py:72 apps/registration/forms.py:23
+#: apps/member/views.py:73 apps/registration/forms.py:23
 msgid "This address must be valid."
 msgstr "Cette adresse doit être valide."
 
-#: apps/member/views.py:139
+#: apps/member/views.py:140
 msgid "Profile detail"
 msgstr "Détails de l'utilisateur⋅rice"
 
-#: apps/member/views.py:205
+#: apps/member/views.py:206
 msgid "Search user"
 msgstr "Chercher un·e utilisateur·rice"
 
-#: apps/member/views.py:253
+#: apps/member/views.py:258
 msgid "Note friendships"
 msgstr "Amitiés note"
 
-#: apps/member/views.py:308
+#: apps/member/views.py:328
 msgid "Update note picture"
 msgstr "Modifier la photo de la note"
 
-#: apps/member/views.py:357
+#: apps/member/views.py:377
 msgid "Manage auth token"
 msgstr "Gérer les jetons d'authentification"
 
-#: apps/member/views.py:384
+#: apps/member/views.py:404
 msgid "Create new club"
 msgstr "Créer un nouveau club"
 
-#: apps/member/views.py:403
+#: apps/member/views.py:423
 msgid "Search club"
 msgstr "Chercher un club"
 
-#: apps/member/views.py:436
+#: apps/member/views.py:461
 msgid "Club detail"
 msgstr "Détails du club"
 
-#: apps/member/views.py:543
+#: apps/member/views.py:573
 msgid "Update club"
 msgstr "Modifier le club"
 
-#: apps/member/views.py:577
+#: apps/member/views.py:607
 msgid "Add new member to the club"
 msgstr "Ajouter un·e nouvelleau membre au club"
 
-#: apps/member/views.py:706 apps/wei/views.py:973
+#: apps/member/views.py:736 apps/wei/views.py:991
 msgid ""
 "This user don't have enough money to join this club, and can't have a "
 "negative balance."
@@ -1532,19 +1557,19 @@ msgstr ""
 "Cet⋅te utilisateur⋅rice n'a pas assez d'argent pour rejoindre ce club et ne "
 "peut pas avoir un solde négatif."
 
-#: apps/member/views.py:728
+#: apps/member/views.py:758
 msgid "The membership must start after {:%m-%d-%Y}."
 msgstr "L'adhésion doit commencer après le {:%d/%m/%Y}."
 
-#: apps/member/views.py:733
+#: apps/member/views.py:763
 msgid "The membership must begin before {:%m-%d-%Y}."
 msgstr "L'adhésion doit commencer avant le {:%d/%m/%Y}."
 
-#: apps/member/views.py:883
+#: apps/member/views.py:913
 msgid "Manage roles of an user in the club"
 msgstr "Gérer les rôles d'un⋅e utilisateur⋅rice dans le club"
 
-#: apps/member/views.py:908
+#: apps/member/views.py:938
 msgid "Members of the club"
 msgstr "Membres du club"
 
@@ -1575,35 +1600,35 @@ msgstr ""
 "La transaction ne peut pas être sauvegardée puisque la note source ou la "
 "note de destination n'est pas active."
 
-#: apps/note/forms.py:39
+#: apps/note/forms.py:40
 msgid "Source"
 msgstr "Source"
 
-#: apps/note/forms.py:53
+#: apps/note/forms.py:54
 msgid "Destination"
 msgstr "Destination"
 
-#: apps/note/forms.py:74 apps/note/templates/note/transaction_form.html:123
+#: apps/note/forms.py:75 apps/note/templates/note/transaction_form.html:123
 msgid "Reason"
 msgstr "Raison"
 
-#: apps/note/forms.py:79 apps/treasury/tables.py:136
+#: apps/note/forms.py:80 apps/treasury/tables.py:141
 msgid "Valid"
 msgstr "Valide"
 
-#: apps/note/forms.py:85
+#: apps/note/forms.py:86
 msgid "Total amount greater than"
 msgstr "Montant total supérieur à"
 
-#: apps/note/forms.py:93
+#: apps/note/forms.py:94
 msgid "Total amount less than"
 msgstr "Montant total inférieur à"
 
-#: apps/note/forms.py:99
+#: apps/note/forms.py:100
 msgid "Created after"
 msgstr "Créé après"
 
-#: apps/note/forms.py:106
+#: apps/note/forms.py:107
 msgid "Created before"
 msgstr "Créé avant"
 
@@ -1656,7 +1681,6 @@ msgstr ""
 "La note est bloquée de force par le BDE et ne peut pas être débloquée par læ "
 "propriétaire de la note."
 
-
 #: apps/note/models/notes.py:78
 msgid "notes"
 msgstr "notes"
@@ -1708,7 +1732,9 @@ msgid "trusted"
 msgstr "ami·e"
 
 #: apps/note/models/notes.py:243
-msgid "friendship"
+#, fuzzy
+#| msgid "friendship"
+msgid "frienship"
 msgstr "amitié"
 
 #: apps/note/models/notes.py:248
@@ -1860,8 +1886,8 @@ msgstr ""
 "mode de paiement et un⋅e utilisateur⋅rice ou un club"
 
 #: apps/note/models/transactions.py:357 apps/note/models/transactions.py:360
-#: apps/note/models/transactions.py:363 apps/wei/views.py:978
-#: apps/wei/views.py:982
+#: apps/note/models/transactions.py:363 apps/wei/views.py:996
+#: apps/wei/views.py:1000
 msgid "This field is required."
 msgstr "Ce champ est requis."
 
@@ -1885,18 +1911,6 @@ msgstr "Cliquez pour valider"
 msgid "No reason specified"
 msgstr "Pas de motif spécifié"
 
-#: apps/note/tables.py:166 apps/note/tables.py:173 apps/note/tables.py:234
-#: apps/note/tables.py:279 apps/treasury/tables.py:39
-#: apps/treasury/templates/treasury/invoice_confirm_delete.html:30
-#: apps/treasury/templates/treasury/sogecredit_detail.html:65
-#: apps/wei/tables.py:75 apps/wei/tables.py:118
-#: apps/wei/templates/wei/weiregistration_confirm_delete.html:31
-#: note_kfet/templates/oauth2_provider/application_confirm_delete.html:18
-#: note_kfet/templates/oauth2_provider/application_detail.html:39
-#: note_kfet/templates/oauth2_provider/authorized-token-delete.html:12
-msgid "Delete"
-msgstr "Supprimer"
-
 #: apps/note/tables.py:191
 msgid "Trust back"
 msgstr "Ajouter en ami·e"
@@ -1915,7 +1929,7 @@ msgstr "Ajouter"
 msgid "Edit"
 msgstr "Éditer"
 
-#: apps/note/tables.py:266 apps/note/tables.py:293
+#: apps/note/tables.py:267 apps/note/tables.py:296
 msgid "Hide/Show"
 msgstr "Afficher/Masquer"
 
@@ -1975,6 +1989,10 @@ msgstr "Historique des transactions récentes"
 #: apps/note/templates/note/mails/weekly_report.txt:32
 #: apps/registration/templates/registration/mails/email_validation_email.html:40
 #: apps/registration/templates/registration/mails/email_validation_email.txt:16
+#: apps/scripts/templates/scripts/horaires.html:35
+#: apps/scripts/templates/scripts/horaires.txt:17
+#: apps/scripts/templates/scripts/intro_mail.html:49
+#: apps/scripts/templates/scripts/intro_mail.txt:25
 msgid "Mail generated by the Note Kfet on the"
 msgstr "Mail généré par la Note Kfet le"
 
@@ -1997,8 +2015,8 @@ msgid "Action"
 msgstr "Action"
 
 #: apps/note/templates/note/transaction_form.html:116
-#: apps/treasury/forms.py:137 apps/treasury/tables.py:67
-#: apps/treasury/tables.py:132
+#: apps/treasury/forms.py:137 apps/treasury/tables.py:68
+#: apps/treasury/tables.py:136
 #: apps/treasury/templates/treasury/remittance_form.html:23
 msgid "Amount"
 msgstr "Montant"
@@ -2040,15 +2058,21 @@ msgid "New button"
 msgstr "Nouveau bouton"
 
 #: apps/note/templates/note/transactiontemplate_list.html:22
-msgid "buttons listing"
+#, fuzzy
+#| msgid "buttons listing"
+msgid "buttons listing "
 msgstr "liste des boutons"
 
 #: apps/note/templates/note/transactiontemplate_list.html:73
-msgid "button successfully deleted"
+#, fuzzy
+#| msgid "button successfully deleted"
+msgid "button successfully deleted "
 msgstr "le bouton a bien été supprimé"
 
 #: apps/note/templates/note/transactiontemplate_list.html:77
-msgid "Unable to delete button"
+#, fuzzy
+#| msgid "Unable to delete button"
+msgid "Unable to delete button "
 msgstr "Impossible de supprimer le bouton"
 
 #: apps/note/templates/note/transactiontemplate_list.html:95
@@ -2060,34 +2084,35 @@ msgid "Button displayed"
 msgstr "Bouton affiché"
 
 #: apps/note/templates/note/transactiontemplate_list.html:100
+#: apps/wrapped/templates/wrapped/wrapped_list.html:63
 msgid "An error occured"
 msgstr "Une erreur s'est produite"
 
-#: apps/note/views.py:36
+#: apps/note/views.py:37
 msgid "Transfer money"
 msgstr "Transférer de l'argent"
 
-#: apps/note/views.py:74
+#: apps/note/views.py:75
 msgid "Create new button"
 msgstr "Créer un nouveau bouton"
 
-#: apps/note/views.py:83
+#: apps/note/views.py:84
 msgid "Search button"
 msgstr "Chercher un bouton"
 
-#: apps/note/views.py:111
+#: apps/note/views.py:116
 msgid "Update button"
 msgstr "Modifier le bouton"
 
-#: apps/note/views.py:151 note_kfet/templates/base.html:66
+#: apps/note/views.py:156 note_kfet/templates/base.html:66
 msgid "Consumptions"
 msgstr "Consommations"
 
-#: apps/note/views.py:165
+#: apps/note/views.py:170
 msgid "You can't see any button."
 msgstr "Vous ne pouvez pas voir le moindre bouton."
 
-#: apps/note/views.py:204
+#: apps/note/views.py:209
 msgid "Search transactions"
 msgstr "Rechercher des transactions"
 
@@ -2181,7 +2206,7 @@ msgstr ""
 "Vous n'avez pas la permission de modifier le champ {field} sur l'instance du "
 "modèle {app_label}.{model_name}."
 
-#: apps/permission/signals.py:83 apps/permission/views.py:105
+#: apps/permission/signals.py:83 apps/permission/views.py:104
 #, python-brace-format
 msgid ""
 "You don't have the permission to add an instance of model {app_label}."
@@ -2206,7 +2231,8 @@ msgstr "Liste des utilisateur·rice·s ayant des droits surnormaux"
 #: apps/permission/templates/permission/all_rights.html:16
 msgid "Superusers have all rights on everything, to manage the website."
 msgstr ""
-"Les super-utilisateur·rice·s ont tous les droits sur tout, afin de gérer le site."
+"Les super-utilisateur·rice·s ont tous les droits sur tout, afin de gérer le "
+"site."
 
 #: apps/permission/templates/permission/all_rights.html:21
 msgid "Superusers"
@@ -2259,7 +2285,7 @@ msgstr "Cliquez ici"
 msgid "if you want to register a new one"
 msgstr "si vous voulez en enregistrer une nouvelle"
 
-#: apps/permission/views.py:72
+#: apps/permission/views.py:71
 #, python-brace-format
 msgid ""
 "You don't have the permission to update this instance of the model "
@@ -2268,7 +2294,7 @@ msgstr ""
 "Vous n'avez pas la permission de modifier cette instance du modèle « {model} "
 "» avec ces paramètres. Merci de les corriger et de réessayer."
 
-#: apps/permission/views.py:76
+#: apps/permission/views.py:75
 #, python-brace-format
 msgid ""
 "You don't have the permission to create an instance of the model \"{model}\" "
@@ -2277,11 +2303,11 @@ msgstr ""
 "Vous n'avez pas la permission d'ajouter une instance du modèle « {model} » "
 "avec ces paramètres. Merci de les corriger et de réessayer."
 
-#: apps/permission/views.py:112 note_kfet/templates/base.html:114
+#: apps/permission/views.py:111 note_kfet/templates/base.html:120
 msgid "Rights"
 msgstr "Droits"
 
-#: apps/permission/views.py:117
+#: apps/permission/views.py:137
 msgid "All rights"
 msgstr "Tous les droits"
 
@@ -2365,7 +2391,8 @@ msgstr "Valider le compte"
 #: apps/registration/templates/registration/future_profile_detail.html:63
 msgid ""
 "The user declared that he/she opened a bank account in the Société générale."
-msgstr "L'utilisateur·rice a déclaré avoir ouvert un compte à la société générale."
+msgstr ""
+"L'utilisateur·rice a déclaré avoir ouvert un compte à la société générale."
 
 #: apps/registration/templates/registration/future_profile_detail.html:73
 #: apps/wei/templates/wei/weimembership_form.html:127
@@ -2417,59 +2444,67 @@ msgstr "Merci"
 msgid "The Note Kfet team."
 msgstr "L'équipe de la Note Kfet."
 
-#: apps/registration/views.py:42
+#: apps/registration/views.py:43
 msgid "Register new user"
 msgstr "Enregistrer un⋅e nouvel⋅le utilisateur⋅rice"
 
-#: apps/registration/views.py:100
+#: apps/registration/views.py:101
 msgid "Email validation"
 msgstr "Validation de l'adresse e-mail"
 
-#: apps/registration/views.py:102
+#: apps/registration/views.py:103
 msgid "Validate email"
 msgstr "Valider l'adresse e-mail"
 
-#: apps/registration/views.py:146
+#: apps/registration/views.py:147
 msgid "Email validation unsuccessful"
 msgstr "La validation de l'adresse e-mail a échoué"
 
-#: apps/registration/views.py:157
+#: apps/registration/views.py:158
 msgid "Email validation email sent"
 msgstr "L'e-mail de vérification de l'adresse e-mail a bien été envoyé"
 
-#: apps/registration/views.py:165
+#: apps/registration/views.py:166
 msgid "Resend email validation link"
 msgstr "Renvoyer le lien de validation"
 
-#: apps/registration/views.py:183
+#: apps/registration/views.py:184
 msgid "Pre-registered users list"
 msgstr "Liste des utilisateur⋅rices en attente d'inscription"
 
-#: apps/registration/views.py:207
+#: apps/registration/views.py:213
 msgid "Unregistered users"
 msgstr "Utilisateur·rices en attente d'inscription"
 
-#: apps/registration/views.py:220
+#: apps/registration/views.py:226
 msgid "Registration detail"
 msgstr "Détails de l'inscription"
 
-#: apps/registration/views.py:256
+#: apps/registration/views.py:262
 #, python-format
 msgid "Join %(club)s Club"
 msgstr "Adhérer au club %(club)s"
 
-#: apps/registration/views.py:299
-msgid "You must join the BDE."
+#: apps/registration/views.py:305
+#, fuzzy
+#| msgid "You must join the BDE."
+msgid "You must join a club."
 msgstr "Vous devez adhérer au BDE."
 
-#: apps/registration/views.py:330
+#: apps/registration/views.py:309
+#, fuzzy
+#| msgid "You must join the BDE."
+msgid "You must also join the parent club BDE."
+msgstr "Vous devez adhérer au BDE."
+
+#: apps/registration/views.py:340
 msgid ""
 "The entered amount is not enough for the memberships, should be at least {}"
 msgstr ""
 "Le montant crédité est trop faible pour adhérer, il doit être au minimum de "
 "{}"
 
-#: apps/registration/views.py:425
+#: apps/registration/views.py:435
 msgid "Invalidate pre-registration"
 msgstr "Invalider l'inscription"
 
@@ -2491,7 +2526,7 @@ msgid "You can't change the type of the remittance."
 msgstr "Vous ne pouvez pas changer le type de la remise."
 
 #: apps/treasury/forms.py:125 apps/treasury/models.py:275
-#: apps/treasury/tables.py:97 apps/treasury/tables.py:105
+#: apps/treasury/tables.py:99 apps/treasury/tables.py:108
 #: apps/treasury/templates/treasury/invoice_list.html:16
 #: apps/treasury/templates/treasury/remittance_list.html:16
 #: apps/treasury/templates/treasury/sogecredit_list.html:17
@@ -2506,7 +2541,8 @@ msgstr "Pas de remise associée"
 msgid "Invoice identifier"
 msgstr "Numéro de facture"
 
-#: apps/treasury/models.py:42
+#: apps/treasury/models.py:42 apps/wrapped/models.py:28
+#: apps/wrapped/models.py:29
 msgid "BDE"
 msgstr "BDE"
 
@@ -2642,8 +2678,9 @@ msgid ""
 "This user doesn't have enough money to pay the memberships with its note. "
 "Please ask her/him to credit the note before invalidating this credit."
 msgstr ""
-"Cet·te utilisateur·rice n'a pas assez d'argent pour payer les adhésions avec sa "
-"note. Merci de lui demander de recharger sa note avant d'invalider ce crédit."
+"Cet·te utilisateur·rice n'a pas assez d'argent pour payer les adhésions avec "
+"sa note. Merci de lui demander de recharger sa note avant d'invalider ce "
+"crédit."
 
 #: apps/treasury/tables.py:20
 msgid "Invoice #{:d}"
@@ -2656,25 +2693,26 @@ msgstr "Facture n°{:d}"
 msgid "Invoice"
 msgstr "Facture"
 
-#: apps/treasury/tables.py:65
+#: apps/treasury/tables.py:66
 msgid "Transaction count"
 msgstr "Nombre de transactions"
 
-#: apps/treasury/tables.py:70 apps/treasury/tables.py:72
+#: apps/treasury/tables.py:71 apps/treasury/tables.py:73
+#: apps/wrapped/tables.py:42
 msgid "View"
 msgstr "Voir"
 
-#: apps/treasury/tables.py:143
+#: apps/treasury/tables.py:149
 msgid "Yes"
 msgstr "Oui"
 
 #: apps/treasury/templates/treasury/invoice_confirm_delete.html:10
-#: apps/treasury/views.py:173
+#: apps/treasury/views.py:174
 msgid "Delete invoice"
 msgstr "Supprimer la facture"
 
 #: apps/treasury/templates/treasury/invoice_confirm_delete.html:15
-#: apps/treasury/views.py:177
+#: apps/treasury/views.py:178
 msgid "This invoice is locked and can't be deleted."
 msgstr "Cette facture est verrouillée et ne peut pas être supprimée."
 
@@ -2794,8 +2832,8 @@ msgid ""
 "If this credit is validated, then the user won't be able to ask for a credit "
 "from the Société générale."
 msgstr ""
-"Si ce crédit est validé, alors l'utilisateur·rice ne pourra plus demander d'être "
-"crédité·e par la Société générale à l'avenir."
+"Si ce crédit est validé, alors l'utilisateur·rice ne pourra plus demander "
+"d'être crédité·e par la Société générale à l'avenir."
 
 #: apps/treasury/templates/treasury/sogecredit_detail.html:44
 msgid "If you think there is an error, please contact the \"respos info\"."
@@ -2811,14 +2849,14 @@ msgid ""
 "Warning: if you don't validate this credit, the note of the user doesn't "
 "have enough money to pay its memberships."
 msgstr ""
-"Attention : si vous ne validez pas ce crédit, la note de l'utilisateur·rice n'a "
-"pas assez d'argent pour payer les adhésions."
+"Attention : si vous ne validez pas ce crédit, la note de l'utilisateur·rice "
+"n'a pas assez d'argent pour payer les adhésions."
 
 #: apps/treasury/templates/treasury/sogecredit_detail.html:56
 msgid "Please ask the user to credit its note before deleting this credit."
 msgstr ""
-"Merci de demander à l'utilisateur·rice de recharger sa note avant de supprimer la "
-"demande de crédit."
+"Merci de demander à l'utilisateur·rice de recharger sa note avant de "
+"supprimer la demande de crédit."
 
 #: apps/treasury/templates/treasury/sogecredit_detail.html:63
 #: apps/wei/tables.py:60 apps/wei/tables.py:102
@@ -2836,8 +2874,8 @@ msgstr "Filtrer avec uniquement les crédits non valides"
 #: apps/treasury/templates/treasury/sogecredit_list.html:50
 msgid "There is no matched user that have asked for a Société générale credit."
 msgstr ""
-"Il n'y a pas d'utilisateur·rice trouvé·e ayant demandé un crédit de la Société "
-"générale."
+"Il n'y a pas d'utilisateur·rice trouvé·e ayant demandé un crédit de la "
+"Société générale."
 
 #: apps/treasury/templates/treasury/sogecredit_list.html:63
 msgid "Add credit from the Société générale"
@@ -2847,44 +2885,44 @@ msgstr "Ajouter un crédit de la Société générale"
 msgid "Credit successfully registered"
 msgstr "Le crédit a bien été enregistré"
 
-#: apps/treasury/views.py:40
+#: apps/treasury/views.py:41
 msgid "Create new invoice"
 msgstr "Créer une nouvelle facture"
 
-#: apps/treasury/views.py:97
+#: apps/treasury/views.py:98
 msgid "Invoices list"
 msgstr "Liste des factures"
 
-#: apps/treasury/views.py:105 apps/treasury/views.py:275
-#: apps/treasury/views.py:401
+#: apps/treasury/views.py:106 apps/treasury/views.py:281
+#: apps/treasury/views.py:394
 msgid "You are not able to see the treasury interface."
 msgstr "Vous n'êtes pas autorisé·e à voir l'interface de trésorerie."
 
-#: apps/treasury/views.py:115
+#: apps/treasury/views.py:116
 msgid "Update an invoice"
 msgstr "Modifier la facture"
 
-#: apps/treasury/views.py:240
+#: apps/treasury/views.py:241
 msgid "Create a new remittance"
 msgstr "Créer une nouvelle remise"
 
-#: apps/treasury/views.py:267
+#: apps/treasury/views.py:265
 msgid "Remittances list"
 msgstr "Liste des remises"
 
-#: apps/treasury/views.py:326
+#: apps/treasury/views.py:320
 msgid "Update a remittance"
 msgstr "Modifier la remise"
 
-#: apps/treasury/views.py:349
+#: apps/treasury/views.py:342
 msgid "Attach a transaction to a remittance"
 msgstr "Joindre une transaction à une remise"
 
-#: apps/treasury/views.py:393
+#: apps/treasury/views.py:386
 msgid "List of credits from the Société générale"
 msgstr "Liste des crédits de la Société générale"
 
-#: apps/treasury/views.py:438
+#: apps/treasury/views.py:436
 msgid "Manage credits from the Société générale"
 msgstr "Gérer les crédits de la Société générale"
 
@@ -2894,31 +2932,31 @@ msgstr "Gérer les crédits de la Société générale"
 msgid "WEI"
 msgstr "WEI"
 
-#: apps/wei/forms/registration.py:35
+#: apps/wei/forms/registration.py:36
 msgid "The selected user is not validated. Please validate its account first"
 msgstr ""
-"L'utilisateur·rice sélectionné·e n'est pas validé·e. Merci de d'abord valider son "
-"compte"
+"L'utilisateur·rice sélectionné·e n'est pas validé·e. Merci de d'abord "
+"valider son compte"
 
-#: apps/wei/forms/registration.py:59 apps/wei/models.py:126
+#: apps/wei/forms/registration.py:60 apps/wei/models.py:126
 #: apps/wei/models.py:324
 msgid "bus"
 msgstr "bus"
 
-#: apps/wei/forms/registration.py:60
+#: apps/wei/forms/registration.py:61
 msgid ""
 "This choice is not definitive. The WEI organizers are free to attribute for "
 "you a bus and a team, in particular if you are a free eletron."
 msgstr ""
-"Ce choix n'est pas définitif. Les organisateur·rice·s du WEI sont libres de vous "
-"attribuer un bus et une équipe, en particulier si vous êtes un·e électron "
-"libre."
+"Ce choix n'est pas définitif. Les organisateur·rice·s du WEI sont libres de "
+"vous attribuer un bus et une équipe, en particulier si vous êtes un·e "
+"électron libre."
 
-#: apps/wei/forms/registration.py:67
+#: apps/wei/forms/registration.py:68
 msgid "Team"
 msgstr "Équipe"
 
-#: apps/wei/forms/registration.py:69
+#: apps/wei/forms/registration.py:70
 msgid ""
 "Leave this field empty if you won't be in a team (staff, bus chief, free "
 "electron)"
@@ -2926,16 +2964,20 @@ msgstr ""
 "Laissez ce champ vide si vous ne serez pas dans une équipe (staff, chef de "
 "bus ou électron libre)"
 
-#: apps/wei/forms/registration.py:75 apps/wei/forms/registration.py:85
+#: apps/wei/forms/registration.py:76 apps/wei/forms/registration.py:91
 #: apps/wei/models.py:160
 msgid "WEI Roles"
 msgstr "Rôles au WEI"
 
-#: apps/wei/forms/registration.py:76
+#: apps/wei/forms/registration.py:77
 msgid "Select the roles that you are interested in."
 msgstr "Sélectionnez les rôles qui vous intéressent."
 
-#: apps/wei/forms/registration.py:122
+#: apps/wei/forms/registration.py:86 apps/wei/models.py:188
+msgid "Caution check given"
+msgstr "Chèque de caution donné"
+
+#: apps/wei/forms/registration.py:128
 msgid "This team doesn't belong to the given bus."
 msgstr "Cette équipe n'appartient pas à ce bus."
 
@@ -2948,10 +2990,12 @@ msgid "year"
 msgstr "année"
 
 #: apps/wei/models.py:29 apps/wei/templates/wei/base.html:30
+#: apps/wrapped/models.py:20
 msgid "date start"
 msgstr "début"
 
 #: apps/wei/models.py:33 apps/wei/templates/wei/base.html:33
+#: apps/wrapped/models.py:24
 msgid "date end"
 msgstr "fin"
 
@@ -3001,11 +3045,6 @@ msgstr "Rôle au WEI"
 msgid "Credit from Société générale"
 msgstr "Crédit de la Société générale"
 
-#: apps/wei/models.py:188
-#: apps/wei/forms/registration.py:84
-msgid "Caution check given"
-msgstr "Chèque de caution donné"
-
 #: apps/wei/models.py:192 apps/wei/templates/wei/weimembership_form.html:64
 msgid "birth date"
 msgstr "date de naissance"
@@ -3039,8 +3078,7 @@ msgstr "coupe de vêtement"
 msgid "clothing size"
 msgstr "taille de vêtement"
 
-#: apps/wei/models.py:232 apps/wei/templates/wei/attribute_bus_1A.html:28
-#: apps/wei/templates/wei/weimembership_form.html:67
+#: apps/wei/models.py:232
 msgid "health issues"
 msgstr "problèmes de santé"
 
@@ -3160,13 +3198,22 @@ msgid "Attribute first year members into buses"
 msgstr "Attribuer les 1A dans les bus"
 
 #: apps/wei/templates/wei/1A_list.html:15
-msgid "Start attribution!"
+#, fuzzy
+#| msgid "Start attribution!"
+msgid "Start attribution !"
 msgstr "Démarrer l'attribution !"
 
 #: apps/wei/templates/wei/attribute_bus_1A.html:8
 msgid "Bus attribution"
 msgstr "Répartition des bus"
 
+#: apps/wei/templates/wei/attribute_bus_1A.html:28
+#: apps/wei/templates/wei/weimembership_form.html:67
+#, fuzzy
+#| msgid "health issues"
+msgid "health issues or specific diet"
+msgstr "problèmes de santé"
+
 #: apps/wei/templates/wei/attribute_bus_1A.html:31
 msgid "suggested bus"
 msgstr "bus suggéré"
@@ -3195,11 +3242,11 @@ msgstr "Prix du WEI (étudiant⋅es)"
 msgid "WEI list"
 msgstr "Liste des WEI"
 
-#: apps/wei/templates/wei/base.html:81 apps/wei/views.py:528
+#: apps/wei/templates/wei/base.html:81 apps/wei/views.py:540
 msgid "Register 1A"
 msgstr "Inscrire un⋅e 1A"
 
-#: apps/wei/templates/wei/base.html:85 apps/wei/views.py:614
+#: apps/wei/templates/wei/base.html:85 apps/wei/views.py:626
 msgid "Register 2A+"
 msgstr "Inscrire un⋅e 2A+"
 
@@ -3228,8 +3275,8 @@ msgstr "Télécharger au format PDF"
 
 #: apps/wei/templates/wei/survey.html:11
 #: apps/wei/templates/wei/survey_closed.html:11
-#: apps/wei/templates/wei/survey_end.html:11 apps/wei/views.py:1028
-#: apps/wei/views.py:1083 apps/wei/views.py:1130
+#: apps/wei/templates/wei/survey_end.html:11 apps/wei/views.py:1046
+#: apps/wei/views.py:1101 apps/wei/views.py:1148
 msgid "Survey WEI"
 msgstr "Questionnaire WEI"
 
@@ -3274,7 +3321,7 @@ msgstr "Inscriptions non validées"
 msgid "Attribute buses"
 msgstr "Répartition dans les bus"
 
-#: apps/wei/templates/wei/weiclub_list.html:14 apps/wei/views.py:79
+#: apps/wei/templates/wei/weiclub_list.html:14 apps/wei/views.py:80
 msgid "Create WEI"
 msgstr "Créer un WEI"
 
@@ -3408,70 +3455,72 @@ msgid "There is no pre-registration found with this pattern."
 msgstr "Il n'y a pas de pré-inscription en attente avec cette entrée."
 
 #: apps/wei/templates/wei/weiregistration_list.html:27
-msgid "View validated membershipis..."
+#, fuzzy
+#| msgid "View validated membershipis..."
+msgid "View validated memberships..."
 msgstr "Voir les adhésions validées..."
 
-#: apps/wei/views.py:58
+#: apps/wei/views.py:59
 msgid "Search WEI"
 msgstr "Chercher un WEI"
 
-#: apps/wei/views.py:109
+#: apps/wei/views.py:110
 msgid "WEI Detail"
 msgstr "Détails du WEI"
 
-#: apps/wei/views.py:208
+#: apps/wei/views.py:210
 msgid "View members of the WEI"
 msgstr "Voir les membres du WEI"
 
-#: apps/wei/views.py:236
+#: apps/wei/views.py:243
 msgid "Find WEI Membership"
 msgstr "Trouver une adhésion au WEI"
 
-#: apps/wei/views.py:246
+#: apps/wei/views.py:253
 msgid "View registrations to the WEI"
 msgstr "Voir les inscriptions au WEI"
 
-#: apps/wei/views.py:270
+#: apps/wei/views.py:282
 msgid "Find WEI Registration"
 msgstr "Trouver une inscription au WEI"
 
-#: apps/wei/views.py:281
+#: apps/wei/views.py:293
 msgid "Update the WEI"
 msgstr "Modifier le WEI"
 
-#: apps/wei/views.py:302
+#: apps/wei/views.py:314
 msgid "Create new bus"
 msgstr "Ajouter un nouveau bus"
 
-#: apps/wei/views.py:340
+#: apps/wei/views.py:352
 msgid "Update bus"
 msgstr "Modifier le bus"
 
-#: apps/wei/views.py:372
+#: apps/wei/views.py:384
 msgid "Manage bus"
 msgstr "Gérer le bus"
 
-#: apps/wei/views.py:399
+#: apps/wei/views.py:411
 msgid "Create new team"
 msgstr "Créer une nouvelle équipe"
 
-#: apps/wei/views.py:439
+#: apps/wei/views.py:451
 msgid "Update team"
 msgstr "Modifier l'équipe"
 
-#: apps/wei/views.py:470
+#: apps/wei/views.py:482
 msgid "Manage WEI team"
 msgstr "Gérer l'équipe WEI"
 
-#: apps/wei/views.py:492
+#: apps/wei/views.py:504
 msgid "Register first year student to the WEI"
 msgstr "Inscrire un⋅e 1A au WEI"
 
-#: apps/wei/views.py:550 apps/wei/views.py:649
+#: apps/wei/views.py:562 apps/wei/views.py:661
 msgid "This user is already registered to this WEI."
 msgstr "Cette personne est déjà inscrite au WEI."
 
-#: apps/wei/views.py:555
+#: apps/wei/views.py:567
 msgid ""
 "This user can't be in her/his first year since he/she has already "
 "participated to a WEI."
@@ -3479,51 +3528,214 @@ msgstr ""
 "Cet⋅te utilisateur⋅rice ne peut pas être en première année puisqu'iel a déjà "
 "participé à un WEI."
 
-#: apps/wei/views.py:578
+#: apps/wei/views.py:590
 msgid "Register old student to the WEI"
 msgstr "Inscrire un⋅e 2A+ au WEI"
 
-#: apps/wei/views.py:633 apps/wei/views.py:721
+#: apps/wei/views.py:645 apps/wei/views.py:733
 msgid "You already opened an account in the Société générale."
 msgstr "Vous avez déjà ouvert un compte auprès de la société générale."
 
-#: apps/wei/views.py:685
+#: apps/wei/views.py:697
 msgid "Update WEI Registration"
 msgstr "Modifier l'inscription WEI"
 
-#: apps/wei/views.py:795
+#: apps/wei/views.py:807
 msgid "Delete WEI registration"
 msgstr "Supprimer l'inscription WEI"
 
-#: apps/wei/views.py:806
+#: apps/wei/views.py:818
 msgid "You don't have the right to delete this WEI registration."
 msgstr "Vous n'avez pas la permission de supprimer cette inscription au WEI."
 
-#: apps/wei/views.py:824
+#: apps/wei/views.py:836
 msgid "Validate WEI registration"
 msgstr "Valider l'inscription WEI"
 
-#: apps/wei/views.py:1223
+#: apps/wei/views.py:1241
 msgid "Attribute buses to first year members"
 msgstr "Répartir les 1A dans les bus"
 
-#: apps/wei/views.py:1248
+#: apps/wei/views.py:1266
 msgid "Attribute bus"
 msgstr "Attribuer un bus"
 
-#: note_kfet/settings/base.py:173
+#: apps/wrapped/apps.py:10
+msgid "wrapped"
+msgstr "wrapped"
+
+#: apps/wrapped/models.py:40
+msgid "generated"
+msgstr "generé"
+
+#: apps/wrapped/models.py:45
+msgid "public"
+msgstr "public"
+
+#: apps/wrapped/models.py:53
+msgid "bde"
+msgstr "bde"
+
+#: apps/wrapped/models.py:65
+msgid "data json"
+msgstr "donnée json"
+
+#: apps/wrapped/models.py:66
+msgid "data in the wrapped and generated by the script generate_wrapped"
+msgstr "donnée dans le wrapped et générée par le script generate_wrapped"
+
+#: apps/wrapped/models.py:70 note_kfet/templates/base.html:114
+msgid "Wrapped"
+msgstr "Wrapped"
+
+#: apps/wrapped/models.py:71
+msgid "Wrappeds"
+msgstr "Wrappeds"
+
+#: apps/wrapped/tables.py:40
+msgid "view the wrapped"
+msgstr "voir le wrapped"
+
+#: apps/wrapped/tables.py:55
+msgid "Click to make this wrapped private"
+msgstr "Cliquer pour rendre ce wrapped privé"
+
+#: apps/wrapped/tables.py:56
+msgid "Click to make this wrapped public"
+msgstr "Cliquer pour rendre ce wrapped public"
+
+#: apps/wrapped/tables.py:67
+msgid "Share"
+msgstr "Partager"
+
+#: apps/wrapped/tables.py:73
+msgid "Click to copy the link in the press paper"
+msgstr "Cliquer pour copier le lien"
+
+#: apps/wrapped/tables.py:81
+msgid "Copy link"
+msgstr "Copier le lien"
+
+#: apps/wrapped/templates/wrapped/1/wrapped_base.html:16
+#: note_kfet/templates/base.html:14
+msgid "The ENS Paris-Saclay BDE note."
+msgstr "La note du BDE de l'ENS Paris-Saclay."
+
+#: apps/wrapped/templates/wrapped/1/wrapped_base.html:58
+msgid "The NoteKfet this year it's also"
+msgstr "La NoteKfet cette année, c'est aussi :"
+
+#: apps/wrapped/templates/wrapped/1/wrapped_base.html:60
+msgid " transactions"
+msgstr " transactions"
+
+#: apps/wrapped/templates/wrapped/1/wrapped_base.html:61
+msgid " parties"
+msgstr " soirées"
+
+#: apps/wrapped/templates/wrapped/1/wrapped_base.html:62
+msgid " Pot entries"
+msgstr " entrées au Pot"
+
+#: apps/wrapped/templates/wrapped/1/wrapped_base.html:72
+msgid " old dickhead behind the bar"
+msgstr " vieilleux con·ne·s derrière le bar"
+
+#: apps/wrapped/templates/wrapped/1/wrapped_view_club.html:9
+#: apps/wrapped/templates/wrapped/1/wrapped_view_user.html:9
+msgid "NoteKfet Wrapped"
+msgstr "NoteKfet Wrapped"
+
+#: apps/wrapped/templates/wrapped/1/wrapped_view_club.html:11
+msgid "Your best consumer:"
+msgstr "Ton plus gros consommateur :"
+
+#: apps/wrapped/templates/wrapped/1/wrapped_view_club.html:13
+msgid "Your worst creditor:"
+msgstr "Ton pire créancier :"
+
+#: apps/wrapped/templates/wrapped/1/wrapped_view_club.html:16
+msgid "party·ies organised"
+msgstr "soirée·s organisée·s"
+
+#: apps/wrapped/templates/wrapped/1/wrapped_view_club.html:17
+msgid "distinct members"
+msgstr "Membres distinct·e·s"
+
+#: apps/wrapped/templates/wrapped/1/wrapped_view_user.html:13
+msgid "You participate to the wei: "
+msgstr "Tu as participé au wei : "
+
+#: apps/wrapped/templates/wrapped/1/wrapped_view_user.html:13
+msgid "in the"
+msgstr "dans le"
+
+#: apps/wrapped/templates/wrapped/1/wrapped_view_user.html:18
+msgid "pots !"
+msgstr "pots !"
+
+#: apps/wrapped/templates/wrapped/1/wrapped_view_user.html:27
+msgid "Your first conso of the year: "
+msgstr "Ta première conso de l'année : "
+
+#: apps/wrapped/templates/wrapped/1/wrapped_view_user.html:28
+msgid "Your prefered consumtion category: "
+msgstr "Ta catégorie de bouton préférée : "
+
+#: apps/wrapped/templates/wrapped/1/wrapped_view_user.html:41
+msgid ": it's the number of time your reload your note"
+msgstr ": c'est le nombre de fois où tu as rechargé·e ta note"
+
+#: apps/wrapped/templates/wrapped/1/wrapped_view_user.html:44
+msgid "Your overall expenses: "
+msgstr "Tes dépenses totales : "
+
+#: apps/wrapped/templates/wrapped/1/wrapped_view_user.html:47
+#: apps/wrapped/templates/wrapped/1/wrapped_view_user.html:60
+msgid "with"
+msgstr "avec"
+
+#: apps/wrapped/templates/wrapped/1/wrapped_view_user.html:57
+msgid "Your expenses to BDE: "
+msgstr "Tes dépenses au BDE : "
+
+#: apps/wrapped/templates/wrapped/wrapped_list.html:26
+msgid ""
+"Do not forget to ask permission to people who are in your wrapped before to "
+"make them public"
+msgstr ""
+"N'oublies pas de demander la permission des personnes apparaissant dans un "
+"wrapped avant de le rendre public"
+
+#: apps/wrapped/templates/wrapped/wrapped_list.html:33
+msgid "Link copied"
+msgstr "Lien copié"
+
+#: apps/wrapped/templates/wrapped/wrapped_list.html:58
+msgid "Wrapped is private"
+msgstr "Le wrapped est privé"
+
+#: apps/wrapped/templates/wrapped/wrapped_list.html:59
+msgid "Wrapped is public"
+msgstr "Le wrapped est public"
+
+#: apps/wrapped/views.py:24
+msgid "List of wrapped"
+msgstr "Liste des wrapped"
+
+#: note_kfet/settings/base.py:177
 msgid "German"
 msgstr "Allemand"
 
-#: note_kfet/settings/base.py:174
+#: note_kfet/settings/base.py:178
 msgid "English"
 msgstr "Anglais"
 
-#: note_kfet/settings/base.py:175
+#: note_kfet/settings/base.py:179
 msgid "Spanish"
 msgstr "Espagnol"
 
-#: note_kfet/settings/base.py:176
+#: note_kfet/settings/base.py:180
 msgid "French"
 msgstr "Français"
 
@@ -3575,19 +3787,15 @@ msgid ""
 "sent to webmasters with the detail of the error, and this will be fixed "
 "soon. You can now drink a beer."
 msgstr ""
-"Désolé, une erreur est survenue lors de l'analyse de votre requête. Un e-mail "
-"a été envoyé aux responsables de la plateforme avec les détails de cette "
-"erreur, qui sera corrigée rapidement. Vous pouvez désormais aller boire une "
-"bière, avec modération."
+"Désolé, une erreur est survenue lors de l'analyse de votre requête. Un e-"
+"mail a été envoyé aux responsables de la plateforme avec les détails de "
+"cette erreur, qui sera corrigée rapidement. Vous pouvez désormais aller "
+"boire une bière, avec modération."
 
 #: note_kfet/templates/autocomplete_model.html:15
 msgid "Reset"
 msgstr "Réinitialiser"
 
-#: note_kfet/templates/base.html:14
-msgid "The ENS Paris-Saclay BDE note."
-msgstr "La note du BDE de l'ENS Paris-Saclay."
-
 #: note_kfet/templates/base.html:72
 msgid "Food"
 msgstr "Bouffe"
@@ -3600,26 +3808,26 @@ msgstr "Utilisateur·rices"
 msgid "Clubs"
 msgstr "Clubs"
 
-#: note_kfet/templates/base.html:119
+#: note_kfet/templates/base.html:125
 msgid "Admin"
 msgstr "Admin"
 
-#: note_kfet/templates/base.html:133
+#: note_kfet/templates/base.html:139
 msgid "My account"
 msgstr "Mon compte"
 
-#: note_kfet/templates/base.html:136
+#: note_kfet/templates/base.html:142
 msgid "Log out"
 msgstr "Se déconnecter"
 
-#: note_kfet/templates/base.html:144
+#: note_kfet/templates/base.html:150
 #: note_kfet/templates/registration/signup.html:6
 #: note_kfet/templates/registration/signup.html:11
 #: note_kfet/templates/registration/signup.html:28
 msgid "Sign up"
 msgstr "Inscription"
 
-#: note_kfet/templates/base.html:151
+#: note_kfet/templates/base.html:157
 #: note_kfet/templates/registration/login.html:6
 #: note_kfet/templates/registration/login.html:15
 #: note_kfet/templates/registration/login.html:38
@@ -3627,7 +3835,7 @@ msgstr "Inscription"
 msgid "Log in"
 msgstr "Se connecter"
 
-#: note_kfet/templates/base.html:165
+#: note_kfet/templates/base.html:171
 msgid ""
 "You are not a BDE member anymore. Please renew your membership if you want "
 "to use the note."
@@ -3635,7 +3843,7 @@ msgstr ""
 "Vous n'êtes plus adhérent·e BDE. Merci de réadhérer si vous voulez profiter "
 "de la note."
 
-#: note_kfet/templates/base.html:171
+#: note_kfet/templates/base.html:177
 msgid ""
 "Your e-mail address is not validated. Please check your mail inbox and click "
 "on the validation link."
@@ -3643,7 +3851,7 @@ msgstr ""
 "Votre adresse e-mail n'est pas validée. Merci de vérifier votre boîte mail "
 "et de cliquer sur le lien de validation."
 
-#: note_kfet/templates/base.html:177
+#: note_kfet/templates/base.html:183
 msgid ""
 "You declared that you opened a bank account in the Société générale. The "
 "bank did not validate the creation of the account to the BDE, so the "
@@ -3657,19 +3865,19 @@ msgstr ""
 "vérification peut durer quelques jours. Merci de vous assurer de bien aller "
 "au bout de vos démarches."
 
-#: note_kfet/templates/base.html:200
+#: note_kfet/templates/base.html:206
 msgid "Contact us"
 msgstr "Nous contacter"
 
-#: note_kfet/templates/base.html:202
+#: note_kfet/templates/base.html:208
 msgid "Technical Support"
 msgstr "Support technique"
 
-#: note_kfet/templates/base.html:204
+#: note_kfet/templates/base.html:210
 msgid "Charte Info (FR)"
 msgstr "Charte Info (FR)"
 
-#: note_kfet/templates/base.html:206
+#: note_kfet/templates/base.html:212
 msgid "FAQ (FR)"
 msgstr "FAQ (FR)"
 
diff --git a/locale/fr/LC_MESSAGES/djangojs.po b/locale/fr/LC_MESSAGES/djangojs.po
index 90f85fc4..59989ae6 100644
--- a/locale/fr/LC_MESSAGES/djangojs.po
+++ b/locale/fr/LC_MESSAGES/djangojs.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2022-10-07 09:07+0200\n"
+"POT-Creation-Date: 2025-02-25 13:27+0100\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,11 +17,11 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
 
-#: apps/member/static/member/js/alias.js:17
+#: apps/activity/static/activity/js/opener.js:31
 msgid "Opener successfully added"
 msgstr "Ouvreureuse ajouté avec succès"
 
-#: apps/member/static/member/js/alias.js:17
+#: apps/activity/static/activity/js/opener.js:47
 msgid "Opener successfully deleted"
 msgstr "Ouvreureuse supprimé avec succès"
 
diff --git a/note_kfet/settings/base.py b/note_kfet/settings/base.py
index 8378448d..113cf626 100644
--- a/note_kfet/settings/base.py
+++ b/note_kfet/settings/base.py
@@ -79,6 +79,7 @@ INSTALLED_APPS = [
     'scripts',
     'treasury',
     'wei',
+    'wrapped',
 ]
 
 MIDDLEWARE = [
diff --git a/note_kfet/templates/base.html b/note_kfet/templates/base.html
index a84f29b2..1c601c50 100644
--- a/note_kfet/templates/base.html
+++ b/note_kfet/templates/base.html
@@ -107,6 +107,12 @@ SPDX-License-Identifier: GPL-3.0-or-later
                             {% url 'wei:current_wei_detail' as url %}
                             <a class="nav-link {% if request.path_info == url %}active{% endif %}" href="{{ url }}"><i class="fa fa-bus"></i> {% trans 'WEI' %}</a>
                         </li>
+		    {% endif %}
+		    {% if "wrapped.wrapped"|model_list_length >= 1 %}
+			<li class="nav-item">
+			    {% url 'wrapped:wrapped_list' as url %}
+			    <a class="nav-link {% if request.path_info == url %}active{% endif %}" href="{{ url }}"><i class="fa fa-gift"></i> {% trans 'Wrapped' %}</a>
+			</li>
                     {% endif %}
                     {% if request.user.is_authenticated %}
                         <li class="nav-item">
diff --git a/note_kfet/urls.py b/note_kfet/urls.py
index b2b64dcf..3bc3da41 100644
--- a/note_kfet/urls.py
+++ b/note_kfet/urls.py
@@ -22,6 +22,7 @@ urlpatterns = [
     path('treasury/', include('treasury.urls')),
     path('wei/', include('wei.urls')),
     path('food/',include('food.urls')),
+    path('wrapped/',include('wrapped.urls')),
 
     # Include Django Contrib and Core routers
     path('i18n/', include('django.conf.urls.i18n')),
diff --git a/tox.ini b/tox.ini
index 924ea514..1bfeb593 100644
--- a/tox.ini
+++ b/tox.ini
@@ -32,7 +32,8 @@ deps =
     pep8-naming
     pyflakes
 commands =
-    flake8 apps --extend-exclude apps/scripts
+    flake8 apps --extend-exclude apps/scripts,apps/wrapped/management/commands
+    flake8 apps/wrapped/management/commands --extend-ignore=C901
 
 [flake8]
 ignore = W503, I100, I101, B019