Many updates

This commit is contained in:
Naiel
2026-03-16 22:51:13 +00:00
parent d4c17fc219
commit 174276da04
195 changed files with 583 additions and 12788 deletions

View File

@@ -1,6 +1,6 @@
from django.contrib import admin from django.contrib import admin
from .models import Aulario, ComedorMenu, ComedorMenuType, StudentAttachment from .models import Aulario, ComedorMenu, ComedorMenuType, Cuaderno, StudentAttachment
@admin.register(Aulario) @admin.register(Aulario)
@@ -30,4 +30,11 @@ class ComedorMenuTypeAdmin(admin.ModelAdmin):
list_display = ("org_id", "source_aulario_id", "type_id", "label", "color", "created_by") list_display = ("org_id", "source_aulario_id", "type_id", "label", "color", "created_by")
search_fields = ("org_id", "source_aulario_id", "type_id", "label", "created_by") search_fields = ("org_id", "source_aulario_id", "type_id", "label", "created_by")
list_filter = ("org_id", "source_aulario_id", "created_at") list_filter = ("org_id", "source_aulario_id", "created_at")
filter_horizontal = ("shared_aularios",) filter_horizontal = ("shared_aularios",)
@admin.register(Cuaderno)
class CuadernoAdmin(admin.ModelAdmin):
list_display = ("org_id", "aulario_id", "alumno", "titulo", "created_by", "updated_at")
search_fields = ("org_id", "aulario_id", "alumno", "titulo", "created_by", "updated_by")
list_filter = ("org_id", "aulario_id", "created_at", "updated_at")

View File

@@ -0,0 +1,30 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("aulatek", "0005_comedormenutype"),
]
operations = [
migrations.CreateModel(
name="Cuaderno",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("org_id", models.TextField()),
("aulario_id", models.TextField()),
("alumno", models.TextField(default="")),
("titulo", models.TextField(default="")),
("contenido_encriptado", models.TextField(default="")),
("pin_hash", models.TextField(default="")),
("pin_salt", models.TextField(default="")),
("created_by", models.TextField(default="")),
("updated_by", models.TextField(default="")),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
],
options={
"db_table": "aulatek_cuadernos",
},
),
]

View File

@@ -104,6 +104,28 @@ class ComedorMenuType(models.Model):
return f"{self.org_id}/{self.source_aulario_id}/{self.type_id}" return f"{self.org_id}/{self.source_aulario_id}/{self.type_id}"
class Cuaderno(models.Model):
org_id = models.TextField()
aulario_id = models.TextField()
alumno = models.TextField(default="")
titulo = models.TextField(default="")
contenido_encriptado = models.TextField(default="")
pin_hash = models.TextField(default="")
pin_salt = models.TextField(default="")
created_by = models.TextField(default="")
updated_by = models.TextField(default="")
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
db_table = "aulatek_cuadernos"
def __str__(self):
alumno = self.alumno or "sin-alumno"
titulo = self.titulo or "sin-titulo"
return f"{self.org_id}/{self.aulario_id}/{alumno}/{titulo}"
class Aulario(CoreAulario): class Aulario(CoreAulario):
class Meta: class Meta:
proxy = True proxy = True

View File

