initial version

This commit is contained in:
2026-06-28 14:24:41 +01:00
commit a5fa596244
388 changed files with 71390 additions and 0 deletions
+17
View File
@@ -0,0 +1,17 @@
.git
.github
venv
.env
__pycache__
*.pyc
media
.idea
.vscode
*.sqlite3
node_modules
+84
View File
@@ -0,0 +1,84 @@
############################
# Python
############################
__pycache__/
*.py[cod]
*.so
############################
# Virtual Environment
############################
venv/
env/
ENV/
############################
# VSCode
############################
.vscode/
############################
# PyCharm
############################
.idea/
############################
# macOS
############################
.DS_Store
############################
# Database
############################
db.sqlite3
############################
# Logs
############################
*.log
############################
# Media
############################
media/
############################
# Static files
############################
staticfiles/
############################
# dotenv
############################
.env
############################
# Migrations
############################
**/__pycache__/
############################
# Coverage
############################
.coverage
htmlcov/
############################
# pytest
############################
.pytest_cache/
+34
View File
@@ -0,0 +1,34 @@
FROM python:3.12-slim
# Evite les fichiers .pyc
ENV PYTHONDONTWRITEBYTECODE=1
# Affiche directement les logs
ENV PYTHONUNBUFFERED=1
WORKDIR /app
# Dépendances système
RUN apt-get update && apt-get install -y \
gcc \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
# Création du dossier media
RUN mkdir -p /app/media
# Script de démarrage
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
EXPOSE 8000
CMD ["/entrypoint.sh"]
View File
+3
View File
@@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.
+6
View File
@@ -0,0 +1,6 @@
from django.apps import AppConfig
class AuthenticationConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'authentication'
+67
View File
@@ -0,0 +1,67 @@
# Generated by Django 4.2.17 on 2025-12-27 12:09
from django.conf import settings
import django.contrib.auth.models
import django.contrib.auth.validators
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import phonenumber_field.modelfields
class Migration(migrations.Migration):
initial = True
dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
]
operations = [
migrations.CreateModel(
name='User',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('profile_photo', models.ImageField(blank=True, null=True, upload_to='authentication/images/')),
('phone_number', phonenumber_field.modelfields.PhoneNumberField(max_length=128, region=None)),
('address', models.TextField()),
('role', models.CharField(blank=True, choices=[('CREATOR', 'Creator'), ('SUBSCRIBER', 'Subscriber')], max_length=30)),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
],
options={
'verbose_name': 'user',
'verbose_name_plural': 'users',
'abstract': False,
},
managers=[
('objects', django.contrib.auth.models.UserManager()),
],
),
migrations.CreateModel(
name='Phone',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('phone', phonenumber_field.modelfields.PhoneNumberField(max_length=128, region=None)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='Addresse',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('addresse', models.TextField()),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]
+31
View File
@@ -0,0 +1,31 @@
from django.db import models
from django.contrib.auth.models import AbstractUser
from PIL import Image
from phonenumber_field.modelfields import PhoneNumberField
class User(AbstractUser):
CREATOR = 'CREATOR'
SUBSCRIBER = 'SUBSCRIBER'
ROLE_CHOICES = (
(CREATOR, 'Creator'),
(SUBSCRIBER, 'Subscriber'),
)
profile_photo = models.ImageField(upload_to='authentication/images/', null=True, blank=True)
phone_number = PhoneNumberField()
address = models.TextField()
role = models.CharField(max_length=30, choices=ROLE_CHOICES, blank=True)
IMAGE_MAX_SIZE = (800,800)
def resize_image(self):
image = Image.open(self.image)
image.thumbnail(self.IMAGE_MAX_SIZE)
image.save(self.image.path)
def save(self,*args, **kwargs):
super().save(*args, **kwargs)
self.resize_image
class Addresse(models.Model):
addresse = models.TextField()
user = models.ForeignKey(User, on_delete=models.CASCADE)
class Phone(models.Model):
phone = PhoneNumberField()
user = models.ForeignKey(User, on_delete=models.CASCADE)
+3
View File
@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.
+3
View File
@@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.
View File
+3
View File
@@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.
+6
View File
@@ -0,0 +1,6 @@
from django.apps import AppConfig
class BlogConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'blog'
+78
View File
@@ -0,0 +1,78 @@
# Generated by Django 4.2.17 on 2024-12-18 21:32
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Articles',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=200)),
('slug', models.SlugField(blank=True, null=True, unique=True)),
('image', models.ImageField(upload_to='blog/images')),
('content', models.TextField(blank=True)),
('date_created', models.DateTimeField(auto_now_add=True)),
('date_updated', models.DateTimeField(auto_now=True)),
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name_plural': 'Articles',
},
),
migrations.CreateModel(
name='Images',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(blank=True, max_length=33)),
('file', models.ImageField(blank=True, null=True, upload_to='dashboard/images')),
('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='articles', to='blog.articles')),
],
options={
'verbose_name_plural': 'Images',
},
),
migrations.CreateModel(
name='Comment',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('commentaire', models.TextField(blank=True)),
('created', models.DateTimeField(auto_now_add=True)),
('active', models.BooleanField(default=False)),
('article', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='blog.articles')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name_plural': 'Comments',
},
),
migrations.CreateModel(
name='BlogCategories',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(blank=True, max_length=100)),
('slug', models.SlugField(blank=True, null=True, unique=True)),
('picture', models.ImageField(blank=True, null=True, upload_to='blog/images')),
('citation', models.TextField(blank=True)),
('parentcategory', models.ManyToManyField(blank=True, to='blog.blogcategories')),
],
options={
'verbose_name_plural': 'Blog Categories',
},
),
migrations.AddField(
model_name='articles',
name='category',
field=models.ManyToManyField(to='blog.blogcategories'),
),
]
View File
Executable
+110
View File
@@ -0,0 +1,110 @@
from django.db import models
from django.utils.text import slugify
from django.urls import reverse
from django.core.validators import FileExtensionValidator
from PIL import Image
class BlogCategories(models.Model):
title = models.CharField(max_length=100, blank=True)
slug = models.SlugField(unique=True, blank=True, null=True)
picture = models.ImageField(upload_to='blog/images', null=True, blank=True)
citation = models.TextField(blank=True)
parentcategory = models.ManyToManyField('self', symmetrical=False, blank=True)
class Meta:
verbose_name_plural = 'Blog Categories'
IMAGE_MAX_SIZE = (500,350)
def resize_image(self):
if self.picture:
picture = Image.open(self.picture)
picture.thumbnail(self.IMAGE_MAX_SIZE)
picture.save(self.picture.path)
def save(self, *args, **kwargs):
if not self.slug:
base_slug = slugify(self.title)
slug = base_slug
counter = 1
while Articles.objects.filter(slug=slug).exists():
slug = '{}-{}'.format(base_slug, counter)
counter += 1
self.slug = slug
self.resize_image()
super().save(*args, **kwargs)
def __str__(self):
return self.title
class Articles(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey('authentication.User', on_delete=models.CASCADE)
slug = models.SlugField(unique=True, blank=True, null=True)
category = models.ManyToManyField('BlogCategories')
image = models.ImageField(upload_to='blog/images')
content = models.TextField(blank=True)
date_created = models.DateTimeField(auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True)
class Meta:
verbose_name_plural = 'Articles'
IMAGE_MAX_SIZE = (600, 400)
def resize_image(self):
image = Image.open(self.image)
image.thumbnail(self.IMAGE_MAX_SIZE)
image.save(self.image.path)
def save(self, *args, **kwargs):
if not self.slug:
base_slug = slugify(self.title)
slug = base_slug
counter = 1
while Articles.objects.filter(slug=slug).exists():
slug = '{}-{}'.format(base_slug, counter)
counter += 1
self.slug = slug
self.resize_image()
super().save(*args, **kwargs)
def get_absolute_url(self):
return reverse('blog:article_detail', kwargs={'slug': self.slug})
def __str__(self):
return self.title
class Images(models.Model):
title = models.CharField(max_length=33, blank=True)
article = models.ForeignKey('Articles', related_name="articles", on_delete=models.CASCADE)
file = models.ImageField(upload_to='dashboard/images', blank=True, null=True)
class Meta:
verbose_name_plural = 'Images'
IMAGE_MAX_SIZE = (500, 350)
def resize_image(self):
file = Image.open(self.file)
file.thumbnail(self.IMAGE_MAX_SIZE)
file.save(self.file.path)
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
self.resize_image()
def __str__(self):
return self.title
class Comment(models.Model):
commentaire = models.TextField(blank=True)
article = models.ForeignKey(Articles, null=True, on_delete=models.CASCADE)
user = models.ForeignKey('authentication.User', on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=False)
class Meta:
verbose_name_plural = 'Comments'
def __str__(self):
return self.commentaire
+294
View File
@@ -0,0 +1,294 @@
{% extends 'base.html' %}
{% load static %}
{% block headblock %}
<title>Blog</title>
<meta name="description" content="Welcome to Adel blog!" >
{% endblock %}
{% block content %}
<!-- breadcrumb start-->
<section class="breadcrumb"><img class="img-fluid img-src" src="{% static 'main/assets/images/herointro/3.webp' %}" alt="herointro image">
<div class="container">
<div class="grid grid-cols-12">
<div class="col-span-12">
<div class="breadcrumb-contain">
<h1 data-sal-delay="100" data-sal="slide-up" data-sal-duration="800">blog</h1>
<ul data-sal-delay="200" data-sal="slide-up" data-sal-duration="800">
<li><a href="index.html">Home<i class="bi bi-chevron-right"></i></a></li>
<li><a href="contact.html">blog</a></li>
</ul>
</div>
</div>
</div>
</div>
</section>
<!-- breadcrumb end-->
<!-- blog start-->
<section class="space-py-100">
<div class="container">
<div class="grid grid-cols-12 cdx-gap">
<div class="col-span-12"><a class="btn btn-outline-primary filter-toggle btn-filter" href="javascript:void(0)"><i data-feather="filter"></i>filter</a></div>
<div class="col-span-12 2xl:col-span-4 lg:col-span-4 filter-sidebar">
<div class="cdx-layer"></div>
<div class="cdx-sidebar">
<div class="close-filter">close filter <i data-feather="x"> </i></div>
<div class="card">
<div class="card-body">
<form>
<div class="input-group">
<input class="form-control" type="text" placeholder="Search..."><span class="input-group-text bg-transparent"><i class="bi bi-search"></i></span>
</div>
</form>
</div>
</div>
<div class="card">
<div class="card-body">
<h4 class="filter-title">Category</h4>
<form action="#" method="post">
<ul class="filter-list">
<li>
<div class="form-check custom-chek">
<input class="form-check-input" id="category1" type="checkbox" value="">
<label class="form-check-label" for="category1">Business</label>
</div>
<div class="coursecount">(20)</div>
</li>
<li>
<div class="form-check custom-chek">
<input class="form-check-input" id="category2" type="checkbox" value="">
<label class="form-check-label" for="category2">Design</label>
</div>
<div class="coursecount">(99)</div>
</li>
<li>
<div class="form-check custom-chek">
<input class="form-check-input" id="category3" type="checkbox" value="">
<label class="form-check-label" for="category3">Development</label>
</div>
<div class="coursecount">(56)</div>
</li>
<li>
<div class="form-check custom-chek">
<input class="form-check-input" id="category4" type="checkbox" value="">
<label class="form-check-label" for="category4">Graphic Design</label>
</div>
<div class="coursecount">(48)</div>
</li>
<li>
<div class="form-check custom-chek">
<input class="form-check-input" id="category5" type="checkbox" value="">
<label class="form-check-label" for="category5">Heath & Fitness</label>
</div>
<div class="coursecount">(75)</div>
</li>
<li>
<div class="form-check custom-chek">
<input class="form-check-input" id="category6" type="checkbox" value="">
<label class="form-check-label" for="category6">Marketing</label>
</div>
<div class="coursecount">(18)</div>
</li>
<li>
<div class="form-check custom-chek">
<input class="form-check-input" id="category7" type="checkbox" value="">
<label class="form-check-label" for="category7">Math</label>
</div>
<div class="coursecount">(09)</div>
</li>
<li>
<div class="form-check custom-chek">
<input class="form-check-input" id="category8" type="checkbox" value="">
<label class="form-check-label" for="category8">Photography</label>
</div>
<div class="coursecount">(67)</div>
</li>
<li>
<div class="form-check custom-chek">
<input class="form-check-input" id="category9" type="checkbox" value="">
<label class="form-check-label" for="category9">PHP</label>
</div>
<div class="coursecount">(08)</div>
</li>
<li>
<div class="form-check custom-chek mb-0">
<input class="form-check-input" id="category10" type="checkbox" value="">
<label class="form-check-label" for="category10">WordPress</label>
</div>
<div class="coursecount">(18)</div>
</li>
</ul>
</form>
</div>
</div>
<div class="card">
<div class="card-body">
<h4 class="filter-title">Recent Posts</h4>
<div class="media">
<div class="img-wrap"><img class="img-fluid" src="{% static 'main/assets//images/blog/1.webp' %}" alt=""></div>
<div class="media-body">
<h6><a href="#">Learn Webs Applications Development from Experts</a></h6><span>April 1, 2022</span>
</div>
</div>
<div class="media">
<div class="img-wrap"><img class="img-fluid" src="{% static 'main/assets//images/blog/2.webp' %}" alt=""></div>
<div class="media-body">
<h6><a href="#">Learn Webs Applications Development from Experts</a></h6><span>April 1, 2022</span>
</div>
</div>
<div class="media">
<div class="img-wrap"><img class="img-fluid" src="{% static 'main/assets//images/blog/3.webp' %}" alt=""></div>
<div class="media-body">
<h6><a href="#">Learn Webs Applications Development from Experts</a></h6><span>April 1, 2022 </span>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-body">
<h4 class="filter-title">Our Archives</h4>
<ul class="filter-list">
<li>
<div class="form-check custom-chek">
<input class="form-check-input" id="archives1" type="checkbox" value="">
<label class="form-check-label" for="archives1"> May</label>
</div>
<div class="coursecount">2022</div>
</li>
<li>
<div class="form-check custom-chek">
<input class="form-check-input" id="archives2" type="checkbox" value="">
<label class="form-check-label" for="archives2"> Jun</label>
</div>
<div class="coursecount">2022</div>
</li>
<li>
<div class="form-check custom-chek">
<input class="form-check-input" id="archives3" type="checkbox" value="">
<label class="form-check-label" for="archives3"> July</label>
</div>
<div class="coursecount">2022</div>
</li>
<li>
<div class="form-check custom-chek">
<input class="form-check-input" id="archives4" type="checkbox" value="">
<label class="form-check-label" for="archives4"> August</label>
</div>
<div class="coursecount">2022</div>
</li>
<li>
<div class="form-check custom-chek">
<input class="form-check-input" id="archives5" type="checkbox" value="">
<label class="form-check-label" for="archives5"> September</label>
</div>
<div class="coursecount">2022</div>
</li>
</ul>
</div>
</div>
<div class="card">
<div class="card-body">
<h4 class="filter-title">Gallery post</h4>
<ul class="gallery-post">
<li> <a href="javascript:void(0)" data-fancybox="" data-src="{% static 'main/assets//images/blog/1.webp' %}" data-caption=""><img class="img-fluid" src="{% static 'main/assets//images/blog/1.webp' %}" alt=""></a></li>
<li><a href="javascript:void(0)" data-fancybox="" data-src="{% static 'main/assets//images/blog/2.webp' %}" data-caption=""><img class="img-fluid" src="{% static 'main/assets//images/blog/2.webp' %}" alt=""></a></li>
<li><a href="javascript:void(0)" data-fancybox="" data-src="{% static 'main/assets//images/blog/3.webp' %}" data-caption=""><img class="img-fluid" src="{% static 'main/assets//images/blog/3.webp' %}" alt=""></a></li>
<li><a href="javascript:void(0)" data-fancybox="" data-src="{% static 'main/assets//images/blog/4.webp' %}" data-caption=""><img class="img-fluid" src="{% static 'main/assets//images/blog/4.webp' %}" alt=""></a></li>
<li><a href="javascript:void(0)" data-fancybox="" data-src="{% static 'main/assets//images/blog/5.webp' %}" data-caption=""><img class="img-fluid" src="{% static 'main/assets//images/blog/5.webp' %}" alt=""></a></li>
<li><a href="javascript:void(0)" data-fancybox="" data-src="{% static 'main/assets//images/blog/6.webp' %}" data-caption=""><img class="img-fluid" src="{% static 'main/assets//images/blog/6.webp' %}" alt=""></a></li>
<li><a href="javascript:void(0)" data-fancybox="" data-src="{% static 'main/assets//images/blog/7.webp' %}" data-caption=""><img class="img-fluid" src="{% static 'main/assets//images/blog/7.webp' %}" alt=""></a></li>
<li><a href="javascript:void(0)" data-fancybox="" data-src="{% static 'main/assets//images/blog/8.webp' %}" data-caption=""><img class="img-fluid" src="{% static 'main/assets//images/blog/8.webp' %}" alt=""></a></li>
<li><a href="javascript:void(0)" data-fancybox="" data-src="{% static 'main/assets//images/blog/9.webp' %}" data-caption=""><img class="img-fluid" src="{% static 'main/assets//images/blog/9.webp' %}" alt=""></a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="col-span-12 2xl:col-span-8 lg:col-span-8">
<div class="grid grid-cols-12 cdx-gap">
<div class="col-span-12 md:col-span-6" data-sal-delay="100" data-sal="slide-up" data-sal-duration="800">
<div class="blog-grid">
<div class="img-wrap"><a href="blog-detail.html"><img class="img-fluid" src="{% static 'main/assets//images/blog/1.webp' %}" alt="blog"></a></div>
<div class="blog-detail">
<h3><a href="blog-detail.html">Scottish Creatives To Receive Funded Business.</a></h3>
<ul class="post-meta">
<li><a href="#"><i class="bi bi-person-fill"></i><span>Adel</span></a></li>
<li><a href="#"><i class="bi bi-calendar"></i><span>19 Apr, 2022</span></a></li>
</ul>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet</p><a class="btn btn-primary btn-sm" href="blog-detail.html">read more</a>
</div>
</div>
</div>
<div class="col-span-12 md:col-span-6" data-sal-delay="200" data-sal="slide-up" data-sal-duration="800">
<div class="blog-grid">
<div class="img-wrap"><a href="blog-detail.html"><img class="img-fluid" src="{% static 'main/assets//images/blog/2.webp' %}" alt="blog"></a></div>
<div class="blog-detail">
<h3><a href="blog-detail.html">Designing Better Link Web Site and Emailsite</a></h3>
<ul class="post-meta">
<li><a href="#"><i class="bi bi-person-fill"></i><span>Adel</span></a></li>
<li><a href="#"><i class="bi bi-calendar"></i><span>26 May, 2022</span></a></li>
</ul>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet</p><a class="btn btn-primary btn-sm" href="blog-detail.html">read more</a>
</div>
</div>
</div>
<div class="col-span-12 md:col-span-6" data-sal-delay="100" data-sal="slide-up" data-sal-duration="800">
<div class="blog-grid">
<div class="img-wrap"><a href="blog-detail.html"><img class="img-fluid" src="{% static 'main/assets//images/blog/3.webp' %}" alt="blog"></a></div>
<div class="blog-detail">
<h3><a href="blog-detail.html">Variables In The Hugo Seen Static Site Generator</a></h3>
<ul class="post-meta">
<li><a href="#"><i class="bi bi-person-fill"></i><span>Adel</span></a></li>
<li><a href="#"><i class="bi bi-calendar"></i><span>05 Jul, 2022</span></a></li>
</ul>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet</p><a class="btn btn-primary btn-sm" href="blog-detail.html">read more</a>
</div>
</div>
</div>
<div class="col-span-12 md:col-span-6" data-sal-delay="200" data-sal="slide-up" data-sal-duration="800">
<div class="blog-grid">
<div class="img-wrap"><a href="blog-detail.html"><img class="img-fluid" src="{% static 'main/assets//images/blog/4.webp' %}" alt="blog"></a></div>
<div class="blog-detail">
<h3><a href="blog-detail.html">Expand Your Career Opportunities With Python</a></h3>
<ul class="post-meta">
<li><a href="#"><i class="bi bi-person-fill"></i><span>Adel</span></a></li>
<li><a href="#"><i class="bi bi-calendar"></i><span>22 Aug, 2022</span></a></li>
</ul>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet</p><a class="btn btn-primary btn-sm" href="blog-detail.html">read more</a>
</div>
</div>
</div>
<div class="col-span-12 md:col-span-6" data-sal-delay="100" data-sal="slide-up" data-sal-duration="800">
<div class="blog-grid">
<div class="img-wrap"><a href="blog-detail.html"><img class="img-fluid" src="{% static 'main/assets//images/blog/5.webp' %}" alt="blog"></a></div>
<div class="blog-detail">
<h3><a href="blog-detail.html">Complete PHP Programming Career Guideline</a></h3>
<ul class="post-meta">
<li><a href="#"><i class="bi bi-person-fill"></i><span>Adel</span></a></li>
<li><a href="#"><i class="bi bi-calendar"></i><span>15 Sept, 2022</span></a></li>
</ul>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet</p><a class="btn btn-primary btn-sm" href="blog-detail.html">read more</a>
</div>
</div>
</div>
<div class="col-span-12 md:col-span-6" data-sal-delay="200" data-sal="slide-up" data-sal-duration="800">
<div class="blog-grid">
<div class="img-wrap"><a href="blog-detail.html"><img class="img-fluid" src="{% static 'main/assets//images/blog/6.webp' %}" alt="blog"></a></div>
<div class="blog-detail">
<h3><a href="blog-detail.html">Learn Webs Applications Development from Experts</a></h3>
<ul class="post-meta">
<li><a href="#"><i class="bi bi-person-fill"></i><span>Adel</span></a></li>
<li><a href="#"><i class="bi bi-calendar"></i><span>24 Acto, 2022</span></a></li>
</ul>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet</p><a class="btn btn-primary btn-sm" href="blog-detail.html">read more</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- blog end-->
{% endblock %}
+3
View File
@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.
Executable
+11
View File
@@ -0,0 +1,11 @@
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
path('articles/', views.articles, name='articles'),
]
Executable
+9
View File
@@ -0,0 +1,9 @@
from django.shortcuts import render, redirect, get_object_or_404
from django.core.paginator import Paginator
from django.db.models import Q
from django.contrib.auth.decorators import login_required
def articles(request):
return render(request, 'blog/blog.html')
View File
+3
View File
@@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.
+6
View File
@@ -0,0 +1,6 @@
from django.apps import AppConfig
class CartConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'cart'
View File
+3
View File
@@ -0,0 +1,3 @@
from django.db import models
# Create your models here.
+158
View File
@@ -0,0 +1,158 @@
{% extends 'base.html' %}
{% load static %}
{% block content %}
<!-- Breadcrumb Start-->
<section class="breadcrumb"><img class="img-fluid img-src" src="{% static 'main/assets/images/herointro/3.webp' %}" alt="">
<div class="container">
<div class="grid grid-cols-12">
<div class="col-span-12">
<div class="breadcrumb-contain">
<h1 data-sal-delay="100" data-sal="slide-up" data-sal-duration="800">Shop Cart</h1>
<ul data-sal-delay="200" data-sal="slide-up" data-sal-duration="800">
<li><a href="{% url 'main:home' %}">Home<i class="bi bi-chevron-right"></i></a></li>
<li><a href="#">Shop Cart</a></li>
</ul>
</div>
</div>
</div>
</div>
</section>
<!-- Breadcrumb end-->
<!-- cart start-->
<section class="space-py-100 cdxshopping-cart">
<div class="container">
<div class="grid grid-cols-12 cdx-gap">
<div class="col-span-12">
<div class="card">
<div class="card-body">
<div class="overflow-x-auto">
<table class="table cart-tbl">
<thead>
<tr>
<th class="text-primary fs-16">Product</th>
<th class="text-primary fs-16">Product name</th>
<th class="text-primary fs-16">Quantity</th>
<th class="text-primary fs-16">Price</th>
<th class="text-primary fs-16">Total</th>
<th class="text-primary fs-16">Action</th>
</tr>
</thead>
<tbody class="cartBody">
<tr>
<td>
<div class="product-imgwrap"><img class="img-fluid" src="{% static 'main/assets/images/course/1.webp' %}" alt="herointro image"></div>
</td>
<td class="cart-title">Learn Python: The Complete Python Programming Course</td>
<td>
<div class="input-group pro-quantity"><span class="input-group-text count-minus"><i class="bi bi-dash"></i></span>
<input class="form-control pro-qty" type="text" name="qty count" value="1"><span class="input-group-text count-plus"><i class="bi bi-plus"></i></span>
</div>
</td>
<td>DZD150</td>
<td>DZD200</td>
<td>
<div class="cart-action"><a class="text-light" href="javascript:void(0)"> <i data-feather="heart"></i></a><a href="javascript:void(0)"> <i data-feather="trash-2"></i></a></div>
</td>
</tr>
<tr>
<td>
<div class="product-imgwrap"><img class="img-fluid" src="{% static 'main/assets/images/course/2.webp' %}" alt=""></div>
</td>
<td class="cart-title">Photoshop Master Course: From Beginner to Photoshop Pro</td>
<td>
<div class="input-group pro-quantity"><span class="input-group-text count-minus"><i class="bi bi-dash"></i></span>
<input class="form-control pro-qty" type="text" name="qty count" value="1"><span class="input-group-text count-plus"><i class="bi bi-plus"></i></span>
</div>
</td>
<td>DZD80</td>
<td>DZD320 </td>
<td>
<div class="cart-action"><a class="text-light" href="javascript:void(0)"> <i data-feather="heart"></i></a><a href="javascript:void(0)"> <i data-feather="trash-2"></i></a></div>
</td>
</tr>
<tr>
<td>
<div class="product-imgwrap"><img class="img-fluid" src="{% static 'main/assets/images/course/3.webp' %}" alt=""></div>
</td>
<td class="cart-title">Data Science and Machine Learning Bootcamp with R</td>
<td>
<div class="input-group pro-quantity"><span class="input-group-text count-minus"><i class="bi bi-dash"></i></span>
<input class="form-control pro-qty" type="text" name="qty count" value="1"><span class="input-group-text count-plus"><i class="bi bi-plus"></i></span>
</div>
</td>
<td>DZD180 </td>
<td>DZD180 </td>
<td>
<div class="cart-action"><a class="text-light" href="javascript:void(0)"> <i data-feather="heart"></i></a><a href="javascript:void(0)"> <i data-feather="trash-2"></i></a></div>
</td>
</tr>
<tr>
<td>
<div class="product-imgwrap"><img class="img-fluid" src="{% static 'main/assets/images/course/4.webp' %}" alt=""></div>
</td>
<td class="cart-title">User Experience (UX): The Ultimate Guide to Usability and UX</td>
<td>
<div class="input-group pro-quantity"><span class="input-group-text count-minus"><i class="bi bi-dash"></i></span>
<input class="form-control pro-qty" type="text" name="qty count" value="1"><span class="input-group-text count-plus"><i class="bi bi-plus"></i></span>
</div>
</td>
<td>DZD300 </td>
<td>DZD600 </td>
<td>
<div class="cart-action"><a class="text-light" href="javascript:void(0)"> <i data-feather="heart"></i></a><a href="javascript:void(0)"> <i data-feather="trash-2"></i></a></div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="cartbtn-group">
<div><a class="btn btn-primary btn-md" href="productno-filter.html">Continue Shopping </a></div>
<div>
<div class="group-btn"><a class="btn btn-primary btn-md" href="javascript:void(0);">Update Cart </a><a class="btn btn-primary btn-md removeAll_cart" href="javascript:void(0);">Clear Shopping Cart </a></div>
</div>
</div>
</div>
</div>
</div>
<div class="col-start-auto col-span-12 2xl:col-span-4 2xl:col-start-9 lg.col-span-4 lg:col-start-8 md:col-span-6 md:col-start-7">
<div class="card">
<div class="card-body">
<div class="table-responsive">
<table class="table chekout-tbl mb-0">
<tbody>
<tr>
<th>Discounts</th>
<td>DZD 1600.00</td>
</tr>
<tr>
<th>Special Offer Saving</th>
<td>DZD 0.00</td>
</tr>
<tr>
<th>Subtotal exc VAT</th>
<td>DZD 14.80</td>
</tr>
<tr>
<th>VAT</th>
<td>DZD 140.00</td>
</tr>
<tr>
<th>Grand Total inc VAT</th>
<td>DZD 1660.80</td>
</tr>
<tr>
<td colspan="2"><a class="btn btn-primary btn-md w-100" href="checkout.html">Proceed to checkout</a></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- cart end -->
{% endblock %}
+173
View File
@@ -0,0 +1,173 @@
{% extends 'base.html' %}
{% load static %}
{% block content %}
<!-- Breadcrumb Start-->
<section class="breadcrumb"><img class="img-fluid img-src" src="../assets/images/herointro/3.webp" alt="">
<div class="container">
<div class="grid grid-cols-12">
<div class="col-span-12">
<div class="breadcrumb-contain">
<h1 data-sal-delay="100" data-sal="slide-up" data-sal-duration="800">checkout</h1>
<ul data-sal-delay="200" data-sal="slide-up" data-sal-duration="800">
<li><a href="index.html">Home<i class="fa fa-angle-right"></i></a></li>
<li><a href="contact.html">checkout</a></li>
</ul>
</div>
</div>
</div>
</div>
</section>
<!-- Breadcrumb end-->
<!-- checkout start-->
<section class="cdx-checkout space-py-100">
<div class="container">
<div class="grid grid-cols-12 cdx-gap">
<div class="col-span-12 lg:col-span-5">
<div class="card">
<div class="card-header">
<div>
<h4>Billing Address</h4>
<p><a class="font-primary" href="login.html">Login </a>or<a class="font-primary" href="register.html">Register</a>for faster payment.</p>
</div>
</div>
<div class="card-body">
<form class="form-theme">
<div class="form-group">
<div class="group-small">
<div>
<label class="form-label" for="fname">First name</label>
<input class="form-control" id="fname" type="text" placeholder="First name">
</div>
<div>
<label class="form-label" for="lname">Last name</label>
<input class="form-control" id="lname" type="text" placeholder="Last name">
</div>
</div>
</div>
<div class="form-group">
<label class="form-label">Country</label>
<select class="form-select" name="conuntry">
<option value="Afghanistan">Afghanistan</option>
<option value="Bahrain">Bahrain</option>
<option value="France">France</option>
<option value="Mauritania">Mauritania</option>
</select>
</div>
<div class="form-group">
<div class="group-small">
<div>
<label class="form-label">State</label>
<select class="form-select" name="state">
<option value="Alabama">Alabama </option>
<option value="California">California</option>
<option value="Delaware"> Delaware</option>
<option value="Florida"> Florida</option>
<option value="Georgia"> Georgia</option>
<option value="Wyoming"> Wyoming</option>
</select>
</div>
<div>
<label class="form-label">Zip code</label>
<input class="form-control" type="text">
</div>
</div>
</div>
<div class="form-group mb-0">
<label class="form-label">Address</label>
<textarea class="form-control"> </textarea>
</div>
</form>
</div>
</div>
</div>
<div class="col-span-12 lg:col-span-6">
<div class="card payment-detail">
<div class="card-header">
<h4>Payment Method </h4>
</div>
<div class="card-body">
<form action="#">
<div class="group-form">
<div class="form-group">
<div class="group-small payment-card">
<div class="custom-chek">
<input class="form-check-input" id="debitcard" type="radio" name="payment-type" value="debitcard" checked>
<label for="debitcard">Debit Card</label><br>
</div>
<div class="custom-chek">
<input class="form-check-input" id="creditcard" type="radio" name="payment-type" value="creditcard">
<label for="creditcard">Credit Card</label><br>
</div>
<div class="custom-chek">
<input class="form-check-input" id="paypal" type="radio" name="payment-type" value="paypal">
<label for="paypal">PayPal</label>
</div>
</div>
</div>
</div>
<div class="form-group">
<label class="form-label">Card Number</label>
<input class="form-control" type="text" placeholder="XXXX XXXX XXXX XXXX">
</div>
<div class="form-group">
<div class="form-group">
<div class="group-small">
<div>
<label class="form-label">Month</label>
<select class="form-select">
<option value="january">January</option>
<option value="february">February</option>
<option value="march">March</option>
<option value="april">April</option>
<option value="may">May</option>
<option value="june">June</option>
<option value="july">July</option>
<option value="august">August</option>
<option value="september">September</option>
<option value="october">October</option>
<option value="november">November</option>
<option value="december">December </option>
</select>
</div>
<div>
<label class="form-label">Month</label>
<select class="form-select">
<option value="2022">2022</option>
<option value="2018">2018</option>
<option value="2019">2019</option>
<option value="2020">2020</option>
<option value="2021">2021</option>
<option value="2023">2023</option>
<option value="2024">2024 </option>
</select>
</div>
</div>
</div>
</div>
<div class="form-group">
<label class="form-label">CVV Code </label>
<input class="form-control" type="text" placeholder="XXXX">
</div>
<div class="form-group">
<label class="form-label">Name on Card</label>
<input class="form-control" type="text" placeholder="Address">
</div>
<div class="form-group">
<div class="form-check custom-chek">
<input class="form-check-input" id="remember" type="checkbox" value="">
<label class="form-check-label" for="remember">Remember this card </label>
</div>
</div>
<div class="form-group mb-0">
<button class="btn btn-primary btn-md">make a paymnet</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- checkout end-->
{% endblock %}
+100
View File
@@ -0,0 +1,100 @@
{% extends 'base.html' %}
{% load static %}
{% block headblock %}
<title>Membership Plans</title>
<meta name="description" content="Subscribe now and start your reinvented learning journey!" >
{% endblock %}
{% block content %}
<!-- breadcrumb start-->
<section class="breadcrumb"><img class="img-fluid img-src" src="{% static 'main/assets/images/herointro/3.webp' %}" alt="herointro image">
<div class="container">
<div class="grid grid-cols-12">
<div class="col-span-12">
<div class="breadcrumb-contain">
<h1 data-sal-delay="100" data-sal="slide-up" data-sal-duration="800">Membership Plans</h1>
<ul data-sal-delay="200" data-sal="slide-up" data-sal-duration="800">
<li><a href="{% url 'main:home' %}">Home<i class="bi bi-chevron-right"></i></a></li>
<li><a href="contact.html">Membership Plans</a></li>
</ul>
</div>
</div>
</div>
</div>
</section>
<!-- breadcrumb end-->
<!-- pricing paln start-->
<section class="space-py-100">
<div class="container">
<div class="grid grid-cols-12">
<div class="col-span-12">
<div class="title text-center">
<h4>Our Plans</h4>
<h2>Membership Levels</h2>
</div>
</div>
</div>
<div class="grid grid-cols-12 cdx-gap">
<div class="col-span-12 lg:col-span-4 md:col-span-6" data-sal-delay="100" data-sal="slide-up" data-sal-duration="800">
<div class="pricing-grid">
<div class="pricing-header">
<h2>Basic</h2><span class="pricing-currency">$</span><span class="pricing-price">19.99</span><span class="month">/ Month</span>
</div>
<div class="pricing-body">
<ul>
<li><i data-feather="check"></i>20 Courses Access
</li>
<li><i data-feather="check"></i>Course Certificate</li>
<li><i data-feather="check"></i>Exercise File</li>
<li><i data-feather="check"></i>Lifetime Access</li>
<li><i data-feather="check"></i>Dedicated Support</li>
</ul>
</div>
<button class="btn btn-primary" type="submit">Get started now</button>
</div>
</div>
<div class="col-span-12 lg:col-span-4 md:col-span-6" data-sal-delay="200" data-sal="slide-up" data-sal-duration="800">
<div class="pricing-grid">
<div class="price-lable">popular</div>
<div class="pricing-header">
<h2>Standard</h2><span class="pricing-currency">$</span><span class="pricing-price">29.99</span><span class="month">/ Month</span>
</div>
<div class="pricing-body">
<ul>
<li><i data-feather="check"></i>50 Courses Access
</li>
<li><i data-feather="check"></i>Course Certificate</li>
<li><i data-feather="check"></i>Exercise File</li>
<li><i data-feather="check"></i>Lifetime Access</li>
<li><i data-feather="check"></i>Dedicated Support</li>
</ul>
</div>
<button class="btn btn-primary" type="submit">Get started now</button>
</div>
</div>
<div class="col-span-12 lg:col-span-4 md:col-span-6" data-sal-delay="300" data-sal="slide-up" data-sal-duration="800">
<div class="pricing-grid">
<div class="pricing-header">
<h2>Premium</h2><span class="pricing-currency">$</span><span class="pricing-price">49.99</span><span class="month">/ Month</span>
</div>
<div class="pricing-body">
<ul>
<li><i data-feather="check"></i>all Courses Access
</li>
<li><i data-feather="check"></i>Course Certificate</li>
<li><i data-feather="check"></i>Exercise File</li>
<li><i data-feather="check"></i>Lifetime Access</li>
<li><i data-feather="check"></i>Dedicated Support</li>
</ul>
</div>
<button class="btn btn-primary" type="submit">Get started now</button>
</div>
</div>
</div>
</div>
</section>
<!-- pricing paln end-->
{% endblock %}}
+101
View File
@@ -0,0 +1,101 @@
{% extends 'base.html' %}
{% load static %}
{% block content %}
<!-- Breadcrumb Start-->
<section class="breadcrumb"><img class="img-fluid img-src" src="{% static 'main/assets/images/herointro/3.webp' %}" alt="herointro image">
<div class="container">
<div class="grid grid-cols-12">
<div class="col-span-12">
<div class="breadcrumb-contain">
<h1 data-sal-delay="100" data-sal="slide-up" data-sal-duration="800">wishlist</h1>
<ul data-sal-delay="200" data-sal="slide-up" data-sal-duration="800">
<li><a href="index.html">Home<i class="bi bi-chevron-right"></i></a></li>
<li><a href="contact.html">wishlist</a></li>
</ul>
</div>
</div>
</div>
</div>
</section>
<!-- Breadcrumb end-->
<!-- wishlist start-->
<section class="space-py-100 cdxshopping-cart">
<div class="container">
<div class="grid grid-cols-12">
<div class="col-span-12">
<div class="card">
<div class="card-body">
<div class="overflow-x-auto">
<table class="table cart-tbl">
<thead>
<tr>
<th class="text-primary fs-16">Product</th>
<th class="text-primary fs-16">Product name </th>
<th class="text-primary fs-16">Price</th>
<th class="text-primary fs-16">Stock Status</th>
<th class="text-primary fs-16">Add to cart</th>
<th class="text-primary fs-16">Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="product-imgwrap"><img class="img-fluid" src="{% static 'main/assets/images/course/1.webp' %}" alt=""></div>
</td>
<td><a href="productno-filter.html">Learn Python: The Complete Python Programming Course</a></td>
<td>$356</td>
<td><span>in stock </span></td>
<td><a class="btn btn-primary btn-sm" href="cart.html">Add to cart</a></td>
<td>
<div class="cart-action"><a class="delete" href="javascript:void(0)"> <i data-feather="trash-2"></i></a></div>
</td>
</tr>
<tr>
<td>
<div class="product-imgwrap"><img class="img-fluid" src="{% static 'main/assets/images/course/2.webp' %}" alt=""></div>
</td>
<td> <a href="productno-filter.html">Photoshop Master Course: From Beginner To Photoshop Pro</a></td>
<td>$150</td>
<td><span>in stock </span></td>
<td> <a class="btn btn-primary btn-sm" href="cart.html">Add to cart</a></td>
<td>
<div class="cart-action"><a class="delete" href="javascript:void(0)"> <i data-feather="trash-2"></i></a></div>
</td>
</tr>
<tr>
<td>
<div class="product-imgwrap"><img class="img-fluid" src="{% static 'main/assets/images/course/3.webp' %}" alt=""></div>
</td>
<td> <a href="productno-filter.html">Data Science And Machine Learning Bootcamp With R</a></td>
<td>$220</td>
<td><span>in stock </span></td>
<td> <a class="btn btn-primary btn-sm" href="cart.html">Add to cart</a></td>
<td>
<div class="cart-action"><a class="delete" href="javascript:void(0)"> <i data-feather="trash-2"></i></a></div>
</td>
</tr>
<tr>
<td>
<div class="product-imgwrap"><img class="img-fluid" src="{% static 'main/assets/images/course/4.webp' %}" alt=""></div>
</td>
<td> <a href="productno-filter.html">User Experience (UX): The Ultimate Guide To Usability And UX</a></td>
<td>$300</td>
<td><span>in stock </span></td>
<td> <a class="btn btn-primary btn-sm" href="cart.html">Add to cart</a></td>
<td>
<div class="cart-action"><a class="delete" href="javascript:void(0)"> <i data-feather="trash-2"></i></a></div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- wishlist end-->
{% endblock %}
+3
View File
@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.
Executable
+13
View File
@@ -0,0 +1,13 @@
from django.urls import path
from . import views
app_name = 'cart'
urlpatterns = [
path('plans/', views.plans, name='plans'),
path('cart_summary/', views.cart_summary, name='cart_summary'),
path('order/', views.order, name='order'),
path('wishlist/', views.wishlist, name='wishlist'),
]
+26
View File
@@ -0,0 +1,26 @@
from django.urls import reverse
from django.http import JsonResponse
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator
from decimal import Decimal
def plans(request):
return render(request, 'cart/plans.html')
def cart_summary(request):
return render(request, 'cart/cart_summary.html')
@login_required
def order(request):
return render(request, 'cart/checkout.html')
def wishlist(request):
return render(request, 'cart/wishlist.html')
View File
+16
View File
@@ -0,0 +1,16 @@
"""
ASGI config for creativeschool project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'creativeschool.settings')
application = get_asgi_application()
+82
View File
@@ -0,0 +1,82 @@
user nginx;
worker_processes auto;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
# 🔥 Sécurité basique
server_tokens off;
# 🔥 Logs (Coolify les capte automatiquement)
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
# ===============================
# 🔁 HTTP → HTTPS (obligatoire)
# ===============================
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
# ===============================
# 🔐 HTTPS Django production
# ===============================
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# 🔥 Certificats (gérés par Coolify / Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# 🔥 Sécurité SSL minimale
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
# ===============================
# 📦 Fichiers statiques
# ===============================
location /static/ {
alias /static/;
expires 30d;
access_log off;
}
# ===============================
# 🖼️ Médias uploadés
# ===============================
location /media/ {
alias /media/;
expires 30d;
access_log off;
}
# ===============================
# 🧠 Django via Gunicorn
# ===============================
location / {
proxy_pass http://web:8000;
# 🔥 Headers indispensables pour Django
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_redirect off;
}
}
}
+195
View File
@@ -0,0 +1,195 @@
import os
import dj_database_url
from pathlib import Path
from dotenv import load_dotenv
load_dotenv()
BASE_DIR = Path(__file__).resolve().parent.parent
SECRET_KEY = os.getenv("DJANGO_SECRET_KEY")
DEBUG = os.getenv("DJANGO_DEBUG") == "False"
ALLOWED_HOSTS = os.getenv("DJANGO_ALLOWED_HOSTS", "").split(",")
INSTALLED_APPS = [
'jazzmin',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
"django.contrib.sites",
'main',
'authentication',
'blog',
'cart',
'dashboard',
'allauth',
'allauth.account',
"allauth.socialaccount",
'phonenumber_field',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
"whitenoise.middleware.WhiteNoiseMiddleware",
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'allauth.account.middleware.AccountMiddleware',
]
ROOT_URLCONF = 'creativeschool.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR.joinpath('templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'main.context_processors.categories',
],
},
},
]
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
'allauth.account.auth_backends.AuthenticationBackend',
]
WSGI_APPLICATION = 'creativeschool.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
DATABASES = {
"default": dj_database_url.parse(
os.environ["DATABASE_URL"],
conn_max_age=600,
)
}
# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
SITE_ID = 1
LOGIN_REDIRECT_URL = 'main:home'
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_EMAIL_VERIFICATION = 'mandatory'
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_EMAIL_UNIQUE = True
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = "Africa/Algiers"
USE_I18N = True
USE_TZ = True
AUTH_USER_MODEL = 'authentication.User'
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/
STATIC_URL = "/static/"
STATIC_ROOT = BASE_DIR / "staticfiles"
STATICFILES_STORAGE = (
"whitenoise.storage.CompressedManifestStaticFilesStorage"
)
MEDIA_URL = "/media/"
MEDIA_ROOT = "/app/media"
# =========================================
# 📧 Email (via .env)
# =========================================
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
EMAIL_HOST = os.getenv("EMAIL_HOST")
EMAIL_PORT = int(os.getenv("EMAIL_PORT", 587))
EMAIL_USE_TLS = os.getenv("EMAIL_USE_TLS") == "True"
EMAIL_HOST_USER = os.getenv("EMAIL_HOST_USER")
EMAIL_HOST_PASSWORD = os.getenv("EMAIL_HOST_PASSWORD")
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
# =========================================
# HTTPS / Nginx / Coolify
# =========================================
#SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
#SESSION_COOKIE_SECURE = not DEBUG
#CSRF_COOKIE_SECURE = not DEBUG
#CSRF_TRUSTED_ORIGINS = [
# f"https://{host}" for host in ALLOWED_HOSTS if host
#]
# Optionnel mais recommandé
#SECURE_HSTS_SECONDS = 31536000 if not DEBUG else 0
#SECURE_HSTS_INCLUDE_SUBDOMAINS = not DEBUG
#SECURE_HSTS_PRELOAD = not DEBUG
CSRF_TRUSTED_ORIGINS = os.getenv(
"CSRF_TRUSTED_ORIGINS",
""
).split(",")
SECURE_PROXY_SSL_HEADER = (
("HTTP_X_FORWARDED_PROTO", "https")
)
USE_X_FORWARDED_HOST = True
SESSION_COOKIE_SECURE = not DEBUG
CSRF_COOKIE_SECURE = not DEBUG
SECURE_SSL_REDIRECT = not DEBUG
+16
View File
@@ -0,0 +1,16 @@
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('main.urls')),
path('cart/', include('cart.urls')),
path('blog/', include('blog.urls')),
path('accounts/', include('allauth.urls')),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
+16
View File
@@ -0,0 +1,16 @@
"""
WSGI config for creativeschool project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/3.0/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'creativeschool.settings')
application = get_wsgi_application()
View File
+3
View File
@@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.
+6
View File
@@ -0,0 +1,6 @@
from django.apps import AppConfig
class DashboardConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'dashboard'
View File
+3
View File
@@ -0,0 +1,3 @@
from django.db import models
# Create your models here.
+3
View File
@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.
+3
View File
@@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.
+13
View File
@@ -0,0 +1,13 @@
#!/bin/sh
echo "Collecting static files..."
python manage.py collectstatic --noinput
echo "Applying migrations..."
python manage.py migrate --noinput
echo "Starting Gunicorn..."
exec gunicorn creativeschool.wsgi:application \
--bind 0.0.0.0:8000 \
--workers 3 \
--timeout 120
View File
+6
View File
@@ -0,0 +1,6 @@
from django.contrib import admin
from .models import Categories, Contact
admin.site.register(Categories)
admin.site.register(Contact)
+6
View File
@@ -0,0 +1,6 @@
from django.apps import AppConfig
class MainConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'main'
+7
View File
@@ -0,0 +1,7 @@
from .models import Categories
def categories(request):
return {'parent_categories': Categories.objects.filter(parentcategory__isnull=True)}
Executable
+18
View File
@@ -0,0 +1,18 @@
from django import forms
from .models import Contact
class ContactForm(forms.ModelForm):
message = forms.CharField(widget=forms.Textarea(attrs={'class': 'form-control','rows':8,'placeholder': 'Message'}))
class Meta(forms.ModelForm):
model = Contact
fields = [ 'name', 'email', 'subject', 'phone_number','message']
widgets = {
'name': forms.TextInput(attrs={'class': 'form-control ', 'placeholder': 'Name'}),
'email': forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Email'}),
'subject': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Objet'}),
'phone_number': forms.TextInput(attrs={'class': 'form-control ', 'placeholder': 'Mobile e.g. +213 665 26 45 08'}),
}
+30
View File
@@ -0,0 +1,30 @@
# Generated by Django 4.2.17 on 2024-12-14 18:37
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Categories',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(blank=True, max_length=100)),
('slug', models.SlugField(blank=True, null=True, unique=True)),
('picture', models.ImageField(blank=True, null=True, upload_to='main/images')),
('citation', models.TextField(blank=True)),
('date_created', models.DateTimeField(auto_now_add=True, null=True)),
('parentcategory', models.ManyToManyField(blank=True, related_name='children', to='main.categories')),
],
options={
'verbose_name_plural': 'Categories',
'ordering': ['id'],
},
),
]
+30
View File
@@ -0,0 +1,30 @@
# Generated by Django 4.2.17 on 2024-12-18 12:08
from django.db import migrations, models
import phonenumber_field.modelfields
class Migration(migrations.Migration):
dependencies = [
('main', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Contact',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50)),
('email', models.EmailField(max_length=254)),
('subject', models.CharField(max_length=50)),
('phone_number', phonenumber_field.modelfields.PhoneNumberField(max_length=128, region=None)),
('message', models.TextField()),
('date_created', models.DateTimeField(auto_now_add=True)),
],
options={
'verbose_name_plural': 'Contacts',
'ordering': ['id'],
},
),
]
@@ -0,0 +1,196 @@
# Generated by Django 4.2.17 on 2024-12-18 18:57
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import phonenumber_field.modelfields
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('main', '0002_contact'),
]
operations = [
migrations.CreateModel(
name='Codes',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('code', models.CharField(blank=True, max_length=200)),
],
options={
'verbose_name_plural': 'code Zip',
'ordering': ['id'],
},
),
migrations.CreateModel(
name='Countries',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('country', models.CharField(blank=True, max_length=200)),
],
options={
'verbose_name_plural': 'Pays',
'ordering': ['id'],
},
),
migrations.CreateModel(
name='Courses',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=33)),
('slug', models.SlugField(blank=True, null=True, unique=True)),
('price', models.DecimalField(decimal_places=2, default=0.0, max_digits=19)),
('description', models.TextField(blank=True)),
('status', models.CharField(blank=True, choices=[('Online', 'Online'), ('Facetoface', 'Facetoface'), ('Blended', 'Blended')], default='Online', max_length=30, null=True)),
('date_created', models.DateTimeField(auto_now_add=True)),
('date_updated', models.DateTimeField(auto_now=True)),
('active', models.BooleanField(default=False)),
('category', models.ManyToManyField(to='main.categories')),
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name_plural': 'Courses',
'ordering': ['date_created'],
},
),
migrations.CreateModel(
name='Partners',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=50)),
('slug', models.SlugField(blank=True, null=True, unique=True)),
('image', models.ImageField(upload_to='main/images')),
],
options={
'verbose_name_plural': 'Partners',
'ordering': ['id'],
},
),
migrations.CreateModel(
name='Wilayas',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(blank=True, max_length=200)),
('slug', models.SlugField(blank=True, null=True, unique=True)),
('size', models.IntegerField(blank=True, null=True)),
('image', models.ImageField(blank=True, null=True, upload_to='main/images')),
],
options={
'verbose_name_plural': 'Wilayas',
'ordering': ['id'],
},
),
migrations.CreateModel(
name='Testimonials',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=200)),
('testimonial', models.TextField()),
('date_created', models.DateTimeField(auto_now_add=True)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name_plural': 'Testimonials',
'ordering': ['date_created'],
},
),
migrations.CreateModel(
name='School',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=33)),
('city', models.CharField(blank=True, max_length=33)),
('slug', models.SlugField(blank=True, null=True, unique=True)),
('description', models.TextField(blank=True)),
('logo', models.ImageField(upload_to='main/images')),
('banner', models.ImageField(upload_to='main/images')),
('email', models.EmailField(max_length=254)),
('facebook', models.URLField(blank=True, null=True)),
('instagram', models.URLField(blank=True, null=True)),
('linkedin', models.URLField(blank=True, null=True)),
('youtube', models.URLField(blank=True, null=True)),
('website', models.URLField(blank=True, null=True)),
('whatsapp', phonenumber_field.modelfields.PhoneNumberField(blank=True, max_length=128, null=True, region=None)),
('maps', models.URLField(blank=True, null=True)),
('location', models.TextField(blank=True)),
('date_created', models.DateTimeField(auto_now_add=True)),
('date_updated', models.DateTimeField(auto_now=True)),
('active', models.BooleanField(default=False)),
('sponsored', models.BooleanField(default=False)),
('category', models.ManyToManyField(related_name='product_categories', to='main.categories')),
('code', models.ManyToManyField(blank=True, related_name='code_store', to='main.codes')),
('country', models.ManyToManyField(blank=True, related_name='country_store', to='main.countries')),
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
('partner', models.ManyToManyField(blank=True, to='main.partners')),
('wilaya', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='main.wilayas')),
],
options={
'verbose_name_plural': 'Schools',
'ordering': ['date_created'],
},
),
migrations.CreateModel(
name='Phones',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(blank=True, max_length=200)),
('phone', phonenumber_field.modelfields.PhoneNumberField(max_length=128, region=None)),
('school', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='main.school')),
],
options={
'verbose_name_plural': 'Numéros Téléphone',
'ordering': ['id'],
},
),
migrations.CreateModel(
name='Images',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(blank=True, max_length=33)),
('file', models.ImageField(blank=True, null=True, upload_to='main/images')),
('course', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='main.courses')),
],
options={
'verbose_name_plural': 'Images',
'ordering': ['id'],
},
),
migrations.AddField(
model_name='courses',
name='partner',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='main.partners'),
),
migrations.AddField(
model_name='courses',
name='school',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='main.school'),
),
migrations.CreateModel(
name='Cities',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('city', models.CharField(blank=True, max_length=200)),
('wilaya', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='main.wilayas')),
],
options={
'verbose_name_plural': 'Villes',
'ordering': ['id'],
},
),
migrations.CreateModel(
name='Addresses',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(blank=True, max_length=200)),
('address', models.TextField()),
('school', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='main.school')),
],
options={
'verbose_name_plural': 'Adresses',
'ordering': ['id'],
},
),
]
View File
+313
View File
@@ -0,0 +1,313 @@
from django.db import models
from django.core.validators import FileExtensionValidator
from django.utils import timezone
from django.utils.text import slugify
from django.urls import reverse
from django.core.files import File
from PIL import Image, ImageDraw
from io import BytesIO
from phonenumber_field.modelfields import PhoneNumberField
class Categories(models.Model):
title = models.CharField(max_length=100, blank=True)
slug = models.SlugField(unique=True, blank=True, null=True)
picture = models.ImageField(upload_to='main/images', null=True, blank=True)
citation = models.TextField(blank=True)
date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
parentcategory = models.ManyToManyField('self', symmetrical=False, blank=True, related_name='children')
class Meta:
verbose_name_plural = 'Categories'
ordering = ['id']
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super(Categories, self).save(*args, **kwargs)
def __str__(self):
return self.title
class Images(models.Model):
title = models.CharField(max_length=33, blank=True)
course = models.ForeignKey('Courses', on_delete=models.CASCADE, blank=True, null=True)
file = models.ImageField(upload_to='main/images', blank=True, null=True)
class Meta:
verbose_name_plural = 'Images'
ordering = ['id']
IMAGE_MAX_SIZE = (900, 484)
def resize_image(self):
file = Image.open(self.file)
file.thumbnail(self.IMAGE_MAX_SIZE)
file.save(self.file.path)
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
self.resize_image()
def __str__(self):
return self.title
class Partners(models.Model):
title = models.CharField(max_length=50)
slug = models.SlugField(unique=True, blank=True, null=True)
image = models.ImageField(upload_to='main/images')
class Meta:
verbose_name_plural = 'Partners'
ordering = ['id']
IMAGE_MAX_SIZE = (300, 300)
def resize_image(self):
image = Image.open(self.image)
image.thumbnail(self.IMAGE_MAX_SIZE)
image.save(self.image.path)
def save(self, *args, **kwargs):
if not self.slug:
base_slug = slugify(self.title)
slug = base_slug
counter = 1
while Products.objects.filter(slug=slug).exists():
slug = f'{base_slug}-{counter}'
counter += 1
self.slug = slug
super().save(*args, **kwargs)
self.resize_image()
def __str__(self):
return self.title
class Cities(models.Model):
city = models.CharField(max_length=200, blank=True)
wilaya = models.ForeignKey('Wilayas', on_delete=models.CASCADE, blank=True, null=True)
class Meta:
verbose_name_plural = 'Villes'
ordering = ['id']
def __str__(self):
return self.city
class Wilayas(models.Model):
title = models.CharField(max_length=200, blank=True)
slug = models.SlugField(unique=True, blank=True, null=True)
size = models.IntegerField(blank=True, null=True)
image = models.ImageField(upload_to='main/images', blank=True, null=True)
class Meta:
verbose_name_plural = 'Wilayas'
ordering = ['id']
IMAGE_MAX_SIZE = (500, 350)
def save(self, *args, **kwargs):
if not self.slug:
base_slug = slugify(self.title)
slug = base_slug
counter = 1
while Store.objects.filter(slug=slug).exists():
slug = f'{base_slug}-{counter}'
counter += 1
self.slug = slug
super().save(*args, **kwargs)
def __str__(self):
return self.title
class Codes(models.Model):
code = models.CharField(max_length=200, blank=True)
class Meta:
verbose_name_plural = 'code Zip'
ordering = ['id']
def __str__(self):
return self.code
class Countries(models.Model):
country = models.CharField(max_length=200, blank=True)
class Meta:
verbose_name_plural = 'Pays'
ordering = ['id']
def __str__(self):
return self.country
class School(models.Model):
title = models.CharField(max_length=33)
owner = models.ForeignKey('authentication.User', on_delete=models.CASCADE)
category = models.ManyToManyField('Categories', related_name="product_categories")
partner = models.ManyToManyField('Partners', blank=True)
city = models.CharField(max_length=33, blank=True)
wilaya = models.ForeignKey('Wilayas', blank=True, null=True, on_delete=models.CASCADE)
code = models.ManyToManyField('Codes', related_name="code_store", blank=True)
country = models.ManyToManyField('Countries', related_name="country_store", blank=True)
slug = models.SlugField(unique=True, blank=True, null=True)
description = models.TextField(blank=True)
logo = models.ImageField(upload_to='main/images')
banner = models.ImageField(upload_to='main/images')
email = models.EmailField()
facebook = models.URLField(blank=True, null=True)
instagram = models.URLField(blank=True, null=True)
linkedin = models.URLField(blank=True, null=True)
youtube = models.URLField(blank=True, null=True)
website = models.URLField(blank=True, null=True)
whatsapp = PhoneNumberField(blank=True, null=True)
maps = models.URLField(blank=True, null=True)
location = models.TextField(blank=True)
date_created = models.DateTimeField(auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=False)
sponsored = models.BooleanField(default=False)
class Meta:
verbose_name_plural = 'Schools'
ordering = ['date_created']
LOGO_MAX_SIZE = (370, 200)
BANNER_MAX_SIZE = (1920, 550)
def resize_image(self):
if self.logo:
logo = Image.open(self.logo.path)
logo.thumbnail(self.LOGO_MAX_SIZE)
logo.save(self.logo.path)
if self.banner:
banner = Image.open(self.banner.path)
banner.thumbnail(self.BANNER_MAX_SIZE)
banner.save(self.banner.path)
def save(self, *args, **kwargs):
if not self.slug:
base_slug = slugify(self.title)
slug = base_slug
counter = 1
while Store.objects.filter(slug=slug).exists():
slug = f'{base_slug}-{counter}'
counter += 1
self.slug = slug
super().save(*args, **kwargs)
self.resize_image()
def get_absolute_url(self):
return reverse('main:seller_shop', kwargs={'slug': self.slug})
def __str__(self):
return self.title
class Addresses(models.Model):
title = models.CharField(max_length=200, blank=True) # Par exemple, "Maison", "Bureau", etc.
school = models.ForeignKey(School, on_delete=models.SET_NULL, null=True, blank=True)
address = models.TextField()
class Meta:
verbose_name_plural = 'Adresses'
ordering = ['id']
def __str__(self):
return self.title
class Phones(models.Model):
title = models.CharField(max_length=200, blank=True) # Par exemple, "Portable", "Bureau", etc.
phone = PhoneNumberField() # Champ pour stocker le numéro de téléphone
school = models.ForeignKey(School, on_delete=models.SET_NULL, null=True, blank=True)
class Meta:
verbose_name_plural = 'Numéros Téléphone'
ordering = ['id']
def __str__(self):
return self.title
class Courses(models.Model):
Online = 'Online'
Facetoface = 'Facetoface'
Blended = 'Blended'
ROLE_CHOICES = (
(Online, 'Online'),
(Facetoface, 'Facetoface'),
(Blended, 'Blended'),
)
title = models.CharField(max_length=33)
owner = models.ForeignKey('authentication.User', on_delete=models.CASCADE)
school = models.ForeignKey(School, on_delete=models.CASCADE, null=True, blank=True)
category = models.ManyToManyField('Categories')
slug = models.SlugField(unique=True, blank=True, null=True)
partner = models.ForeignKey('Partners', on_delete=models.CASCADE)
price = models.DecimalField(max_digits=19, decimal_places=2, default=0.0)
description = models.TextField(blank=True)
status = models.CharField(max_length=30, choices=ROLE_CHOICES, default=Online, blank=True, null=True)
date_created = models.DateTimeField(auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=False)
class Meta:
verbose_name_plural = 'Courses'
ordering = ['date_created']
IMAGE_MAX_SIZE = (500, 350)
def save(self, *args, **kwargs):
if not self.slug:
base_slug = slugify(self.title)
slug = base_slug
counter = 1
while Products.objects.filter(slug=slug).exists():
slug = f'{base_slug}-{counter}'
counter += 1
self.slug = slug
super().save(*args, **kwargs)
def get_absolute_url(self):
return reverse('main:product_detail', kwargs={'slug': self.slug})
def __str__(self):
return self.title
class Contact(models.Model):
name = models.CharField(max_length=50)
email = models.EmailField()
subject = models.CharField(max_length=50)
phone_number = PhoneNumberField()
message = models.TextField()
date_created = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = 'Contacts'
ordering = ['id']
def __str__(self):
return self.subject
class Testimonials(models.Model):
title = models.CharField(max_length=200)
testimonial = models.TextField()
date_created = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey('authentication.User', on_delete=models.CASCADE)
class Meta:
verbose_name_plural = 'Testimonials'
ordering = ['date_created']
def __str__(self):
return self.title
+8666
View File
File diff suppressed because it is too large Load Diff
+1114
View File
File diff suppressed because it is too large Load Diff
+874
View File
@@ -0,0 +1,874 @@
.carousel {
position: relative;
box-sizing: border-box;
}
.carousel *,
.carousel *:before,
.carousel *:after {
box-sizing: inherit;
}
.carousel.is-draggable {
cursor: move;
cursor: grab;
}
.carousel.is-dragging {
cursor: move;
cursor: grabbing;
}
.carousel__viewport {
position: relative;
overflow: hidden;
max-width: 100%;
max-height: 100%;
}
.carousel__track {
display: flex;
}
.carousel__slide {
flex: 0 0 auto;
width: var(--carousel-slide-width, 60%);
max-width: 100%;
padding: 1rem;
position: relative;
overflow-x: hidden;
overflow-y: auto;
overscroll-behavior: contain;
}
.has-dots {
margin-bottom: calc(0.5rem + 22px);
}
.carousel__dots {
margin: 0 auto;
padding: 0;
position: absolute;
top: calc(100% + 0.5rem);
left: 0;
right: 0;
display: flex;
justify-content: center;
list-style: none;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.carousel__dots .carousel__dot {
margin: 0;
padding: 0;
display: block;
position: relative;
width: 22px;
height: 22px;
cursor: pointer;
}
.carousel__dots .carousel__dot:after {
content: "";
width: 8px;
height: 8px;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: currentColor;
opacity: 0.25;
transition: opacity 0.15s ease-in-out;
}
.carousel__dots .carousel__dot.is-selected:after {
opacity: 1;
}
.carousel__button {
width: var(--carousel-button-width, 48px);
height: var(--carousel-button-height, 48px);
padding: 0;
border: 0;
display: flex;
justify-content: center;
align-items: center;
pointer-events: all;
cursor: pointer;
color: var(--carousel-button-color, currentColor);
background: var(--carousel-button-bg, transparent);
border-radius: var(--carousel-button-border-radius, 50%);
box-shadow: var(--carousel-button-shadow, none);
transition: opacity 0.15s ease;
}
.carousel__button.is-prev,
.carousel__button.is-next {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
.carousel__button.is-prev {
left: 10px;
}
.carousel__button.is-next {
right: 10px;
}
.carousel__button[disabled] {
cursor: default;
opacity: 0.3;
}
.carousel__button svg {
width: var(--carousel-button-svg-width, 50%);
height: var(--carousel-button-svg-height, 50%);
fill: none;
stroke: currentColor;
stroke-width: var(--carousel-button-svg-stroke-width, 1.5);
stroke-linejoin: bevel;
stroke-linecap: round;
filter: var(--carousel-button-svg-filter, none);
pointer-events: none;
}
html.with-fancybox {
scroll-behavior: auto;
}
body.compensate-for-scrollbar {
overflow: hidden !important;
touch-action: none;
}
.fancybox__container {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
direction: ltr;
margin: 0;
padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
box-sizing: border-box;
display: flex;
flex-direction: column;
color: var(--fancybox-color, #fff);
-webkit-tap-highlight-color: transparent;
overflow: hidden;
z-index: 1050;
outline: none;
transform-origin: top left;
--carousel-button-width: 48px;
--carousel-button-height: 48px;
--carousel-button-svg-width: 24px;
--carousel-button-svg-height: 24px;
--carousel-button-svg-stroke-width: 2.5;
--carousel-button-svg-filter: drop-shadow(1px 1px 1px rgba(0, 0, 0, 0.4));
}
.fancybox__container *,
.fancybox__container *::before,
.fancybox__container *::after {
box-sizing: inherit;
}
.fancybox__container :focus {
outline: none;
}
body:not(.is-using-mouse) .fancybox__container :focus {
box-shadow: 0 0 0 1px #fff, 0 0 0 2px var(--fancybox-accent-color, rgba(1, 210, 232, 0.94));
}
@media all and (min-width: 1024px) {
.fancybox__container {
--carousel-button-width: 48px;
--carousel-button-height: 48px;
--carousel-button-svg-width: 27px;
--carousel-button-svg-height: 27px;
}
}
.fancybox__backdrop {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: -1;
background: var(--fancybox-bg, rgba(24, 24, 27, 0.92));
}
.fancybox__carousel {
position: relative;
flex: 1 1 auto;
min-height: 0;
height: 100%;
z-index: 10;
}
.fancybox__carousel.has-dots {
margin-bottom: calc(0.5rem + 22px);
}
.fancybox__viewport {
position: relative;
width: 100%;
height: 100%;
overflow: visible;
cursor: default;
}
.fancybox__track {
display: flex;
height: 100%;
}
.fancybox__slide {
flex: 0 0 auto;
width: 100%;
max-width: 100%;
margin: 0;
padding: 48px 8px 8px 8px;
position: relative;
overscroll-behavior: contain;
display: flex;
flex-direction: column;
outline: 0;
overflow: auto;
--carousel-button-width: 36px;
--carousel-button-height: 36px;
--carousel-button-svg-width: 22px;
--carousel-button-svg-height: 22px;
}
.fancybox__slide::before,
.fancybox__slide::after {
content: "";
flex: 0 0 0;
margin: auto;
}
@media all and (min-width: 1024px) {
.fancybox__slide {
padding: 64px 100px;
}
}
.fancybox__content {
margin: 0 env(safe-area-inset-right, 0px) 0 env(safe-area-inset-left, 0px);
padding: 36px;
color: var(--fancybox-content-color, #374151);
background: var(--fancybox-content-bg, #fff);
position: relative;
align-self: center;
display: flex;
flex-direction: column;
z-index: 20;
}
.fancybox__content :focus:not(.carousel__button.is-close) {
outline: thin dotted;
box-shadow: none;
}
.fancybox__caption {
align-self: center;
max-width: 100%;
margin: 0;
padding: 1rem 0 0 0;
line-height: 1.375;
color: var(--fancybox-color, currentColor);
visibility: visible;
cursor: auto;
flex-shrink: 0;
overflow-wrap: anywhere;
}
.is-loading .fancybox__caption {
visibility: hidden;
}
.fancybox__container>.carousel__dots {
top: 100%;
color: var(--fancybox-color, #fff);
}
.fancybox__nav .carousel__button {
z-index: 40;
}
.fancybox__nav .carousel__button.is-next {
right: 8px;
}
@media all and (min-width: 1024px) {
.fancybox__nav .carousel__button.is-next {
right: 40px;
}
}
.fancybox__nav .carousel__button.is-prev {
left: 8px;
}
@media all and (min-width: 1024px) {
.fancybox__nav .carousel__button.is-prev {
left: 40px;
}
}
.carousel__button.is-close {
position: absolute;
top: 8px;
right: 8px;
top: calc(env(safe-area-inset-top, 0px) + 8px);
right: calc(env(safe-area-inset-right, 0px) + 8px);
z-index: 40;
}
@media all and (min-width: 1024px) {
.carousel__button.is-close {
right: 40px;
}
}
.fancybox__content>.carousel__button.is-close {
position: absolute;
top: -40px;
right: 0;
color: var(--fancybox-color, #fff);
}
.fancybox__no-click,
.fancybox__no-click button {
pointer-events: none;
}
.fancybox__spinner {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 50px;
height: 50px;
color: var(--fancybox-color, currentColor);
}
.fancybox__slide .fancybox__spinner {
cursor: pointer;
z-index: 1053;
}
.fancybox__spinner svg {
animation: fancybox-rotate 2s linear infinite;
transform-origin: center center;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
width: 100%;
height: 100%;
}
.fancybox__spinner svg circle {
fill: none;
stroke-width: 2.75;
stroke-miterlimit: 10;
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
animation: fancybox-dash 1.5s ease-in-out infinite;
stroke-linecap: round;
stroke: currentColor;
}
@keyframes fancybox-rotate {
100% {
transform: rotate(360deg);
}
}
@keyframes fancybox-dash {
0% {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -35px;
}
100% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -124px;
}
}
.fancybox__backdrop,
.fancybox__caption,
.fancybox__nav,
.carousel__dots,
.carousel__button.is-close {
opacity: var(--fancybox-opacity, 1);
}
.fancybox__container.is-animated[aria-hidden=false] .fancybox__backdrop,
.fancybox__container.is-animated[aria-hidden=false] .fancybox__caption,
.fancybox__container.is-animated[aria-hidden=false] .fancybox__nav,
.fancybox__container.is-animated[aria-hidden=false] .carousel__dots,
.fancybox__container.is-animated[aria-hidden=false] .carousel__button.is-close {
animation: 0.15s ease backwards fancybox-fadeIn;
}
.fancybox__container.is-animated.is-closing .fancybox__backdrop,
.fancybox__container.is-animated.is-closing .fancybox__caption,
.fancybox__container.is-animated.is-closing .fancybox__nav,
.fancybox__container.is-animated.is-closing .carousel__dots,
.fancybox__container.is-animated.is-closing .carousel__button.is-close {
animation: 0.15s ease both fancybox-fadeOut;
}
.fancybox-fadeIn {
animation: 0.15s ease both fancybox-fadeIn;
}
.fancybox-fadeOut {
animation: 0.1s ease both fancybox-fadeOut;
}
.fancybox-zoomInUp {
animation: 0.2s ease both fancybox-zoomInUp;
}
.fancybox-zoomOutDown {
animation: 0.15s ease both fancybox-zoomOutDown;
}
.fancybox-throwOutUp {
animation: 0.15s ease both fancybox-throwOutUp;
}
.fancybox-throwOutDown {
animation: 0.15s ease both fancybox-throwOutDown;
}
@keyframes fancybox-fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fancybox-fadeOut {
to {
opacity: 0;
}
}
@keyframes fancybox-zoomInUp {
from {
transform: scale(0.97) translate3d(0, 16px, 0);
opacity: 0;
}
to {
transform: scale(1) translate3d(0, 0, 0);
opacity: 1;
}
}
@keyframes fancybox-zoomOutDown {
to {
transform: scale(0.97) translate3d(0, 16px, 0);
opacity: 0;
}
}
@keyframes fancybox-throwOutUp {
to {
transform: translate3d(0, -30%, 0);
opacity: 0;
}
}
@keyframes fancybox-throwOutDown {
to {
transform: translate3d(0, 30%, 0);
opacity: 0;
}
}
.fancybox__carousel .carousel__slide {
scrollbar-width: thin;
scrollbar-color: #ccc rgba(255, 255, 255, 0.1);
}
.fancybox__carousel .carousel__slide::-webkit-scrollbar {
width: 8px;
height: 8px;
}
.fancybox__carousel .carousel__slide::-webkit-scrollbar-track {
background-color: rgba(255, 255, 255, 0.1);
}
.fancybox__carousel .carousel__slide::-webkit-scrollbar-thumb {
background-color: #ccc;
border-radius: 2px;
box-shadow: inset 0 0 4px rgba(0, 0, 0, 0.2);
}
.fancybox__carousel.is-draggable .fancybox__slide,
.fancybox__carousel.is-draggable .fancybox__slide .fancybox__content {
cursor: move;
cursor: grab;
}
.fancybox__carousel.is-dragging .fancybox__slide,
.fancybox__carousel.is-dragging .fancybox__slide .fancybox__content {
cursor: move;
cursor: grabbing;
}
.fancybox__carousel .fancybox__slide .fancybox__content {
cursor: auto;
}
.fancybox__carousel .fancybox__slide.can-zoom_in .fancybox__content {
cursor: zoom-in;
}
.fancybox__carousel .fancybox__slide.can-zoom_out .fancybox__content {
cursor: zoom-out;
}
.fancybox__carousel .fancybox__slide.is-draggable .fancybox__content {
cursor: move;
cursor: grab;
}
.fancybox__carousel .fancybox__slide.is-dragging .fancybox__content {
cursor: move;
cursor: grabbing;
}
.fancybox__image {
transform-origin: 0 0;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
transition: none;
}
.has-image .fancybox__content {
padding: 0;
background: transparent;
min-height: 1px;
}
.is-closing .has-image .fancybox__content {
overflow: visible;
}
.has-image[data-image-fit=contain] {
overflow: visible;
touch-action: none;
}
.has-image[data-image-fit=contain] .fancybox__content {
flex-direction: row;
flex-wrap: wrap;
}
.has-image[data-image-fit=contain] .fancybox__image {
max-width: 100%;
max-height: 100%;
-o-object-fit: contain;
object-fit: contain;
}
.has-image[data-image-fit=contain-w] {
overflow-x: hidden;
overflow-y: auto;
}
.has-image[data-image-fit=contain-w] .fancybox__content {
min-height: auto;
}
.has-image[data-image-fit=contain-w] .fancybox__image {
max-width: 100%;
height: auto;
}
.has-image[data-image-fit=cover] {
overflow: visible;
touch-action: none;
}
.has-image[data-image-fit=cover] .fancybox__content {
width: 100%;
height: 100%;
}
.has-image[data-image-fit=cover] .fancybox__image {
width: 100%;
height: 100%;
-o-object-fit: cover;
object-fit: cover;
}
.fancybox__carousel .fancybox__slide.has-iframe .fancybox__content,
.fancybox__carousel .fancybox__slide.has-map .fancybox__content,
.fancybox__carousel .fancybox__slide.has-pdf .fancybox__content,
.fancybox__carousel .fancybox__slide.has-video .fancybox__content,
.fancybox__carousel .fancybox__slide.has-html5video .fancybox__content {
max-width: 100%;
flex-shrink: 1;
min-height: 1px;
overflow: visible;
}
.fancybox__carousel .fancybox__slide.has-iframe .fancybox__content,
.fancybox__carousel .fancybox__slide.has-map .fancybox__content,
.fancybox__carousel .fancybox__slide.has-pdf .fancybox__content {
width: 100%;
height: 80%;
}
.fancybox__carousel .fancybox__slide.has-video .fancybox__content,
.fancybox__carousel .fancybox__slide.has-html5video .fancybox__content {
width: 960px;
height: 540px;
max-width: 100%;
max-height: 100%;
}
.fancybox__carousel .fancybox__slide.has-map .fancybox__content,
.fancybox__carousel .fancybox__slide.has-pdf .fancybox__content,
.fancybox__carousel .fancybox__slide.has-video .fancybox__content,
.fancybox__carousel .fancybox__slide.has-html5video .fancybox__content {
padding: 0;
background: rgba(24, 24, 27, 0.9);
color: #fff;
}
.fancybox__carousel .fancybox__slide.has-map .fancybox__content {
background: #e5e3df;
}
.fancybox__html5video,
.fancybox__iframe {
border: 0;
display: block;
height: 100%;
width: 100%;
background: transparent;
}
.fancybox-placeholder {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}
.fancybox__thumbs {
flex: 0 0 auto;
position: relative;
padding: 0px 3px;
opacity: var(--fancybox-opacity, 1);
}
.fancybox__container.is-animated[aria-hidden=false] .fancybox__thumbs {
animation: 0.15s ease-in backwards fancybox-fadeIn;
}
.fancybox__container.is-animated.is-closing .fancybox__thumbs {
opacity: 0;
}
.fancybox__thumbs .carousel__slide {
flex: 0 0 auto;
width: var(--fancybox-thumbs-width, 96px);
margin: 0;
padding: 8px 3px;
box-sizing: content-box;
display: flex;
align-items: center;
justify-content: center;
overflow: visible;
cursor: pointer;
}
.fancybox__thumbs .carousel__slide .fancybox__thumb::after {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-width: 5px;
border-style: solid;
border-color: var(--fancybox-accent-color, rgba(34, 213, 233, 0.96));
opacity: 0;
transition: opacity 0.15s ease;
border-radius: var(--fancybox-thumbs-border-radius, 4px);
}
.fancybox__thumbs .carousel__slide.is-nav-selected .fancybox__thumb::after {
opacity: 0.92;
}
.fancybox__thumbs .carousel__slide>* {
pointer-events: none;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.fancybox__thumb {
position: relative;
width: 100%;
padding-top: calc(100% / (var(--fancybox-thumbs-ratio, 1.5)));
background-size: cover;
background-position: center center;
background-color: rgba(255, 255, 255, 0.1);
background-repeat: no-repeat;
border-radius: var(--fancybox-thumbs-border-radius, 4px);
}
.fancybox__toolbar {
position: absolute;
top: 0;
right: 0;
left: 0;
z-index: 20;
background: linear-gradient(to top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.006) 8.1%, rgba(0, 0, 0, 0.021) 15.5%, rgba(0, 0, 0, 0.046) 22.5%, rgba(0, 0, 0, 0.077) 29%, rgba(0, 0, 0, 0.114) 35.3%, rgba(0, 0, 0, 0.155) 41.2%, rgba(0, 0, 0, 0.198) 47.1%, rgba(0, 0, 0, 0.242) 52.9%, rgba(0, 0, 0, 0.285) 58.8%, rgba(0, 0, 0, 0.326) 64.7%, rgba(0, 0, 0, 0.363) 71%, rgba(0, 0, 0, 0.394) 77.5%, rgba(0, 0, 0, 0.419) 84.5%, rgba(0, 0, 0, 0.434) 91.9%, rgba(0, 0, 0, 0.44) 100%);
padding: 0;
touch-action: none;
display: flex;
justify-content: space-between;
--carousel-button-svg-width: 20px;
--carousel-button-svg-height: 20px;
opacity: var(--fancybox-opacity, 1);
text-shadow: var(--fancybox-toolbar-text-shadow, 1px 1px 1px rgba(0, 0, 0, 0.4));
}
@media all and (min-width: 1024px) {
.fancybox__toolbar {
padding: 8px;
}
}
.fancybox__container.is-animated[aria-hidden=false] .fancybox__toolbar {
animation: 0.15s ease-in backwards fancybox-fadeIn;
}
.fancybox__container.is-animated.is-closing .fancybox__toolbar {
opacity: 0;
}
.fancybox__toolbar__items {
display: flex;
}
.fancybox__toolbar__items--left {
margin-right: auto;
}
.fancybox__toolbar__items--center {
position: absolute;
left: 50%;
transform: translateX(-50%);
}
.fancybox__toolbar__items--right {
margin-left: auto;
}
@media (max-width: 640px) {
.fancybox__toolbar__items--center:not(:last-child) {
display: none;
}
}
.fancybox__counter {
min-width: 72px;
padding: 0 10px;
line-height: var(--carousel-button-height, 48px);
text-align: center;
font-size: 17px;
font-variant-numeric: tabular-nums;
-webkit-font-smoothing: subpixel-antialiased;
}
.fancybox__progress {
background: var(--fancybox-accent-color, rgba(34, 213, 233, 0.96));
height: 3px;
left: 0;
position: absolute;
right: 0;
top: 0;
transform: scaleX(0);
transform-origin: 0;
transition-property: transform;
transition-timing-function: linear;
z-index: 30;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.fancybox__container:-webkit-full-screen::backdrop {
opacity: 0;
}
.fancybox__container:fullscreen::backdrop {
opacity: 0;
}
.fancybox__button--fullscreen g:nth-child(2) {
display: none;
}
.fancybox__container:-webkit-full-screen .fancybox__button--fullscreen g:nth-child(1) {
display: none;
}
.fancybox__container:fullscreen .fancybox__button--fullscreen g:nth-child(1) {
display: none;
}
.fancybox__container:-webkit-full-screen .fancybox__button--fullscreen g:nth-child(2) {
display: block;
}
.fancybox__container:fullscreen .fancybox__button--fullscreen g:nth-child(2) {
display: block;
}
.fancybox__button--slideshow g:nth-child(2) {
display: none;
}
.fancybox__container.has-slideshow .fancybox__button--slideshow g:nth-child(1) {
display: none;
}
.fancybox__container.has-slideshow .fancybox__button--slideshow g:nth-child(2) {
display: block;
}
File diff suppressed because it is too large Load Diff
+435
View File
@@ -0,0 +1,435 @@
/* Magnific Popup CSS */
.mfp-bg {
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1042;
overflow: hidden;
position: fixed;
background: #0b0b0b;
opacity: 0.8;
}
.mfp-wrap {
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1043;
position: fixed;
outline: none !important;
-webkit-backface-visibility: hidden;
}
.mfp-container {
text-align: center;
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
padding: 0 8px;
box-sizing: border-box;
}
.mfp-container:before {
content: "";
display: inline-block;
height: 100%;
vertical-align: middle;
}
.mfp-align-top .mfp-container:before {
display: none;
}
.mfp-content {
position: relative;
display: inline-block;
vertical-align: middle;
margin: 0 auto;
text-align: left;
z-index: 1045;
}
.mfp-inline-holder .mfp-content,
.mfp-ajax-holder .mfp-content {
width: 100%;
cursor: auto;
}
.mfp-ajax-cur {
cursor: progress;
}
.mfp-zoom-out-cur,
.mfp-zoom-out-cur .mfp-image-holder .mfp-close {
cursor: zoom-out;
}
.mfp-zoom {
cursor: pointer;
cursor: zoom-in;
}
.mfp-auto-cursor .mfp-content {
cursor: auto;
}
.mfp-close,
.mfp-arrow,
.mfp-preloader,
.mfp-counter {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.mfp-loading.mfp-figure {
display: none;
}
.mfp-hide {
display: none !important;
}
.mfp-preloader {
color: #CCC;
position: absolute;
top: 50%;
width: auto;
text-align: center;
margin-top: -0.8em;
left: 8px;
right: 8px;
z-index: 1044;
}
.mfp-preloader a {
color: #CCC;
}
.mfp-preloader a:hover {
color: #FFF;
}
.mfp-s-ready .mfp-preloader {
display: none;
}
.mfp-s-error .mfp-content {
display: none;
}
button.mfp-close,
button.mfp-arrow {
overflow: visible;
cursor: pointer;
background: transparent;
border: 0;
-webkit-appearance: none;
display: block;
outline: none;
padding: 0;
z-index: 1046;
box-shadow: none;
touch-action: manipulation;
}
button::-moz-focus-inner {
padding: 0;
border: 0;
}
.mfp-close {
width: 44px;
height: 44px;
line-height: 44px;
position: absolute;
right: 0;
top: 0;
text-decoration: none;
text-align: center;
opacity: 0.65;
padding: 0 0 18px 10px;
color: #FFF;
font-style: normal;
font-size: 28px;
font-family: Arial, Baskerville, monospace;
}
.mfp-close:hover,
.mfp-close:focus {
opacity: 1;
}
.mfp-close:active {
top: 1px;
}
.mfp-close-btn-in .mfp-close {
color: #333;
}
.mfp-image-holder .mfp-close,
.mfp-iframe-holder .mfp-close {
color: #FFF;
right: -6px;
text-align: right;
padding-right: 6px;
width: 100%;
}
.mfp-counter {
position: absolute;
top: 0;
right: 0;
color: #CCC;
font-size: 12px;
line-height: 18px;
white-space: nowrap;
}
.mfp-arrow {
position: absolute;
opacity: 0.65;
margin: 0;
top: 50%;
margin-top: -55px;
padding: 0;
width: 90px;
height: 110px;
-webkit-tap-highlight-color: transparent;
}
.mfp-arrow:active {
margin-top: -54px;
}
.mfp-arrow:hover,
.mfp-arrow:focus {
opacity: 1;
}
.mfp-arrow:before,
.mfp-arrow:after {
content: "";
display: block;
width: 0;
height: 0;
position: absolute;
left: 0;
top: 0;
margin-top: 35px;
margin-left: 35px;
border: medium inset transparent;
}
.mfp-arrow:after {
border-top-width: 13px;
border-bottom-width: 13px;
top: 8px;
}
.mfp-arrow:before {
border-top-width: 21px;
border-bottom-width: 21px;
opacity: 0.7;
}
.mfp-arrow-left {
left: 0;
}
.mfp-arrow-left:after {
border-right: 17px solid #FFF;
margin-left: 31px;
}
.mfp-arrow-left:before {
margin-left: 25px;
border-right: 27px solid #3F3F3F;
}
.mfp-arrow-right {
right: 0;
}
.mfp-arrow-right:after {
border-left: 17px solid #FFF;
margin-left: 39px;
}
.mfp-arrow-right:before {
border-left: 27px solid #3F3F3F;
}
.mfp-iframe-holder {
padding-top: 40px;
padding-bottom: 40px;
}
.mfp-iframe-holder .mfp-content {
line-height: 0;
width: 100%;
max-width: 900px;
}
.mfp-iframe-holder .mfp-close {
top: -40px;
}
.mfp-iframe-scaler {
width: 100%;
height: 0;
overflow: hidden;
padding-top: 56.25%;
}
.mfp-iframe-scaler iframe {
position: absolute;
display: block;
top: 0;
left: 0;
width: 100%;
height: 100%;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
background: #000;
}
/* Main image in popup */
img.mfp-img {
width: auto;
max-width: 100%;
height: auto;
display: block;
line-height: 0;
box-sizing: border-box;
padding: 40px 0 40px;
margin: 0 auto;
}
/* The shadow behind the image */
.mfp-figure {
line-height: 0;
}
.mfp-figure:after {
content: "";
position: absolute;
left: 0;
top: 40px;
bottom: 40px;
display: block;
right: 0;
width: auto;
height: auto;
z-index: -1;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
background: #444;
}
.mfp-figure small {
color: #BDBDBD;
display: block;
font-size: 12px;
line-height: 14px;
}
.mfp-figure figure {
margin: 0;
}
.mfp-bottom-bar {
margin-top: -36px;
position: absolute;
top: 100%;
left: 0;
width: 100%;
cursor: auto;
}
.mfp-title {
text-align: left;
line-height: 18px;
color: #F3F3F3;
word-wrap: break-word;
padding-right: 36px;
}
.mfp-image-holder .mfp-content {
max-width: 100%;
}
.mfp-gallery .mfp-image-holder .mfp-figure {
cursor: pointer;
}
@media screen and (max-width: 800px) and (orientation: landscape),
screen and (max-height: 300px) {
/**
* Remove all paddings around the image on small screen
*/
.mfp-img-mobile .mfp-image-holder {
padding-left: 0;
padding-right: 0;
}
.mfp-img-mobile img.mfp-img {
padding: 0;
}
.mfp-img-mobile .mfp-figure:after {
top: 0;
bottom: 0;
}
.mfp-img-mobile .mfp-figure small {
display: inline;
margin-left: 5px;
}
.mfp-img-mobile .mfp-bottom-bar {
background: rgba(0, 0, 0, 0.6);
bottom: 0;
margin: 0;
top: auto;
padding: 3px 5px;
position: fixed;
box-sizing: border-box;
}
.mfp-img-mobile .mfp-bottom-bar:empty {
padding: 0;
}
.mfp-img-mobile .mfp-counter {
right: 5px;
top: 3px;
}
.mfp-img-mobile .mfp-close {
top: 0;
right: 0;
width: 35px;
height: 35px;
line-height: 35px;
background: rgba(0, 0, 0, 0.6);
position: fixed;
text-align: center;
padding: 0;
}
}
@media all and (max-width: 900px) {
.mfp-arrow {
transform: scale(0.75);
}
.mfp-arrow-left {
transform-origin: 0;
}
.mfp-arrow-right {
transform-origin: 100%;
}
.mfp-container {
padding-left: 6px;
padding-right: 6px;
}
}
+167
View File
@@ -0,0 +1,167 @@
.nice-select {
background-color: #fff;
border-radius: 5px;
border: solid 1px #e8e8e8;
box-sizing: border-box;
clear: both;
cursor: pointer;
display: block;
float: left;
font-family: inherit;
font-size: 14px;
font-weight: normal;
height: 42px;
line-height: 40px;
outline: none;
padding-left: 18px;
padding-right: 30px;
position: relative;
text-align: left !important;
transition: all 0.2s ease-in-out;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
white-space: nowrap;
width: auto;
}
.nice-select:hover {
border-color: #dbdbdb;
}
.nice-select:active,
.nice-select.open,
.nice-select:focus {
border-color: #999;
}
.nice-select:after {
border-bottom: 2px solid #999;
border-right: 2px solid #999;
content: "";
display: block;
height: 5px;
margin-top: -4px;
pointer-events: none;
position: absolute;
right: 12px;
top: 50%;
transform-origin: 66% 66%;
transform: rotate(45deg);
transition: all 0.15s ease-in-out;
width: 5px;
}
.nice-select.open:after {
transform: rotate(-135deg);
}
.nice-select.open .list {
opacity: 1;
pointer-events: auto;
transform: scale(1) translateY(0);
}
.nice-select.disabled {
border-color: #ededed;
color: #999;
pointer-events: none;
}
.nice-select.disabled:after {
border-color: #cccccc;
}
.nice-select.wide {
width: 100%;
}
.nice-select.wide .list {
left: 0 !important;
right: 0 !important;
}
.nice-select.right {
float: right;
}
.nice-select.right .list {
left: auto;
right: 0;
}
.nice-select.small {
font-size: 12px;
height: 36px;
line-height: 34px;
}
.nice-select.small:after {
height: 4px;
width: 4px;
}
.nice-select.small .option {
line-height: 34px;
min-height: 34px;
}
.nice-select .list {
background-color: #fff;
border-radius: 5px;
box-shadow: 0 0 0 1px rgba(68, 68, 68, 0.11);
box-sizing: border-box;
margin-top: 4px;
opacity: 0;
overflow: hidden;
padding: 0;
pointer-events: none;
position: absolute;
top: 100%;
left: 0;
transform-origin: 50% 0;
transform: scale(0.75) translateY(-21px);
transition: all 0.2s cubic-bezier(0.5, 0, 0, 1.25), opacity 0.15s ease-out;
z-index: 9;
}
.nice-select .list:hover .option:not(:hover) {
background-color: transparent !important;
}
.nice-select .option {
cursor: pointer;
font-weight: 400;
line-height: 40px;
list-style: none;
min-height: 40px;
outline: none;
padding-left: 18px;
padding-right: 29px;
text-align: left;
transition: all 0.2s;
}
.nice-select .option:hover,
.nice-select .option.focus,
.nice-select .option.selected.focus {
background-color: #f6f6f6;
}
.nice-select .option.selected {
font-weight: bold;
}
.nice-select .option.disabled {
background-color: transparent;
color: #999;
cursor: default;
}
.no-csspointerevents .nice-select .list {
display: none;
}
.no-csspointerevents .nice-select.open .list {
display: block;
}
+450
View File
@@ -0,0 +1,450 @@
/**
* Settings
*/
/**
* Easings
*/
/**
* Core
*/
[data-sal] {
transition-duration: 0.2s;
transition-delay: 0s;
transition-duration: var(--sal-duration, 0.2s);
transition-delay: var(--sal-delay, 0s);
transition-timing-function: var(--sal-easing, ease);
}
[data-sal][data-sal-duration="200"] {
transition-duration: 0.2s;
}
[data-sal][data-sal-duration="250"] {
transition-duration: 0.25s;
}
[data-sal][data-sal-duration="300"] {
transition-duration: 0.3s;
}
[data-sal][data-sal-duration="350"] {
transition-duration: 0.35s;
}
[data-sal][data-sal-duration="400"] {
transition-duration: 0.4s;
}
[data-sal][data-sal-duration="450"] {
transition-duration: 0.45s;
}
[data-sal][data-sal-duration="500"] {
transition-duration: 0.5s;
}
[data-sal][data-sal-duration="550"] {
transition-duration: 0.55s;
}
[data-sal][data-sal-duration="600"] {
transition-duration: 0.6s;
}
[data-sal][data-sal-duration="650"] {
transition-duration: 0.65s;
}
[data-sal][data-sal-duration="700"] {
transition-duration: 0.7s;
}
[data-sal][data-sal-duration="750"] {
transition-duration: 0.75s;
}
[data-sal][data-sal-duration="800"] {
transition-duration: 0.8s;
}
[data-sal][data-sal-duration="850"] {
transition-duration: 0.85s;
}
[data-sal][data-sal-duration="900"] {
transition-duration: 0.9s;
}
[data-sal][data-sal-duration="950"] {
transition-duration: 0.95s;
}
[data-sal][data-sal-duration="1000"] {
transition-duration: 1s;
}
[data-sal][data-sal-duration="1050"] {
transition-duration: 1.05s;
}
[data-sal][data-sal-duration="1100"] {
transition-duration: 1.1s;
}
[data-sal][data-sal-duration="1150"] {
transition-duration: 1.15s;
}
[data-sal][data-sal-duration="1200"] {
transition-duration: 1.2s;
}
[data-sal][data-sal-duration="1250"] {
transition-duration: 1.25s;
}
[data-sal][data-sal-duration="1300"] {
transition-duration: 1.3s;
}
[data-sal][data-sal-duration="1350"] {
transition-duration: 1.35s;
}
[data-sal][data-sal-duration="1400"] {
transition-duration: 1.4s;
}
[data-sal][data-sal-duration="1450"] {
transition-duration: 1.45s;
}
[data-sal][data-sal-duration="1500"] {
transition-duration: 1.5s;
}
[data-sal][data-sal-duration="1550"] {
transition-duration: 1.55s;
}
[data-sal][data-sal-duration="1600"] {
transition-duration: 1.6s;
}
[data-sal][data-sal-duration="1650"] {
transition-duration: 1.65s;
}
[data-sal][data-sal-duration="1700"] {
transition-duration: 1.7s;
}
[data-sal][data-sal-duration="1750"] {
transition-duration: 1.75s;
}
[data-sal][data-sal-duration="1800"] {
transition-duration: 1.8s;
}
[data-sal][data-sal-duration="1850"] {
transition-duration: 1.85s;
}
[data-sal][data-sal-duration="1900"] {
transition-duration: 1.9s;
}
[data-sal][data-sal-duration="1950"] {
transition-duration: 1.95s;
}
[data-sal][data-sal-duration="2000"] {
transition-duration: 2s;
}
[data-sal][data-sal-delay="50"] {
transition-delay: 0.05s;
}
[data-sal][data-sal-delay="100"] {
transition-delay: 0.1s;
}
[data-sal][data-sal-delay="150"] {
transition-delay: 0.15s;
}
[data-sal][data-sal-delay="200"] {
transition-delay: 0.2s;
}
[data-sal][data-sal-delay="250"] {
transition-delay: 0.25s;
}
[data-sal][data-sal-delay="300"] {
transition-delay: 0.3s;
}
[data-sal][data-sal-delay="350"] {
transition-delay: 0.35s;
}
[data-sal][data-sal-delay="400"] {
transition-delay: 0.4s;
}
[data-sal][data-sal-delay="450"] {
transition-delay: 0.45s;
}
[data-sal][data-sal-delay="500"] {
transition-delay: 0.5s;
}
[data-sal][data-sal-delay="550"] {
transition-delay: 0.55s;
}
[data-sal][data-sal-delay="600"] {
transition-delay: 0.6s;
}
[data-sal][data-sal-delay="650"] {
transition-delay: 0.65s;
}
[data-sal][data-sal-delay="700"] {
transition-delay: 0.7s;
}
[data-sal][data-sal-delay="750"] {
transition-delay: 0.75s;
}
[data-sal][data-sal-delay="800"] {
transition-delay: 0.8s;
}
[data-sal][data-sal-delay="850"] {
transition-delay: 0.85s;
}
[data-sal][data-sal-delay="900"] {
transition-delay: 0.9s;
}
[data-sal][data-sal-delay="950"] {
transition-delay: 0.95s;
}
[data-sal][data-sal-delay="1000"] {
transition-delay: 1s;
}
[data-sal][data-sal-easing=linear] {
transition-timing-function: linear;
}
[data-sal][data-sal-easing=ease] {
transition-timing-function: ease;
}
[data-sal][data-sal-easing=ease-in] {
transition-timing-function: ease-in;
}
[data-sal][data-sal-easing=ease-out] {
transition-timing-function: ease-out;
}
[data-sal][data-sal-easing=ease-in-out] {
transition-timing-function: ease-in-out;
}
[data-sal][data-sal-easing=ease-in-cubic] {
transition-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
}
[data-sal][data-sal-easing=ease-out-cubic] {
transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}
[data-sal][data-sal-easing=ease-in-out-cubic] {
transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);
}
[data-sal][data-sal-easing=ease-in-circ] {
transition-timing-function: cubic-bezier(0.6, 0.04, 0.98, 0.335);
}
[data-sal][data-sal-easing=ease-out-circ] {
transition-timing-function: cubic-bezier(0.075, 0.82, 0.165, 1);
}
[data-sal][data-sal-easing=ease-in-out-circ] {
transition-timing-function: cubic-bezier(0.785, 0.135, 0.15, 0.86);
}
[data-sal][data-sal-easing=ease-in-expo] {
transition-timing-function: cubic-bezier(0.95, 0.05, 0.795, 0.035);
}
[data-sal][data-sal-easing=ease-out-expo] {
transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1);
}
[data-sal][data-sal-easing=ease-in-out-expo] {
transition-timing-function: cubic-bezier(1, 0, 0, 1);
}
[data-sal][data-sal-easing=ease-in-quad] {
transition-timing-function: cubic-bezier(0.55, 0.085, 0.68, 0.53);
}
[data-sal][data-sal-easing=ease-out-quad] {
transition-timing-function: cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
[data-sal][data-sal-easing=ease-in-out-quad] {
transition-timing-function: cubic-bezier(0.455, 0.03, 0.515, 0.955);
}
[data-sal][data-sal-easing=ease-in-quart] {
transition-timing-function: cubic-bezier(0.895, 0.03, 0.685, 0.22);
}
[data-sal][data-sal-easing=ease-out-quart] {
transition-timing-function: cubic-bezier(0.165, 0.84, 0.44, 1);
}
[data-sal][data-sal-easing=ease-in-out-quart] {
transition-timing-function: cubic-bezier(0.77, 0, 0.175, 1);
}
[data-sal][data-sal-easing=ease-in-quint] {
transition-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
}
[data-sal][data-sal-easing=ease-out-quint] {
transition-timing-function: cubic-bezier(0.23, 1, 0.32, 1);
}
[data-sal][data-sal-easing=ease-in-out-quint] {
transition-timing-function: cubic-bezier(0.86, 0, 0.07, 1);
}
[data-sal][data-sal-easing=ease-in-sine] {
transition-timing-function: cubic-bezier(0.47, 0, 0.745, 0.715);
}
[data-sal][data-sal-easing=ease-out-sine] {
transition-timing-function: cubic-bezier(0.39, 0.575, 0.565, 1);
}
[data-sal][data-sal-easing=ease-in-out-sine] {
transition-timing-function: cubic-bezier(0.445, 0.05, 0.55, 0.95);
}
[data-sal][data-sal-easing=ease-in-back] {
transition-timing-function: cubic-bezier(0.6, -0.28, 0.735, 0.045);
}
[data-sal][data-sal-easing=ease-out-back] {
transition-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
[data-sal][data-sal-easing=ease-in-out-back] {
transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
/**
* Animations
*/
[data-sal|=fade] {
opacity: 0;
transition-property: opacity;
}
[data-sal|=fade].sal-animate,
body.sal-disabled [data-sal|=fade] {
opacity: 1;
}
[data-sal|=slide] {
opacity: 0;
transition-property: opacity, transform;
}
[data-sal=slide-up] {
transform: translateY(20%);
}
[data-sal=slide-down] {
transform: translateY(-20%);
}
[data-sal=slide-left] {
transform: translateX(20%);
}
[data-sal=slide-right] {
transform: translateX(-20%);
}
[data-sal|=slide].sal-animate,
body.sal-disabled [data-sal|=slide] {
opacity: 1;
transform: none;
}
[data-sal|=zoom] {
opacity: 0;
transition-property: opacity, transform;
}
[data-sal=zoom-in] {
transform: scale(0.5);
}
[data-sal=zoom-out] {
transform: scale(1.1);
}
[data-sal|=zoom].sal-animate,
body.sal-disabled [data-sal|=zoom] {
opacity: 1;
transform: none;
}
[data-sal|=flip] {
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
transition-property: transform;
}
[data-sal=flip-left] {
transform: perspective(2000px) rotateY(-91deg);
}
[data-sal=flip-right] {
transform: perspective(2000px) rotateY(91deg);
}
[data-sal=flip-up] {
transform: perspective(2000px) rotateX(-91deg);
}
[data-sal=flip-down] {
transform: perspective(2000px) rotateX(91deg);
}
[data-sal|=flip].sal-animate,
body.sal-disabled [data-sal|=flip] {
transform: none;
}
+210
View File
@@ -0,0 +1,210 @@
[data-simplebar] {
position: relative;
flex-direction: column;
flex-wrap: wrap;
justify-content: flex-start;
align-content: flex-start;
align-items: flex-start;
}
.simplebar-wrapper {
overflow: hidden;
width: inherit;
height: inherit;
max-width: inherit;
max-height: inherit;
}
.simplebar-mask {
direction: inherit;
position: absolute;
overflow: hidden;
padding: 0;
margin: 0;
left: 0;
top: 0;
bottom: 0;
right: 0;
width: auto !important;
height: auto !important;
z-index: 0;
}
.simplebar-offset {
direction: inherit !important;
box-sizing: inherit !important;
resize: none !important;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
padding: 0;
margin: 0;
-webkit-overflow-scrolling: touch;
}
.simplebar-content-wrapper {
direction: inherit;
box-sizing: border-box !important;
position: relative;
display: block;
height: 100%;
width: auto;
max-width: 100%;
max-height: 100%;
scrollbar-width: none;
-ms-overflow-style: none;
}
.simplebar-content-wrapper::-webkit-scrollbar,
.simplebar-hide-scrollbar::-webkit-scrollbar {
width: 0;
height: 0;
}
.simplebar-content:before,
.simplebar-content:after {
content: " ";
display: table;
}
.simplebar-placeholder {
max-height: 100%;
max-width: 100%;
width: 100%;
pointer-events: none;
}
.simplebar-height-auto-observer-wrapper {
box-sizing: inherit !important;
height: 100%;
width: 100%;
max-width: 1px;
position: relative;
float: left;
max-height: 1px;
overflow: hidden;
z-index: -1;
padding: 0;
margin: 0;
pointer-events: none;
flex-grow: inherit;
flex-shrink: 0;
flex-basis: 0;
}
.simplebar-height-auto-observer {
box-sizing: inherit;
display: block;
opacity: 0;
position: absolute;
top: 0;
left: 0;
height: 1000%;
width: 1000%;
min-height: 1px;
min-width: 1px;
overflow: hidden;
pointer-events: none;
z-index: -1;
}
.simplebar-track {
z-index: 1;
position: absolute;
right: 0;
bottom: 0;
pointer-events: none;
overflow: hidden;
}
.simplebar-track.simplebar-vertical {
top: 0;
width: 11px;
}
.simplebar-track.simplebar-vertical .simplebar-scrollbar:before {
top: 2px;
bottom: 2px;
}
.simplebar-track.simplebar-horizontal {
left: 0;
height: 11px;
}
.simplebar-track.simplebar-horizontal .simplebar-scrollbar {
right: auto;
left: 0;
top: 2px;
height: 7px;
min-height: 0;
min-width: 10px;
width: auto;
}
.simplebar-track.simplebar-horizontal .simplebar-scrollbar:before {
height: 100%;
left: 2px;
right: 2px;
}
[data-simplebar].simplebar-dragging .simplebar-content {
pointer-events: none;
-moz-user-select: none;
user-select: none;
-webkit-user-select: none;
}
[data-simplebar].simplebar-dragging .simplebar-track {
pointer-events: all;
}
.simplebar-scrollbar {
position: absolute;
left: 0;
right: 0;
min-height: 10px;
}
.simplebar-scrollbar:before {
position: absolute;
content: "";
background: black;
border-radius: 7px;
left: 2px;
right: 2px;
opacity: 0;
transition: opacity 0.2s linear;
}
.simplebar-scrollbar.simplebar-visible:before {
opacity: 0.5;
transition: opacity 0s linear;
}
[data-simplebar-direction=rtl] .simplebar-track.simplebar-vertical {
right: auto;
left: 0;
}
.hs-dummy-scrollbar-size {
direction: rtl;
position: fixed;
opacity: 0;
visibility: hidden;
height: 500px;
width: 500px;
overflow-y: hidden;
overflow-x: scroll;
}
.simplebar-hide-scrollbar {
position: fixed;
left: 0;
visibility: hidden;
overflow-y: scroll;
scrollbar-width: none;
-ms-overflow-style: none;
}
+707
View File
@@ -0,0 +1,707 @@
/**
* Swiper 8.0.6
* Most modern mobile touch slider and framework with hardware accelerated transitions
* https://swiperjs.com
*
* Copyright 2014-2022 Vladimir Kharlampidi
*
* Released under the MIT License
*
* Released on: February 14, 2022
*/
@font-face {
font-family: swiper-icons;
src: url("data:application/font-woff;charset=utf-8;base64, d09GRgABAAAAAAZgABAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAAGRAAAABoAAAAci6qHkUdERUYAAAWgAAAAIwAAACQAYABXR1BPUwAABhQAAAAuAAAANuAY7+xHU1VCAAAFxAAAAFAAAABm2fPczU9TLzIAAAHcAAAASgAAAGBP9V5RY21hcAAAAkQAAACIAAABYt6F0cBjdnQgAAACzAAAAAQAAAAEABEBRGdhc3AAAAWYAAAACAAAAAj//wADZ2x5ZgAAAywAAADMAAAD2MHtryVoZWFkAAABbAAAADAAAAA2E2+eoWhoZWEAAAGcAAAAHwAAACQC9gDzaG10eAAAAigAAAAZAAAArgJkABFsb2NhAAAC0AAAAFoAAABaFQAUGG1heHAAAAG8AAAAHwAAACAAcABAbmFtZQAAA/gAAAE5AAACXvFdBwlwb3N0AAAFNAAAAGIAAACE5s74hXjaY2BkYGAAYpf5Hu/j+W2+MnAzMYDAzaX6QjD6/4//Bxj5GA8AuRwMYGkAPywL13jaY2BkYGA88P8Agx4j+/8fQDYfA1AEBWgDAIB2BOoAeNpjYGRgYNBh4GdgYgABEMnIABJzYNADCQAACWgAsQB42mNgYfzCOIGBlYGB0YcxjYGBwR1Kf2WQZGhhYGBiYGVmgAFGBiQQkOaawtDAoMBQxXjg/wEGPcYDDA4wNUA2CCgwsAAAO4EL6gAAeNpj2M0gyAACqxgGNWBkZ2D4/wMA+xkDdgAAAHjaY2BgYGaAYBkGRgYQiAHyGMF8FgYHIM3DwMHABGQrMOgyWDLEM1T9/w8UBfEMgLzE////P/5//f/V/xv+r4eaAAeMbAxwIUYmIMHEgKYAYjUcsDAwsLKxc3BycfPw8jEQA/gZBASFhEVExcQlJKWkZWTl5BUUlZRVVNXUNTQZBgMAAMR+E+gAEQFEAAAAKgAqACoANAA+AEgAUgBcAGYAcAB6AIQAjgCYAKIArAC2AMAAygDUAN4A6ADyAPwBBgEQARoBJAEuATgBQgFMAVYBYAFqAXQBfgGIAZIBnAGmAbIBzgHsAAB42u2NMQ6CUAyGW568x9AneYYgm4MJbhKFaExIOAVX8ApewSt4Bic4AfeAid3VOBixDxfPYEza5O+Xfi04YADggiUIULCuEJK8VhO4bSvpdnktHI5QCYtdi2sl8ZnXaHlqUrNKzdKcT8cjlq+rwZSvIVczNiezsfnP/uznmfPFBNODM2K7MTQ45YEAZqGP81AmGGcF3iPqOop0r1SPTaTbVkfUe4HXj97wYE+yNwWYxwWu4v1ugWHgo3S1XdZEVqWM7ET0cfnLGxWfkgR42o2PvWrDMBSFj/IHLaF0zKjRgdiVMwScNRAoWUoH78Y2icB/yIY09An6AH2Bdu/UB+yxopYshQiEvnvu0dURgDt8QeC8PDw7Fpji3fEA4z/PEJ6YOB5hKh4dj3EvXhxPqH/SKUY3rJ7srZ4FZnh1PMAtPhwP6fl2PMJMPDgeQ4rY8YT6Gzao0eAEA409DuggmTnFnOcSCiEiLMgxCiTI6Cq5DZUd3Qmp10vO0LaLTd2cjN4fOumlc7lUYbSQcZFkutRG7g6JKZKy0RmdLY680CDnEJ+UMkpFFe1RN7nxdVpXrC4aTtnaurOnYercZg2YVmLN/d/gczfEimrE/fs/bOuq29Zmn8tloORaXgZgGa78yO9/cnXm2BpaGvq25Dv9S4E9+5SIc9PqupJKhYFSSl47+Qcr1mYNAAAAeNptw0cKwkAAAMDZJA8Q7OUJvkLsPfZ6zFVERPy8qHh2YER+3i/BP83vIBLLySsoKimrqKqpa2hp6+jq6RsYGhmbmJqZSy0sraxtbO3sHRydnEMU4uR6yx7JJXveP7WrDycAAAAAAAH//wACeNpjYGRgYOABYhkgZgJCZgZNBkYGLQZtIJsFLMYAAAw3ALgAeNolizEKgDAQBCchRbC2sFER0YD6qVQiBCv/H9ezGI6Z5XBAw8CBK/m5iQQVauVbXLnOrMZv2oLdKFa8Pjuru2hJzGabmOSLzNMzvutpB3N42mNgZGBg4GKQYzBhYMxJLMlj4GBgAYow/P/PAJJhLM6sSoWKfWCAAwDAjgbRAAB42mNgYGBkAIIbCZo5IPrmUn0hGA0AO8EFTQAA");
font-weight: 400;
font-style: normal;
}
:root {
--swiper-theme-color: #007aff;
}
.swiper {
margin-left: auto;
margin-right: auto;
position: relative;
overflow: hidden;
list-style: none;
padding: 0;
z-index: 1;
}
.swiper-vertical>.swiper-wrapper {
flex-direction: column;
}
.swiper-wrapper {
position: relative;
width: 100%;
height: 100%;
z-index: 1;
display: flex;
transition-property: transform;
box-sizing: content-box;
}
.swiper-android .swiper-slide,
.swiper-wrapper {
transform: translate3d(0px, 0, 0);
}
.swiper-pointer-events {
touch-action: pan-y;
}
.swiper-pointer-events.swiper-vertical {
touch-action: pan-x;
}
.swiper-slide {
flex-shrink: 0;
width: 100%;
height: 100%;
position: relative;
transition-property: transform;
}
.swiper-slide-invisible-blank {
visibility: hidden;
}
.swiper-autoheight,
.swiper-autoheight .swiper-slide {
height: auto;
}
.swiper-autoheight .swiper-wrapper {
align-items: flex-start;
transition-property: transform, height;
}
.swiper-backface-hidden .swiper-slide {
transform: translateZ(0);
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.swiper-3d,
.swiper-3d.swiper-css-mode .swiper-wrapper {
perspective: 1200px;
}
.swiper-3d .swiper-cube-shadow,
.swiper-3d .swiper-slide,
.swiper-3d .swiper-slide-shadow,
.swiper-3d .swiper-slide-shadow-bottom,
.swiper-3d .swiper-slide-shadow-left,
.swiper-3d .swiper-slide-shadow-right,
.swiper-3d .swiper-slide-shadow-top,
.swiper-3d .swiper-wrapper {
transform-style: preserve-3d;
}
.swiper-3d .swiper-slide-shadow,
.swiper-3d .swiper-slide-shadow-bottom,
.swiper-3d .swiper-slide-shadow-left,
.swiper-3d .swiper-slide-shadow-right,
.swiper-3d .swiper-slide-shadow-top {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 10;
}
.swiper-3d .swiper-slide-shadow {
background: rgba(0, 0, 0, 0.15);
}
.swiper-3d .swiper-slide-shadow-left {
background-image: linear-gradient(to left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
}
.swiper-3d .swiper-slide-shadow-right {
background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
}
.swiper-3d .swiper-slide-shadow-top {
background-image: linear-gradient(to top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
}
.swiper-3d .swiper-slide-shadow-bottom {
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
}
.swiper-css-mode>.swiper-wrapper {
overflow: auto;
scrollbar-width: none;
-ms-overflow-style: none;
}
.swiper-css-mode>.swiper-wrapper::-webkit-scrollbar {
display: none;
}
.swiper-css-mode>.swiper-wrapper>.swiper-slide {
scroll-snap-align: start start;
}
.swiper-horizontal.swiper-css-mode>.swiper-wrapper {
scroll-snap-type: x mandatory;
}
.swiper-vertical.swiper-css-mode>.swiper-wrapper {
scroll-snap-type: y mandatory;
}
.swiper-centered>.swiper-wrapper::before {
content: "";
flex-shrink: 0;
order: 9999;
}
.swiper-centered.swiper-horizontal>.swiper-wrapper>.swiper-slide:first-child {
-webkit-margin-start: var(--swiper-centered-offset-before);
margin-inline-start: var(--swiper-centered-offset-before);
}
.swiper-centered.swiper-horizontal>.swiper-wrapper::before {
height: 100%;
min-height: 1px;
width: var(--swiper-centered-offset-after);
}
.swiper-centered.swiper-vertical>.swiper-wrapper>.swiper-slide:first-child {
-webkit-margin-before: var(--swiper-centered-offset-before);
margin-block-start: var(--swiper-centered-offset-before);
}
.swiper-centered.swiper-vertical>.swiper-wrapper::before {
width: 100%;
min-width: 1px;
height: var(--swiper-centered-offset-after);
}
.swiper-centered>.swiper-wrapper>.swiper-slide {
scroll-snap-align: center center;
}
.swiper-virtual .swiper-slide {
-webkit-backface-visibility: hidden;
transform: translateZ(0);
}
.swiper-virtual.swiper-css-mode .swiper-wrapper::after {
content: "";
position: absolute;
left: 0;
top: 0;
pointer-events: none;
}
.swiper-virtual.swiper-css-mode.swiper-horizontal .swiper-wrapper::after {
height: 1px;
width: var(--swiper-virtual-size);
}
.swiper-virtual.swiper-css-mode.swiper-vertical .swiper-wrapper::after {
width: 1px;
height: var(--swiper-virtual-size);
}
:root {
--swiper-navigation-size: 44px;
}
.swiper-button-next,
.swiper-button-prev {
position: absolute;
top: 50%;
width: calc(var(--swiper-navigation-size) / 44 * 27);
height: var(--swiper-navigation-size);
margin-top: calc(0px - var(--swiper-navigation-size) / 2);
z-index: 10;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
color: var(--swiper-navigation-color, var(--swiper-theme-color));
}
.swiper-button-next.swiper-button-disabled,
.swiper-button-prev.swiper-button-disabled {
opacity: 0.35;
cursor: auto;
pointer-events: none;
}
.swiper-button-next:after,
.swiper-button-prev:after {
font-family: swiper-icons;
font-size: var(--swiper-navigation-size);
letter-spacing: 0;
text-transform: none;
font-variant: initial;
line-height: 1;
}
.swiper-button-prev,
.swiper-rtl .swiper-button-next {
left: 10px;
right: auto;
}
.swiper-button-prev:after,
.swiper-rtl .swiper-button-next:after {
content: "prev";
}
.swiper-button-next,
.swiper-rtl .swiper-button-prev {
right: 10px;
left: auto;
}
.swiper-button-next:after,
.swiper-rtl .swiper-button-prev:after {
content: "next";
}
.swiper-button-lock {
display: none;
}
.swiper-pagination {
position: absolute;
text-align: center;
transition: 0.3s opacity;
transform: translate3d(0, 0, 0);
z-index: 10;
}
.swiper-pagination.swiper-pagination-hidden {
opacity: 0;
}
.swiper-horizontal>.swiper-pagination-bullets,
.swiper-pagination-bullets.swiper-pagination-horizontal,
.swiper-pagination-custom,
.swiper-pagination-fraction {
bottom: 10px;
left: 0;
width: 100%;
}
.swiper-pagination-bullets-dynamic {
overflow: hidden;
font-size: 0;
}
.swiper-pagination-bullets-dynamic .swiper-pagination-bullet {
transform: scale(0.33);
position: relative;
}
.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active {
transform: scale(1);
}
.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-main {
transform: scale(1);
}
.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-prev {
transform: scale(0.66);
}
.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-prev-prev {
transform: scale(0.33);
}
.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-next {
transform: scale(0.66);
}
.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-next-next {
transform: scale(0.33);
}
.swiper-pagination-bullet {
width: var(--swiper-pagination-bullet-width, var(--swiper-pagination-bullet-size, 8px));
height: var(--swiper-pagination-bullet-height, var(--swiper-pagination-bullet-size, 8px));
display: inline-block;
border-radius: 50%;
background: var(--swiper-pagination-bullet-inactive-color, #000);
opacity: var(--swiper-pagination-bullet-inactive-opacity, 0.2);
}
button.swiper-pagination-bullet {
border: none;
margin: 0;
padding: 0;
box-shadow: none;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
.swiper-pagination-clickable .swiper-pagination-bullet {
cursor: pointer;
}
.swiper-pagination-bullet:only-child {
display: none !important;
}
.swiper-pagination-bullet-active {
opacity: var(--swiper-pagination-bullet-opacity, 1);
background: var(--swiper-pagination-color, var(--swiper-theme-color));
}
.swiper-pagination-vertical.swiper-pagination-bullets,
.swiper-vertical>.swiper-pagination-bullets {
right: 10px;
top: 50%;
transform: translate3d(0px, -50%, 0);
}
.swiper-pagination-vertical.swiper-pagination-bullets .swiper-pagination-bullet,
.swiper-vertical>.swiper-pagination-bullets .swiper-pagination-bullet {
margin: var(--swiper-pagination-bullet-vertical-gap, 6px) 0;
display: block;
}
.swiper-pagination-vertical.swiper-pagination-bullets.swiper-pagination-bullets-dynamic,
.swiper-vertical>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic {
top: 50%;
transform: translateY(-50%);
width: 8px;
}
.swiper-pagination-vertical.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet,
.swiper-vertical>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet {
display: inline-block;
transition: 0.2s transform, 0.2s top;
}
.swiper-horizontal>.swiper-pagination-bullets .swiper-pagination-bullet,
.swiper-pagination-horizontal.swiper-pagination-bullets .swiper-pagination-bullet {
margin: 0 var(--swiper-pagination-bullet-horizontal-gap, 4px);
}
.swiper-horizontal>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic,
.swiper-pagination-horizontal.swiper-pagination-bullets.swiper-pagination-bullets-dynamic {
left: 50%;
transform: translateX(-50%);
white-space: nowrap;
}
.swiper-horizontal>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet,
.swiper-pagination-horizontal.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet {
transition: 0.2s transform, 0.2s left;
}
.swiper-horizontal.swiper-rtl>.swiper-pagination-bullets-dynamic .swiper-pagination-bullet {
transition: 0.2s transform, 0.2s right;
}
.swiper-pagination-progressbar {
background: rgba(0, 0, 0, 0.25);
position: absolute;
}
.swiper-pagination-progressbar .swiper-pagination-progressbar-fill {
background: var(--swiper-pagination-color, var(--swiper-theme-color));
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
transform: scale(0);
transform-origin: left top;
}
.swiper-rtl .swiper-pagination-progressbar .swiper-pagination-progressbar-fill {
transform-origin: right top;
}
.swiper-horizontal>.swiper-pagination-progressbar,
.swiper-pagination-progressbar.swiper-pagination-horizontal,
.swiper-pagination-progressbar.swiper-pagination-vertical.swiper-pagination-progressbar-opposite,
.swiper-vertical>.swiper-pagination-progressbar.swiper-pagination-progressbar-opposite {
width: 100%;
height: 4px;
left: 0;
top: 0;
}
.swiper-horizontal>.swiper-pagination-progressbar.swiper-pagination-progressbar-opposite,
.swiper-pagination-progressbar.swiper-pagination-horizontal.swiper-pagination-progressbar-opposite,
.swiper-pagination-progressbar.swiper-pagination-vertical,
.swiper-vertical>.swiper-pagination-progressbar {
width: 4px;
height: 100%;
left: 0;
top: 0;
}
.swiper-pagination-lock {
display: none;
}
.swiper-scrollbar {
border-radius: 10px;
position: relative;
-ms-touch-action: none;
background: rgba(0, 0, 0, 0.1);
}
.swiper-horizontal>.swiper-scrollbar {
position: absolute;
left: 1%;
bottom: 3px;
z-index: 50;
height: 5px;
width: 98%;
}
.swiper-vertical>.swiper-scrollbar {
position: absolute;
right: 3px;
top: 1%;
z-index: 50;
width: 5px;
height: 98%;
}
.swiper-scrollbar-drag {
height: 100%;
width: 100%;
position: relative;
background: rgba(0, 0, 0, 0.5);
border-radius: 10px;
left: 0;
top: 0;
}
.swiper-scrollbar-cursor-drag {
cursor: move;
}
.swiper-scrollbar-lock {
display: none;
}
.swiper-zoom-container {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
.swiper-zoom-container>canvas,
.swiper-zoom-container>img,
.swiper-zoom-container>svg {
max-width: 100%;
max-height: 100%;
-o-object-fit: contain;
object-fit: contain;
}
.swiper-slide-zoomed {
cursor: move;
}
.swiper-lazy-preloader {
width: 42px;
height: 42px;
position: absolute;
left: 50%;
top: 50%;
margin-left: -21px;
margin-top: -21px;
z-index: 10;
transform-origin: 50%;
box-sizing: border-box;
border: 4px solid var(--swiper-preloader-color, var(--swiper-theme-color));
border-radius: 50%;
border-top-color: transparent;
}
.swiper-slide-visible .swiper-lazy-preloader {
animation: swiper-preloader-spin 1s infinite linear;
}
.swiper-lazy-preloader-white {
--swiper-preloader-color: #fff;
}
.swiper-lazy-preloader-black {
--swiper-preloader-color: #000;
}
@keyframes swiper-preloader-spin {
100% {
transform: rotate(360deg);
}
}
.swiper .swiper-notification {
position: absolute;
left: 0;
top: 0;
pointer-events: none;
opacity: 0;
z-index: -1000;
}
.swiper-free-mode>.swiper-wrapper {
transition-timing-function: ease-out;
margin: 0 auto;
}
.swiper-grid>.swiper-wrapper {
flex-wrap: wrap;
}
.swiper-grid-column>.swiper-wrapper {
flex-wrap: wrap;
flex-direction: column;
}
.swiper-fade.swiper-free-mode .swiper-slide {
transition-timing-function: ease-out;
}
.swiper-fade .swiper-slide {
pointer-events: none;
transition-property: opacity;
}
.swiper-fade .swiper-slide .swiper-slide {
pointer-events: none;
}
.swiper-fade .swiper-slide-active,
.swiper-fade .swiper-slide-active .swiper-slide-active {
pointer-events: auto;
}
.swiper-cube {
overflow: visible;
}
.swiper-cube .swiper-slide {
pointer-events: none;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
z-index: 1;
visibility: hidden;
transform-origin: 0 0;
width: 100%;
height: 100%;
}
.swiper-cube .swiper-slide .swiper-slide {
pointer-events: none;
}
.swiper-cube.swiper-rtl .swiper-slide {
transform-origin: 100% 0;
}
.swiper-cube .swiper-slide-active,
.swiper-cube .swiper-slide-active .swiper-slide-active {
pointer-events: auto;
}
.swiper-cube .swiper-slide-active,
.swiper-cube .swiper-slide-next,
.swiper-cube .swiper-slide-next+.swiper-slide,
.swiper-cube .swiper-slide-prev {
pointer-events: auto;
visibility: visible;
}
.swiper-cube .swiper-slide-shadow-bottom,
.swiper-cube .swiper-slide-shadow-left,
.swiper-cube .swiper-slide-shadow-right,
.swiper-cube .swiper-slide-shadow-top {
z-index: 0;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.swiper-cube .swiper-cube-shadow {
position: absolute;
left: 0;
bottom: 0px;
width: 100%;
height: 100%;
opacity: 0.6;
z-index: 0;
}
.swiper-cube .swiper-cube-shadow:before {
content: "";
background: #000;
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
filter: blur(50px);
}
.swiper-flip {
overflow: visible;
}
.swiper-flip .swiper-slide {
pointer-events: none;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
z-index: 1;
}
.swiper-flip .swiper-slide .swiper-slide {
pointer-events: none;
}
.swiper-flip .swiper-slide-active,
.swiper-flip .swiper-slide-active .swiper-slide-active {
pointer-events: auto;
}
.swiper-flip .swiper-slide-shadow-bottom,
.swiper-flip .swiper-slide-shadow-left,
.swiper-flip .swiper-slide-shadow-right,
.swiper-flip .swiper-slide-shadow-top {
z-index: 0;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.swiper-creative .swiper-slide {
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
overflow: hidden;
transition-property: transform, opacity, height;
}
.swiper-cards {
overflow: visible;
}
.swiper-cards .swiper-slide {
transform-origin: center bottom;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
overflow: hidden;
}
@@ -0,0 +1 @@
No Content: https://codextheme.codexperts.in/tailwind-theme/uero/assets/fonts/font-awesome/fontawesome-webfont.woff2?v=4.7.0
+1
View File
@@ -0,0 +1 @@
No Content: https://codextheme.codexperts.in/tailwind-theme/uero/assets/fonts/themify-icon/themify.woff?-fvbane
Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

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