@@ -10,6 +10,9 @@ urlpatterns = [
path("aulario/", views.aulatek_aulario, name="aulatek_aulario"), path("aulario/", views.aulatek_aulario, name="aulatek_aulario"),
path("paneldiario/", views.paneldiario, name="paneldiario"), path("paneldiario/", views.paneldiario, name="paneldiario"),
path("alumnos/", views.alumnos, name="alumnos"), path("alumnos/", views.alumnos, name="alumnos"),
path("cuadernos/", views.cuadernos, name="cuadernos"),
path("cuadernos/new/", views.cuaderno_new, name="cuaderno_new"),
path("cuadernos/<int:cuaderno_id>/", views.cuaderno_edit, name="cuaderno_edit"),
path("alumnos/new/", views.alumno_new, name="alumno_new"), path("alumnos/new/", views.alumno_new, name="alumno_new"),
path("alumnos/edit/<int:student_id>/", views.alumno_edit, name="alumno_edit"), path("alumnos/edit/<int:student_id>/", views.alumno_edit, name="alumno_edit"),
path("alumnos/delete/<int:student_id>/", views.alumno_delete, name="alumno_delete"), path("alumnos/delete/<int:student_id>/", views.alumno_delete, name="alumno_delete"),

View File

@@ -12,7 +12,7 @@ from django.shortcuts import redirect, render
from core.models import Aulario from core.models import Aulario
from core.shell import require_axia_login, shell_context from core.shell import require_axia_login, shell_context
from .models import ComedorMenu, ComedorMenuType, StudentAttachment from .models import ComedorMenu, ComedorMenuType, Cuaderno, StudentAttachment
def _safe_organization_id(value: str) -> str: def _safe_organization_id(value: str) -> str:
@@ -48,6 +48,13 @@ def _alumnos_permission(request: HttpRequest) -> bool:
) )
def _cuadernos_permission(request: HttpRequest) -> bool:
return (
request.axia_user.has_permission("aulatek:docente")
or request.axia_user.has_permission("entreaulas:docente")
)
def _alumnos_access(request: HttpRequest): def _alumnos_access(request: HttpRequest):
gate = require_axia_login(request) gate = require_axia_login(request)
if gate: if gate:
@@ -60,6 +67,15 @@ def _alumnos_access(request: HttpRequest):
return None, request.axia_user, org_id return None, request.axia_user, org_id
def _cuadernos_access(request: HttpRequest):
gate, user, org_id = _alumnos_access(request)
if gate:
return gate, None, None
if not _cuadernos_permission(request):
return HttpResponseForbidden("No tienes permiso para ver cuadernos."), None, None
return None, user, org_id
def _comedor_access(request: HttpRequest): def _comedor_access(request: HttpRequest):
gate, user, org_id = _alumnos_access(request) gate, user, org_id = _alumnos_access(request)
if gate: if gate:
@@ -83,6 +99,16 @@ def _parse_menu_date(value: str):
return None return None
def _safe_titulo(value: str) -> str:
value = (value or "").strip()
value = re.sub(r"[\x00-\x1F\x7F]", "", value)
return value[:140]
def _signature_verified(request: HttpRequest) -> bool:
return (request.POST.get("_firma_signed") or "") == "1"
def aulatek_home(request: HttpRequest): def aulatek_home(request: HttpRequest):
gate = require_axia_login(request) gate = require_axia_login(request)
if gate: if gate:
@@ -139,6 +165,13 @@ def aulatek_aulario(request: HttpRequest):
"variant": "info", "variant": "info",
"visible": _alumnos_permission(request), "visible": _alumnos_permission(request),
}, },
{
"href": f"/aulatek/cuadernos/?aulario={aulario_id}",
"label": "Cuadernos",
"icon": "/static/iconexperience/contract.png",
"variant": "dark",
"visible": _cuadernos_permission(request),
},
{ {
"href": f"/sysadmin/aularios/?aulario={aulario_id}", "href": f"/sysadmin/aularios/?aulario={aulario_id}",
"label": "Cambiar Ajustes", "label": "Cambiar Ajustes",
@@ -198,6 +231,7 @@ def alumnos(request: HttpRequest):
"module_title": "Gestion de Alumnos", "module_title": "Gestion de Alumnos",
"aulario_id": aulario_id, "aulario_id": aulario_id,
"students": students, "students": students,
"can_view_cuadernos": _cuadernos_permission(request),
} }
) )
return render(request, "aulatek/alumnos.html", context) return render(request, "aulatek/alumnos.html", context)
@@ -283,6 +317,8 @@ def alumno_delete(request: HttpRequest, student_id: int):
return gate return gate
if request.method != "POST": if request.method != "POST":
return HttpResponseForbidden("Metodo no permitido.") return HttpResponseForbidden("Metodo no permitido.")
if not _signature_verified(request):
return HttpResponseForbidden("Firma requerida para eliminar.")
student = StudentAttachment.objects.filter(id=student_id, org_id=org_id).first() student = StudentAttachment.objects.filter(id=student_id, org_id=org_id).first()
if not student: if not student:
@@ -313,6 +349,148 @@ def alumno_photo(request: HttpRequest, student_id: int):
return FileResponse(student.photo.open("rb"), content_type=mime_type or "application/octet-stream") return FileResponse(student.photo.open("rb"), content_type=mime_type or "application/octet-stream")
def cuadernos(request: HttpRequest):
gate, _, org_id = _cuadernos_access(request)
if gate:
return gate
aulario_id = _safe_aulario_id(request.GET.get("aulario", ""))
context = shell_context(request, "aulatek", "Cuadernos")
if not aulario_id or not org_id:
context.update(
{
"module_title": "Cuadernos",
"aulario_id": "",
"cuadernos": [],
"alumnos": [],
}
)
return render(request, "aulatek/cuadernos.html", context)
if not Aulario.objects.filter(org_id=org_id, aulario_id=aulario_id).exists():
raise Http404("Aulario no encontrado")
cuadernos_rows = Cuaderno.objects.filter(org_id=org_id, aulario_id=aulario_id).order_by("-updated_at", "-created_at")
context.update(
{
"module_title": "Cuadernos",
"aulario_id": aulario_id,
"cuadernos": cuadernos_rows,
}
)
return render(request, "aulatek/cuadernos.html", context)
def cuaderno_new(request: HttpRequest):
gate, user, org_id = _cuadernos_access(request)
if gate:
return gate
aulario_id = _safe_aulario_id(request.GET.get("aulario", ""))
if not aulario_id or not org_id:
messages.error(request, "No se ha indicado un aulario valido.")
return redirect("/aulatek/")
if not Aulario.objects.filter(org_id=org_id, aulario_id=aulario_id).exists():
raise Http404("Aulario no encontrado")
if request.method == "POST":
titulo = _safe_titulo(request.POST.get("titulo", ""))
alumno = _safe_alumno_name(request.POST.get("alumno", ""))
contenido = (request.POST.get("contenido") or "").strip()
if not titulo:
messages.error(request, "El titulo es obligatorio.")
return redirect(f"/aulatek/cuadernos/new/?aulario={aulario_id}")
if not contenido:
messages.error(request, "El contenido no puede estar vacio.")
return redirect(f"/aulatek/cuadernos/new/?aulario={aulario_id}")
Cuaderno.objects.create(
org_id=org_id,
aulario_id=aulario_id,
alumno=alumno,
titulo=titulo,
contenido_encriptado=contenido,
pin_hash="",
pin_salt="",
created_by=user.username if user else "",
updated_by=user.username if user else "",
)
messages.success(request, "Cuaderno creado correctamente.")
return redirect(f"/aulatek/cuadernos/?aulario={aulario_id}")
alumnos_rows = StudentAttachment.objects.filter(org_id=org_id, aulario_id=aulario_id).order_by("alumno")
context = shell_context(request, "aulatek", "Nuevo Cuaderno")
context.update(
{
"module_title": "Nuevo Cuaderno",
"aulario_id": aulario_id,
"alumnos": [row.alumno for row in alumnos_rows],
}
)
return render(request, "aulatek/cuaderno_new.html", context)
def cuaderno_edit(request: HttpRequest, cuaderno_id: int):
gate, user, org_id = _cuadernos_access(request)
if gate:
return gate
cuaderno = Cuaderno.objects.filter(id=cuaderno_id, org_id=org_id).first()
if not cuaderno:
raise Http404("Cuaderno no encontrado")
aulario_id = cuaderno.aulario_id
decrypted_content = cuaderno.contenido_encriptado or ""
if request.method == "POST":
action = (request.POST.get("action") or "unlock").strip().lower()
if action == "unlock":
return redirect(f"/aulatek/cuadernos/{cuaderno.id}/")
if action == "update":
titulo = _safe_titulo(request.POST.get("titulo", ""))
alumno = _safe_alumno_name(request.POST.get("alumno", ""))
contenido = (request.POST.get("contenido") or "").strip()
if not titulo:
messages.error(request, "El titulo es obligatorio.")
return redirect(f"/aulatek/cuadernos/{cuaderno.id}/")
if not contenido:
messages.error(request, "El contenido no puede estar vacio.")
return redirect(f"/aulatek/cuadernos/{cuaderno.id}/")
cuaderno.titulo = titulo
cuaderno.alumno = alumno
cuaderno.pin_salt = ""
cuaderno.pin_hash = ""
cuaderno.contenido_encriptado = contenido
cuaderno.updated_by = user.username if user else ""
cuaderno.save(update_fields=["titulo", "alumno", "pin_hash", "pin_salt", "contenido_encriptado", "updated_by", "updated_at"])
messages.success(request, "Cuaderno actualizado correctamente.")
return redirect(f"/aulatek/cuadernos/{cuaderno.id}/")
if action == "delete":
if not _signature_verified(request):
messages.error(request, "Firma requerida para eliminar el cuaderno.")
return redirect(f"/aulatek/cuadernos/{cuaderno.id}/")
cuaderno.delete()
messages.success(request, "Cuaderno eliminado.")
return redirect(f"/aulatek/cuadernos/?aulario={aulario_id}")
context = shell_context(request, "aulatek", f"Cuaderno: {cuaderno.titulo}")
context.update(
{
"module_title": "Editar Cuaderno",
"cuaderno": cuaderno,
"aulario_id": aulario_id,
"decrypted_content": decrypted_content,
}
)
return render(request, "aulatek/cuaderno_edit.html", context)
def comedor(request: HttpRequest): def comedor(request: HttpRequest):
gate, user, org_id, aulario_row = _comedor_access(request) gate, user, org_id, aulario_row = _comedor_access(request)
if gate: if gate:
@@ -400,6 +578,8 @@ def comedor(request: HttpRequest):
return redirect(comedor_url(selected_date, row.type_id)) return redirect(comedor_url(selected_date, row.type_id))
if action == "delete_type": if action == "delete_type":
if not _signature_verified(request):
return HttpResponseForbidden("Firma requerida para eliminar tipo.")
delete_id = (request.POST.get("delete_type_id") or "").strip() delete_id = (request.POST.get("delete_type_id") or "").strip()
row = ComedorMenuType.objects.filter(org_id=org_id, source_aulario_id=aulario_row.aulario_id, type_id=delete_id).first() row = ComedorMenuType.objects.filter(org_id=org_id, source_aulario_id=aulario_row.aulario_id, type_id=delete_id).first()
if row: if row:
@@ -475,6 +655,8 @@ def comedor(request: HttpRequest):
if action == "delete": if action == "delete":
if not selected_type_row or not can_edit_selected_type: if not selected_type_row or not can_edit_selected_type:
return HttpResponseForbidden("No puedes eliminar menu de un tipo compartido.") return HttpResponseForbidden("No puedes eliminar menu de un tipo compartido.")
if not _signature_verified(request):
return HttpResponseForbidden("Firma requerida para eliminar menu.")
menu_id = int(request.POST.get("menu_id") or 0) menu_id = int(request.POST.get("menu_id") or 0)
menu = ComedorMenu.objects.filter( menu = ComedorMenu.objects.filter(
id=menu_id, id=menu_id,

View File

@@ -87,7 +87,7 @@ USE_I18N = True
USE_TZ = True USE_TZ = True
STATIC_URL = "/static/" STATIC_URL = "/static/"
STATICFILES_DIRS = [REPO_ROOT / "public_html" / "static"] STATICFILES_DIRS = [BASE_DIR / "static"]
MEDIA_URL = "/media/" MEDIA_URL = "/media/"
MEDIA_ROOT = DATA_ROOT / "attachments" MEDIA_ROOT = DATA_ROOT / "attachments"

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 411 B

After

Width:  |  Height:  |  Size: 411 B

View File

Before

Width:  |  Height:  |  Size: 353 B

After

Width:  |  Height:  |  Size: 353 B

View File

Before

Width:  |  Height:  |  Size: 172 B

After

Width:  |  Height:  |  Size: 172 B

View File

Before

Width:  |  Height:  |  Size: 194 B

After

Width:  |  Height:  |  Size: 194 B

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

View File

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View File

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 59 KiB

View File

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View File

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 57 KiB

View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View File

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 77 KiB

View File

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

View File

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

View File

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

View File

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

View File

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

View File

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

View File

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

View File

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 63 KiB

View File

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 72 KiB

View File

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

View File

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 61 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

Before

Width:  |  Height:  |  Size: 347 KiB

After

Width:  |  Height:  |  Size: 347 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

View File

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Some files were not shown because too many files have changed in this diff Show More