diff --git a/.gitignore b/.gitignore index a088991..812bff3 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,9 @@ ENV/ # OS .DS_Store -Thumbs.db \ No newline at end of file +Thumbs.db + +# Project specific +*.log +*.pot +*.py[co] \ No newline at end of file diff --git a/OneCprogsite/OneCprogsite/__init__.py b/OneCprogsite/OneCprogsite/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/OneCprogsite/OneCprogsite/asgi.py b/OneCprogsite/OneCprogsite/asgi.py deleted file mode 100644 index d008858..0000000 --- a/OneCprogsite/OneCprogsite/asgi.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -ASGI config for OneCprogsite 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/4.2/howto/deployment/asgi/ -""" - -import os - -from django.core.asgi import get_asgi_application - -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'OneCprogsite.settings') - -application = get_asgi_application() diff --git a/OneCprogsite/OneCprogsite/settings.py b/OneCprogsite/OneCprogsite/settings.py deleted file mode 100644 index a02cb85..0000000 --- a/OneCprogsite/OneCprogsite/settings.py +++ /dev/null @@ -1,212 +0,0 @@ -""" -Django settings for OneCprogsite project. - -Generated by 'django-admin startproject' using Django 4.2.7. - -For more information on this file, see -https://docs.djangoproject.com/en/4.2/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/4.2/ref/settings/ -""" -import os.path -from pathlib import Path - -# Build paths inside the project like this: BASE_DIR / 'subdir'. -BASE_DIR = Path(__file__).resolve().parent.parent - - -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/ - -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'django-insecure-5rs2a1*8cxjkv*%6k1-88biv&1#nep%@i+%1^dk=5j$s&e&hwm' - -# Безопасность cookies для HTTPS -SESSION_COOKIE_SECURE = True -CSRF_COOKIE_SECURE = True -SESSION_COOKIE_HTTPONLY = True -CSRF_COOKIE_HTTPONLY = False # Django требует доступ к CSRF cookie через JS -SESSION_COOKIE_SAMESITE = 'Lax' -CSRF_COOKIE_SAMESITE = 'Lax' - -# Если используете другие cookies -LANGUAGE_COOKIE_SECURE = True -LANGUAGE_COOKIE_HTTPONLY = True -LANGUAGE_COOKIE_SAMESITE = 'Lax' - -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = False - -X_FRAME_OPTIONS = 'SAMEORIGIN' -# Или разрешить конкретные домены (Django 4.0+) -X_FRAME_OPTIONS = 'ALLOW-FROM https://metrika.yandex.ru' - -# ОБЯЗАТЕЛЬНО укажите ваши домены -ALLOWED_HOSTS = [ - 'nikdizell.ru', - 'www.nikdizell.ru', - 'localhost', - '127.0.0.1', - '192.168.31.88' # Добавьте IP сервера -] - -# Важно для работы за прокси -SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') -SECURE_SSL_REDIRECT = True - -# Дополнительная безопасность -SECURE_BROWSER_XSS_FILTER = True -SECURE_CONTENT_TYPE_NOSNIFF = True -SECURE_HSTS_SECONDS = 31536000 -SECURE_HSTS_INCLUDE_SUBDOMAINS = True -SECURE_HSTS_PRELOAD = True - -CSRF_TRUSTED_ORIGINS = [ - 'https://nikdizell.ru', - 'https://www.nikdizell.ru', -] - -# Application definition - -INSTALLED_APPS = [ - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'programmer.apps.ProgrammerConfig', - 'django_bootstrap5', - 'django_extensions', - 'django.contrib.sites', - 'django.contrib.sitemaps', -] - -MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - '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', - 'programmer.middleware.PageViewMiddleware', -] - -ROOT_URLCONF = 'OneCprogsite.urls' - -# Кастомный middleware для CSP -class CSPMiddleware: - def __init__(self, get_response): - self.get_response = get_response - - def __call__(self, request): - response = self.get_response(request) - response['Content-Security-Policy'] = "frame-ancestors 'self' https://metrika.yandex.ru https://metrika.yandex.by https://metrica.yandex.com https://metrica.yandex.com.tr https://*.webvisor.com" - return response - -TEMPLATES = [ - { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], - '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', - 'programmer.context_processors.menu_processor', - 'programmer.context_processors.contact_info', - ], - }, - }, -] - -WSGI_APPLICATION = 'OneCprogsite.wsgi.application' - - -# Database -# https://docs.djangoproject.com/en/4.2/ref/settings/#databases - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql', - 'NAME': 'App', - 'USER': 'postgres', - 'PASSWORD': 'NikDi94Zell', - 'HOST': 'postgres', - 'PORT': 5432, - } -} - - -# Password validation -# https://docs.djangoproject.com/en/4.2/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', - }, -] - - -# Internationalization -# https://docs.djangoproject.com/en/4.2/topics/i18n/ - -LANGUAGE_CODE = 'ru' - -TIME_ZONE = 'Europe/Moscow' -USE_I18N = True -USE_I18N = True -USE_TZ = True - - -# Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/4.2/howto/static-files/ - -STATIC_URL = 'static/' -STATIC_ROOT = os.path.join(BASE_DIR, 'static') -STATICFILES_DIRS = [] - -# Default primary key field type -# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field - -DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' - -MEDIA_ROOT = os.path.join(BASE_DIR, 'media') -MEDIA_URL = '/media/' - -# Настройки email -EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' -# EMAIL_HOST = 'smtp.yandex.ru' # или smtp.gmail.com, smtp.mail.ru -# EMAIL_PORT = 587 -# EMAIL_USE_TLS = True -# EMAIL_HOST_USER = os.getenv('EMAIL_HOST_USER', 'it@yandex.ru') -# EMAIL_HOST_PASSWORD = os.getenv('EMAIL_HOST_PASSWORD', 'tifdctkrcjcqwxyc') -# DEFAULT_FROM_EMAIL = EMAIL_HOST_USER -# SERVER_EMAIL = EMAIL_HOST_USER - -EMAIL_HOST = 'smtp.gmail.com' # или smtp.gmail.com, smtp.mail.ru -EMAIL_PORT = 587 -EMAIL_USE_TLS = True -EMAIL_HOST_USER = os.getenv('EMAIL_HOST_USER', 'nikdizell@gmail.com') -EMAIL_HOST_PASSWORD = os.getenv('EMAIL_HOST_PASSWORD', 'qvmw yccb msqv mmpj') -DEFAULT_FROM_EMAIL = EMAIL_HOST_USER -SERVER_EMAIL = EMAIL_HOST_USER - -# Email для уведомлений (можно указать несколько через запятую) -# ADMIN_EMAILS = os.getenv('ADMIN_EMAILS', 'nikdizell@gmail.com').split(',') -ADMIN_EMAILS = os.getenv('ADMIN_EMAILS', 'it@nserdyuk.ru').split(',') - - diff --git a/OneCprogsite/OneCprogsite/urls.py b/OneCprogsite/OneCprogsite/urls.py deleted file mode 100644 index fdecba6..0000000 --- a/OneCprogsite/OneCprogsite/urls.py +++ /dev/null @@ -1,39 +0,0 @@ -""" -URL configuration for OneCprogsite project. - -The `urlpatterns` list routes URLs to views. For more information please see: - https://docs.djangoproject.com/en/4.2/topics/http/urls/ -Examples: -Function views - 1. Add an import: from my_app import views - 2. Add a URL to urlpatterns: path('', views.home, name='home') -Class-based views - 1. Add an import: from other_app.views import Home - 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') -Including another URLconf - 1. Import the include() function: from django.urls import include, path - 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) -""" -from django.conf.urls.static import static -from django.contrib import admin -from django.urls import path - -from OneCprogsite import settings -from programmer.views import * -from django.urls import path, include - -urlpatterns = [ - path('admin/', admin.site.urls), - path('', include('programmer.urls')), - # path('', index, name='home'), - # path('about/', about, name='about'), - # path('solution/', solution, name='solution'), - # path('ability/', ability, name='ability'), - # path('recall/', recall, name='recall'), - # path('post/', show_post, name='post'), -] - -if settings.DEBUG: - urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) - -handler404 = pageNotFound diff --git a/OneCprogsite/OneCprogsite/wsgi.py b/OneCprogsite/OneCprogsite/wsgi.py deleted file mode 100644 index 05e8dc4..0000000 --- a/OneCprogsite/OneCprogsite/wsgi.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -WSGI config for OneCprogsite 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/4.2/howto/deployment/wsgi/ -""" - -import os - -from django.core.wsgi import get_wsgi_application - -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'OneCprogsite.settings') - -application = get_wsgi_application() diff --git a/OneCprogsite/manage.py b/OneCprogsite/manage.py deleted file mode 100644 index e263efa..0000000 --- a/OneCprogsite/manage.py +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env python -"""Django's command-line utility for administrative tasks.""" -import os -import sys - - -def main(): - """Run administrative tasks.""" - os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'OneCprogsite.settings') - try: - from django.core.management import execute_from_command_line - except ImportError as exc: - raise ImportError( - "Couldn't import Django. Are you sure it's installed and " - "available on your PYTHONPATH environment variable? Did you " - "forget to activate a virtual environment?" - ) from exc - execute_from_command_line(sys.argv) - - -if __name__ == '__main__': - main() diff --git a/OneCprogsite/programmer/__init__.py b/OneCprogsite/programmer/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/OneCprogsite/programmer/admin.py b/OneCprogsite/programmer/admin.py deleted file mode 100644 index b14ce10..0000000 --- a/OneCprogsite/programmer/admin.py +++ /dev/null @@ -1,169 +0,0 @@ -from django.contrib import admin -from django.utils import timezone -from django.utils.html import format_html -from django.urls import path -from django.shortcuts import render -from django.http import HttpResponseRedirect -from django.contrib import messages -from .models import * - - -class ProgrammerAdmin(admin.ModelAdmin): - list_display = ('id', 'title', 'time_create', 'photo', 'is_published') - list_display_links = ('id', 'title') - search_fields = ('title', 'content') - list_editable = ('is_published',) - list_filter = ('time_create', 'is_published') - - -class RecallAdmin(admin.ModelAdmin): - list_display = ('id', 'title', 'time_create', 'scan', 'is_published') - list_display_links = ('id', 'title') - search_fields = ('title', 'content') - list_editable = ('is_published',) - list_filter = ('time_create', 'is_published') - - -class SolutionAdmin(admin.ModelAdmin): - list_display = ('id', 'title', 'time_create', 'is_published') - list_display_links = ('id', 'title') - search_fields = ('title', 'description', 'implementation') - list_editable = ('is_published',) - list_filter = ('time_create', 'is_published') - - -class HomeAdmin(admin.ModelAdmin): - list_display = ('id', 'title', 'time_create', 'is_published') - list_display_links = ('id', 'title') - search_fields = ('title', 'content') - list_editable = ('is_published',) - list_filter = ('time_create', 'is_published') - - -@admin.register(CallbackRequest) -class CallbackAdmin(admin.ModelAdmin): - list_display = ('name', 'phone', 'email', 'time_create', 'is_processed', 'is_read', 'new_badge') - list_display_links = ('name', 'phone') - list_editable = ('is_processed', 'is_read') - list_filter = ('time_create', 'is_processed', 'is_read') - search_fields = ('name', 'phone', 'email') - readonly_fields = ('time_create',) - actions = ['mark_as_read', 'mark_as_unread', 'mark_as_processed'] - actions = ['mark_as_read', 'mark_as_unread', 'mark_as_processed', 'resend_notification'] - - def resend_notification(self, request, queryset): - from .utils.email_notifications import send_callback_notification - count = 0 - for callback in queryset: - success = send_callback_notification(callback) - if success: - count += 1 - self.message_user(request, f'Уведомления отправлены для {count} заявок') - - resend_notification.short_description = "Переотправить email уведомления" - - def new_badge(self, obj): - if not obj.is_read: - return format_html('🆕 НОВАЯ') - return "" - - new_badge.short_description = 'Статус' - - def get_queryset(self, request): - # Показываем количество непрочитанных в заголовке - unread_count = CallbackRequest.objects.filter(is_read=False).count() - if unread_count > 0: - self.message_user( - request, - f'У вас {unread_count} непрочитанных заявок!', - messages.WARNING - ) - return super().get_queryset(request) - - def mark_as_read(self, request, queryset): - updated = queryset.update(is_read=True) - self.message_user(request, f'{updated} заявок отмечены как прочитанные') - - mark_as_read.short_description = "Отметить как прочитанные" - - def mark_as_unread(self, request, queryset): - updated = queryset.update(is_read=False) - self.message_user(request, f'{updated} заявок отмечены как непрочитанные') - - mark_as_unread.short_description = "Отметить как непрочитанные" - - def mark_as_processed(self, request, queryset): - updated = queryset.update(is_processed=True) - self.message_user(request, f'{updated} заявок отмечены как обработанные') - - mark_as_processed.short_description = "Отметить как обработанные" - - # Добавляем кастомное представление для статистики - def get_urls(self): - urls = super().get_urls() - custom_urls = [ - path('callback-stats/', self.admin_site.admin_view(self.callback_stats), name='callback_stats'), - ] - return custom_urls + urls - - def callback_stats(self, request): - today = timezone.now().date() - week_ago = today - timezone.timedelta(days=7) - - stats = { - 'total': CallbackRequest.objects.count(), - 'today': CallbackRequest.objects.filter(time_create__date=today).count(), - 'week': CallbackRequest.objects.filter(time_create__date__gte=week_ago).count(), - 'unread': CallbackRequest.objects.filter(is_read=False).count(), - 'unprocessed': CallbackRequest.objects.filter(is_processed=False).count(), - } - - context = { - **self.admin_site.each_context(request), - 'title': 'Статистика заявок', - 'stats': stats, - } - return render(request, 'admin/callback_stats.html', context) - -class ProgrammerAdmin(admin.ModelAdmin): - list_display = ('id', 'title', 'time_create', 'photo', 'is_published') - list_display_links = ('id', 'title') - search_fields = ('title', 'content') - list_editable = ('is_published',) - list_filter = ('time_create', 'is_published') - -class RecallAdmin(admin.ModelAdmin): - list_display = ('id', 'title', 'time_create', 'scan', 'is_published') - list_display_links = ('id', 'title') - search_fields = ('title', 'content') - list_editable = ('is_published',) - list_filter = ('time_create', 'is_published') - -class SolutionAdmin(admin.ModelAdmin): - list_display = ('id', 'title', 'time_create', 'is_published') - list_display_links = ('id', 'title') - search_fields = ('title', 'description', 'implementation') - list_editable = ('is_published',) - list_filter = ('time_create', 'is_published') - -class HomeAdmin(admin.ModelAdmin): - list_display = ('id', 'title', 'time_create', 'is_published') - list_display_links = ('id', 'title') - search_fields = ('title', 'content') - list_editable = ('is_published',) - list_filter = ('time_create', 'is_published') - -@admin.register(PageView) -class PageViewAdmin(admin.ModelAdmin): - list_display = ['url', 'timestamp', 'ip_address'] - list_filter = ['timestamp', 'url'] - search_fields = ['url', 'ip_address'] - date_hierarchy = 'timestamp' - - def get_queryset(self, request): - return super().get_queryset(request).order_by('-timestamp') - -admin.site.register(Competence, ProgrammerAdmin) -admin.site.register(Recall, RecallAdmin) -admin.site.register(Solution, SolutionAdmin) -admin.site.register(Home, HomeAdmin) diff --git a/OneCprogsite/programmer/apps.py b/OneCprogsite/programmer/apps.py deleted file mode 100644 index d96696b..0000000 --- a/OneCprogsite/programmer/apps.py +++ /dev/null @@ -1,7 +0,0 @@ -from django.apps import AppConfig - - -class ProgrammerConfig(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' - name = 'programmer' - verbose_name = 'Программисты' diff --git a/OneCprogsite/programmer/context_processors.py b/OneCprogsite/programmer/context_processors.py deleted file mode 100644 index 998554b..0000000 --- a/OneCprogsite/programmer/context_processors.py +++ /dev/null @@ -1,12 +0,0 @@ -from .views import menu -from django.conf import settings - - -def menu_processor(request): - return {'menu': menu} - -def contact_info(request): - return { - 'CONTACT_EMAIL': getattr(settings, 'CONTACT_EMAIL', 'it@nserdyuk.ru'), - 'CONTACT_PHONE': getattr(settings, 'CONTACT_PHONE', '+7 (960) 469-40-88'), - } \ No newline at end of file diff --git a/OneCprogsite/programmer/forms.py b/OneCprogsite/programmer/forms.py deleted file mode 100644 index 826ef05..0000000 --- a/OneCprogsite/programmer/forms.py +++ /dev/null @@ -1,33 +0,0 @@ -from django import forms -from .models import CallbackRequest - - -class CallbackForm(forms.ModelForm): - class Meta: - model = CallbackRequest - fields = ['name', 'phone', 'email', 'question'] - widgets = { - 'name': forms.TextInput(attrs={ - 'class': 'form-input', - 'placeholder': 'Ваше имя' - }), - 'phone': forms.TextInput(attrs={ - 'class': 'form-input', - 'placeholder': '+7 (___) ___-__-__' - }), - 'email': forms.EmailInput(attrs={ - 'class': 'form-input', - 'placeholder': 'your@email.com' - }), - 'question': forms.Textarea(attrs={ - 'class': 'form-textarea', - 'placeholder': 'Опишите ваш вопрос или задачу...', - 'rows': 4 - }), - } - labels = { - 'name': 'Имя', - 'phone': 'Телефон', - 'email': 'Электронная почта', - 'question': 'Ваш вопрос' - } \ No newline at end of file diff --git a/OneCprogsite/programmer/management/__init__.py b/OneCprogsite/programmer/management/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/OneCprogsite/programmer/management/commands/__init__.py b/OneCprogsite/programmer/management/commands/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/OneCprogsite/programmer/management/commands/send_daily_summary.py b/OneCprogsite/programmer/management/commands/send_daily_summary.py deleted file mode 100644 index cff2dcb..0000000 --- a/OneCprogsite/programmer/management/commands/send_daily_summary.py +++ /dev/null @@ -1,33 +0,0 @@ -# programmer/management/commands/send_daily_summary.py -from django.core.management.base import BaseCommand -from django.utils import timezone -from programmer.utils.email_notifications import send_daily_summary - - -class Command(BaseCommand): - help = 'Отправляет ежедневную сводку по заявкам на email' - - def add_arguments(self, parser): - parser.add_argument( - '--test', - action='store_true', - help='Тестовая отправка (не учитывает реальные данные)', - ) - - def handle(self, *args, **options): - if options['test']: - self.stdout.write(self.style.WARNING('Тестовая отправка ежедневной сводки...')) - # Здесь можно добавить тестовые данные - else: - self.stdout.write('Отправка ежедневной сводки...') - - success = send_daily_summary() - - if success: - self.stdout.write( - self.style.SUCCESS(f'Ежедневная сводка отправлена успешно! Время: {timezone.now()}') - ) - else: - self.stdout.write( - self.style.WARNING('Ежедневная сводка не отправлена (нет данных или ошибка)') - ) \ No newline at end of file diff --git a/OneCprogsite/programmer/management/commands/test_email.py b/OneCprogsite/programmer/management/commands/test_email.py deleted file mode 100644 index bfbd10e..0000000 --- a/OneCprogsite/programmer/management/commands/test_email.py +++ /dev/null @@ -1,29 +0,0 @@ -# programmer/management/commands/test_email.py -from django.core.management.base import BaseCommand -from django.conf import settings -from programmer.utils.email_notifications import send_test_email - - -class Command(BaseCommand): - help = 'Test email configuration' - - def handle(self, *args, **options): - self.stdout.write("Testing email configuration...") - - # Проверяем настройки - self.stdout.write(f"EMAIL_HOST: {settings.EMAIL_HOST}") - self.stdout.write(f"EMAIL_PORT: {settings.EMAIL_PORT}") - self.stdout.write(f"EMAIL_HOST_USER: {settings.EMAIL_HOST_USER}") - self.stdout.write(f"ADMIN_EMAILS: {settings.ADMIN_EMAILS}") - - # Тестируем отправку - success = send_test_email() - - if success: - self.stdout.write( - self.style.SUCCESS('✅ Test email sent successfully!') - ) - else: - self.stdout.write( - self.style.ERROR('❌ Failed to send test email. Check your email settings.') - ) \ No newline at end of file diff --git a/OneCprogsite/programmer/management/commands/test_sitemap.py b/OneCprogsite/programmer/management/commands/test_sitemap.py deleted file mode 100644 index 6ae9555..0000000 --- a/OneCprogsite/programmer/management/commands/test_sitemap.py +++ /dev/null @@ -1,27 +0,0 @@ -from django.core.management.base import BaseCommand -from django.contrib.sitemaps import Sitemap -from django.urls import reverse -from programmer.models import Home, Solution, Competence, Recall - - -class Command(BaseCommand): - help = 'Test sitemap generation' - - def handle(self, *args, **options): - from programmer.sitemaps import sitemaps - - self.stdout.write('Testing sitemap generation...') - - for name, sitemap in sitemaps.items(): - self.stdout.write(f'\n{name}:') - items = sitemap().items() - self.stdout.write(f' Items found: {len(items)}') - - for item in items[:3]: # Показываем первые 3 элемента - try: - url = sitemap().location(item) - self.stdout.write(f' - {url}') - except Exception as e: - self.stdout.write(f' - Error: {e}') - - self.stdout.write('\nSitemap test completed!') diff --git a/OneCprogsite/programmer/middleware.py b/OneCprogsite/programmer/middleware.py deleted file mode 100644 index 88ec46d..0000000 --- a/OneCprogsite/programmer/middleware.py +++ /dev/null @@ -1,54 +0,0 @@ -from .models import PageView, Visitor -from django.utils import timezone -from django.db import transaction - - -class PageViewMiddleware: - def __init__(self, get_response): - self.get_response = get_response - - def __call__(self, request): - # Игнорируем статические файлы и админку - if not request.path.startswith('/static/') and not request.path.startswith('/admin/'): - self.track_page_view(request) - - response = self.get_response(request) - return response - - def track_page_view(self, request): - try: - with transaction.atomic(): - # Сохраняем просмотр страницы - PageView.objects.create( - url=request.path, - ip_address=self.get_client_ip(request), - user_agent=request.META.get('HTTP_USER_AGENT', ''), - referer=request.META.get('HTTP_REFERER', '') - ) - - # Обновляем статистику посетителя - ip = self.get_client_ip(request) - visitor, created = Visitor.objects.get_or_create( - ip_address=ip, - defaults={ - 'first_visit': timezone.now(), - 'last_visit': timezone.now() - } - ) - - if not created: - visitor.last_visit = timezone.now() - visitor.visit_count += 1 - visitor.save() - - except Exception as e: - # Логируем ошибку, но не прерываем выполнение - print(f"Error tracking page view: {e}") - - def get_client_ip(self, request): - x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') - if x_forwarded_for: - ip = x_forwarded_for.split(',')[0] - else: - ip = request.META.get('REMOTE_ADDR') - return ip \ No newline at end of file diff --git a/OneCprogsite/programmer/migrations/0001_initial.py b/OneCprogsite/programmer/migrations/0001_initial.py deleted file mode 100644 index 73e2bf5..0000000 --- a/OneCprogsite/programmer/migrations/0001_initial.py +++ /dev/null @@ -1,26 +0,0 @@ -# Generated by Django 4.2.7 on 2023-11-23 12:47 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ] - - operations = [ - migrations.CreateModel( - name='Competence', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('title', models.CharField(max_length=255)), - ('content', models.TextField(blank=True)), - ('photo', models.ImageField(upload_to='photos/%Y/%m/%d/')), - ('time_create', models.DateTimeField(auto_now_add=True)), - ('time_update', models.DateTimeField(auto_now=True)), - ('is_publiched', models.BooleanField(default=True)), - ], - ), - ] diff --git a/OneCprogsite/programmer/migrations/0002_alter_competence_options_alter_competence_content_and_more.py b/OneCprogsite/programmer/migrations/0002_alter_competence_options_alter_competence_content_and_more.py deleted file mode 100644 index af54c6c..0000000 --- a/OneCprogsite/programmer/migrations/0002_alter_competence_options_alter_competence_content_and_more.py +++ /dev/null @@ -1,47 +0,0 @@ -# Generated by Django 4.2.7 on 2023-11-24 08:03 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('programmer', '0001_initial'), - ] - - operations = [ - migrations.AlterModelOptions( - name='competence', - options={'ordering': ['time_create', 'title'], 'verbose_name': 'Компитенция', 'verbose_name_plural': 'Компитенции'}, - ), - migrations.AlterField( - model_name='competence', - name='content', - field=models.TextField(blank=True, verbose_name='Компетенция'), - ), - migrations.AlterField( - model_name='competence', - name='is_publiched', - field=models.BooleanField(default=True, verbose_name='Опубликован'), - ), - migrations.AlterField( - model_name='competence', - name='photo', - field=models.ImageField(upload_to='photos/%Y/%m/%d/', verbose_name='Фото'), - ), - migrations.AlterField( - model_name='competence', - name='time_create', - field=models.DateTimeField(auto_now_add=True, verbose_name='Дата создания'), - ), - migrations.AlterField( - model_name='competence', - name='time_update', - field=models.DateTimeField(auto_now=True, verbose_name='Дата изменения'), - ), - migrations.AlterField( - model_name='competence', - name='title', - field=models.CharField(max_length=255, verbose_name='Программист'), - ), - ] diff --git a/OneCprogsite/programmer/migrations/0003_recall_rename_is_publiched_competence_is_published.py b/OneCprogsite/programmer/migrations/0003_recall_rename_is_publiched_competence_is_published.py deleted file mode 100644 index 5943c25..0000000 --- a/OneCprogsite/programmer/migrations/0003_recall_rename_is_publiched_competence_is_published.py +++ /dev/null @@ -1,35 +0,0 @@ -# Generated by Django 4.2.7 on 2023-11-24 11:54 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('programmer', '0002_alter_competence_options_alter_competence_content_and_more'), - ] - - operations = [ - migrations.CreateModel( - name='Recall', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('title', models.CharField(max_length=255, verbose_name='Организация')), - ('content', models.TextField(blank=True, verbose_name='Отзыв')), - ('photo', models.ImageField(upload_to='photos/%Y/%m/%d/', verbose_name='Фото')), - ('time_create', models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')), - ('time_update', models.DateTimeField(auto_now=True, verbose_name='Дата изменения')), - ('is_published', models.BooleanField(default=True, verbose_name='Опубликован')), - ], - options={ - 'verbose_name': 'Отзыв', - 'verbose_name_plural': 'Отзывы', - 'ordering': ['time_create', 'title'], - }, - ), - migrations.RenameField( - model_name='competence', - old_name='is_publiched', - new_name='is_published', - ), - ] diff --git a/OneCprogsite/programmer/migrations/0004_rename_photo_recall_scan.py b/OneCprogsite/programmer/migrations/0004_rename_photo_recall_scan.py deleted file mode 100644 index 9bb8335..0000000 --- a/OneCprogsite/programmer/migrations/0004_rename_photo_recall_scan.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.2.7 on 2023-11-24 12:02 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('programmer', '0003_recall_rename_is_publiched_competence_is_published'), - ] - - operations = [ - migrations.RenameField( - model_name='recall', - old_name='photo', - new_name='scan', - ), - ] diff --git a/OneCprogsite/programmer/migrations/0005_auto_20231124_1519.py b/OneCprogsite/programmer/migrations/0005_auto_20231124_1519.py deleted file mode 100644 index 5567067..0000000 --- a/OneCprogsite/programmer/migrations/0005_auto_20231124_1519.py +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by Django 4.2.7 on 2023-11-24 12:19 - -from django.db import migrations, models - - - -class Migration(migrations.Migration): - - dependencies = [ - ('programmer', '0004_rename_photo_recall_scan'), - ] - - operations = [ - migrations.CreateModel( - name='Recall', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('title', models.CharField(max_length=255, verbose_name='Организация')), - ('content', models.TextField(blank=True, verbose_name='Отзыв')), - ('scan', models.ImageField(upload_to='photos/%Y/%m/%d/', verbose_name='Скан')), - ('time_create', models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')), - ('time_update', models.DateTimeField(auto_now=True, verbose_name='Дата изменения')), - ('is_published', models.BooleanField(default=True, verbose_name='Опубликован')), - ], - options={ - 'verbose_name': 'Отзыв', - 'verbose_name_plural': 'Отзывы', - 'ordering': ['time_create', 'title'], - }, - ), - ] diff --git a/OneCprogsite/programmer/migrations/0006_alter_recall_scan.py b/OneCprogsite/programmer/migrations/0006_alter_recall_scan.py deleted file mode 100644 index 403ecd1..0000000 --- a/OneCprogsite/programmer/migrations/0006_alter_recall_scan.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.2.7 on 2023-11-25 09:18 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('programmer', '0005_auto_20231124_1519'), - ] - - operations = [ - migrations.AlterField( - model_name='recall', - name='scan', - field=models.ImageField(upload_to='scan/%Y/%m/%d/', verbose_name='Фото'), - ), - ] diff --git a/OneCprogsite/programmer/migrations/0007_solution.py b/OneCprogsite/programmer/migrations/0007_solution.py deleted file mode 100644 index 8e14c40..0000000 --- a/OneCprogsite/programmer/migrations/0007_solution.py +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by Django 4.2.7 on 2023-11-25 09:51 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('programmer', '0006_alter_recall_scan'), - ] - - operations = [ - migrations.CreateModel( - name='Solution', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('title', models.CharField(max_length=255, verbose_name='Наименование')), - ('description', models.TextField(blank=True, verbose_name='Описание')), - ('implementation', models.TextField(blank=True, verbose_name='Реализация')), - ('closing', models.TextField(blank=True, verbose_name='Заключение')), - ('time_create', models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')), - ('time_update', models.DateTimeField(auto_now=True, verbose_name='Дата изменения')), - ('is_published', models.BooleanField(default=True, verbose_name='Опубликован')), - ], - options={ - 'verbose_name': 'Проекты', - 'verbose_name_plural': 'Проекты', - 'ordering': ['time_create', 'title'], - }, - ), - ] diff --git a/OneCprogsite/programmer/migrations/0008_home.py b/OneCprogsite/programmer/migrations/0008_home.py deleted file mode 100644 index 0f8d897..0000000 --- a/OneCprogsite/programmer/migrations/0008_home.py +++ /dev/null @@ -1,30 +0,0 @@ -# Generated by Django 4.2.7 on 2023-11-25 10:45 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('programmer', '0007_solution'), - ] - - operations = [ - migrations.CreateModel( - name='Home', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('title', models.CharField(max_length=255, verbose_name='Наименование')), - ('content', models.TextField(blank=True, verbose_name='Статья')), - ('home_image', models.ImageField(upload_to='home_image/%Y/%m/%d/', verbose_name='Фото')), - ('time_create', models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')), - ('time_update', models.DateTimeField(auto_now=True, verbose_name='Дата изменения')), - ('is_published', models.BooleanField(default=True, verbose_name='Опубликован')), - ], - options={ - 'verbose_name': 'Главная страница', - 'verbose_name_plural': 'Главная страница', - 'ordering': ['time_create', 'title'], - }, - ), - ] diff --git a/OneCprogsite/programmer/migrations/0009_callbackrequest_alter_competence_options.py b/OneCprogsite/programmer/migrations/0009_callbackrequest_alter_competence_options.py deleted file mode 100644 index 3a8582b..0000000 --- a/OneCprogsite/programmer/migrations/0009_callbackrequest_alter_competence_options.py +++ /dev/null @@ -1,34 +0,0 @@ -# Generated by Django 4.2.7 on 2025-11-09 12:00 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('programmer', '0008_home'), - ] - - operations = [ - migrations.CreateModel( - name='CallbackRequest', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=100, verbose_name='Имя')), - ('phone', models.CharField(max_length=20, verbose_name='Телефон')), - ('email', models.EmailField(max_length=254, verbose_name='Электронная почта')), - ('question', models.TextField(verbose_name='Ваш вопрос')), - ('time_create', models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')), - ('is_processed', models.BooleanField(default=False, verbose_name='Обработано')), - ], - options={ - 'verbose_name': 'Заявка на звонок', - 'verbose_name_plural': 'Заявки на звонок', - 'ordering': ['-time_create'], - }, - ), - migrations.AlterModelOptions( - name='competence', - options={'ordering': ['time_create', 'title'], 'verbose_name': 'Компетенция', 'verbose_name_plural': 'Компетенции'}, - ), - ] diff --git a/OneCprogsite/programmer/migrations/0010_alter_callbackrequest_email_and_more.py b/OneCprogsite/programmer/migrations/0010_alter_callbackrequest_email_and_more.py deleted file mode 100644 index fc93190..0000000 --- a/OneCprogsite/programmer/migrations/0010_alter_callbackrequest_email_and_more.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 4.2.7 on 2025-11-09 12:09 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('programmer', '0009_callbackrequest_alter_competence_options'), - ] - - operations = [ - migrations.AlterField( - model_name='callbackrequest', - name='email', - field=models.EmailField(blank=True, max_length=254, null=True, verbose_name='Электронная почта'), - ), - migrations.AlterField( - model_name='callbackrequest', - name='question', - field=models.TextField(blank=True, verbose_name='Ваш вопрос'), - ), - ] diff --git a/OneCprogsite/programmer/migrations/0011_visitor_pageview.py b/OneCprogsite/programmer/migrations/0011_visitor_pageview.py deleted file mode 100644 index ab5e555..0000000 --- a/OneCprogsite/programmer/migrations/0011_visitor_pageview.py +++ /dev/null @@ -1,41 +0,0 @@ -# Generated by Django 4.2.7 on 2025-11-12 11:43 - -from django.db import migrations, models -import django.utils.timezone - - -class Migration(migrations.Migration): - - dependencies = [ - ('programmer', '0010_alter_callbackrequest_email_and_more'), - ] - - operations = [ - migrations.CreateModel( - name='Visitor', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('ip_address', models.GenericIPAddressField()), - ('first_visit', models.DateTimeField(default=django.utils.timezone.now)), - ('last_visit', models.DateTimeField(default=django.utils.timezone.now)), - ('visit_count', models.IntegerField(default=1)), - ], - options={ - 'indexes': [models.Index(fields=['ip_address'], name='programmer__ip_addr_2c6dca_idx')], - }, - ), - migrations.CreateModel( - name='PageView', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('url', models.CharField(max_length=500)), - ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), - ('ip_address', models.GenericIPAddressField()), - ('user_agent', models.TextField(blank=True)), - ('referer', models.CharField(blank=True, max_length=500)), - ], - options={ - 'indexes': [models.Index(fields=['url', 'timestamp'], name='programmer__url_9a41b2_idx'), models.Index(fields=['timestamp'], name='programmer__timesta_070072_idx')], - }, - ), - ] diff --git a/OneCprogsite/programmer/migrations/0012_callbackrequest_is_read.py b/OneCprogsite/programmer/migrations/0012_callbackrequest_is_read.py deleted file mode 100644 index 6ddb498..0000000 --- a/OneCprogsite/programmer/migrations/0012_callbackrequest_is_read.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.2.7 on 2025-11-14 09:37 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('programmer', '0011_visitor_pageview'), - ] - - operations = [ - migrations.AddField( - model_name='callbackrequest', - name='is_read', - field=models.BooleanField(default=False, verbose_name='Прочитано'), - ), - ] diff --git a/OneCprogsite/programmer/migrations/0013_callbackrequest_notification_sent.py b/OneCprogsite/programmer/migrations/0013_callbackrequest_notification_sent.py deleted file mode 100644 index 23739b4..0000000 --- a/OneCprogsite/programmer/migrations/0013_callbackrequest_notification_sent.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.2.7 on 2025-11-14 10:03 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('programmer', '0012_callbackrequest_is_read'), - ] - - operations = [ - migrations.AddField( - model_name='callbackrequest', - name='notification_sent', - field=models.BooleanField(default=False, verbose_name='Уведомление отправлено'), - ), - ] diff --git a/OneCprogsite/programmer/migrations/__init__.py b/OneCprogsite/programmer/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/OneCprogsite/programmer/models.py b/OneCprogsite/programmer/models.py deleted file mode 100644 index 11bc2d1..0000000 --- a/OneCprogsite/programmer/models.py +++ /dev/null @@ -1,180 +0,0 @@ -from django.db import models -from django.urls import reverse -from django.utils import timezone -from django.db.models.signals import post_save, post_delete -from django.dispatch import receiver -from django.core.cache import cache -from .utils.email_notifications import send_callback_notification - - -class Recall(models.Model): - title = models.CharField(max_length=255, verbose_name='Организация') - content = models.TextField(blank=True, verbose_name='Отзыв') - scan = models.ImageField(upload_to="scan/%Y/%m/%d/", verbose_name='Фото') - time_create = models.DateTimeField(auto_now_add=True, verbose_name='Дата создания') - time_update = models.DateTimeField(auto_now=True, verbose_name='Дата изменения') - is_published = models.BooleanField(default=True, verbose_name='Опубликован') - - def __str__(self): - return self.title - - def get_absolute_url(self): - return reverse('post', kwargs={'post_id': self.pk}) - - class Meta: - verbose_name = 'Отзыв' - verbose_name_plural = 'Отзывы' - ordering = ['time_create', 'title'] - - def get_seo_title(self): - return f"Отзыв от {self.title} | Программист 1С" - - def get_seo_description(self): - if self.content: - clean_content = self.content[:160].replace('\n', ' ').strip() - return f"Отзыв о работе программиста 1С от {self.title}. {clean_content}..." - return f"Отзыв клиента {self.title} о работе программиста 1С Николая Сердюк" - - -class Competence(models.Model): - title = models.CharField(max_length=255, verbose_name='Программист') - content = models.TextField(blank=True, verbose_name='Компетенция') - photo = models.ImageField(upload_to="photos/%Y/%m/%d/", verbose_name='Фото') - time_create = models.DateTimeField(auto_now_add=True, verbose_name='Дата создания') - time_update = models.DateTimeField(auto_now=True, verbose_name='Дата изменения') - is_published = models.BooleanField(default=True, verbose_name='Опубликован') - - def __str__(self): - return self.title - - def get_absolute_url(self): - return reverse('post', kwargs={'post_id': self.pk}) - - class Meta: - verbose_name = 'Компетенция' - verbose_name_plural = 'Компетенции' - ordering = ['time_create', 'title'] - - -class Solution(models.Model): - title = models.CharField(max_length=255, verbose_name='Наименование') - description = models.TextField(blank=True, verbose_name='Описание') - implementation = models.TextField(blank=True, verbose_name='Реализация') - closing = models.TextField(blank=True, verbose_name='Заключение') - time_create = models.DateTimeField(auto_now_add=True, verbose_name='Дата создания') - time_update = models.DateTimeField(auto_now=True, verbose_name='Дата изменения') - is_published = models.BooleanField(default=True, verbose_name='Опубликован') - - def __str__(self): - return self.title - - def get_absolute_url(self): - return reverse('post', kwargs={'post_id': self.pk}) - - class Meta: - verbose_name = 'Проекты' - verbose_name_plural = 'Проекты' - ordering = ['time_create', 'title'] - - def get_seo_title(self): - """Генерирует SEO-заголовок для проекта""" - return f"Проект: {self.title} | Автоматизация 1С" - - def get_seo_description(self): - """Генерирует SEO-описание для проекта""" - if self.description: - clean_desc = self.description[:160].replace('\n', ' ').strip() - return f"Проект автоматизации: {self.title}. {clean_desc}..." - return f"Реализация проекта {self.title} - программист 1С Николай Сердюк" - - def get_meta_keywords(self): - """Автоматические ключевые слова для проекта""" - base_keywords = ["проект 1С", "автоматизация 1С", "внедрение 1С"] - title_words = self.title.lower().split() - return base_keywords + title_words - - -class Home(models.Model): - title = models.CharField(max_length=255, verbose_name='Наименование') - content = models.TextField(blank=True, verbose_name='Статья') - home_image = models.ImageField(upload_to="home_image/%Y/%m/%d/", verbose_name='Фото') - time_create = models.DateTimeField(auto_now_add=True, verbose_name='Дата создания') - time_update = models.DateTimeField(auto_now=True, verbose_name='Дата изменения') - is_published = models.BooleanField(default=True, verbose_name='Опубликован') - - def __str__(self): - return self.title - - def get_absolute_url(self): - return reverse('post', kwargs={'post_id': self.pk}) - - class Meta: - verbose_name = 'Главная страница' - verbose_name_plural = 'Главная страница' - ordering = ['time_create', 'title'] - - -class CallbackRequest(models.Model): - name = models.CharField(max_length=100, verbose_name='Имя') - phone = models.CharField(max_length=20, verbose_name='Телефон') - email = models.EmailField(blank=True, null=True, verbose_name='Электронная почта') # Сделать необязательным - question = models.TextField(blank=True, verbose_name='Ваш вопрос') # Сделать необязательным - time_create = models.DateTimeField(auto_now_add=True, verbose_name='Дата создания') - is_processed = models.BooleanField(default=False, verbose_name='Обработано') - is_read = models.BooleanField(default=False, verbose_name='Прочитано') - notification_sent = models.BooleanField(default=False, verbose_name='Уведомление отправлено') - - def __str__(self): - return f"{self.name} - {self.phone}" - - class Meta: - verbose_name = 'Заявка на звонок' - verbose_name_plural = 'Заявки на звонок' - ordering = ['-time_create'] - - -# Сигнал для отправки уведомления при создании заявки -@receiver(post_save, sender=CallbackRequest) -def send_callback_email_notification(sender, instance, created, **kwargs): - if created and not instance.notification_sent: - # Отправляем email уведомление - success = send_callback_notification(instance) - if success: - instance.notification_sent = True - # Сохраняем без повторного вызова сигнала - sender.objects.filter(pk=instance.pk).update(notification_sent=True) - - -class PageView(models.Model): - url = models.CharField(max_length=500) - timestamp = models.DateTimeField(default=timezone.now) - ip_address = models.GenericIPAddressField() - user_agent = models.TextField(blank=True) - referer = models.CharField(max_length=500, blank=True) - - class Meta: - indexes = [ - models.Index(fields=['url', 'timestamp']), - models.Index(fields=['timestamp']), - ] - - -class Visitor(models.Model): - ip_address = models.GenericIPAddressField() - first_visit = models.DateTimeField(default=timezone.now) - last_visit = models.DateTimeField(default=timezone.now) - visit_count = models.IntegerField(default=1) - - class Meta: - indexes = [ - models.Index(fields=['ip_address']), - ] - - -@receiver([post_save, post_delete], sender=Home) -@receiver([post_save, post_delete], sender=Solution) -@receiver([post_save, post_delete], sender=Competence) -@receiver([post_save, post_delete], sender=Recall) -def clear_sitemap_cache(sender, **kwargs): - """Очищаем кэш sitemap при изменении контента""" - cache.delete('sitemap_cache') diff --git a/OneCprogsite/programmer/sitemaps.py b/OneCprogsite/programmer/sitemaps.py deleted file mode 100644 index d0c1132..0000000 --- a/OneCprogsite/programmer/sitemaps.py +++ /dev/null @@ -1,64 +0,0 @@ -from django.contrib.sitemaps import Sitemap -from django.urls import reverse -from .models import Home, Solution, Competence, Recall - -class StaticViewSitemap(Sitemap): - priority = 1.0 - changefreq = 'monthly' - - def items(self): - return ['home', 'about', 'solution', 'ability', 'recall'] - - def location(self, item): - return reverse(item) - -class HomeSitemap(Sitemap): - changefreq = 'weekly' - priority = 1.0 - - def items(self): - return Home.objects.filter(is_published=True) - - def lastmod(self, obj): - return obj.time_update - - # УБИРАЕМ метод location - используем default - # Django автоматически сгенерирует правильные URL - -class SolutionSitemap(Sitemap): - changefreq = 'weekly' - priority = 0.9 - - def items(self): - return Solution.objects.filter(is_published=True) - - def lastmod(self, obj): - return obj.time_update - -class CompetenceSitemap(Sitemap): - changefreq = 'monthly' - priority = 0.8 - - def items(self): - return Competence.objects.filter(is_published=True) - - def lastmod(self, obj): - return obj.time_update - -class RecallSitemap(Sitemap): - changefreq = 'monthly' - priority = 0.7 - - def items(self): - return Recall.objects.filter(is_published=True) - - def lastmod(self, obj): - return obj.time_update - -# Упрощаем sitemaps - убираем HomeSitemap если он дублирует главную -sitemaps = { - 'static': StaticViewSitemap, - 'solutions': SolutionSitemap, - 'competence': CompetenceSitemap, - 'recall': RecallSitemap, -} \ No newline at end of file diff --git a/OneCprogsite/programmer/static/programmer/css/competence.css b/OneCprogsite/programmer/static/programmer/css/competence.css deleted file mode 100644 index 5073dab..0000000 --- a/OneCprogsite/programmer/static/programmer/css/competence.css +++ /dev/null @@ -1,299 +0,0 @@ -/* competence.css - Стили для страницы компетенций */ - -/* Основные стили для страницы компетенций */ -.competence-item { - display: flex; - gap: 2rem; - align-items: flex-start; - padding: 2rem; - background: var(--bg-card); - border-radius: var(--radius-xl); - box-shadow: var(--shadow-lg); - border-left: 4px solid var(--secondary); - transition: var(--transition); - border: 1px solid var(--border-light); -} - -.competence-item:hover { - transform: translateX(8px); - box-shadow: var(--shadow-xl); - border-color: var(--primary-light); -} - -.competence-scan-wrapper { - flex-shrink: 0; -} - -.competence-scan-container { - width: 280px; - cursor: pointer; - border-radius: var(--radius-lg); - overflow: hidden; - border: 2px solid var(--border-light); - transition: var(--transition); - position: relative; - box-shadow: var(--shadow-md); -} - -.competence-scan-container:hover { - transform: translateY(-4px) scale(1.02); - box-shadow: var(--shadow-xl); - border-color: var(--primary); -} - -.competence-scan { - width: 100%; - height: auto; - display: block; - transition: var(--transition); -} - -.competence-content { - flex: 1; - min-width: 0; -} - -.competence-title { - font-size: 1.5rem; - font-weight: 700; - color: var(--text-primary); - margin-bottom: 1rem; - background: var(--gradient-primary); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -.competence-description { - line-height: 1.7; - font-size: 1.05rem; - color: var(--text-primary); -} - -.competence-description p { - margin-bottom: 1rem; -} - -.competence-description p:last-child { - margin-bottom: 0; -} - -.scan-hint { - position: absolute; - bottom: 0; - left: 0; - right: 0; - background: linear-gradient(transparent, rgba(0,0,0,0.8)); - color: white; - padding: 1rem; - text-align: center; - opacity: 0; - transition: var(--transition); - transform: translateY(10px); -} - -.competence-scan-container:hover .scan-hint { - opacity: 1; - transform: translateY(0); -} - -/* Стили для модального окна с изображением компетенций */ -.modal.competence-modal { - background-color: rgba(15, 19, 31, 0.95); - backdrop-filter: blur(10px); -} - -.modal.competence-modal .modal-content { - background: transparent; - border: none; - box-shadow: none; - max-width: 95vw; - max-height: 95vh; - margin: 2% auto; -} - -.modal.competence-modal .modal-header { - background: var(--bg-card); - border-bottom: 2px solid var(--border-light); - padding: 1.5rem 2rem; -} - -.modal.competence-modal .modal-header h3 { - margin: 0; - color: var(--text-primary); - font-size: 1.25rem; - font-weight: 600; - background: var(--gradient-primary); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -.modal.competence-modal .modal-body { - padding: 1rem; - display: flex; - align-items: center; - justify-content: center; - background: transparent; -} - -.modal-image { - max-width: 90vw; - max-height: 80vh; - width: auto; - height: auto; - display: block; - margin: 0 auto; - border-radius: var(--radius-md); - box-shadow: var(--shadow-xl); - transition: all 0.3s ease; -} - -/* Анимации для модального окна */ -.modal.competence-modal { - transition: opacity 0.3s ease; - opacity: 0; -} - -.modal.competence-modal.active { - opacity: 1; -} - -.modal.competence-modal .modal-content { - transform: scale(0.7); - transition: transform 0.3s ease; -} - -.modal.competence-modal.active .modal-content { - transform: scale(1); -} - -/* Улучшенные тени и границы */ -.competence-scan-container { - border: 2px solid var(--border-light); - box-shadow: var(--shadow-lg); -} - -.competence-scan-container:hover { - border-color: var(--primary-light); - box-shadow: var(--shadow-xl); -} - -/* Адаптивность для мобильных устройств */ -@media (max-width: 768px) { - .competence-item { - flex-direction: column; - padding: 1.5rem; - gap: 1.5rem; - } - - .competence-scan-container { - width: 100%; - max-width: 300px; - margin: 0 auto; - } - - .competence-title { - font-size: 1.375rem; - text-align: center; - } - - .modal-image { - max-width: 95vw; - max-height: 70vh; - } - - .modal.competence-modal .modal-content { - margin: 10% auto; - } - - .modal.competence-modal .modal-header { - padding: 1rem 1.5rem; - } -} - -@media (max-width: 480px) { - .competence-item { - padding: 1.25rem; - } - - .competence-scan-container { - max-width: 100%; - } - - .competence-title { - font-size: 1.25rem; - } - - .modal.competence-modal .modal-content { - margin: 5% auto; - max-width: 98vw; - } - - .modal.competence-modal .modal-body { - padding: 0.5rem; - } - - .modal.competence-modal .modal-header { - padding: 1rem; - } - - .modal.competence-modal .modal-header h3 { - font-size: 1.1rem; - } -} - -/* Стили для светлой темы */ -@media (prefers-color-scheme: light) { - .modal.competence-modal { - background-color: rgba(0, 0, 0, 0.8); - } - - .modal.competence-modal .modal-header { - background: var(--bg-primary); - } - - .scan-hint { - background: linear-gradient(transparent, rgba(0,0,0,0.7)); - } - - .competence-item { - background: var(--bg-primary); - } - - .competence-description { - color: var(--text-primary); - } -} - -/* Улучшенные стили для сетки компетенций */ -.competence-grid { - display: grid; - gap: 2rem; -} - -.competence-grid .modern-card { - padding: 0; - overflow: hidden; -} - -.competence-grid .modern-card::before { - height: 4px; - background: var(--gradient-secondary); -} - -/* Анимации появления */ -.fade-in { - animation: fadeInUp 0.8s ease-out; -} - -@keyframes fadeInUp { - from { - opacity: 0; - transform: translateY(40px); - } - to { - opacity: 1; - transform: translateY(0); - } -} \ No newline at end of file diff --git a/OneCprogsite/programmer/static/programmer/css/recall.css b/OneCprogsite/programmer/static/programmer/css/recall.css deleted file mode 100644 index 9b7cc7a..0000000 --- a/OneCprogsite/programmer/static/programmer/css/recall.css +++ /dev/null @@ -1,228 +0,0 @@ -/* recall.css - Стили для страницы отзывов */ - -/* Основные стили для страницы отзывов */ -.recall-item { - display: flex; - flex-direction: column; - gap: 1.5rem; -} - -.recall-content { - display: flex; - gap: 2rem; - align-items: flex-start; -} - -.recall-scan-wrapper { - flex-shrink: 0; -} - -.recall-scan-container { - width: 280px; - cursor: pointer; - border-radius: var(--radius-lg); - overflow: hidden; - border: 2px solid var(--border-light); - transition: var(--transition); - position: relative; - box-shadow: var(--shadow-md); -} - -.recall-scan-container:hover { - transform: translateY(-4px) scale(1.02); - box-shadow: var(--shadow-xl); - border-color: var(--primary); -} - -.recall-scan { - width: 100%; - height: auto; - display: block; - transition: var(--transition); -} - -.recall-text { - flex: 1; - min-width: 0; - line-height: 1.7; - font-size: 1.05rem; - color: var(--text-primary); -} - -.recall-text p { - margin-bottom: 1rem; -} - -.recall-text p:last-child { - margin-bottom: 0; -} - -.scan-hint { - position: absolute; - bottom: 0; - left: 0; - right: 0; - background: linear-gradient(transparent, rgba(0,0,0,0.8)); - color: white; - padding: 1rem; - text-align: center; - opacity: 0; - transition: var(--transition); - transform: translateY(10px); -} - -.recall-scan-container:hover .scan-hint { - opacity: 1; - transform: translateY(0); -} - -/* Стили для модального окна с изображением */ -.modal.image-modal { - background-color: rgba(15, 19, 31, 0.95); - backdrop-filter: blur(10px); -} - -.modal.image-modal .modal-content { - background: transparent; - border: none; - box-shadow: none; - max-width: 95vw; - max-height: 95vh; - margin: 2% auto; -} - -.modal.image-modal .modal-header { - background: var(--bg-card); - border-bottom: 2px solid var(--border-light); - padding: 1.5rem 2rem; -} - -.modal.image-modal .modal-header h3 { - margin: 0; - color: var(--text-primary); - font-size: 1.25rem; - font-weight: 600; - background: var(--gradient-primary); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -.modal.image-modal .modal-body { - padding: 1rem; - display: flex; - align-items: center; - justify-content: center; - background: transparent; -} - -.modal-image { - max-width: 90vw; - max-height: 80vh; - width: auto; - height: auto; - display: block; - margin: 0 auto; - border-radius: var(--radius-md); - box-shadow: var(--shadow-xl); - transition: all 0.3s ease; -} - -/* Анимации для модального окна */ -.modal.image-modal { - transition: opacity 0.3s ease; - opacity: 0; -} - -.modal.image-modal.active { - opacity: 1; -} - -.modal.image-modal .modal-content { - transform: scale(0.7); - transition: transform 0.3s ease; -} - -.modal.image-modal.active .modal-content { - transform: scale(1); -} - -/* Улучшенные тени и границы */ -.recall-scan-container { - border: 2px solid var(--border-light); - box-shadow: var(--shadow-lg); -} - -.recall-scan-container:hover { - border-color: var(--primary-light); - box-shadow: var(--shadow-xl); -} - -/* Адаптивность для мобильных устройств */ -@media (max-width: 768px) { - .recall-content { - flex-direction: column; - gap: 1.5rem; - } - - .recall-scan-container { - width: 100%; - max-width: 300px; - margin: 0 auto; - } - - .recall-scan-wrapper { - order: -1; - } - - .modal-image { - max-width: 95vw; - max-height: 70vh; - } - - .modal.image-modal .modal-content { - margin: 10% auto; - } - - .modal.image-modal .modal-header { - padding: 1rem 1.5rem; - } -} - -@media (max-width: 480px) { - .recall-scan-container { - max-width: 100%; - } - - .modal.image-modal .modal-content { - margin: 5% auto; - max-width: 98vw; - } - - .modal.image-modal .modal-body { - padding: 0.5rem; - } - - .modal.image-modal .modal-header { - padding: 1rem; - } - - .modal.image-modal .modal-header h3 { - font-size: 1.1rem; - } -} - -/* Стили для светлой темы */ -@media (prefers-color-scheme: light) { - .modal.image-modal { - background-color: rgba(0, 0, 0, 0.8); - } - - .modal.image-modal .modal-header { - background: var(--bg-primary); - } - - .scan-hint { - background: linear-gradient(transparent, rgba(0,0,0,0.7)); - } -} \ No newline at end of file diff --git a/OneCprogsite/programmer/static/programmer/css/styles_dark.css b/OneCprogsite/programmer/static/programmer/css/styles_dark.css deleted file mode 100644 index 5be643e..0000000 --- a/OneCprogsite/programmer/static/programmer/css/styles_dark.css +++ /dev/null @@ -1,1473 +0,0 @@ -/* ===== CSS RESET & VARIABLES ===== */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -:root { - /* 1C Brand Colors - Modern Gradient Palette */ - --primary: #FF6B00; /* 1C Orange */ - --primary-dark: #E55A00; - --primary-light: #FF8A3D; - --secondary: #0055A5; /* 1C Blue */ - --secondary-dark: #004488; - --secondary-light: #3377CC; - --accent: #00A8FF; - - /* Extended 1C Color Palette */ - --gradient-primary: linear-gradient(135deg, #FF6B00 0%, #FF8A3D 100%); - --gradient-secondary: linear-gradient(135deg, #0055A5 0%, #3377CC 100%); - --gradient-hero: linear-gradient(135deg, #FF6B00 0%, #0055A5 100%); - - /* Dark Theme Colors */ - --bg-primary: #1A1F2E; - --bg-secondary: #151925; - --bg-tertiary: #0F131F; - --bg-card: #222738; - - --text-primary: #FFFFFF; - --text-secondary: #B0B8D1; - --text-light: #8A93B0; - - --border-light: #2D3447; - --border-medium: #3A4158; - --border-dark: #252A3A; - - /* Modern Shadows */ - --shadow-sm: 0 1px 3px 0 rgba(0, 0, 0, 0.3), 0 1px 2px 0 rgba(0, 0, 0, 0.2); - --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -1px rgba(0, 0, 0, 0.3); - --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.5), 0 4px 6px -2px rgba(0, 0, 0, 0.4); - --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.6), 0 10px 10px -5px rgba(0, 0, 0, 0.5); - - /* Border radius */ - --radius-sm: 8px; - --radius-md: 12px; - --radius-lg: 16px; - --radius-xl: 20px; - - /* Transitions */ - --transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); - --transition-slow: all 0.5s cubic-bezier(0.4, 0, 0.2, 1); -} - -/* ===== BASE STYLES ===== */ -html { - scroll-behavior: smooth; -} - -body { - font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; - line-height: 1.6; - color: var(--text-primary); - background: linear-gradient(135deg, var(--bg-tertiary) 0%, var(--bg-secondary) 50%, var(--bg-primary) 100%); - font-size: 16px; - overflow-x: hidden; - min-height: 100vh; -} - -.container { - max-width: 1200px; - margin: 0 auto; - padding: 0 20px; -} - -/* ===== ENHANCED HEADER ===== */ -.header { - background: rgba(26, 31, 46, 0.95); - border-bottom: 1px solid var(--border-dark); - box-shadow: var(--shadow-lg); - position: sticky; - top: 0; - z-index: 1000; - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); -} - -.nav { - display: flex; - align-items: center; - justify-content: space-between; - padding: 1rem 0; - gap: 2rem; -} - -.logo { - display: flex; - align-items: center; - text-decoration: none; - font-weight: 700; - font-size: 1.375rem; - color: var(--text-primary); - transition: var(--transition); - background: var(--gradient-primary); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -.logo:hover { - transform: translateY(-1px); -} - -.logo-img { - width: 40px; - height: 40px; - margin-right: 12px; - border-radius: var(--radius-md); - background: var(--gradient-primary); - padding: 4px; - filter: drop-shadow(0 4px 8px rgba(255, 107, 0, 0.3)); -} - -.nav-menu { - display: flex; - list-style: none; - gap: 2.5rem; - margin: 0; - flex-wrap: wrap; -} - -.nav-link { - text-decoration: none; - color: var(--text-secondary); - font-weight: 600; - padding: 0.75rem 0; - position: relative; - transition: var(--transition); - font-size: 1rem; -} - -.nav-link:hover { - color: var(--primary); -} - -.nav-link.active { - color: var(--primary); - font-weight: 700; -} - -.nav-link.active::after { - content: ''; - position: absolute; - bottom: -2px; - left: 0; - right: 0; - height: 3px; - background: var(--gradient-primary); - border-radius: 2px; -} - -.telegram-btn { - display: flex; - align-items: center; - gap: 10px; - background: var(--gradient-primary); - color: white; - text-decoration: none; - padding: 0.6rem 1.2rem; - border-radius: var(--radius-lg); - font-weight: 600; - transition: var(--transition); - white-space: nowrap; - box-shadow: var(--shadow-md); - border: none; - cursor: pointer; - font-size: 0.95rem; -} - -.telegram-btn:hover { - transform: translateY(-2px); - box-shadow: var(--shadow-lg); - background: var(--gradient-primary); -} - -/* ===== ENHANCED HERO SECTION ===== */ -.hero-section { - text-align: center; - padding: 5rem 0 4rem; - margin-bottom: 3rem; - position: relative; -} - -.hero-section::before { - content: ''; - position: absolute; - top: 0; - left: 50%; - transform: translateX(-50%); - width: 200px; - height: 200px; - background: radial-gradient(circle, rgba(255, 107, 0, 0.2) 0%, transparent 70%); - border-radius: 50%; -} - -.hero-title { - font-size: 3.5rem; - font-weight: 800; - margin-bottom: 1.5rem; - line-height: 1.1; - background: var(--gradient-hero); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; - text-shadow: 0 4px 20px rgba(255, 107, 0, 0.3); -} - -.hero-subtitle { - font-size: 1.375rem; - color: var(--text-secondary); - font-weight: 500; - max-width: 600px; - margin: 0 auto; - line-height: 1.6; -} - -/* ===== MODERN CARD STYLES ===== */ -.modern-card { - background: var(--bg-card); - border-radius: var(--radius-xl); - padding: 2rem; - box-shadow: var(--shadow-lg); - border: 1px solid var(--border-light); - transition: var(--transition-slow); - margin-bottom: 2rem; - position: relative; - overflow: hidden; -} - -.modern-card::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 4px; - background: var(--gradient-primary); -} - -.modern-card:hover { - transform: translateY(-8px); - box-shadow: var(--shadow-xl); - border-color: var(--primary-light); -} - -.modern-card.secondary::before { - background: var(--gradient-secondary); -} - -.card-header { - display: flex; - align-items: flex-start; - justify-content: space-between; - margin-bottom: 1.5rem; - gap: 1rem; -} - -.card-title { - font-size: 1.5rem; - font-weight: 700; - color: var(--text-primary); - margin-bottom: 0.75rem; - background: var(--gradient-primary); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -.card-subtitle { - color: var(--text-secondary); - font-size: 1rem; - margin-bottom: 1.5rem; - line-height: 1.6; -} - -.card-content { - color: var(--text-primary); - line-height: 1.7; - font-size: 1.05rem; -} - -.card-content p { - margin-bottom: 1rem; -} - -.card-actions { - margin-top: 2rem; - display: flex; - gap: 1rem; - flex-wrap: wrap; -} - -/* ===== GRID LAYOUTS ===== */ -.grid { - display: grid; - gap: 2rem; -} - -.grid-2 { - grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); -} - -.grid-3 { - grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); -} - -/* ===== ENHANCED BUTTONS ===== */ -.btn { - display: inline-flex; - align-items: center; - gap: 0.75rem; - padding: 1rem 2rem; - border-radius: var(--radius-lg); - text-decoration: none; - font-weight: 600; - border: none; - cursor: pointer; - transition: var(--transition); - font-size: 1rem; - position: relative; - overflow: hidden; -} - -.btn::before { - content: ''; - position: absolute; - top: 0; - left: -100%; - width: 100%; - height: 100%; - background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent); - transition: left 0.5s; -} - -.btn:hover::before { - left: 100%; -} - -.btn-primary { - background: var(--gradient-primary); - color: white; - box-shadow: var(--shadow-md); -} - -.btn-primary:hover { - transform: translateY(-2px); - box-shadow: var(--shadow-lg); -} - -.btn-secondary { - background: var(--gradient-secondary); - color: white; - box-shadow: var(--shadow-md); -} - -.btn-secondary:hover { - transform: translateY(-2px); - box-shadow: var(--shadow-lg); -} - -.btn-outline { - background: transparent; - color: var(--primary); - border: 2px solid var(--primary); -} - -.btn-outline:hover { - background: var(--primary); - color: white; - transform: translateY(-2px); -} - -/* ===== ENHANCED ABOUT PAGE ===== */ -.about-header { - text-align: center; - margin-bottom: 3rem; - padding: 3rem 0; - background: linear-gradient(135deg, var(--bg-card) 0%, var(--bg-primary) 100%); - border-radius: var(--radius-xl); - box-shadow: var(--shadow-lg); - border: 1px solid var(--border-light); -} - -.about-header h2 { - font-size: 2.5rem; - font-weight: 800; - margin-bottom: 0.5rem; - background: var(--gradient-hero); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -.about-header .subtitle { - font-size: 1.25rem; - color: var(--text-secondary); - font-weight: 500; -} - -.about-section { - margin-bottom: 3rem; - padding: 2.5rem; - background: var(--bg-card); - border-radius: var(--radius-xl); - box-shadow: var(--shadow-lg); - border-left: 4px solid var(--primary); - border: 1px solid var(--border-light); -} - -.about-section h3 { - font-size: 1.5rem; - font-weight: 700; - margin-bottom: 1.5rem; - color: var(--text-primary); - display: flex; - align-items: center; - gap: 0.75rem; -} - -.skills-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); - gap: 2rem; - margin-top: 1.5rem; -} - -.skill-category { - background: var(--bg-primary); - padding: 1.5rem; - border-radius: var(--radius-lg); - border: 1px solid var(--border-light); - transition: var(--transition); -} - -.skill-category:hover { - transform: translateY(-4px); - box-shadow: var(--shadow-md); - border-color: var(--primary-light); -} - -.skill-category h4 { - color: var(--primary); - font-weight: 600; - margin-bottom: 1rem; - font-size: 1.125rem; -} - -.skill-category ul { - list-style: none; - padding: 0; -} - -.skill-category li { - padding: 0.5rem 0; - color: var(--text-secondary); - border-bottom: 1px solid var(--border-dark); - position: relative; - padding-left: 1.5rem; -} - -.skill-category li:before { - content: '▸'; - position: absolute; - left: 0; - color: var(--primary); - font-weight: bold; -} - -.skill-category li:last-child { - border-bottom: none; -} - -/* ===== ENHANCED COMPETENCE STYLES ===== */ -.competence-grid { - display: grid; - gap: 2rem; -} - -.competence-item { - display: flex; - gap: 2rem; - align-items: flex-start; - padding: 2rem; - background: var(--bg-card); - border-radius: var(--radius-xl); - box-shadow: var(--shadow-lg); - border-left: 4px solid var(--secondary); - transition: var(--transition); - border: 1px solid var(--border-light); -} - -.competence-item:hover { - transform: translateX(8px); - box-shadow: var(--shadow-xl); - border-color: var(--primary-light); -} - -.competence-scan-wrapper { - flex-shrink: 0; -} - -.competence-scan-container { - width: 220px; - cursor: pointer; - border-radius: var(--radius-lg); - overflow: hidden; - border: 2px solid var(--border-light); - transition: var(--transition); - position: relative; - box-shadow: var(--shadow-md); -} - -.competence-scan-container:hover { - transform: translateY(-4px) scale(1.02); - box-shadow: var(--shadow-xl); - border-color: var(--primary); -} - -.competence-scan { - width: 100%; - height: auto; - display: block; - transition: var(--transition); -} - -.scan-hint { - position: absolute; - bottom: 0; - left: 0; - right: 0; - background: linear-gradient(transparent, rgba(0,0,0,0.8)); - color: white; - padding: 1rem; - text-align: center; - opacity: 0; - transition: var(--transition); - transform: translateY(10px); -} - -.competence-scan-container:hover .scan-hint { - opacity: 1; - transform: translateY(0); -} - -/* ===== ENHANCED RECALL STYLES ===== */ -.recall-grid { - display: grid; - gap: 2rem; -} - -.recall-header { - display: flex; - justify-content: space-between; - align-items: flex-start; - margin-bottom: 1.5rem; - padding-bottom: 1.5rem; - border-bottom: 2px solid var(--border-light); -} - -.recall-title { - font-size: 1.375rem; - font-weight: 700; - color: var(--text-primary); - margin-bottom: 0.75rem; -} - -.recall-meta { - display: flex; - gap: 1rem; - font-size: 0.875rem; - font-weight: 500; -} - -.recall-date { - background: var(--gradient-primary); - color: white; - padding: 0.5rem 1rem; - border-radius: var(--radius-md); - font-weight: 600; -} - -.recall-client { - background: var(--gradient-secondary); - color: white; - padding: 0.5rem 1rem; - border-radius: var(--radius-md); - font-weight: 600; -} - -/* ===== ENHANCED PAGE HEADERS ===== */ -.page-header { - margin-bottom: 3rem; - padding: 3rem 0; - text-align: center; - background: linear-gradient(135deg, var(--bg-card) 0%, var(--bg-primary) 100%); - border-radius: var(--radius-xl); - box-shadow: var(--shadow-lg); - border: 1px solid var(--border-light); - position: relative; - overflow: hidden; -} - -.page-header::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 4px; - background: var(--gradient-primary); -} - -.page-title { - font-size: 3rem; - font-weight: 800; - color: var(--text-primary); - margin-bottom: 1rem; - background: var(--gradient-hero); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; - text-shadow: 0 4px 20px rgba(255, 107, 0, 0.3); -} - -.page-subtitle { - color: var(--text-secondary); - font-size: 1.25rem; - font-weight: 500; - max-width: 600px; - margin: 0 auto; -} - -/* ===== ENHANCED FOOTER ===== */ -.footer { - background: linear-gradient(135deg, var(--bg-tertiary) 0%, var(--bg-secondary) 100%); - color: var(--text-primary); - padding: 4rem 0 2rem; - margin-top: 6rem; - position: relative; - border-top: 1px solid var(--border-dark); -} - -.footer::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 4px; - background: var(--gradient-primary); -} - -.footer-content { - display: grid; - grid-template-columns: 1fr 1fr 1fr; - gap: 3rem; - margin-bottom: 3rem; -} - -.footer-info h3 { - margin-bottom: 1rem; - color: var(--text-primary); - font-size: 1.5rem; - font-weight: 700; -} - -.footer-info p { - opacity: 0.9; - font-size: 1.05rem; - color: var(--text-secondary); -} - -.footer-contacts p { - margin-bottom: 0.75rem; - opacity: 0.9; - display: flex; - align-items: center; - gap: 0.5rem; - font-size: 1.05rem; - color: var(--text-secondary); -} - -.footer-copyright { - grid-column: 1 / -1; - text-align: center; - padding-top: 2rem; - border-top: 1px solid var(--border-light); - opacity: 0.7; - font-size: 0.95rem; - color: var(--text-light); -} - -/* ===== ANIMATIONS ===== */ -@keyframes fadeInUp { - from { - opacity: 0; - transform: translateY(40px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -@keyframes float { - 0%, 100% { - transform: translateY(0); - } - 50% { - transform: translateY(-10px); - } -} - -@keyframes gradientShift { - 0% { - background-position: 0% 50%; - } - 50% { - background-position: 100% 50%; - } - 100% { - background-position: 0% 50%; - } -} - -.fade-in { - animation: fadeInUp 0.8s ease-out; -} - -.float { - animation: float 3s ease-in-out infinite; -} - -.gradient-animate { - background-size: 200% 200%; - animation: gradientShift 3s ease infinite; -} - -/* ===== RESPONSIVE DESIGN ===== */ -@media (max-width: 1024px) { - .nav-menu { - gap: 1.5rem; - } - - .nav-actions { - gap: 0.75rem; - } -} - -@media (max-width: 768px) { - .nav-menu { - display: none !important; - } - - .mobile-menu-btn { - display: block !important; - } - - .nav-actions .telegram-btn span:not(.telegram-icon), - .nav-actions .telegram-btn .telegram-icon { - display: none; - } - - .nav-actions .telegram-btn { - padding: 0.75rem; - width: 45px; - height: 45px; - display: flex; - align-items: center; - justify-content: center; - } - - .nav-actions .telegram-btn::after { - content: "📱"; - font-size: 1.2rem; - } - - .theme-switcher { - display: none; - } - - .nav { - gap: 1rem; - } - - .logo-text { - font-size: 1.1rem; - } -} - -@media (max-width: 480px) { - .container { - padding: 0 12px; - } - - .nav { - padding: 0.75rem 0; - } - - .logo-img { - width: 32px; - height: 32px; - } - - .logo-text { - font-size: 1rem; - } - - .mobile-menu { - width: 280px; - } - - .nav-actions { - gap: 0.5rem; - } - - .nav-actions .telegram-btn { - width: 40px; - height: 40px; - padding: 0.5rem; - } -} - -@media (min-width: 769px) { - .mobile-menu-btn, - .mobile-menu-overlay, - .mobile-menu { - display: none !important; - } -} - -/* ===== UTILITY CLASSES ===== */ -.text-center { text-align: center; } -.text-left { text-align: left; } -.text-right { text-align: right; } - -.justify-center { justify-content: center; } -.justify-between { justify-content: space-between; } - -.mb-1 { margin-bottom: 0.5rem; } -.mb-2 { margin-bottom: 1rem; } -.mb-3 { margin-bottom: 1.5rem; } -.mb-4 { margin-bottom: 2rem; } - -.mt-1 { margin-top: 0.5rem; } -.mt-2 { margin-top: 1rem; } -.mt-3 { margin-top: 1.5rem; } -.mt-4 { margin-top: 2rem; } - -.hidden { display: none; } - -/* ===== CUSTOM COMPONENTS ===== */ -.content-card { - background: var(--bg-card); - border-radius: var(--radius-xl); - padding: 2.5rem; - box-shadow: var(--shadow-lg); - border: 1px solid var(--border-light); - margin-bottom: 2rem; - position: relative; - overflow: hidden; -} - -.content-card::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 4px; - background: var(--gradient-primary); -} - -.improved-list { - list-style: none; - padding: 0; -} - -.improved-list li { - margin-bottom: 2rem; -} - -/* ===== FORM STYLES ===== */ -.form-group { - margin-bottom: 1.5rem; -} - -.form-group label { - display: block; - margin-bottom: 0.5rem; - font-weight: 600; - color: var(--text-primary); -} - -.form-input, .form-textarea { - width: 100%; - padding: 1rem 1.25rem; - border: 2px solid var(--border-light); - border-radius: var(--radius-lg); - font-size: 1rem; - transition: var(--transition); - background: var(--bg-primary); - color: var(--text-primary); - font-family: inherit; -} - -.form-input::placeholder, .form-textarea::placeholder { - color: var(--text-light); -} - -.form-input:focus, .form-textarea:focus { - outline: none; - border-color: var(--primary); - box-shadow: 0 0 0 4px rgba(255, 107, 0, 0.2); - transform: translateY(-2px); - background: var(--bg-card); -} - -.form-textarea { - resize: vertical; - min-height: 120px; - line-height: 1.5; -} - -/* ===== MODAL ENHANCEMENTS ===== */ -.modal { - display: none; - position: fixed; - z-index: 1000; - left: 0; - top: 0; - width: 100%; - height: 100%; - background-color: rgba(15, 19, 31, 0.95); - backdrop-filter: blur(10px); - animation: fadeIn 0.3s ease; -} - -.modal-content { - background: var(--bg-card); - margin: 2% auto; - border-radius: var(--radius-xl); - box-shadow: var(--shadow-xl); - animation: slideIn 0.3s ease; - position: relative; - max-width: 90%; - max-height: 90vh; - overflow: auto; - border: 1px solid var(--border-light); -} - -.modal-header { - display: flex; - justify-content: space-between; - align-items: center; - padding: 2rem 2rem 1rem; - border-bottom: 2px solid var(--border-light); -} - -.modal-header h3 { - margin: 0; - color: var(--text-primary); - font-size: 1.5rem; - font-weight: 700; - background: var(--gradient-primary); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -.modal-body { - padding: 2rem; -} - -.modal-close { - color: var(--text-light); - font-size: 2rem; - font-weight: bold; - cursor: pointer; - transition: var(--transition); - background: none; - border: none; - padding: 0; - width: 40px; - height: 40px; - display: flex; - align-items: center; - justify-content: center; - border-radius: var(--radius-md); -} - -.modal-close:hover { - color: var(--primary); - background: var(--bg-primary); - transform: rotate(90deg); -} - -@keyframes fadeIn { - from { opacity: 0; } - to { opacity: 1; } -} - -@keyframes slideIn { - from { - opacity: 0; - transform: translateY(-50px) scale(0.9); - } - to { - opacity: 1; - transform: translateY(0) scale(1); - } -} - -/* ===== SOLUTION PAGE STYLES ===== */ -.solution-accordion { - margin: 2rem 0; -} - -.accordion-item { - background: var(--bg-primary); - border-radius: var(--radius-lg); - margin-bottom: 1rem; - border: 2px solid var(--border-light); - overflow: hidden; - transition: var(--transition); -} - -.accordion-item:hover { - border-color: var(--primary-light); - transform: translateX(4px); -} - -.accordion-header { - padding: 1.5rem; - background: var(--gradient-primary); - color: white; - font-weight: 600; - font-size: 1.125rem; - cursor: pointer; - display: flex; - justify-content: space-between; - align-items: center; - transition: var(--transition); -} - -.accordion-header:hover { - background: var(--primary-dark); -} - -.accordion-content { - padding: 1.5rem; - background: var(--bg-card); - line-height: 1.7; - color: var(--text-secondary); -} - -.accordion-content p { - margin-bottom: 1rem; -} - -.accordion-content p:last-child { - margin-bottom: 0; -} - -/* ===== MAIN CONTENT AREA ===== */ -.main { - min-height: calc(100vh - 140px); - padding: 2rem 0; -} - -.content { - min-height: 600px; -} - -.breadcrumbs { - display: flex; - align-items: center; - gap: 0.5rem; - margin-bottom: 2rem; - font-size: 0.875rem; - color: var(--text-light); -} - -.breadcrumb-link { - color: var(--text-secondary); - text-decoration: none; - transition: var(--transition); -} - -.breadcrumb-link:hover { - color: var(--primary); -} - -.breadcrumb-separator { - color: var(--text-light); -} - -.breadcrumb-current { - color: var(--text-primary); - font-weight: 500; -} - -.page-content { - background: var(--bg-card); - border-radius: var(--radius-xl); - padding: 2rem; - box-shadow: var(--shadow-lg); - border: 1px solid var(--border-light); -} - - -/* ===== THEME SWITCHER STYLES ===== */ -.theme-switcher { - display: flex; - align-items: center; -} - -.theme-toggle-checkbox { - display: none; -} - -.theme-toggle-label { - position: relative; - display: flex; - align-items: center; - width: 60px; - height: 30px; - background: var(--bg-card); - border: 2px solid var(--border-light); - border-radius: 25px; - cursor: pointer; - transition: all 0.3s ease; - padding: 2px; - box-shadow: var(--shadow-sm); -} - -.theme-toggle-label:hover { - border-color: var(--primary); - box-shadow: 0 0 10px rgba(255, 107, 0, 0.3); -} - -.theme-toggle-slider { - position: absolute; - width: 24px; - height: 24px; - background: var(--primary); - border-radius: 50%; - transition: all 0.3s ease; - left: 2px; - z-index: 2; -} - -.theme-toggle-checkbox:checked + .theme-toggle-label .theme-toggle-slider { - transform: translateX(30px); - background: var(--secondary); -} - -.theme-icon { - position: absolute; - font-size: 12px; - transition: all 0.3s ease; - z-index: 1; -} - -.theme-icon.sun { - left: 8px; - opacity: 1; -} - -.theme-icon.moon { - right: 8px; - opacity: 0; -} - -.theme-toggle-checkbox:checked + .theme-toggle-label .theme-icon.sun { - opacity: 0; -} - -.theme-toggle-checkbox:checked + .theme-toggle-label .theme-icon.moon { - opacity: 1; -} - -/* ===== MOBILE RESPONSIVE STYLES ===== */ -@media (max-width: 768px) { - .hero-title { - font-size: 2.5rem; - } - - .hero-subtitle { - font-size: 1.125rem; - padding: 0 1rem; - } - - .page-title { - font-size: 2.25rem; - } - - .page-subtitle { - font-size: 1.125rem; - padding: 0 1rem; - } - - .grid-2 { - grid-template-columns: 1fr; - gap: 1.5rem; - } - - .modern-card { - padding: 1.5rem; - margin-bottom: 1.5rem; - } - - .card-title { - font-size: 1.375rem; - } - - .content-card { - padding: 1.5rem; - } - - .about-section { - padding: 1.5rem; - } - - .skills-grid { - grid-template-columns: 1fr; - gap: 1.5rem; - } - - .competence-item { - flex-direction: column; - padding: 1.5rem; - gap: 1.5rem; - } - - .competence-scan-container { - width: 100%; - max-width: 280px; - margin: 0 auto; - } - - .recall-header { - flex-direction: column; - gap: 1rem; - align-items: flex-start; - } - - .recall-meta { - flex-direction: column; - gap: 0.5rem; - } - - .footer-content { - grid-template-columns: 1fr; - gap: 2rem; - text-align: center; - } - - .footer-contacts p { - justify-content: center; - } - - .card-actions { - flex-direction: column; - } - - .btn { - width: 100%; - justify-content: center; - } - - .modal-content { - margin: 5% auto; - max-width: 95%; - } - - .modal-header { - padding: 1.5rem 1.5rem 1rem; - } - - .modal-body { - padding: 1.5rem; - } - - .page-content { - padding: 1.5rem; - } - - .breadcrumbs { - font-size: 0.8rem; - } -} - -@media (max-width: 480px) { - .hero-title { - font-size: 2rem; - } - - .hero-subtitle { - font-size: 1rem; - } - - .page-title { - font-size: 1.875rem; - } - - .modern-card { - padding: 1.25rem; - } - - .content-card { - padding: 1.25rem; - } - - .about-section { - padding: 1.25rem; - } - - .card-title { - font-size: 1.25rem; - } - - .competence-scan-container { - max-width: 100%; - } -} - -/* Стили для страницы отзывов */ -.recall-item { - display: flex; - flex-direction: column; - gap: 1.5rem; -} - -.recall-content { - display: flex; - gap: 2rem; - align-items: flex-start; -} - -.recall-scan-wrapper { - flex-shrink: 0; -} - -.recall-scan-container { - width: 280px; - cursor: pointer; - border-radius: var(--radius-lg); - overflow: hidden; - border: 2px solid var(--border-light); - transition: var(--transition); - position: relative; - box-shadow: var(--shadow-md); -} - -.recall-scan-container:hover { - transform: translateY(-4px) scale(1.02); - box-shadow: var(--shadow-xl); - border-color: var(--primary); -} - -.recall-scan { - width: 100%; - height: auto; - display: block; - transition: var(--transition); -} - -.recall-text { - flex: 1; - min-width: 0; - line-height: 1.7; - font-size: 1.05rem; -} - -.scan-hint { - position: absolute; - bottom: 0; - left: 0; - right: 0; - background: linear-gradient(transparent, rgba(0,0,0,0.8)); - color: white; - padding: 1rem; - text-align: center; - opacity: 0; - transition: var(--transition); - transform: translateY(10px); -} - -.recall-scan-container:hover .scan-hint { - opacity: 1; - transform: translateY(0); -} - -/* Стили для модального окна с изображением */ -.modal-image { - max-width: 90vw; - max-height: 80vh; - width: auto; - height: auto; - display: block; - margin: 0 auto; - border-radius: var(--radius-md); - box-shadow: var(--shadow-xl); - transition: all 0.3s ease; -} - -.modal-content.image-modal { - max-width: 95vw; - max-height: 95vh; - background: transparent; - border: none; - box-shadow: none; -} - -.modal-body.image-modal-body { - padding: 1rem; - display: flex; - align-items: center; - justify-content: center; - background: transparent; -} - -/* Адаптивность для мобильных устройств */ -@media (max-width: 768px) { - .recall-content { - flex-direction: column; - gap: 1.5rem; - } - - .recall-scan-container { - width: 100%; - max-width: 300px; - margin: 0 auto; - } - - .recall-scan-wrapper { - order: -1; - } - - .modal-image { - max-width: 95vw; - max-height: 70vh; - } - - .modal-content.image-modal { - margin: 10% auto; - } -} - -@media (max-width: 480px) { - .recall-scan-container { - max-width: 100%; - } - - .modal-content.image-modal { - margin: 5% auto; - max-width: 98vw; - } - - .modal-body.image-modal-body { - padding: 0.5rem; - } -} \ No newline at end of file diff --git a/OneCprogsite/programmer/static/programmer/css/styles_w.css b/OneCprogsite/programmer/static/programmer/css/styles_w.css deleted file mode 100644 index 5dd6e1d..0000000 --- a/OneCprogsite/programmer/static/programmer/css/styles_w.css +++ /dev/null @@ -1,1406 +0,0 @@ -/* ===== CSS RESET & VARIABLES ===== */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -:root { - /* 1C Brand Colors - Modern Gradient Palette */ - --primary: #FF6B00; /* 1C Orange */ - --primary-dark: #E55A00; - --primary-light: #FF8A3D; - --secondary: #0055A5; /* 1C Blue */ - --secondary-dark: #004488; - --secondary-light: #3377CC; - --accent: #00A8FF; - - /* Extended 1C Color Palette */ - --gradient-primary: linear-gradient(135deg, #FF6B00 0%, #FF8A3D 100%); - --gradient-secondary: linear-gradient(135deg, #0055A5 0%, #3377CC 100%); - --gradient-hero: linear-gradient(135deg, #FF6B00 0%, #0055A5 100%); - - --text-primary: #1A1F36; - --text-secondary: #4A5568; - --text-light: #718096; - - --bg-primary: #FFFFFF; - --bg-secondary: #F7FAFC; - --bg-tertiary: #EDF2F7; - - --border-light: #E2E8F0; - --border-medium: #CBD5E0; - - /* Modern Shadows */ - --shadow-sm: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); - --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); - --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); - --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); - - /* Border radius */ - --radius-sm: 8px; - --radius-md: 12px; - --radius-lg: 16px; - --radius-xl: 20px; - - /* Transitions */ - --transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); - --transition-slow: all 0.5s cubic-bezier(0.4, 0, 0.2, 1); -} - -/* ===== BASE STYLES ===== */ -html { - scroll-behavior: smooth; -} - -body { - font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; - line-height: 1.6; - color: var(--text-primary); - background: linear-gradient(135deg, #F7FAFC 0%, #EDF2F7 100%); - font-size: 16px; - overflow-x: hidden; -} - -.container { - max-width: 1200px; - margin: 0 auto; - padding: 0 20px; -} - -/* ===== ENHANCED HEADER ===== */ -.header { - background: rgba(255, 255, 255, 0.95); - border-bottom: 1px solid var(--border-light); - box-shadow: var(--shadow-sm); - position: sticky; - top: 0; - z-index: 1000; - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); -} - -.nav { - display: flex; - align-items: center; - justify-content: space-between; - padding: 1rem 0; - gap: 2rem; -} - -.logo { - display: flex; - align-items: center; - text-decoration: none; - font-weight: 700; - font-size: 1.375rem; - color: var(--text-primary); - transition: var(--transition); - background: var(--gradient-primary); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -.logo:hover { - transform: translateY(-1px); -} - -.logo-img { - width: 40px; - height: 40px; - margin-right: 12px; - border-radius: var(--radius-md); - background: var(--gradient-primary); - padding: 4px; -} - -.nav-menu { - display: flex; - list-style: none; - gap: 2.5rem; - margin: 0; - flex-wrap: wrap; -} - -.nav-link { - text-decoration: none; - color: var(--text-secondary); - font-weight: 600; - padding: 0.75rem 0; - position: relative; - transition: var(--transition); - font-size: 1rem; -} - -.nav-link:hover { - color: var(--primary); -} - -.nav-link.active { - color: var(--primary); - font-weight: 700; -} - -.nav-link.active::after { - content: ''; - position: absolute; - bottom: -2px; - left: 0; - right: 0; - height: 3px; - background: var(--gradient-primary); - border-radius: 2px; -} - -.telegram-btn { - display: flex; - align-items: center; - gap: 10px; - background: var(--gradient-primary); - color: white; - text-decoration: none; - padding: 0.6rem 1.2rem; - border-radius: var(--radius-lg); - font-weight: 600; - transition: var(--transition); - white-space: nowrap; - box-shadow: var(--shadow-md); - border: none; - cursor: pointer; - font-size: 0.95rem; -} - -.telegram-btn:hover { - transform: translateY(-2px); - box-shadow: var(--shadow-lg); - background: var(--gradient-primary); -} - -/* ===== ENHANCED HERO SECTION ===== */ -.hero-section { - text-align: center; - padding: 4rem 0 3rem; - background: var(--gradient-hero); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; - margin-bottom: 3rem; -} - -.hero-title { - font-size: 3.5rem; - font-weight: 800; - margin-bottom: 1.5rem; - line-height: 1.1; - background: var(--gradient-hero); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -.hero-subtitle { - font-size: 1.375rem; - color: var(--text-secondary); - font-weight: 500; - max-width: 600px; - margin: 0 auto; - line-height: 1.6; -} - -/* ===== MODERN CARD STYLES ===== */ -.modern-card { - background: var(--bg-primary); - border-radius: var(--radius-xl); - padding: 2rem; - box-shadow: var(--shadow-lg); - border: 1px solid var(--border-light); - transition: var(--transition-slow); - margin-bottom: 2rem; - position: relative; - overflow: hidden; -} - -.modern-card::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 4px; - background: var(--gradient-primary); -} - -.modern-card:hover { - transform: translateY(-8px); - box-shadow: var(--shadow-xl); -} - -.modern-card.secondary::before { - background: var(--gradient-secondary); -} - -.card-header { - display: flex; - align-items: flex-start; - justify-content: space-between; - margin-bottom: 1.5rem; - gap: 1rem; -} - -.card-title { - font-size: 1.5rem; - font-weight: 700; - color: var(--text-primary); - margin-bottom: 0.75rem; - background: var(--gradient-primary); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -.card-subtitle { - color: var(--text-secondary); - font-size: 1rem; - margin-bottom: 1.5rem; - line-height: 1.6; -} - -.card-content { - color: var(--text-primary); - line-height: 1.7; - font-size: 1.05rem; -} - -.card-content p { - margin-bottom: 1rem; -} - -.card-actions { - margin-top: 2rem; - display: flex; - gap: 1rem; - flex-wrap: wrap; -} - -/* ===== GRID LAYOUTS ===== */ -.grid { - display: grid; - gap: 2rem; -} - -.grid-2 { - grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); -} - -.grid-3 { - grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); -} - -/* ===== ENHANCED BUTTONS ===== */ -.btn { - display: inline-flex; - align-items: center; - gap: 0.75rem; - padding: 1rem 2rem; - border-radius: var(--radius-lg); - text-decoration: none; - font-weight: 600; - border: none; - cursor: pointer; - transition: var(--transition); - font-size: 1rem; - position: relative; - overflow: hidden; -} - -.btn::before { - content: ''; - position: absolute; - top: 0; - left: -100%; - width: 100%; - height: 100%; - background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent); - transition: left 0.5s; -} - -.btn:hover::before { - left: 100%; -} - -.btn-primary { - background: var(--gradient-primary); - color: white; - box-shadow: var(--shadow-md); -} - -.btn-primary:hover { - transform: translateY(-2px); - box-shadow: var(--shadow-lg); -} - -.btn-secondary { - background: var(--gradient-secondary); - color: white; - box-shadow: var(--shadow-md); -} - -.btn-secondary:hover { - transform: translateY(-2px); - box-shadow: var(--shadow-lg); -} - -.btn-outline { - background: transparent; - color: var(--primary); - border: 2px solid var(--primary); -} - -.btn-outline:hover { - background: var(--primary); - color: white; - transform: translateY(-2px); -} - -/* ===== ENHANCED ABOUT PAGE ===== */ -.about-header { - text-align: center; - margin-bottom: 3rem; - padding: 2rem 0; -} - -.about-header h2 { - font-size: 2.5rem; - font-weight: 800; - margin-bottom: 0.5rem; - background: var(--gradient-hero); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -.about-header .subtitle { - font-size: 1.25rem; - color: var(--text-secondary); - font-weight: 500; -} - -.about-section { - margin-bottom: 3rem; - padding: 2.5rem; - background: var(--bg-primary); - border-radius: var(--radius-xl); - box-shadow: var(--shadow-lg); - border-left: 4px solid var(--primary); -} - -.about-section h3 { - font-size: 1.5rem; - font-weight: 700; - margin-bottom: 1.5rem; - color: var(--text-primary); - display: flex; - align-items: center; - gap: 0.75rem; -} - -.skills-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); - gap: 2rem; - margin-top: 1.5rem; -} - -.skill-category { - background: var(--bg-secondary); - padding: 1.5rem; - border-radius: var(--radius-lg); - border: 1px solid var(--border-light); - transition: var(--transition); -} - -.skill-category:hover { - transform: translateY(-4px); - box-shadow: var(--shadow-md); -} - -.skill-category h4 { - color: var(--primary); - font-weight: 600; - margin-bottom: 1rem; - font-size: 1.125rem; -} - -/* ===== ENHANCED COMPETENCE STYLES ===== */ -.competence-grid { - display: grid; - gap: 2rem; -} - -.competence-item { - display: flex; - gap: 2rem; - align-items: flex-start; - padding: 2rem; - background: var(--bg-primary); - border-radius: var(--radius-xl); - box-shadow: var(--shadow-lg); - border-left: 4px solid var(--secondary); - transition: var(--transition); -} - -.competence-item:hover { - transform: translateX(8px); - box-shadow: var(--shadow-xl); -} - -.competence-scan-wrapper { - flex-shrink: 0; -} - -.competence-scan-container { - width: 220px; - cursor: pointer; - border-radius: var(--radius-lg); - overflow: hidden; - border: 2px solid var(--border-light); - transition: var(--transition); - position: relative; - box-shadow: var(--shadow-md); -} - -.competence-scan-container:hover { - transform: translateY(-4px) scale(1.02); - box-shadow: var(--shadow-xl); - border-color: var(--primary); -} - -.competence-scan { - width: 100%; - height: auto; - display: block; - transition: var(--transition); -} - -.scan-hint { - position: absolute; - bottom: 0; - left: 0; - right: 0; - background: linear-gradient(transparent, rgba(0,0,0,0.8)); - color: white; - padding: 1rem; - text-align: center; - opacity: 0; - transition: var(--transition); - transform: translateY(10px); -} - -.competence-scan-container:hover .scan-hint { - opacity: 1; - transform: translateY(0); -} - -/* ===== ENHANCED RECALL STYLES ===== */ -.recall-grid { - display: grid; - gap: 2rem; -} - -.recall-header { - display: flex; - justify-content: space-between; - align-items: flex-start; - margin-bottom: 1.5rem; - padding-bottom: 1.5rem; - border-bottom: 2px solid var(--border-light); -} - -.recall-title { - font-size: 1.375rem; - font-weight: 700; - color: var(--text-primary); - margin-bottom: 0.75rem; -} - -.recall-meta { - display: flex; - gap: 1rem; - font-size: 0.875rem; - font-weight: 500; -} - -.recall-date { - background: var(--gradient-primary); - color: white; - padding: 0.5rem 1rem; - border-radius: var(--radius-md); - font-weight: 600; -} - -.recall-client { - background: var(--gradient-secondary); - color: white; - padding: 0.5rem 1rem; - border-radius: var(--radius-md); - font-weight: 600; -} - -/* ===== ENHANCED PAGE HEADERS ===== */ -.page-header { - margin-bottom: 3rem; - padding: 3rem 0; - text-align: center; - background: linear-gradient(135deg, var(--bg-primary) 0%, var(--bg-secondary) 100%); - border-radius: var(--radius-xl); - box-shadow: var(--shadow-md); - border: 1px solid var(--border-light); -} - -.page-title { - font-size: 3rem; - font-weight: 800; - color: var(--text-primary); - margin-bottom: 1rem; - background: var(--gradient-hero); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -.page-subtitle { - color: var(--text-secondary); - font-size: 1.25rem; - font-weight: 500; - max-width: 600px; - margin: 0 auto; -} - -/* ===== ENHANCED FOOTER ===== */ -.footer { - background: linear-gradient(135deg, var(--text-primary) 0%, #2D3748 100%); - color: white; - padding: 4rem 0 2rem; - margin-top: 6rem; - position: relative; -} - -.footer::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 4px; - background: var(--gradient-primary); -} - -.footer-content { - display: grid; - grid-template-columns: 1fr 1fr 1fr; - gap: 3rem; - margin-bottom: 3rem; -} - -.footer-info h3 { - margin-bottom: 1rem; - color: white; - font-size: 1.5rem; - font-weight: 700; -} - -.footer-info p { - opacity: 0.9; - font-size: 1.05rem; -} - -.footer-contacts p { - margin-bottom: 0.75rem; - opacity: 0.9; - display: flex; - align-items: center; - gap: 0.5rem; - font-size: 1.05rem; -} - -.footer-copyright { - grid-column: 1 / -1; - text-align: center; - padding-top: 2rem; - border-top: 1px solid rgba(255, 255, 255, 0.2); - opacity: 0.7; - font-size: 0.95rem; -} - -/* ===== ANIMATIONS ===== */ -@keyframes fadeInUp { - from { - opacity: 0; - transform: translateY(40px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -@keyframes float { - 0%, 100% { - transform: translateY(0); - } - 50% { - transform: translateY(-10px); - } -} - -@keyframes gradientShift { - 0% { - background-position: 0% 50%; - } - 50% { - background-position: 100% 50%; - } - 100% { - background-position: 0% 50%; - } -} - -.fade-in { - animation: fadeInUp 0.8s ease-out; -} - -.float { - animation: float 3s ease-in-out infinite; -} - -.gradient-animate { - background-size: 200% 200%; - animation: gradientShift 3s ease infinite; -} - -/* ===== RESPONSIVE DESIGN ===== */ -@media (max-width: 1024px) { - .nav-menu { - gap: 1.5rem; - } - - .nav-actions { - gap: 0.75rem; - } -} - -@media (max-width: 768px) { - .nav-menu { - display: none !important; - } - - .mobile-menu-btn { - display: block !important; - } - - .nav-actions .telegram-btn span:not(.telegram-icon), - .nav-actions .telegram-btn .telegram-icon { - display: none; - } - - .nav-actions .telegram-btn { - padding: 0.75rem; - width: 45px; - height: 45px; - display: flex; - align-items: center; - justify-content: center; - background: var(--primary); - color: white; - border-radius: 8px; - text-decoration: none; - } - - .nav-actions .telegram-btn::after { - content: "📱"; - font-size: 1.2rem; - } - - .theme-switcher { - display: none; - } - - .nav { - gap: 1rem; - } - - .logo-text { - font-size: 1.1rem; - } -} - -@media (max-width: 480px) { - .container { - padding: 0 12px; - } - - .nav { - padding: 0.75rem 0; - } - - .logo-img { - width: 32px; - height: 32px; - } - - .logo-text { - font-size: 1rem; - } - - .mobile-menu { - width: 280px; - } - - .nav-actions { - gap: 0.5rem; - } - - .nav-actions .telegram-btn { - width: 40px; - height: 40px; - padding: 0.5rem; - } -} - -@media (min-width: 769px) { - .mobile-menu-btn, - .mobile-menu-overlay, - .mobile-menu { - display: none !important; - } -} - -/* ===== UTILITY CLASSES ===== */ -.text-center { text-align: center; } -.text-left { text-align: left; } -.text-right { text-align: right; } - -.justify-center { justify-content: center; } -.justify-between { justify-content: space-between; } - -.mb-1 { margin-bottom: 0.5rem; } -.mb-2 { margin-bottom: 1rem; } -.mb-3 { margin-bottom: 1.5rem; } -.mb-4 { margin-bottom: 2rem; } - -.mt-1 { margin-top: 0.5rem; } -.mt-2 { margin-top: 1rem; } -.mt-3 { margin-top: 1.5rem; } -.mt-4 { margin-top: 2rem; } - -.hidden { display: none; } - -/* ===== CUSTOM COMPONENTS ===== */ -.content-card { - background: var(--bg-primary); - border-radius: var(--radius-xl); - padding: 2.5rem; - box-shadow: var(--shadow-lg); - border: 1px solid var(--border-light); - margin-bottom: 2rem; - position: relative; - overflow: hidden; -} - -.content-card::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 4px; - background: var(--gradient-primary); -} - -.improved-list { - list-style: none; - padding: 0; -} - -.improved-list li { - margin-bottom: 2rem; -} - -/* ===== FORM STYLES ===== */ -.form-group { - margin-bottom: 1.5rem; -} - -.form-group label { - display: block; - margin-bottom: 0.5rem; - font-weight: 600; - color: var(--text-primary); -} - -.form-input, .form-textarea { - width: 100%; - padding: 1rem 1.25rem; - border: 2px solid var(--border-light); - border-radius: var(--radius-lg); - font-size: 1rem; - transition: var(--transition); - background: var(--bg-primary); - font-family: inherit; -} - -.form-input:focus, .form-textarea:focus { - outline: none; - border-color: var(--primary); - box-shadow: 0 0 0 4px rgba(255, 107, 0, 0.1); - transform: translateY(-2px); -} - -.form-textarea { - resize: vertical; - min-height: 120px; - line-height: 1.5; -} - -/* ===== MODAL ENHANCEMENTS ===== */ -.modal { - display: none; - position: fixed; - z-index: 1000; - left: 0; - top: 0; - width: 100%; - height: 100%; - background-color: rgba(0, 0, 0, 0.8); - backdrop-filter: blur(10px); - animation: fadeIn 0.3s ease; -} - -.modal-content { - background: var(--bg-primary); - margin: 2% auto; - border-radius: var(--radius-xl); - box-shadow: var(--shadow-xl); - animation: slideIn 0.3s ease; - position: relative; - max-width: 90%; - max-height: 90vh; - overflow: auto; -} - -.modal-header { - display: flex; - justify-content: space-between; - align-items: center; - padding: 2rem 2rem 1rem; - border-bottom: 2px solid var(--border-light); -} - -.modal-header h3 { - margin: 0; - color: var(--text-primary); - font-size: 1.5rem; - font-weight: 700; - background: var(--gradient-primary); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -.modal-body { - padding: 2rem; -} - -.modal-close { - color: var(--text-light); - font-size: 2rem; - font-weight: bold; - cursor: pointer; - transition: var(--transition); - background: none; - border: none; - padding: 0; - width: 40px; - height: 40px; - display: flex; - align-items: center; - justify-content: center; - border-radius: var(--radius-md); -} - -.modal-close:hover { - color: var(--primary); - background: var(--bg-secondary); - transform: rotate(90deg); -} - -@keyframes fadeIn { - from { opacity: 0; } - to { opacity: 1; } -} - -@keyframes slideIn { - from { - opacity: 0; - transform: translateY(-50px) scale(0.9); - } - to { - opacity: 1; - transform: translateY(0) scale(1); - } -} - -/* ===== SOLUTION PAGE STYLES ===== */ -.solution-accordion { - margin: 2rem 0; -} - -.accordion-item { - background: var(--bg-secondary); - border-radius: var(--radius-lg); - margin-bottom: 1rem; - border: 2px solid var(--border-light); - overflow: hidden; - transition: var(--transition); -} - -.accordion-item:hover { - border-color: var(--primary-light); - transform: translateX(4px); -} - -.accordion-header { - padding: 1.5rem; - background: var(--gradient-primary); - color: white; - font-weight: 600; - font-size: 1.125rem; - cursor: pointer; - display: flex; - justify-content: space-between; - align-items: center; - transition: var(--transition); -} - -.accordion-header:hover { - background: var(--primary-dark); -} - -.accordion-content { - padding: 1.5rem; - background: var(--bg-primary); - line-height: 1.7; -} - -.accordion-content p { - margin-bottom: 1rem; -} - -.accordion-content p:last-child { - margin-bottom: 0; -} - - -/* ===== THEME SWITCHER STYLES ===== */ -.theme-switcher { - display: flex; - align-items: center; -} - -.theme-toggle-checkbox { - display: none; -} - -.theme-toggle-label { - position: relative; - display: flex; - align-items: center; - width: 60px; - height: 30px; - background: var(--bg-card); - border: 2px solid var(--border-light); - border-radius: 25px; - cursor: pointer; - transition: all 0.3s ease; - padding: 2px; - box-shadow: var(--shadow-sm); -} - -.theme-toggle-label:hover { - border-color: var(--primary); - box-shadow: 0 0 10px rgba(255, 107, 0, 0.3); -} - -.theme-toggle-slider { - position: absolute; - width: 24px; - height: 24px; - background: var(--primary); - border-radius: 50%; - transition: all 0.3s ease; - left: 2px; - z-index: 2; -} - -.theme-toggle-checkbox:checked + .theme-toggle-label .theme-toggle-slider { - transform: translateX(30px); - background: var(--secondary); -} - -.theme-icon { - position: absolute; - font-size: 12px; - transition: all 0.3s ease; - z-index: 1; -} - -.theme-icon.sun { - left: 8px; - opacity: 1; -} - -.theme-icon.moon { - right: 8px; - opacity: 0; -} - -.theme-toggle-checkbox:checked + .theme-toggle-label .theme-icon.sun { - opacity: 0; -} - -.theme-toggle-checkbox:checked + .theme-toggle-label .theme-icon.moon { - opacity: 1; -} - -/* ===== MOBILE RESPONSIVE STYLES ===== */ -@media (max-width: 768px) { - .hero-title { - font-size: 2.5rem; - } - - .hero-subtitle { - font-size: 1.125rem; - padding: 0 1rem; - } - - .page-title { - font-size: 2.25rem; - } - - .page-subtitle { - font-size: 1.125rem; - padding: 0 1rem; - } - - .grid-2 { - grid-template-columns: 1fr; - gap: 1.5rem; - } - - .modern-card { - padding: 1.5rem; - margin-bottom: 1.5rem; - } - - .card-title { - font-size: 1.375rem; - } - - .content-card { - padding: 1.5rem; - } - - .about-section { - padding: 1.5rem; - } - - .skills-grid { - grid-template-columns: 1fr; - gap: 1.5rem; - } - - .competence-item { - flex-direction: column; - padding: 1.5rem; - gap: 1.5rem; - } - - .competence-scan-container { - width: 100%; - max-width: 280px; - margin: 0 auto; - } - - .recall-header { - flex-direction: column; - gap: 1rem; - align-items: flex-start; - } - - .recall-meta { - flex-direction: column; - gap: 0.5rem; - } - - .footer-content { - grid-template-columns: 1fr; - gap: 2rem; - text-align: center; - } - - .footer-contacts p { - justify-content: center; - } - - .card-actions { - flex-direction: column; - } - - .btn { - width: 100%; - justify-content: center; - } - - .modal-content { - margin: 5% auto; - max-width: 95%; - } - - .modal-header { - padding: 1.5rem 1.5rem 1rem; - } - - .modal-body { - padding: 1.5rem; - } - - .page-content { - padding: 1.5rem; - } - - .breadcrumbs { - font-size: 0.8rem; - } -} - -@media (max-width: 480px) { - .hero-title { - font-size: 2rem; - } - - .hero-subtitle { - font-size: 1rem; - } - - .page-title { - font-size: 1.875rem; - } - - .modern-card { - padding: 1.25rem; - } - - .content-card { - padding: 1.25rem; - } - - .about-section { - padding: 1.25rem; - } - - .card-title { - font-size: 1.25rem; - } - - .competence-scan-container { - max-width: 100%; - } -} - -/* Явные стили для мобильного меню в светлой теме */ -.mobile-menu { - background: #FFFFFF !important; -} - -.mobile-menu-header { - border-bottom: 1px solid #E2E8F0 !important; -} - -.mobile-menu-close { - color: #1A1F36 !important; -} - -.mobile-menu-close:hover { - background: #F7FAFC !important; -} - -.mobile-nav-link { - color: #1A1F36 !important; -} - -.mobile-nav-link:hover, -.mobile-nav-link.active { - background: var(--primary) !important; - color: white !important; -} - -.mobile-nav-actions { - border-top: 1px solid #E2E8F0 !important; -} - -/* Стили для переключателя темы в мобильном меню */ -.mobile-menu .theme-toggle-label { - background: #F7FAFC !important; - border: 2px solid #CBD5E0 !important; -} - -.mobile-menu .theme-toggle-label:hover { - border-color: var(--primary) !important; -} - -.mobile-menu .theme-icon.sun { - color: #1A1F36 !important; -} - -.mobile-menu .theme-icon.moon { - color: #1A1F36 !important; -} - -/* Стили для страницы отзывов */ -.recall-item { - display: flex; - flex-direction: column; - gap: 1.5rem; -} - -.recall-content { - display: flex; - gap: 2rem; - align-items: flex-start; -} - -.recall-scan-wrapper { - flex-shrink: 0; -} - -.recall-scan-container { - width: 280px; - cursor: pointer; - border-radius: var(--radius-lg); - overflow: hidden; - border: 2px solid var(--border-light); - transition: var(--transition); - position: relative; - box-shadow: var(--shadow-md); -} - -.recall-scan-container:hover { - transform: translateY(-4px) scale(1.02); - box-shadow: var(--shadow-xl); - border-color: var(--primary); -} - -.recall-scan { - width: 100%; - height: auto; - display: block; - transition: var(--transition); -} - -.recall-text { - flex: 1; - min-width: 0; - line-height: 1.7; - font-size: 1.05rem; -} - -.scan-hint { - position: absolute; - bottom: 0; - left: 0; - right: 0; - background: linear-gradient(transparent, rgba(0,0,0,0.8)); - color: white; - padding: 1rem; - text-align: center; - opacity: 0; - transition: var(--transition); - transform: translateY(10px); -} - -.recall-scan-container:hover .scan-hint { - opacity: 1; - transform: translateY(0); -} - -/* Стили для модального окна с изображением */ -.modal-image { - max-width: 90vw; - max-height: 80vh; - width: auto; - height: auto; - display: block; - margin: 0 auto; - border-radius: var(--radius-md); - box-shadow: var(--shadow-xl); - transition: all 0.3s ease; -} - -.modal-content.image-modal { - max-width: 95vw; - max-height: 95vh; - background: transparent; - border: none; - box-shadow: none; -} - -.modal-body.image-modal-body { - padding: 1rem; - display: flex; - align-items: center; - justify-content: center; - background: transparent; -} - -/* Адаптивность для мобильных устройств */ -@media (max-width: 768px) { - .recall-content { - flex-direction: column; - gap: 1.5rem; - } - - .recall-scan-container { - width: 100%; - max-width: 300px; - margin: 0 auto; - } - - .recall-scan-wrapper { - order: -1; - } - - .modal-image { - max-width: 95vw; - max-height: 70vh; - } - - .modal-content.image-modal { - margin: 10% auto; - } -} - -@media (max-width: 480px) { - .recall-scan-container { - max-width: 100%; - } - - .modal-content.image-modal { - margin: 5% auto; - max-width: 98vw; - } - - .modal-body.image-modal-body { - padding: 0.5rem; - } -} \ No newline at end of file diff --git a/OneCprogsite/programmer/static/programmer/images/blockquote.png b/OneCprogsite/programmer/static/programmer/images/blockquote.png deleted file mode 100644 index 0fd9974..0000000 Binary files a/OneCprogsite/programmer/static/programmer/images/blockquote.png and /dev/null differ diff --git a/OneCprogsite/programmer/static/programmer/images/btn_yt.png b/OneCprogsite/programmer/static/programmer/images/btn_yt.png deleted file mode 100644 index 3052a38..0000000 Binary files a/OneCprogsite/programmer/static/programmer/images/btn_yt.png and /dev/null differ diff --git a/OneCprogsite/programmer/static/programmer/images/logo.png b/OneCprogsite/programmer/static/programmer/images/logo.png deleted file mode 100644 index 8cb56a1..0000000 Binary files a/OneCprogsite/programmer/static/programmer/images/logo.png and /dev/null differ diff --git a/OneCprogsite/programmer/static/programmer/images/main.ico b/OneCprogsite/programmer/static/programmer/images/main.ico deleted file mode 100644 index 4895094..0000000 Binary files a/OneCprogsite/programmer/static/programmer/images/main.ico and /dev/null differ diff --git a/OneCprogsite/programmer/static/programmer/images/share_tg.png b/OneCprogsite/programmer/static/programmer/images/share_tg.png deleted file mode 100644 index a907ecd..0000000 Binary files a/OneCprogsite/programmer/static/programmer/images/share_tg.png and /dev/null differ diff --git a/OneCprogsite/programmer/static/programmer/images/share_tg_hover.png b/OneCprogsite/programmer/static/programmer/images/share_tg_hover.png deleted file mode 100644 index d5862f7..0000000 Binary files a/OneCprogsite/programmer/static/programmer/images/share_tg_hover.png and /dev/null differ diff --git a/OneCprogsite/programmer/static/programmer/images/share_yt.png b/OneCprogsite/programmer/static/programmer/images/share_yt.png deleted file mode 100644 index 7cf40f7..0000000 Binary files a/OneCprogsite/programmer/static/programmer/images/share_yt.png and /dev/null differ diff --git a/OneCprogsite/programmer/static/programmer/images/smallmenu.png b/OneCprogsite/programmer/static/programmer/images/smallmenu.png deleted file mode 100644 index 7a983d8..0000000 Binary files a/OneCprogsite/programmer/static/programmer/images/smallmenu.png and /dev/null differ diff --git a/OneCprogsite/programmer/static/programmer/js/bootstrap.bundle.min.js b/OneCprogsite/programmer/static/programmer/js/bootstrap.bundle.min.js deleted file mode 100644 index fe19d88..0000000 --- a/OneCprogsite/programmer/static/programmer/js/bootstrap.bundle.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * Bootstrap v5.3.0 (https://getbootstrap.com/) - * Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t=new Map,e={set(e,i,n){t.has(e)||t.set(e,new Map);const s=t.get(e);s.has(i)||0===s.size?s.set(i,n):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(s.keys())[0]}.`)},get:(e,i)=>t.has(e)&&t.get(e).get(i)||null,remove(e,i){if(!t.has(e))return;const n=t.get(e);n.delete(i),0===n.size&&t.delete(e)}},i="transitionend",n=t=>(t&&window.CSS&&window.CSS.escape&&(t=t.replace(/#([^\s"#']+)/g,((t,e)=>`#${CSS.escape(e)}`))),t),s=t=>{t.dispatchEvent(new Event(i))},o=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),r=t=>o(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(n(t)):null,a=t=>{if(!o(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},l=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),c=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?c(t.parentNode):null},h=()=>{},d=t=>{t.offsetHeight},u=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,f=[],p=()=>"rtl"===document.documentElement.dir,m=t=>{var e;e=()=>{const e=u();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(f.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of f)t()})),f.push(e)):e()},g=(t,e=[],i=t)=>"function"==typeof t?t(...e):i,_=(t,e,n=!0)=>{if(!n)return void g(t);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(e)+5;let r=!1;const a=({target:n})=>{n===e&&(r=!0,e.removeEventListener(i,a),g(t))};e.addEventListener(i,a),setTimeout((()=>{r||s(e)}),o)},b=(t,e,i,n)=>{const s=t.length;let o=t.indexOf(e);return-1===o?!i&&n?t[s-1]:t[0]:(o+=i?1:-1,n&&(o=(o+s)%s),t[Math.max(0,Math.min(o,s-1))])},v=/[^.]*(?=\..*)\.|.*/,y=/\..*/,w=/::\d+$/,A={};let E=1;const T={mouseenter:"mouseover",mouseleave:"mouseout"},C=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function O(t,e){return e&&`${e}::${E++}`||t.uidEvent||E++}function x(t){const e=O(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function k(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function L(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=N(t);return C.has(o)||(o=t),[n,s,o]}function S(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=L(e,i,n);if(e in T){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=x(t),c=l[a]||(l[a]={}),h=k(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=O(r,e.replace(v,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return M(s,{delegateTarget:r}),n.oneOff&&P.off(t,s.type,e,i),i.apply(r,[s])}}(t,i,r):function(t,e){return function i(n){return M(n,{delegateTarget:t}),i.oneOff&&P.off(t,n.type,e),e.apply(t,[n])}}(t,r);u.delegationSelector=o?i:null,u.callable=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function D(t,e,i,n,s){const o=k(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function I(t,e,i,n){const s=e[i]||{};for(const[o,r]of Object.entries(s))o.includes(n)&&D(t,e,i,r.callable,r.delegationSelector)}function N(t){return t=t.replace(y,""),T[t]||t}const P={on(t,e,i,n){S(t,e,i,n,!1)},one(t,e,i,n){S(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=L(e,i,n),a=r!==e,l=x(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))I(t,l,i,e.slice(1));for(const[i,n]of Object.entries(c)){const s=i.replace(w,"");a&&!e.includes(s)||D(t,l,r,n.callable,n.delegationSelector)}}else{if(!Object.keys(c).length)return;D(t,l,r,o,s?i:null)}},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=u();let s=null,o=!0,r=!0,a=!1;e!==N(e)&&n&&(s=n.Event(e,i),n(t).trigger(s),o=!s.isPropagationStopped(),r=!s.isImmediatePropagationStopped(),a=s.isDefaultPrevented());const l=M(new Event(e,{bubbles:o,cancelable:!0}),i);return a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&s&&s.preventDefault(),l}};function M(t,e={}){for(const[i,n]of Object.entries(e))try{t[i]=n}catch(e){Object.defineProperty(t,i,{configurable:!0,get:()=>n})}return t}function j(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function F(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const H={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${F(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${F(e)}`)},getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const n of i){let i=n.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1,i.length),e[i]=j(t.dataset[n])}return e},getDataAttribute:(t,e)=>j(t.getAttribute(`data-bs-${F(e)}`))};class ${static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const i=o(e)?H.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof i?i:{},...o(e)?H.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const[n,s]of Object.entries(e)){const e=t[n],r=o(e)?"element":null==(i=e)?`${i}`:Object.prototype.toString.call(i).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(s).test(r))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${n}" provided type "${r}" but expected type "${s}".`)}var i}}class W extends ${constructor(t,i){super(),(t=r(t))&&(this._element=t,this._config=this._getConfig(i),e.set(this._element,this.constructor.DATA_KEY,this))}dispose(){e.remove(this._element,this.constructor.DATA_KEY),P.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,i=!0){_(t,e,i)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return e.get(r(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.3.0"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const B=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?i.trim():null}return n(e)},z={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode.closest(e);for(;n;)i.push(n),n=n.parentNode.closest(e);return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!l(t)&&a(t)))},getSelectorFromElement(t){const e=B(t);return e&&z.findOne(e)?e:null},getElementFromSelector(t){const e=B(t);return e?z.findOne(e):null},getMultipleElementsFromSelector(t){const e=B(t);return e?z.find(e):[]}},R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,n=t.NAME;P.on(document,i,`[data-bs-dismiss="${n}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),l(this))return;const s=z.getElementFromSelector(this)||this.closest(`.${n}`);t.getOrCreateInstance(s)[e]()}))};class q extends W{static get NAME(){return"alert"}close(){if(P.trigger(this._element,"close.bs.alert").defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),P.trigger(this._element,"closed.bs.alert"),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=q.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}R(q,"close"),m(q);const V='[data-bs-toggle="button"]';class K extends W{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=K.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}P.on(document,"click.bs.button.data-api",V,(t=>{t.preventDefault();const e=t.target.closest(V);K.getOrCreateInstance(e).toggle()})),m(K);const Q={endCallback:null,leftCallback:null,rightCallback:null},X={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class Y extends ${constructor(t,e){super(),this._element=t,t&&Y.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return Q}static get DefaultType(){return X}static get NAME(){return"swipe"}dispose(){P.off(this._element,".bs.swipe")}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),g(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&g(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(P.on(this._element,"pointerdown.bs.swipe",(t=>this._start(t))),P.on(this._element,"pointerup.bs.swipe",(t=>this._end(t))),this._element.classList.add("pointer-event")):(P.on(this._element,"touchstart.bs.swipe",(t=>this._start(t))),P.on(this._element,"touchmove.bs.swipe",(t=>this._move(t))),P.on(this._element,"touchend.bs.swipe",(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const U="next",G="prev",J="left",Z="right",tt="slid.bs.carousel",et="carousel",it="active",nt={ArrowLeft:Z,ArrowRight:J},st={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},ot={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class rt extends W{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=z.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===et&&this.cycle()}static get Default(){return st}static get DefaultType(){return ot}static get NAME(){return"carousel"}next(){this._slide(U)}nextWhenVisible(){!document.hidden&&a(this._element)&&this.next()}prev(){this._slide(G)}pause(){this._isSliding&&s(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?P.one(this._element,tt,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void P.one(this._element,tt,(()=>this.to(t)));const i=this._getItemIndex(this._getActive());if(i===t)return;const n=t>i?U:G;this._slide(n,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&P.on(this._element,"keydown.bs.carousel",(t=>this._keydown(t))),"hover"===this._config.pause&&(P.on(this._element,"mouseenter.bs.carousel",(()=>this.pause())),P.on(this._element,"mouseleave.bs.carousel",(()=>this._maybeEnableCycle()))),this._config.touch&&Y.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of z.find(".carousel-item img",this._element))P.on(t,"dragstart.bs.carousel",(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(J)),rightCallback:()=>this._slide(this._directionToOrder(Z)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new Y(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=nt[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=z.findOne(".active",this._indicatorsElement);e.classList.remove(it),e.removeAttribute("aria-current");const i=z.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);i&&(i.classList.add(it),i.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),n=t===U,s=e||b(this._getItems(),i,n,this._config.wrap);if(s===i)return;const o=this._getItemIndex(s),r=e=>P.trigger(this._element,e,{relatedTarget:s,direction:this._orderToDirection(t),from:this._getItemIndex(i),to:o});if(r("slide.bs.carousel").defaultPrevented)return;if(!i||!s)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=s;const l=n?"carousel-item-start":"carousel-item-end",c=n?"carousel-item-next":"carousel-item-prev";s.classList.add(c),d(s),i.classList.add(l),s.classList.add(l),this._queueCallback((()=>{s.classList.remove(l,c),s.classList.add(it),i.classList.remove(it,c,l),this._isSliding=!1,r(tt)}),i,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return z.findOne(".active.carousel-item",this._element)}_getItems(){return z.find(".carousel-item",this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return p()?t===J?G:U:t===J?U:G}_orderToDirection(t){return p()?t===G?J:Z:t===G?Z:J}static jQueryInterface(t){return this.each((function(){const e=rt.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}P.on(document,"click.bs.carousel.data-api","[data-bs-slide], [data-bs-slide-to]",(function(t){const e=z.getElementFromSelector(this);if(!e||!e.classList.contains(et))return;t.preventDefault();const i=rt.getOrCreateInstance(e),n=this.getAttribute("data-bs-slide-to");return n?(i.to(n),void i._maybeEnableCycle()):"next"===H.getDataAttribute(this,"slide")?(i.next(),void i._maybeEnableCycle()):(i.prev(),void i._maybeEnableCycle())})),P.on(window,"load.bs.carousel.data-api",(()=>{const t=z.find('[data-bs-ride="carousel"]');for(const e of t)rt.getOrCreateInstance(e)})),m(rt);const at="show",lt="collapse",ct="collapsing",ht='[data-bs-toggle="collapse"]',dt={parent:null,toggle:!0},ut={parent:"(null|element)",toggle:"boolean"};class ft extends W{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const i=z.find(ht);for(const t of i){const e=z.getSelectorFromElement(t),i=z.find(e).filter((t=>t===this._element));null!==e&&i.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return dt}static get DefaultType(){return ut}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>ft.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(P.trigger(this._element,"show.bs.collapse").defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(lt),this._element.classList.add(ct),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const i=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(ct),this._element.classList.add(lt,at),this._element.style[e]="",P.trigger(this._element,"shown.bs.collapse")}),this._element,!0),this._element.style[e]=`${this._element[i]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(P.trigger(this._element,"hide.bs.collapse").defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,d(this._element),this._element.classList.add(ct),this._element.classList.remove(lt,at);for(const t of this._triggerArray){const e=z.getElementFromSelector(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(ct),this._element.classList.add(lt),P.trigger(this._element,"hidden.bs.collapse")}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(at)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=r(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(ht);for(const e of t){const t=z.getElementFromSelector(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=z.find(":scope .collapse .collapse",this._config.parent);return z.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classList.toggle("collapsed",!e),i.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const i=ft.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}P.on(document,"click.bs.collapse.data-api",ht,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();for(const t of z.getMultipleElementsFromSelector(this))ft.getOrCreateInstance(t,{toggle:!1}).toggle()})),m(ft);var pt="top",mt="bottom",gt="right",_t="left",bt="auto",vt=[pt,mt,gt,_t],yt="start",wt="end",At="clippingParents",Et="viewport",Tt="popper",Ct="reference",Ot=vt.reduce((function(t,e){return t.concat([e+"-"+yt,e+"-"+wt])}),[]),xt=[].concat(vt,[bt]).reduce((function(t,e){return t.concat([e,e+"-"+yt,e+"-"+wt])}),[]),kt="beforeRead",Lt="read",St="afterRead",Dt="beforeMain",It="main",Nt="afterMain",Pt="beforeWrite",Mt="write",jt="afterWrite",Ft=[kt,Lt,St,Dt,It,Nt,Pt,Mt,jt];function Ht(t){return t?(t.nodeName||"").toLowerCase():null}function $t(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function Wt(t){return t instanceof $t(t).Element||t instanceof Element}function Bt(t){return t instanceof $t(t).HTMLElement||t instanceof HTMLElement}function zt(t){return"undefined"!=typeof ShadowRoot&&(t instanceof $t(t).ShadowRoot||t instanceof ShadowRoot)}const Rt={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];Bt(s)&&Ht(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});Bt(n)&&Ht(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function qt(t){return t.split("-")[0]}var Vt=Math.max,Kt=Math.min,Qt=Math.round;function Xt(){var t=navigator.userAgentData;return null!=t&&t.brands&&Array.isArray(t.brands)?t.brands.map((function(t){return t.brand+"/"+t.version})).join(" "):navigator.userAgent}function Yt(){return!/^((?!chrome|android).)*safari/i.test(Xt())}function Ut(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var n=t.getBoundingClientRect(),s=1,o=1;e&&Bt(t)&&(s=t.offsetWidth>0&&Qt(n.width)/t.offsetWidth||1,o=t.offsetHeight>0&&Qt(n.height)/t.offsetHeight||1);var r=(Wt(t)?$t(t):window).visualViewport,a=!Yt()&&i,l=(n.left+(a&&r?r.offsetLeft:0))/s,c=(n.top+(a&&r?r.offsetTop:0))/o,h=n.width/s,d=n.height/o;return{width:h,height:d,top:c,right:l+h,bottom:c+d,left:l,x:l,y:c}}function Gt(t){var e=Ut(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function Jt(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&zt(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function Zt(t){return $t(t).getComputedStyle(t)}function te(t){return["table","td","th"].indexOf(Ht(t))>=0}function ee(t){return((Wt(t)?t.ownerDocument:t.document)||window.document).documentElement}function ie(t){return"html"===Ht(t)?t:t.assignedSlot||t.parentNode||(zt(t)?t.host:null)||ee(t)}function ne(t){return Bt(t)&&"fixed"!==Zt(t).position?t.offsetParent:null}function se(t){for(var e=$t(t),i=ne(t);i&&te(i)&&"static"===Zt(i).position;)i=ne(i);return i&&("html"===Ht(i)||"body"===Ht(i)&&"static"===Zt(i).position)?e:i||function(t){var e=/firefox/i.test(Xt());if(/Trident/i.test(Xt())&&Bt(t)&&"fixed"===Zt(t).position)return null;var i=ie(t);for(zt(i)&&(i=i.host);Bt(i)&&["html","body"].indexOf(Ht(i))<0;){var n=Zt(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function oe(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function re(t,e,i){return Vt(t,Kt(e,i))}function ae(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function le(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const ce={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=qt(i.placement),l=oe(a),c=[_t,gt].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return ae("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:le(t,vt))}(s.padding,i),d=Gt(o),u="y"===l?pt:_t,f="y"===l?mt:gt,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=se(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,A=re(v,w,y),E=l;i.modifiersData[n]=((e={})[E]=A,e.centerOffset=A-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&Jt(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function he(t){return t.split("-")[1]}var de={top:"auto",right:"auto",bottom:"auto",left:"auto"};function ue(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=t.isFixed,u=r.x,f=void 0===u?0:u,p=r.y,m=void 0===p?0:p,g="function"==typeof h?h({x:f,y:m}):{x:f,y:m};f=g.x,m=g.y;var _=r.hasOwnProperty("x"),b=r.hasOwnProperty("y"),v=_t,y=pt,w=window;if(c){var A=se(i),E="clientHeight",T="clientWidth";A===$t(i)&&"static"!==Zt(A=ee(i)).position&&"absolute"===a&&(E="scrollHeight",T="scrollWidth"),(s===pt||(s===_t||s===gt)&&o===wt)&&(y=mt,m-=(d&&A===w&&w.visualViewport?w.visualViewport.height:A[E])-n.height,m*=l?1:-1),s!==_t&&(s!==pt&&s!==mt||o!==wt)||(v=gt,f-=(d&&A===w&&w.visualViewport?w.visualViewport.width:A[T])-n.width,f*=l?1:-1)}var C,O=Object.assign({position:a},c&&de),x=!0===h?function(t,e){var i=t.x,n=t.y,s=e.devicePixelRatio||1;return{x:Qt(i*s)/s||0,y:Qt(n*s)/s||0}}({x:f,y:m},$t(i)):{x:f,y:m};return f=x.x,m=x.y,l?Object.assign({},O,((C={})[y]=b?"0":"",C[v]=_?"0":"",C.transform=(w.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",C)):Object.assign({},O,((e={})[y]=b?m+"px":"",e[v]=_?f+"px":"",e.transform="",e))}const fe={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:qt(e.placement),variation:he(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s,isFixed:"fixed"===e.options.strategy};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,ue(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,ue(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var pe={passive:!0};const me={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=$t(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,pe)})),a&&l.addEventListener("resize",i.update,pe),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,pe)})),a&&l.removeEventListener("resize",i.update,pe)}},data:{}};var ge={left:"right",right:"left",bottom:"top",top:"bottom"};function _e(t){return t.replace(/left|right|bottom|top/g,(function(t){return ge[t]}))}var be={start:"end",end:"start"};function ve(t){return t.replace(/start|end/g,(function(t){return be[t]}))}function ye(t){var e=$t(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function we(t){return Ut(ee(t)).left+ye(t).scrollLeft}function Ae(t){var e=Zt(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ee(t){return["html","body","#document"].indexOf(Ht(t))>=0?t.ownerDocument.body:Bt(t)&&Ae(t)?t:Ee(ie(t))}function Te(t,e){var i;void 0===e&&(e=[]);var n=Ee(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=$t(n),r=s?[o].concat(o.visualViewport||[],Ae(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(Te(ie(r)))}function Ce(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function Oe(t,e,i){return e===Et?Ce(function(t,e){var i=$t(t),n=ee(t),s=i.visualViewport,o=n.clientWidth,r=n.clientHeight,a=0,l=0;if(s){o=s.width,r=s.height;var c=Yt();(c||!c&&"fixed"===e)&&(a=s.offsetLeft,l=s.offsetTop)}return{width:o,height:r,x:a+we(t),y:l}}(t,i)):Wt(e)?function(t,e){var i=Ut(t,!1,"fixed"===e);return i.top=i.top+t.clientTop,i.left=i.left+t.clientLeft,i.bottom=i.top+t.clientHeight,i.right=i.left+t.clientWidth,i.width=t.clientWidth,i.height=t.clientHeight,i.x=i.left,i.y=i.top,i}(e,i):Ce(function(t){var e,i=ee(t),n=ye(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=Vt(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=Vt(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+we(t),l=-n.scrollTop;return"rtl"===Zt(s||i).direction&&(a+=Vt(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(ee(t)))}function xe(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?qt(s):null,r=s?he(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case pt:e={x:a,y:i.y-n.height};break;case mt:e={x:a,y:i.y+i.height};break;case gt:e={x:i.x+i.width,y:l};break;case _t:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?oe(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case yt:e[c]=e[c]-(i[h]/2-n[h]/2);break;case wt:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function ke(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.strategy,r=void 0===o?t.strategy:o,a=i.boundary,l=void 0===a?At:a,c=i.rootBoundary,h=void 0===c?Et:c,d=i.elementContext,u=void 0===d?Tt:d,f=i.altBoundary,p=void 0!==f&&f,m=i.padding,g=void 0===m?0:m,_=ae("number"!=typeof g?g:le(g,vt)),b=u===Tt?Ct:Tt,v=t.rects.popper,y=t.elements[p?b:u],w=function(t,e,i,n){var s="clippingParents"===e?function(t){var e=Te(ie(t)),i=["absolute","fixed"].indexOf(Zt(t).position)>=0&&Bt(t)?se(t):t;return Wt(i)?e.filter((function(t){return Wt(t)&&Jt(t,i)&&"body"!==Ht(t)})):[]}(t):[].concat(e),o=[].concat(s,[i]),r=o[0],a=o.reduce((function(e,i){var s=Oe(t,i,n);return e.top=Vt(s.top,e.top),e.right=Kt(s.right,e.right),e.bottom=Kt(s.bottom,e.bottom),e.left=Vt(s.left,e.left),e}),Oe(t,r,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(Wt(y)?y:y.contextElement||ee(t.elements.popper),l,h,r),A=Ut(t.elements.reference),E=xe({reference:A,element:v,strategy:"absolute",placement:s}),T=Ce(Object.assign({},v,E)),C=u===Tt?T:A,O={top:w.top-C.top+_.top,bottom:C.bottom-w.bottom+_.bottom,left:w.left-C.left+_.left,right:C.right-w.right+_.right},x=t.modifiersData.offset;if(u===Tt&&x){var k=x[s];Object.keys(O).forEach((function(t){var e=[gt,mt].indexOf(t)>=0?1:-1,i=[pt,mt].indexOf(t)>=0?"y":"x";O[t]+=k[i]*e}))}return O}function Le(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?xt:l,h=he(n),d=h?a?Ot:Ot.filter((function(t){return he(t)===h})):vt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=ke(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[qt(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const Se={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=qt(g),b=l||(_!==g&&p?function(t){if(qt(t)===bt)return[];var e=_e(t);return[ve(t),e,ve(e)]}(g):[_e(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat(qt(i)===bt?Le(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,A=new Map,E=!0,T=v[0],C=0;C=0,S=L?"width":"height",D=ke(e,{placement:O,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),I=L?k?gt:_t:k?mt:pt;y[S]>w[S]&&(I=_e(I));var N=_e(I),P=[];if(o&&P.push(D[x]<=0),a&&P.push(D[I]<=0,D[N]<=0),P.every((function(t){return t}))){T=O,E=!1;break}A.set(O,P)}if(E)for(var M=function(t){var e=v.find((function(e){var i=A.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},j=p?3:1;j>0&&"break"!==M(j);j--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function De(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function Ie(t){return[pt,gt,mt,_t].some((function(e){return t[e]>=0}))}const Ne={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=ke(e,{elementContext:"reference"}),a=ke(e,{altBoundary:!0}),l=De(r,n),c=De(a,s,o),h=Ie(l),d=Ie(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},Pe={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=xt.reduce((function(t,i){return t[i]=function(t,e,i){var n=qt(t),s=[_t,pt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[_t,gt].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},Me={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=xe({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},je={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=ke(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=qt(e.placement),b=he(e.placement),v=!b,y=oe(_),w="x"===y?"y":"x",A=e.modifiersData.popperOffsets,E=e.rects.reference,T=e.rects.popper,C="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,O="number"==typeof C?{mainAxis:C,altAxis:C}:Object.assign({mainAxis:0,altAxis:0},C),x=e.modifiersData.offset?e.modifiersData.offset[e.placement]:null,k={x:0,y:0};if(A){if(o){var L,S="y"===y?pt:_t,D="y"===y?mt:gt,I="y"===y?"height":"width",N=A[y],P=N+g[S],M=N-g[D],j=f?-T[I]/2:0,F=b===yt?E[I]:T[I],H=b===yt?-T[I]:-E[I],$=e.elements.arrow,W=f&&$?Gt($):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},z=B[S],R=B[D],q=re(0,E[I],W[I]),V=v?E[I]/2-j-q-z-O.mainAxis:F-q-z-O.mainAxis,K=v?-E[I]/2+j+q+R+O.mainAxis:H+q+R+O.mainAxis,Q=e.elements.arrow&&se(e.elements.arrow),X=Q?"y"===y?Q.clientTop||0:Q.clientLeft||0:0,Y=null!=(L=null==x?void 0:x[y])?L:0,U=N+K-Y,G=re(f?Kt(P,N+V-Y-X):P,N,f?Vt(M,U):M);A[y]=G,k[y]=G-N}if(a){var J,Z="x"===y?pt:_t,tt="x"===y?mt:gt,et=A[w],it="y"===w?"height":"width",nt=et+g[Z],st=et-g[tt],ot=-1!==[pt,_t].indexOf(_),rt=null!=(J=null==x?void 0:x[w])?J:0,at=ot?nt:et-E[it]-T[it]-rt+O.altAxis,lt=ot?et+E[it]+T[it]-rt-O.altAxis:st,ct=f&&ot?function(t,e,i){var n=re(t,e,i);return n>i?i:n}(at,et,lt):re(f?at:nt,et,f?lt:st);A[w]=ct,k[w]=ct-et}e.modifiersData[n]=k}},requiresIfExists:["offset"]};function Fe(t,e,i){void 0===i&&(i=!1);var n,s,o=Bt(e),r=Bt(e)&&function(t){var e=t.getBoundingClientRect(),i=Qt(e.width)/t.offsetWidth||1,n=Qt(e.height)/t.offsetHeight||1;return 1!==i||1!==n}(e),a=ee(e),l=Ut(t,r,i),c={scrollLeft:0,scrollTop:0},h={x:0,y:0};return(o||!o&&!i)&&(("body"!==Ht(e)||Ae(a))&&(c=(n=e)!==$t(n)&&Bt(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:ye(n)),Bt(e)?((h=Ut(e,!0)).x+=e.clientLeft,h.y+=e.clientTop):a&&(h.x=we(a))),{x:l.left+c.scrollLeft-h.x,y:l.top+c.scrollTop-h.y,width:l.width,height:l.height}}function He(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var $e={placement:"bottom",modifiers:[],strategy:"absolute"};function We(){for(var t=arguments.length,e=new Array(t),i=0;iNumber.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(H.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,...g(this._config.popperConfig,[t])}}_selectMenuItem({key:t,target:e}){const i=z.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>a(t)));i.length&&b(i,e,t===Xe,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=ci.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=z.find(Ze);for(const i of e){const e=ci.getInstance(i);if(!e||!1===e._config.autoClose)continue;const n=t.composedPath(),s=n.includes(e._menu);if(n.includes(e._element)||"inside"===e._config.autoClose&&!s||"outside"===e._config.autoClose&&s)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),i="Escape"===t.key,n=[Qe,Xe].includes(t.key);if(!n&&!i)return;if(e&&!i)return;t.preventDefault();const s=this.matches(Je)?this:z.prev(this,Je)[0]||z.next(this,Je)[0]||z.findOne(Je,t.delegateTarget.parentNode),o=ci.getOrCreateInstance(s);if(n)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),s.focus())}}P.on(document,Ue,Je,ci.dataApiKeydownHandler),P.on(document,Ue,ti,ci.dataApiKeydownHandler),P.on(document,Ye,ci.clearMenus),P.on(document,"keyup.bs.dropdown.data-api",ci.clearMenus),P.on(document,Ye,Je,(function(t){t.preventDefault(),ci.getOrCreateInstance(this).toggle()})),m(ci);const hi="show",di="mousedown.bs.backdrop",ui={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},fi={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class pi extends ${constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return ui}static get DefaultType(){return fi}static get NAME(){return"backdrop"}show(t){if(!this._config.isVisible)return void g(t);this._append();const e=this._getElement();this._config.isAnimated&&d(e),e.classList.add(hi),this._emulateAnimation((()=>{g(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(hi),this._emulateAnimation((()=>{this.dispose(),g(t)}))):g(t)}dispose(){this._isAppended&&(P.off(this._element,di),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=r(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),P.on(t,di,(()=>{g(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){_(t,this._getElement(),this._config.isAnimated)}}const mi=".bs.focustrap",gi="backward",_i={autofocus:!0,trapElement:null},bi={autofocus:"boolean",trapElement:"element"};class vi extends ${constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return _i}static get DefaultType(){return bi}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),P.off(document,mi),P.on(document,"focusin.bs.focustrap",(t=>this._handleFocusin(t))),P.on(document,"keydown.tab.bs.focustrap",(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,P.off(document,mi))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const i=z.focusableChildren(e);0===i.length?e.focus():this._lastTabNavDirection===gi?i[i.length-1].focus():i[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?gi:"forward")}}const yi=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",wi=".sticky-top",Ai="padding-right",Ei="margin-right";class Ti{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,Ai,(e=>e+t)),this._setElementAttributes(yi,Ai,(e=>e+t)),this._setElementAttributes(wi,Ei,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,Ai),this._resetElementAttributes(yi,Ai),this._resetElementAttributes(wi,Ei)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${i(Number.parseFloat(s))}px`)}))}_saveInitialAttribute(t,e){const i=t.style.getPropertyValue(e);i&&H.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=H.getDataAttribute(t,e);null!==i?(H.removeDataAttribute(t,e),t.style.setProperty(e,i)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(o(t))e(t);else for(const i of z.find(t,this._element))e(i)}}const Ci=".bs.modal",Oi="hidden.bs.modal",xi="show.bs.modal",ki="modal-open",Li="show",Si="modal-static",Di={backdrop:!0,focus:!0,keyboard:!0},Ii={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class Ni extends W{constructor(t,e){super(t,e),this._dialog=z.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new Ti,this._addEventListeners()}static get Default(){return Di}static get DefaultType(){return Ii}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||P.trigger(this._element,xi,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(ki),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(P.trigger(this._element,"hide.bs.modal").defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(Li),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){P.off(window,Ci),P.off(this._dialog,Ci),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new pi({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new vi({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=z.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),d(this._element),this._element.classList.add(Li),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,P.trigger(this._element,"shown.bs.modal",{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){P.on(this._element,"keydown.dismiss.bs.modal",(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():this._triggerBackdropTransition())})),P.on(window,"resize.bs.modal",(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),P.on(this._element,"mousedown.dismiss.bs.modal",(t=>{P.one(this._element,"click.dismiss.bs.modal",(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(ki),this._resetAdjustments(),this._scrollBar.reset(),P.trigger(this._element,Oi)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(P.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(Si)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(Si),this._queueCallback((()=>{this._element.classList.remove(Si),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;if(i&&!t){const t=p()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!i&&t){const t=p()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=Ni.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}P.on(document,"click.bs.modal.data-api",'[data-bs-toggle="modal"]',(function(t){const e=z.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),P.one(e,xi,(t=>{t.defaultPrevented||P.one(e,Oi,(()=>{a(this)&&this.focus()}))}));const i=z.findOne(".modal.show");i&&Ni.getInstance(i).hide(),Ni.getOrCreateInstance(e).toggle(this)})),R(Ni),m(Ni);const Pi="show",Mi="showing",ji="hiding",Fi=".offcanvas.show",Hi="hidePrevented.bs.offcanvas",$i="hidden.bs.offcanvas",Wi={backdrop:!0,keyboard:!0,scroll:!1},Bi={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class zi extends W{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return Wi}static get DefaultType(){return Bi}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||P.trigger(this._element,"show.bs.offcanvas",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new Ti).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(Mi),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add(Pi),this._element.classList.remove(Mi),P.trigger(this._element,"shown.bs.offcanvas",{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(P.trigger(this._element,"hide.bs.offcanvas").defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add(ji),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove(Pi,ji),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new Ti).reset(),P.trigger(this._element,$i)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new pi({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():P.trigger(this._element,Hi)}:null})}_initializeFocusTrap(){return new vi({trapElement:this._element})}_addEventListeners(){P.on(this._element,"keydown.dismiss.bs.offcanvas",(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():P.trigger(this._element,Hi))}))}static jQueryInterface(t){return this.each((function(){const e=zi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}P.on(document,"click.bs.offcanvas.data-api",'[data-bs-toggle="offcanvas"]',(function(t){const e=z.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this))return;P.one(e,$i,(()=>{a(this)&&this.focus()}));const i=z.findOne(Fi);i&&i!==e&&zi.getInstance(i).hide(),zi.getOrCreateInstance(e).toggle(this)})),P.on(window,"load.bs.offcanvas.data-api",(()=>{for(const t of z.find(Fi))zi.getOrCreateInstance(t).show()})),P.on(window,"resize.bs.offcanvas",(()=>{for(const t of z.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&zi.getOrCreateInstance(t).hide()})),R(zi),m(zi);const Ri={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},qi=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Vi=/^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i,Ki=(t,e)=>{const i=t.nodeName.toLowerCase();return e.includes(i)?!qi.has(i)||Boolean(Vi.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(i)))},Qi={allowList:Ri,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
"},Xi={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},Yi={entry:"(string|element|function|null)",selector:"(string|element)"};class Ui extends ${constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return Qi}static get DefaultType(){return Xi}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,i]of Object.entries(this._config.content))this._setContent(t,i,e);const e=t.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&e.classList.add(...i.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,i]of Object.entries(t))super._typeCheckConfig({selector:e,entry:i},Yi)}_setContent(t,e,i){const n=z.findOne(i,t);n&&((e=this._resolvePossibleFunction(e))?o(e)?this._putElementInTemplate(r(e),n):this._config.html?n.innerHTML=this._maybeSanitize(e):n.textContent=e:n.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,i){if(!t.length)return t;if(i&&"function"==typeof i)return i(t);const n=(new window.DOMParser).parseFromString(t,"text/html"),s=[].concat(...n.body.querySelectorAll("*"));for(const t of s){const i=t.nodeName.toLowerCase();if(!Object.keys(e).includes(i)){t.remove();continue}const n=[].concat(...t.attributes),s=[].concat(e["*"]||[],e[i]||[]);for(const e of n)Ki(e,s)||t.removeAttribute(e.nodeName)}return n.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return g(t,[this])}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const Gi=new Set(["sanitize","allowList","sanitizeFn"]),Ji="fade",Zi="show",tn=".modal",en="hide.bs.modal",nn="hover",sn="focus",on={AUTO:"auto",TOP:"top",RIGHT:p()?"left":"right",BOTTOM:"bottom",LEFT:p()?"right":"left"},rn={allowList:Ri,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,6],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},an={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class ln extends W{constructor(t,e){if(void 0===Ve)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t,e),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return rn}static get DefaultType(){return an}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._activeTrigger.click=!this._activeTrigger.click,this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),P.off(this._element.closest(tn),en,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=P.trigger(this._element,this.constructor.eventName("show")),e=(c(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const i=this._getTipElement();this._element.setAttribute("aria-describedby",i.getAttribute("id"));const{container:n}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(n.append(i),P.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(i),i.classList.add(Zi),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))P.on(t,"mouseover",h);this._queueCallback((()=>{P.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!P.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(Zi),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))P.off(t,"mouseover",h);this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),P.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(Ji,Zi),e.classList.add(`bs-${this.constructor.NAME}-auto`);const i=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",i),this._isAnimated()&&e.classList.add(Ji),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new Ui({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{".tooltip-inner":this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(Ji)}_isShown(){return this.tip&&this.tip.classList.contains(Zi)}_createPopper(t){const e=g(this._config.placement,[this,t,this._element]),i=on[e.toUpperCase()];return qe(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return g(t,[this._element])}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,...g(this._config.popperConfig,[e])}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)P.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===nn?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),i=e===nn?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");P.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?sn:nn]=!0,e._enter()})),P.on(this._element,i,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?sn:nn]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},P.on(this._element.closest(tn),en,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=H.getDataAttributes(this._element);for(const t of Object.keys(e))Gi.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:r(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const[e,i]of Object.entries(this._config))this.constructor.Default[e]!==i&&(t[e]=i);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=ln.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(ln);const cn={...ln.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},hn={...ln.DefaultType,content:"(null|string|element|function)"};class dn extends ln{static get Default(){return cn}static get DefaultType(){return hn}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{".popover-header":this._getTitle(),".popover-body":this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=dn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(dn);const un="click.bs.scrollspy",fn="active",pn="[href]",mn={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},gn={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class _n extends W{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return mn}static get DefaultType(){return gn}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=r(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(P.off(this._config.target,un),P.on(this._config.target,un,pn,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const i=this._rootElement||window,n=e.offsetTop-this._element.offsetTop;if(i.scrollTo)return void i.scrollTo({top:n,behavior:"smooth"});i.scrollTop=n}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),i=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},n=(this._rootElement||document.documentElement).scrollTop,s=n>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=n;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(s&&t){if(i(o),!n)return}else s||t||i(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=z.find(pn,this._config.target);for(const e of t){if(!e.hash||l(e))continue;const t=z.findOne(decodeURI(e.hash),this._element);a(t)&&(this._targetLinks.set(decodeURI(e.hash),e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(fn),this._activateParents(t),P.trigger(this._element,"activate.bs.scrollspy",{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))z.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add(fn);else for(const e of z.parents(t,".nav, .list-group"))for(const t of z.prev(e,".nav-link, .nav-item > .nav-link, .list-group-item"))t.classList.add(fn)}_clearActiveClass(t){t.classList.remove(fn);const e=z.find("[href].active",t);for(const t of e)t.classList.remove(fn)}static jQueryInterface(t){return this.each((function(){const e=_n.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}P.on(window,"load.bs.scrollspy.data-api",(()=>{for(const t of z.find('[data-bs-spy="scroll"]'))_n.getOrCreateInstance(t)})),m(_n);const bn="ArrowLeft",vn="ArrowRight",yn="ArrowUp",wn="ArrowDown",An="active",En="fade",Tn="show",Cn='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',On=`.nav-link:not(.dropdown-toggle), .list-group-item:not(.dropdown-toggle), [role="tab"]:not(.dropdown-toggle), ${Cn}`;class xn extends W{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),P.on(this._element,"keydown.bs.tab",(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),i=e?P.trigger(e,"hide.bs.tab",{relatedTarget:t}):null;P.trigger(t,"show.bs.tab",{relatedTarget:e}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(An),this._activate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),P.trigger(t,"shown.bs.tab",{relatedTarget:e})):t.classList.add(Tn)}),t,t.classList.contains(En)))}_deactivate(t,e){t&&(t.classList.remove(An),t.blur(),this._deactivate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),P.trigger(t,"hidden.bs.tab",{relatedTarget:e})):t.classList.remove(Tn)}),t,t.classList.contains(En)))}_keydown(t){if(![bn,vn,yn,wn].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=[vn,wn].includes(t.key),i=b(this._getChildren().filter((t=>!l(t))),t.target,e,!0);i&&(i.focus({preventScroll:!0}),xn.getOrCreateInstance(i).show())}_getChildren(){return z.find(On,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),i=this._getOuterElement(t);t.setAttribute("aria-selected",e),i!==t&&this._setAttributeIfNotExists(i,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=z.getElementFromSelector(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`${t.id}`))}_toggleDropDown(t,e){const i=this._getOuterElement(t);if(!i.classList.contains("dropdown"))return;const n=(t,n)=>{const s=z.findOne(t,i);s&&s.classList.toggle(n,e)};n(".dropdown-toggle",An),n(".dropdown-menu",Tn),i.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,i){t.hasAttribute(e)||t.setAttribute(e,i)}_elemIsActive(t){return t.classList.contains(An)}_getInnerElement(t){return t.matches(On)?t:z.findOne(On,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=xn.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}P.on(document,"click.bs.tab",Cn,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this)||xn.getOrCreateInstance(this).show()})),P.on(window,"load.bs.tab",(()=>{for(const t of z.find('.active[data-bs-toggle="tab"], .active[data-bs-toggle="pill"], .active[data-bs-toggle="list"]'))xn.getOrCreateInstance(t)})),m(xn);const kn="hide",Ln="show",Sn="showing",Dn={animation:"boolean",autohide:"boolean",delay:"number"},In={animation:!0,autohide:!0,delay:5e3};class Nn extends W{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return In}static get DefaultType(){return Dn}static get NAME(){return"toast"}show(){P.trigger(this._element,"show.bs.toast").defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(kn),d(this._element),this._element.classList.add(Ln,Sn),this._queueCallback((()=>{this._element.classList.remove(Sn),P.trigger(this._element,"shown.bs.toast"),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(P.trigger(this._element,"hide.bs.toast").defaultPrevented||(this._element.classList.add(Sn),this._queueCallback((()=>{this._element.classList.add(kn),this._element.classList.remove(Sn,Ln),P.trigger(this._element,"hidden.bs.toast")}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(Ln),super.dispose()}isShown(){return this._element.classList.contains(Ln)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){P.on(this._element,"mouseover.bs.toast",(t=>this._onInteraction(t,!0))),P.on(this._element,"mouseout.bs.toast",(t=>this._onInteraction(t,!1))),P.on(this._element,"focusin.bs.toast",(t=>this._onInteraction(t,!0))),P.on(this._element,"focusout.bs.toast",(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=Nn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(Nn),m(Nn),{Alert:q,Button:K,Carousel:rt,Collapse:ft,Dropdown:ci,Modal:Ni,Offcanvas:zi,Popover:dn,ScrollSpy:_n,Tab:xn,Toast:Nn,Tooltip:ln}})); -//# sourceMappingURL=bootstrap.bundle.min.js.map \ No newline at end of file diff --git a/OneCprogsite/programmer/static/programmer/js/recall.js b/OneCprogsite/programmer/static/programmer/js/recall.js deleted file mode 100644 index 8d84992..0000000 --- a/OneCprogsite/programmer/static/programmer/js/recall.js +++ /dev/null @@ -1,74 +0,0 @@ -// recall.js - Скрипты для страницы отзывов -function openModal(imageUrl, title) { - console.log('Opening modal with:', imageUrl); - const modal = document.getElementById('imageModal'); - const modalImg = document.getElementById('modalImage'); - const modalTitle = document.getElementById('modalTitle'); - - if (modal && modalImg) { - modal.style.display = "block"; - modalImg.src = imageUrl; - if (title && modalTitle) { - modalTitle.textContent = title; - } - - // Добавляем класс для анимации - setTimeout(() => { - modal.classList.add('active'); - }, 10); - - // Подстраиваем размер изображения - adjustModalImageSize(); - } -} - -function closeModal() { - const modal = document.getElementById('imageModal'); - if (modal) { - modal.classList.remove('active'); - setTimeout(() => { - modal.style.display = "none"; - }, 300); - } -} - -function adjustModalImageSize() { - const modalImg = document.getElementById('modalImage'); - const modalContent = document.querySelector('.modal-content'); - - if (modalImg && modalContent) { - const maxWidth = window.innerWidth * 0.9; - const maxHeight = window.innerHeight * 0.8; - - modalImg.style.maxWidth = `${maxWidth}px`; - modalImg.style.maxHeight = `${maxHeight}px`; - } -} - -// Инициализация после загрузки DOM -document.addEventListener('DOMContentLoaded', function() { - // Закрытие модального окна при клике вне изображения - document.addEventListener('click', function(event) { - const modal = document.getElementById('imageModal'); - if (event.target === modal) { - closeModal(); - } - }); - - // Закрытие по ESC - document.addEventListener('keydown', function(event) { - if (event.key === 'Escape') { - closeModal(); - } - }); - - // Адаптация размера изображения при изменении размера окна - window.addEventListener('resize', function() { - const modalImg = document.getElementById('modalImage'); - if (modalImg && modalImg.src) { - adjustModalImageSize(); - } - }); - - console.log('Recall page scripts initialized'); -}); \ No newline at end of file diff --git a/OneCprogsite/programmer/templates/admin/base.html b/OneCprogsite/programmer/templates/admin/base.html deleted file mode 100644 index 7c2ee58..0000000 --- a/OneCprogsite/programmer/templates/admin/base.html +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - {% block title %}Админ-панель - Статистика{% endblock %} - {% load django_bootstrap5 %} - {% bootstrap_css %} - - - -
-
-
-

{% block page_title %}Админ-панель{% endblock %}

- -
-
-
- -
- {% bootstrap_messages %} - {% block content %} - {% endblock %} -
- - {% bootstrap_javascript %} - - \ No newline at end of file diff --git a/OneCprogsite/programmer/templates/admin/base_site.html b/OneCprogsite/programmer/templates/admin/base_site.html deleted file mode 100644 index c847198..0000000 --- a/OneCprogsite/programmer/templates/admin/base_site.html +++ /dev/null @@ -1,26 +0,0 @@ -{% extends "admin/base.html" %} - -{% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %} - -{% block branding %} -

{{ site_header|default:_('Django administration') }}

-{% endblock %} - -{% block nav-global %} -{% endblock %} - -{% block userlinks %} - {% load programmer_tags %} - - - {% get_unread_callbacks as unread_callbacks %} - {% if unread_callbacks %} - - 🚨 {{ unread_callbacks }} новых заявок - / - {% endif %} - - 📊 Статистика заявок / - 📈 Посещения / - {{ block.super }} -{% endblock %} \ No newline at end of file diff --git a/OneCprogsite/programmer/templates/admin/callback_stats.html b/OneCprogsite/programmer/templates/admin/callback_stats.html deleted file mode 100644 index 31ee95a..0000000 --- a/OneCprogsite/programmer/templates/admin/callback_stats.html +++ /dev/null @@ -1,45 +0,0 @@ -{% extends "admin/base_site.html" %} - -{% block title %}Статистика заявок{% endblock %} - -{% block content %} -
-

📊 Статистика заявок на обратный звонок

- -
-
-

📋 Всего заявок

-

{{ stats.total }}

-
- -
-

📅 Сегодня

-

{{ stats.today }}

-
- -
-

📈 За неделю

-

{{ stats.week }}

-
- -
-

🆕 Непрочитанные

-

{{ stats.unread }}

-
- -
-

⏳ В обработке

-

{{ stats.unprocessed }}

-
-
- -
- - 📋 Перейти к списку заявок - - - 🏠 На главную админки - -
-
-{% endblock %} \ No newline at end of file diff --git a/OneCprogsite/programmer/templates/admin/statistics.html b/OneCprogsite/programmer/templates/admin/statistics.html deleted file mode 100644 index ae21071..0000000 --- a/OneCprogsite/programmer/templates/admin/statistics.html +++ /dev/null @@ -1,131 +0,0 @@ -{% extends 'admin/base.html' %} -{% load programmer_tags %} - -{% block title %}Статистика посещений{% endblock %} -{% block page_title %}Статистика посещений{% endblock %} - -{% block content %} - -{% get_unread_callbacks as unread_callbacks %} -{% get_today_callbacks as today_callbacks %} -{% if unread_callbacks > 0 %} - -{% endif %} - -
-
-
-
-

📊 Просмотров сегодня

-

{{ today_views }}

-
-
-

📈 Просмотров за неделю

-

{{ weekly_views }}

-
-
-

👥 Уникальных посетителей

-

{{ unique_visitors }}

-
-
-

🕒 Всего просмотров

-

{{ total_views }}

-
- -
-

📞 Заявок сегодня

-

{{ today_callbacks }}

-
-
-

📋 Всего заявок

-

{% get_unread_callbacks %}/{{ total_callbacks }}

- (непрочитанные/всего) -
-
-
-
- - -
-
-
-
-

🔥 Популярные страницы (за неделю)

-
-
- - - - - - - - - {% for page in popular_pages %} - - - - - {% empty %} - - - - {% endfor %} - -
СтраницаПросмотров
- {{ page.url }} - {% if page.url == '/' %} - Главная - {% endif %} - {{ page.views }}
Нет данных за выбранный период
-
-
-
-
- -
-
-
-
-

📋 Последние посещения

-
-
- - - - - - - - - - {% for view in recent_views %} - - - - - - {% empty %} - - - - {% endfor %} - -
ВремяСтраницаIP-адрес
{{ view.timestamp|date:"d.m.Y H:i" }}{{ view.url }}{{ view.ip_address }}
Нет данных
-
-
-
-
-{% endblock %} \ No newline at end of file diff --git a/OneCprogsite/programmer/templates/emails/callback_notification.html b/OneCprogsite/programmer/templates/emails/callback_notification.html deleted file mode 100644 index 503b2df..0000000 --- a/OneCprogsite/programmer/templates/emails/callback_notification.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - -
-
-

🚨 Новая заявка на сайте

-

Требуется ваше внимание!

-
- -
-
- ⚠️ Срочно! Пользователь оставил заявку на обратный звонок. -
- -
-

📋 Информация о заявке:

-

👤 Имя: {{ callback.name }}

-

📞 Телефон: {{ callback.phone }}

- {% if callback.email %} -

📧 Email: {{ callback.email }}

- {% endif %} - {% if callback.question %} -

❓ Вопрос:
{{ callback.question }}

- {% endif %} -

🕒 Время отправки: {{ callback.time_create|date:"d.m.Y H:i" }}

-
- - - -

Не забудьте отметить заявку как обработанную после связи с клиентом!

-
- - -
- - \ No newline at end of file diff --git a/OneCprogsite/programmer/templates/emails/daily_summary.html b/OneCprogsite/programmer/templates/emails/daily_summary.html deleted file mode 100644 index 960740f..0000000 --- a/OneCprogsite/programmer/templates/emails/daily_summary.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - -
-
-

📊 Ежедневная сводка

-

Статистика заявок за {{ yesterday|date:"d.m.Y" }}

-
- -
-
-
-

📅 Вчерашние заявки

-

{{ yesterday_callbacks }}

-
- -
-

⏳ Ожидают обработки

-

{{ unprocessed_callbacks }}

-
-
- - {% if unprocessed_callbacks > 0 %} -
- ⚠️ Внимание! У вас есть {{ unprocessed_callbacks }} необработанных заявок. -
- {% endif %} - - - -

Не забудьте обработать все pending заявки!

-
- - -
- - \ No newline at end of file diff --git a/OneCprogsite/programmer/templates/programmer/about.html b/OneCprogsite/programmer/templates/programmer/about.html deleted file mode 100644 index d7f55c7..0000000 --- a/OneCprogsite/programmer/templates/programmer/about.html +++ /dev/null @@ -1,154 +0,0 @@ -{% extends 'programmer/base.html' %} -{% load django_bootstrap5 %} - -{% block content %} - - -
-
-

Николай Сердюк

-

Разработчик 1С

-
- -
-

🚀 Опыт работы

-

Более 10 лет успешной работы в разработке и сопровождении систем на платформе 1С

- -
-

Основные направления:

-
-
-

💻 Разработка

-
    -
  • Разработка и доработка конфигураций 1С
  • -
  • Создание внешних обработок и отчетов
  • -
  • Кастомизация под бизнес-процессы
  • -
-
-
-

🔗 Интеграция

-
    -
  • Интеграция 1С с веб-сервисами
  • -
  • Связь с сайтами и мобильными приложениями
  • -
  • API и веб-сервисы
  • -
-
-
-

⚡ Оптимизация

-
    -
  • Оптимизация бизнес-процессов
  • -
  • Ускорение работы баз данных
  • -
  • Автоматизация рутинных операций
  • -
-
-
-
-
- -
-

🛠 Технологии и навыки

-
-
-

🎯 1С Разработка

-
    -
  • 1С:Предприятие 8.3
  • -
  • Управление торговлей
  • -
  • Бухгалтерия предприятия
  • -
  • Зарплата и управление персоналом
  • -
  • Внешние обработки и отчеты
  • -
-
-
-

🔧 Дополнительные технологии

-
    -
  • SQL и оптимизация запросов
  • -
  • Веб-сервисы и API
  • -
  • XML, JSON, REST
  • -
  • Системное администрирование
  • -
-
-
-
- -
-

📈 Проекты и достижения

-

Успешно реализовал более 50 проектов различной сложности

- -
-
-

🏆 Ключевые проекты

-
    -
  • Автоматизация учетных систем для предприятий
  • -
  • Интеграция 1С с сайтами и мобильными приложениями
  • -
  • Разработка кастомизированных отчетов и дашбордов
  • -
  • Оптимизация производительности баз данных
  • -
-
-
-
- -
-

📞 Контакты

-
-
-
-

📧 Электронная почта

-

{{ CONTACT_EMAIL }}

-
-
-

📱 Телефон

-

{{ CONTACT_PHONE }}

-
-
-

💬 Telegram

-

@odinesina_prog

-
-
-
-
- - -
- - - -{% endblock %} \ No newline at end of file diff --git a/OneCprogsite/programmer/templates/programmer/base.html b/OneCprogsite/programmer/templates/programmer/base.html deleted file mode 100644 index 937b093..0000000 --- a/OneCprogsite/programmer/templates/programmer/base.html +++ /dev/null @@ -1,578 +0,0 @@ -{% load static %} -{% load programmer_tags %} -{% load django_bootstrap5 %} - - - - {{title}} - - - - - - - - - - - - - - - - - - - - - - - {% bootstrap_css %} - - - - - - - - - - - - {% block extra_css %} - - {% endblock %} - - - - - - - - - - - - - - - {% block mainmenu %} -
-
- -
-
- - -
-
-
-

Меню

- -
- - - -
- - - Telegram - - -
- - -
-
-
- {% endblock mainmenu %} - - -
-
-
- - {% block breadcrumbs %} - - {% endblock %} - - - {% bootstrap_messages %} - - -
- {% block content %} - {% endblock %} -
-
-
-
- - -
-
- -
-
- - {% bootstrap_javascript %} - - - - {% block extra_js %} - - {% endblock %} - - - - - \ No newline at end of file diff --git a/OneCprogsite/programmer/templates/programmer/callback.html b/OneCprogsite/programmer/templates/programmer/callback.html deleted file mode 100644 index b5d665d..0000000 --- a/OneCprogsite/programmer/templates/programmer/callback.html +++ /dev/null @@ -1,8 +0,0 @@ -{% extends 'programmer/base.html' %} -{% load django_bootstrap5 %} - -{% block content %} - - - -{% endblock %} \ No newline at end of file diff --git a/OneCprogsite/programmer/templates/programmer/competence.html b/OneCprogsite/programmer/templates/programmer/competence.html deleted file mode 100644 index b425251..0000000 --- a/OneCprogsite/programmer/templates/programmer/competence.html +++ /dev/null @@ -1,72 +0,0 @@ -{% extends 'programmer/base.html' %} -{% load django_bootstrap5 %} -{% load static %} - -{% block extra_css %} - -{% endblock %} - -{% block content %} - - -
- {% for p in posts %} -
-
- {% if p.photo %} -
-
- Сертификат 1С: {{ p.title }} - {{ p.content|striptags }} -
- 🔍 - Нажмите для увеличения -
-
-
- {% endif %} - -
-

{{ p.title }}

-
- {{ p.content|linebreaks }} -
-
-
-
- {% endfor %} -
- -{% if not posts %} -
-

📚 Информация о компетенциях

-

Раздел находится в разработке

- -
-{% endif %} - - - -{% endblock %} - -{% block extra_js %} - -{% endblock %} \ No newline at end of file diff --git a/OneCprogsite/programmer/templates/programmer/humans.txt b/OneCprogsite/programmer/templates/programmer/humans.txt deleted file mode 100644 index b4cb295..0000000 --- a/OneCprogsite/programmer/templates/programmer/humans.txt +++ /dev/null @@ -1,13 +0,0 @@ -/* TEAM */ -Developer: Николай Сердюк -Site: https://nikdizell.ru -Email: {{ CONTACT_EMAIL }} - -/* THANKS */ -Django Framework -Bootstrap - -/* SITE */ -Last update: 2025 -Language: Russian -Doctype: HTML5 \ No newline at end of file diff --git a/OneCprogsite/programmer/templates/programmer/index.html b/OneCprogsite/programmer/templates/programmer/index.html deleted file mode 100644 index ff5aa19..0000000 --- a/OneCprogsite/programmer/templates/programmer/index.html +++ /dev/null @@ -1,103 +0,0 @@ -{% extends 'programmer/base.html' %} -{% load django_bootstrap5 %} - -{% block content %} -
-

🚀 Добро пожаловать!

-

Я профессиональный программист 1С с опытом создания эффективных бизнес-решений

-
- -
- {% autoescape off %} - {% for p in posts %} -
-
-

{{p.title}}

-
-
- {{p.content}} -
-
- -
-
- {% endfor %} - {% endautoescape %} -
- - - - -{% if not posts %} -
-

🚀 Контент скоро появится

-

Мы готовим для вас интересные материалы и кейсы

-
- -
-
-{% endif %} - - -{% endblock %} \ No newline at end of file diff --git a/OneCprogsite/programmer/templates/programmer/recall.html b/OneCprogsite/programmer/templates/programmer/recall.html deleted file mode 100644 index c1bd193..0000000 --- a/OneCprogsite/programmer/templates/programmer/recall.html +++ /dev/null @@ -1,174 +0,0 @@ -{% extends 'programmer/base.html' %} -{% load django_bootstrap5 %} -{% load static %} -{% load seo_tags %} - -{% block extra_css %} - -{% endblock %} - -{% block content %} - - -
- {% for p in posts %} -
- - - - -
-
-
-

{{ p.title }}

- {% if p.time_create %} - - - - {% endif %} -
-
- -
- {% if p.scan %} -
-
- Отзыв от {{ p.title }} -
- 🔍 - Нажмите для увеличения -
-
-
- {% endif %} - -
- {{ p.content|linebreaks }} -
-
-
-
- {% endfor %} -
- -{% if not posts %} -
-

💬 Отзывы клиентов

-

Здесь будут отображаться отзывы от довольных клиентов

- -
-{% endif %} - - - - - -{% endblock %} \ No newline at end of file diff --git a/OneCprogsite/programmer/templates/programmer/robots.txt b/OneCprogsite/programmer/templates/programmer/robots.txt deleted file mode 100644 index a3197a0..0000000 --- a/OneCprogsite/programmer/templates/programmer/robots.txt +++ /dev/null @@ -1,19 +0,0 @@ -User-agent: * -Allow: / - -# Основной сайт -Sitemap: {{ request.scheme }}://{{ request.get_host }}/sitemap.xml - -# Запрещаем служебные разделы -Disallow: /admin/ -Disallow: /media/cache/ -Disallow: /static/admin/ -Disallow: /callback/ -Disallow: /api/ - -# Разрешаем индексацию статических файлов -Allow: /static/ -Allow: /media/ - -# Указываем главное зеркало -Host: {{ request.scheme }}://{{ request.get_host }} \ No newline at end of file diff --git a/OneCprogsite/programmer/templates/programmer/sitemap.xml b/OneCprogsite/programmer/templates/programmer/sitemap.xml deleted file mode 100644 index 59012bd..0000000 --- a/OneCprogsite/programmer/templates/programmer/sitemap.xml +++ /dev/null @@ -1,12 +0,0 @@ - - -{% for url in urlset %} - - {{ url.location }} - {% if url.lastmod %}{{ url.lastmod|date:"Y-m-d" }}{% endif %} - {% if url.changefreq %}{{ url.changefreq }}{% endif %} - {% if url.priority %}{{ url.priority }}{% endif %} - -{% endfor %} - \ No newline at end of file diff --git a/OneCprogsite/programmer/templates/programmer/solution.html b/OneCprogsite/programmer/templates/programmer/solution.html deleted file mode 100644 index 6a9e42f..0000000 --- a/OneCprogsite/programmer/templates/programmer/solution.html +++ /dev/null @@ -1,96 +0,0 @@ -{% extends 'programmer/base.html' %} -{% load django_bootstrap5 %} -{% load static %} -{% load seo_tags %} - -{% block extra_css %} - -{% endblock %} - -{% block content %} - - -
- {% autoescape off %} - {% for p in posts %} -
  • -
    -

    {{p.title}}

    - - - - -
    -
    -
    - 📋 Описание задачи - -
    -
    - {{p.description}} -
    -
    - -
    -
    - 🔧 Описание решения - -
    -
    - {{p.implementation}} -
    -
    - -
    -
    - ✅ Результат - -
    -
    - {{p.closing}} -
    -
    -
    - -
    -

    Опубликовано: {{p.time_create|date:"d.m.Y"}}

    -
    -
    - - {% empty %} -
    -

    🚀 Проекты в разработке

    -

    Скоро здесь появятся новые кейсы автоматизации

    -
    - -
  • - {% endfor %} - {% endautoescape %} -
    - -{% if not posts %} -
    -

    Примеры решений скоро появятся

    -

    Мы готовим для вас интересные кейсы и решения

    -
    -{% endif %} - - - - -{% endblock %} \ No newline at end of file diff --git a/OneCprogsite/programmer/templatetags/__init__.py b/OneCprogsite/programmer/templatetags/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/OneCprogsite/programmer/templatetags/programmer_tags.py b/OneCprogsite/programmer/templatetags/programmer_tags.py deleted file mode 100644 index cbb735b..0000000 --- a/OneCprogsite/programmer/templatetags/programmer_tags.py +++ /dev/null @@ -1,14 +0,0 @@ -from django import template -from ..models import CallbackRequest - -register = template.Library() - -@register.simple_tag -def get_unread_callbacks(): - return CallbackRequest.objects.filter(is_read=False).count() - -@register.simple_tag -def get_today_callbacks(): - from django.utils import timezone - today = timezone.now().date() - return CallbackRequest.objects.filter(time_create__date=today).count() \ No newline at end of file diff --git a/OneCprogsite/programmer/templatetags/seo_tags.py b/OneCprogsite/programmer/templatetags/seo_tags.py deleted file mode 100644 index dcbf0a9..0000000 --- a/OneCprogsite/programmer/templatetags/seo_tags.py +++ /dev/null @@ -1,21 +0,0 @@ -from django import template -from django.utils.html import strip_tags - -register = template.Library() - -@register.simple_tag -def generate_meta_description(obj, default=""): - """Генерирует meta description для объектов""" - if hasattr(obj, 'get_seo_description'): - return obj.get_seo_description() - elif hasattr(obj, 'content'): - clean_content = strip_tags(obj.content)[:160] - return clean_content + '...' if len(clean_content) > 160 else clean_content - return default - -@register.simple_tag -def generate_meta_keywords(obj, default=""): - """Генерирует meta keywords для объектов""" - if hasattr(obj, 'get_meta_keywords'): - return ', '.join(obj.get_meta_keywords()) - return default \ No newline at end of file diff --git a/OneCprogsite/programmer/tests.py b/OneCprogsite/programmer/tests.py deleted file mode 100644 index de8bdc0..0000000 --- a/OneCprogsite/programmer/tests.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here. diff --git a/OneCprogsite/programmer/urls.py b/OneCprogsite/programmer/urls.py deleted file mode 100644 index 2c961c3..0000000 --- a/OneCprogsite/programmer/urls.py +++ /dev/null @@ -1,27 +0,0 @@ -from django.contrib import admin -from django.urls import path, include -from django.conf import settings -from django.conf.urls.static import static -from .views import * -from django.contrib.sitemaps.views import sitemap -from .sitemaps import sitemaps - - -urlpatterns = [ - path('', index, name='home'), - path('about/', about, name='about'), - path('solutions/', solution, name='solution'), - path('competence/', ability, name='ability'), - path('recall/', recall, name='recall'), - path('post//', show_post, name='post'), - path('callback/', callback_request, name='callback'), - path('admin/statistics/', statistics_view, name='statistics'), - # Sitemap - path('sitemap.xml', sitemap, {'sitemaps': sitemaps}, - name='django.contrib.sitemaps.views.sitemap'), - path('robots.txt', robots_txt, name='robots'), -] - - -if settings.DEBUG: - urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \ No newline at end of file diff --git a/OneCprogsite/programmer/utils/email_notifications.py b/OneCprogsite/programmer/utils/email_notifications.py deleted file mode 100644 index ffbe2ad..0000000 --- a/OneCprogsite/programmer/utils/email_notifications.py +++ /dev/null @@ -1,65 +0,0 @@ -# programmer/utils/email_notifications.py -from django.core.mail import send_mail, EmailMultiAlternatives -from django.template.loader import render_to_string -from django.conf import settings -from django.utils.html import strip_tags -import logging - -logger = logging.getLogger(__name__) - - -def send_callback_notification(callback_request): - """ - Отправляет уведомление о новой заявке на обратный звонок - """ - try: - subject = f'🚨 Новая заявка на обратный звонок от {callback_request.name}' - - # HTML версия письма - html_message = render_to_string('emails/callback_notification.html', { - 'callback': callback_request, - 'site_url': settings.ALLOWED_HOSTS[0] if settings.ALLOWED_HOSTS else 'localhost', - }) - - # Текстовая версия письма - plain_message = strip_tags(html_message) - - # Проверяем настройки email - if not all([settings.EMAIL_HOST_USER, settings.EMAIL_HOST_PASSWORD]): - logger.error("Email settings are not configured properly") - return False - - # Отправляем email - send_mail( - subject=subject, - message=plain_message, - from_email=settings.DEFAULT_FROM_EMAIL, - recipient_list=settings.ADMIN_EMAILS, - html_message=html_message, - fail_silently=False, - ) - - logger.info(f"Email notification sent successfully for callback #{callback_request.id}") - return True - - except Exception as e: - logger.error(f"Error sending email notification: {e}") - return False - - -def send_test_email(): - """ - Функция для тестирования отправки email - """ - try: - send_mail( - subject='📧 Test Email from Django', - message='This is a test email from your Django application.', - from_email=settings.DEFAULT_FROM_EMAIL, - recipient_list=settings.ADMIN_EMAILS, - fail_silently=False, - ) - return True - except Exception as e: - logger.error(f"Test email failed: {e}") - return False diff --git a/OneCprogsite/programmer/views.py b/OneCprogsite/programmer/views.py deleted file mode 100644 index a4a09ae..0000000 --- a/OneCprogsite/programmer/views.py +++ /dev/null @@ -1,259 +0,0 @@ -from django.http import HttpResponse, HttpResponseNotFound -from .models import * -from django.shortcuts import render, redirect -from django.contrib import messages -from .models import CallbackRequest # Импортируем из models, а не forms -from .forms import CallbackForm -from django.utils import timezone -from datetime import timedelta -from .models import PageView, Visitor -from django.db.models import Count -from django.contrib.auth.decorators import login_required, user_passes_test -from django.views.decorators.http import require_GET - - -menu = [ - {'title': "Главная", 'url_name': 'home'}, - {'title': "Проекты", 'url_name': 'solution'}, - {'title': "Компетенции", 'url_name': 'ability'}, - {'title': "Отзывы", 'url_name': 'recall'}, - {'title': "Обо мне", 'url_name': 'about'} - ] - - -# === ДОБАВЬТЕ ЭТИ ФУНКЦИИ ЗДЕСЬ === - -def get_client_ip(request): - """Получаем реальный IP клиента""" - x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') - if x_forwarded_for: - ip = x_forwarded_for.split(',')[0] - else: - ip = request.META.get('REMOTE_ADDR') - return ip - - -def should_track_request(request): - """Определяем, нужно ли отслеживать запрос""" - - client_ip = get_client_ip(request) - path = request.path - - # Игнорируемые пути (Nextcloud специфичные) - nextcloud_paths = [ - '/index.php', - '/status.php', - '/cron', - '/remote.php', - '/ocs', - '/apps/', - '/custom_apps/', - ] - - # Игнорируемые IP (Docker сети) - docker_ips = [ - '192.168.64.1', - '192.168.65.1', - '172.17.0.1', - '172.18.0.1', - '172.19.0.1', - ] - - # Игнорируем статические файлы и админку - if path.startswith('/static/') or path.startswith('/admin/'): - return False - - # Не отслеживаем Nextcloud и Docker запросы - if any(path.startswith(p) for p in nextcloud_paths): - return False - if client_ip in docker_ips: - return False - - return True - - -def track_page_view(request): - """Основная функция отслеживания просмотров""" - if not should_track_request(request): - return - - try: - PageView.objects.create( - url=request.path, - ip_address=get_client_ip(request), - user_agent=request.META.get('HTTP_USER_AGENT', '')[:500], - referer=request.META.get('HTTP_REFERER', '')[:500], - ) - except Exception as e: - print(f"Error tracking page: {e}") - - -def track_view(view_func): - """Декоратор для отслеживания просмотров страниц""" - from functools import wraps - - @wraps(view_func) - def _wrapped_view(request, *args, **kwargs): - # Отслеживаем просмотр перед выполнением view - track_page_view(request) - return view_func(request, *args, **kwargs) - - return _wrapped_view - - -@track_view -def index(request): - posts = Home.objects.filter(is_published=True) - context = { - 'posts': posts, - 'menu': menu, - 'title': "Программист 1С Николай Сердюк - разработка и сопровождение", - 'meta_description': "Профессиональный программист 1С с более чем 10-летним опытом. Разработка, доработка, обновление и интеграция систем 1С. Сопровождение 1С.", - 'meta_keywords': "программист 1С, разработка 1С, обновление 1С, сопровождение 1С, интеграция 1С, доработка 1С, 1С предприятие 8.3", - 'form': CallbackForm() - } - return render(request, 'programmer/index.html', context=context) - - -@track_view -def about(request): - context = { - 'menu': menu, - 'title': "Программист 1С Николай Сердюк - 10+ лет опыта | Услуги 1С", - 'meta_description': "Николай Сердюк - сертифицированный программист 1С с 10+ лет опыта. Специализация: обновление 1С, разработка под ключ, интеграция, миграция с 1С 7.7.", - 'meta_keywords': "программист 1С Николай Сердюк, обновление 1С, разработка 1С под ключ, интеграция 1С, сертифицированный 1С, миграция 1С 7.7" - } - return render(request, 'programmer/about.html', context=context) - - -@track_view -def solution(request): - posts = Solution.objects.filter(is_published=True) - context = { - 'posts': posts, - 'menu': menu, - 'meta_description': "Реализованные проекты по автоматизации 1С: складской учет с ТСД, интеграция с оборудованием, миграция с 1С 7.7. Примеры работ и кейсы.", - 'meta_keywords': "проекты 1С, автоматизация склада 1С, интеграция ТСД 1С, миграция 1С 7.7, кейсы 1С, примеры работ 1С", - 'title': "Проекты автоматизации 1С | Реализованные кейсы и решения", - } - return render(request, 'programmer/solution.html', context=context) - - -@track_view -def ability(request): - posts = Competence.objects.filter(is_published=True) - context = { - 'posts': posts, - 'menu': menu, - 'title': "Сертификаты и компетенции 1С | Программист 1С Николай Сердюк", - 'meta_description': "Сертификаты 1С: Профессионал по платформе 8.3 и БП 3.0. Подтвержденная квалификация программиста 1С с сертификатами фирмы 1С.", - 'meta_keywords': "сертификаты 1С, 1С профессионал, компетенции 1С, квалификация программиста 1С, сертифицированный специалист 1С" - } - return render(request, 'programmer/competence.html', context=context) - - -@track_view -def recall(request): - posts = Recall.objects.filter(is_published=True) - context = { - 'posts': posts, - 'menu': menu, - 'title': "Отзывы клиентов о работе программиста 1С | Реальные кейсы", - 'meta_description': "Реальные отзывы клиентов о работе программиста 1С Николая Сердюка. Отзывы от ООО «РОВЕН-Регионы» и других компаний.", - 'meta_keywords': "отзывы программист 1С, рекомендации 1С, отзывы клиентов 1С, реальные кейсы 1С, отзыв ООО РОВЕН" - } - return render(request, 'programmer/recall.html', context=context) - - -def show_post(request, post_id): - return HttpResponse(f"Отображение № {post_id}") - - -def pageNotFound(request, exception): - return HttpResponseNotFound('

    Страница не найдена

    ') - - -def callback_request(request): - if request.method == 'POST': - form = CallbackForm(request.POST) - if form.is_valid(): - # Сохраняем заявку через форму - form.save() - messages.success(request, '✅ Ваша заявка успешно отправлена! Я свяжусь с вами в ближайшее время.') - return redirect('home') - else: - # Если форма невалидна, показываем ошибки - for field, errors in form.errors.items(): - for error in errors: - messages.error(request, f'❌ Ошибка в поле {form.fields[field].label}: {error}') - return redirect('home') - - # Если GET запрос, просто показываем главную страницу - return redirect('home') - - -def is_admin(user): - return user.is_staff - - -def is_staff(user): - return user.is_staff - - -@login_required -@user_passes_test(is_staff) -def statistics_view(request): - today = timezone.now().date() - week_ago = today - timedelta(days=7) - - # Статистика за сегодня - today_views = PageView.objects.filter( - timestamp__date=today - ).count() - - # Статистика за неделю - weekly_views = PageView.objects.filter( - timestamp__date__gte=week_ago - ).count() - - # Всего просмотров - total_views = PageView.objects.count() - - # Популярные страницы за неделю - popular_pages = PageView.objects.filter( - timestamp__date__gte=week_ago - ).values('url').annotate( - views=Count('id') - ).order_by('-views')[:10] - - # Уникальные посетители за неделю - unique_visitors = Visitor.objects.filter( - last_visit__date__gte=week_ago - ).count() - - # Последние посещения - recent_views = PageView.objects.select_related().order_by('-timestamp')[:20] - - today = timezone.now().date() - total_callbacks = CallbackRequest.objects.count() - today_callbacks = CallbackRequest.objects.filter(time_create__date=today).count() - unread_callbacks = CallbackRequest.objects.filter(is_read=False).count() - - context = { - 'today_views': today_views, - 'weekly_views': weekly_views, - 'total_views': total_views, - 'unique_visitors': unique_visitors, - 'popular_pages': popular_pages, - 'recent_views': recent_views, - 'total_callbacks': total_callbacks, - 'today_callbacks': today_callbacks, - 'unread_callbacks': unread_callbacks, - } - - return render(request, 'admin/statistics.html', context) - - -@require_GET -def robots_txt(request): - return render(request, 'robots.txt', content_type='text/plain') diff --git a/OneCprogsite/settings.py b/OneCprogsite/settings.py index a02cb85..edbbfc3 100644 --- a/OneCprogsite/settings.py +++ b/OneCprogsite/settings.py @@ -1,212 +1,226 @@ -""" -Django settings for OneCprogsite project. - -Generated by 'django-admin startproject' using Django 4.2.7. - -For more information on this file, see -https://docs.djangoproject.com/en/4.2/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/4.2/ref/settings/ -""" -import os.path -from pathlib import Path - -# Build paths inside the project like this: BASE_DIR / 'subdir'. -BASE_DIR = Path(__file__).resolve().parent.parent - - -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/ - -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'django-insecure-5rs2a1*8cxjkv*%6k1-88biv&1#nep%@i+%1^dk=5j$s&e&hwm' - -# Безопасность cookies для HTTPS -SESSION_COOKIE_SECURE = True -CSRF_COOKIE_SECURE = True -SESSION_COOKIE_HTTPONLY = True -CSRF_COOKIE_HTTPONLY = False # Django требует доступ к CSRF cookie через JS -SESSION_COOKIE_SAMESITE = 'Lax' -CSRF_COOKIE_SAMESITE = 'Lax' - -# Если используете другие cookies -LANGUAGE_COOKIE_SECURE = True -LANGUAGE_COOKIE_HTTPONLY = True -LANGUAGE_COOKIE_SAMESITE = 'Lax' - -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = False - -X_FRAME_OPTIONS = 'SAMEORIGIN' -# Или разрешить конкретные домены (Django 4.0+) -X_FRAME_OPTIONS = 'ALLOW-FROM https://metrika.yandex.ru' - -# ОБЯЗАТЕЛЬНО укажите ваши домены -ALLOWED_HOSTS = [ - 'nikdizell.ru', - 'www.nikdizell.ru', - 'localhost', - '127.0.0.1', - '192.168.31.88' # Добавьте IP сервера -] - -# Важно для работы за прокси -SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') -SECURE_SSL_REDIRECT = True - -# Дополнительная безопасность -SECURE_BROWSER_XSS_FILTER = True -SECURE_CONTENT_TYPE_NOSNIFF = True -SECURE_HSTS_SECONDS = 31536000 -SECURE_HSTS_INCLUDE_SUBDOMAINS = True -SECURE_HSTS_PRELOAD = True - -CSRF_TRUSTED_ORIGINS = [ - 'https://nikdizell.ru', - 'https://www.nikdizell.ru', -] - -# Application definition - -INSTALLED_APPS = [ - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'programmer.apps.ProgrammerConfig', - 'django_bootstrap5', - 'django_extensions', - 'django.contrib.sites', - 'django.contrib.sitemaps', -] - -MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - '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', - 'programmer.middleware.PageViewMiddleware', -] - -ROOT_URLCONF = 'OneCprogsite.urls' - -# Кастомный middleware для CSP -class CSPMiddleware: - def __init__(self, get_response): - self.get_response = get_response - - def __call__(self, request): - response = self.get_response(request) - response['Content-Security-Policy'] = "frame-ancestors 'self' https://metrika.yandex.ru https://metrika.yandex.by https://metrica.yandex.com https://metrica.yandex.com.tr https://*.webvisor.com" - return response - -TEMPLATES = [ - { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], - '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', - 'programmer.context_processors.menu_processor', - 'programmer.context_processors.contact_info', - ], - }, - }, -] - -WSGI_APPLICATION = 'OneCprogsite.wsgi.application' - - -# Database -# https://docs.djangoproject.com/en/4.2/ref/settings/#databases - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql', - 'NAME': 'App', - 'USER': 'postgres', - 'PASSWORD': 'NikDi94Zell', - 'HOST': 'postgres', - 'PORT': 5432, - } -} - - -# Password validation -# https://docs.djangoproject.com/en/4.2/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', - }, -] - - -# Internationalization -# https://docs.djangoproject.com/en/4.2/topics/i18n/ - -LANGUAGE_CODE = 'ru' - -TIME_ZONE = 'Europe/Moscow' -USE_I18N = True -USE_I18N = True -USE_TZ = True - - -# Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/4.2/howto/static-files/ - -STATIC_URL = 'static/' -STATIC_ROOT = os.path.join(BASE_DIR, 'static') -STATICFILES_DIRS = [] - -# Default primary key field type -# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field - -DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' - -MEDIA_ROOT = os.path.join(BASE_DIR, 'media') -MEDIA_URL = '/media/' - -# Настройки email -EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' -# EMAIL_HOST = 'smtp.yandex.ru' # или smtp.gmail.com, smtp.mail.ru -# EMAIL_PORT = 587 -# EMAIL_USE_TLS = True -# EMAIL_HOST_USER = os.getenv('EMAIL_HOST_USER', 'it@yandex.ru') -# EMAIL_HOST_PASSWORD = os.getenv('EMAIL_HOST_PASSWORD', 'tifdctkrcjcqwxyc') -# DEFAULT_FROM_EMAIL = EMAIL_HOST_USER -# SERVER_EMAIL = EMAIL_HOST_USER - -EMAIL_HOST = 'smtp.gmail.com' # или smtp.gmail.com, smtp.mail.ru -EMAIL_PORT = 587 -EMAIL_USE_TLS = True -EMAIL_HOST_USER = os.getenv('EMAIL_HOST_USER', 'nikdizell@gmail.com') -EMAIL_HOST_PASSWORD = os.getenv('EMAIL_HOST_PASSWORD', 'qvmw yccb msqv mmpj') -DEFAULT_FROM_EMAIL = EMAIL_HOST_USER -SERVER_EMAIL = EMAIL_HOST_USER - -# Email для уведомлений (можно указать несколько через запятую) -# ADMIN_EMAILS = os.getenv('ADMIN_EMAILS', 'nikdizell@gmail.com').split(',') -ADMIN_EMAILS = os.getenv('ADMIN_EMAILS', 'it@nserdyuk.ru').split(',') - - +""" +Django settings for OneCprogsite project. + +Generated by 'django-admin startproject' using Django 4.2.7. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/4.2/ref/settings/ +""" +import os.path +import sys +from pathlib import Path + + +SITE_ID = 1 + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + +sys.path.insert(0, str(BASE_DIR)) # Добавляем корень проекта +sys.path.insert(0, str(BASE_DIR / "OneCprogsite")) # Добавляем папку OneCprogsite + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'django-insecure-5rs2a1*8cxjkv*%6k1-88biv&1#nep%@i+%1^dk=5j$s&e&hwm' + +# Безопасность cookies для HTTPS +# SESSION_COOKIE_SECURE = True +# CSRF_COOKIE_SECURE = True +# SESSION_COOKIE_HTTPONLY = True +# CSRF_COOKIE_HTTPONLY = False # Django требует доступ к CSRF cookie через JS +# SESSION_COOKIE_SAMESITE = 'Lax' +# CSRF_COOKIE_SAMESITE = 'Lax' + +# Если используете другие cookies +# LANGUAGE_COOKIE_SECURE = True +# LANGUAGE_COOKIE_HTTPONLY = True +# LANGUAGE_COOKIE_SAMESITE = 'Lax' + +# Для разработки (HTTP) +SESSION_COOKIE_SECURE = False +CSRF_COOKIE_SECURE = False +SECURE_SSL_REDIRECT = False + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +# Или разрешить конкретные домены (Django 4.0+) +X_FRAME_OPTIONS = 'ALLOW-FROM https://metrika.yandex.ru' + +# ОБЯЗАТЕЛЬНО укажите ваши домены +ALLOWED_HOSTS = [ + 'nikdizell.ru', + 'www.nikdizell.ru', + 'localhost', + '127.0.0.1', + '192.168.31.88', # Добавьте IP сервера + '192.168.31.221', +] + +# Важно для работы за прокси +# SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') +# SECURE_SSL_REDIRECT = True +# +# # Дополнительная безопасность +# SECURE_BROWSER_XSS_FILTER = True +# SECURE_CONTENT_TYPE_NOSNIFF = True +# SECURE_HSTS_SECONDS = 31536000 +# SECURE_HSTS_INCLUDE_SUBDOMAINS = True +# SECURE_HSTS_PRELOAD = True + +CSRF_TRUSTED_ORIGINS = [ + 'https://nikdizell.ru', + 'https://www.nikdizell.ru', +] + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'programmer.apps.ProgrammerConfig', + 'django_bootstrap5', + 'django_extensions', + 'django.contrib.sites', + 'django.contrib.sitemaps', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + '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', + 'programmer.middleware.CSPMiddleware', + 'programmer.middleware.PageViewMiddleware', +] + +ROOT_URLCONF = 'OneCprogsite.urls' + +# Кастомный middleware для CSP вынесен в отдельный файл +# class CSPMiddleware: +# def __init__(self, get_response): +# self.get_response = get_response +# +# def __call__(self, request): +# response = self.get_response(request) +# response['Content-Security-Policy'] = "frame-ancestors 'self' https://metrika.yandex.ru https://metrika.yandex.by https://metrica.yandex.com https://metrica.yandex.com.tr https://*.webvisor.com" +# return response + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + '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', + 'programmer.context_processors.menu_processor', + 'programmer.context_processors.contact_info', + ], + }, + }, +] + +WSGI_APPLICATION = 'OneCprogsite.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/4.2/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql', + 'NAME': 'App', + 'USER': 'postgres', + 'PASSWORD': 'NikDi94Zell', + 'HOST': 'postgres', + 'PORT': 5432, + } +} + + +# Password validation +# https://docs.djangoproject.com/en/4.2/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', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/4.2/topics/i18n/ + +LANGUAGE_CODE = 'ru' + +TIME_ZONE = 'Europe/Moscow' +USE_I18N = True +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/4.2/howto/static-files/ + +STATIC_URL = '/static/' +STATIC_ROOT = os.path.join(BASE_DIR, 'static') + +STATICFILES_DIRS = [ + os.path.join(BASE_DIR, 'programmer', 'static'), +] + +# Default primary key field type +# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' + +MEDIA_URL = '/media/' +MEDIA_ROOT = os.path.join(BASE_DIR, 'media') + +# Настройки email +EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' +# EMAIL_HOST = 'smtp.yandex.ru' # или smtp.gmail.com, smtp.mail.ru +# EMAIL_PORT = 587 +# EMAIL_USE_TLS = True +# EMAIL_HOST_USER = os.getenv('EMAIL_HOST_USER', 'it@yandex.ru') +# EMAIL_HOST_PASSWORD = os.getenv('EMAIL_HOST_PASSWORD', 'tifdctkrcjcqwxyc') +# DEFAULT_FROM_EMAIL = EMAIL_HOST_USER +# SERVER_EMAIL = EMAIL_HOST_USER + +EMAIL_HOST = 'smtp.gmail.com' # или smtp.gmail.com, smtp.mail.ru +EMAIL_PORT = 587 +EMAIL_USE_TLS = True +EMAIL_HOST_USER = os.getenv('EMAIL_HOST_USER', 'nikdizell@gmail.com') +EMAIL_HOST_PASSWORD = os.getenv('EMAIL_HOST_PASSWORD', 'qvmw yccb msqv mmpj') +DEFAULT_FROM_EMAIL = EMAIL_HOST_USER +SERVER_EMAIL = EMAIL_HOST_USER + +# Email для уведомлений (можно указать несколько через запятую) +# ADMIN_EMAILS = os.getenv('ADMIN_EMAILS', 'nikdizell@gmail.com').split(',') +ADMIN_EMAILS = os.getenv('ADMIN_EMAILS', 'it@nserdyuk.ru').split(',') + + diff --git a/OneCprogsite/static/admin/css/autocomplete.css b/OneCprogsite/static/admin/css/autocomplete.css deleted file mode 100644 index 69c94e7..0000000 --- a/OneCprogsite/static/admin/css/autocomplete.css +++ /dev/null @@ -1,275 +0,0 @@ -select.admin-autocomplete { - width: 20em; -} - -.select2-container--admin-autocomplete.select2-container { - min-height: 30px; -} - -.select2-container--admin-autocomplete .select2-selection--single, -.select2-container--admin-autocomplete .select2-selection--multiple { - min-height: 30px; - padding: 0; -} - -.select2-container--admin-autocomplete.select2-container--focus .select2-selection, -.select2-container--admin-autocomplete.select2-container--open .select2-selection { - border-color: var(--body-quiet-color); - min-height: 30px; -} - -.select2-container--admin-autocomplete.select2-container--focus .select2-selection.select2-selection--single, -.select2-container--admin-autocomplete.select2-container--open .select2-selection.select2-selection--single { - padding: 0; -} - -.select2-container--admin-autocomplete.select2-container--focus .select2-selection.select2-selection--multiple, -.select2-container--admin-autocomplete.select2-container--open .select2-selection.select2-selection--multiple { - padding: 0; -} - -.select2-container--admin-autocomplete .select2-selection--single { - background-color: var(--body-bg); - border: 1px solid var(--border-color); - border-radius: 4px; -} - -.select2-container--admin-autocomplete .select2-selection--single .select2-selection__rendered { - color: var(--body-fg); - line-height: 30px; -} - -.select2-container--admin-autocomplete .select2-selection--single .select2-selection__clear { - cursor: pointer; - float: right; - font-weight: bold; -} - -.select2-container--admin-autocomplete .select2-selection--single .select2-selection__placeholder { - color: var(--body-quiet-color); -} - -.select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow { - height: 26px; - position: absolute; - top: 1px; - right: 1px; - width: 20px; -} - -.select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow b { - border-color: #888 transparent transparent transparent; - border-style: solid; - border-width: 5px 4px 0 4px; - height: 0; - left: 50%; - margin-left: -4px; - margin-top: -2px; - position: absolute; - top: 50%; - width: 0; -} - -.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--single .select2-selection__clear { - float: left; -} - -.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--single .select2-selection__arrow { - left: 1px; - right: auto; -} - -.select2-container--admin-autocomplete.select2-container--disabled .select2-selection--single { - background-color: var(--darkened-bg); - cursor: default; -} - -.select2-container--admin-autocomplete.select2-container--disabled .select2-selection--single .select2-selection__clear { - display: none; -} - -.select2-container--admin-autocomplete.select2-container--open .select2-selection--single .select2-selection__arrow b { - border-color: transparent transparent #888 transparent; - border-width: 0 4px 5px 4px; -} - -.select2-container--admin-autocomplete .select2-selection--multiple { - background-color: var(--body-bg); - border: 1px solid var(--border-color); - border-radius: 4px; - cursor: text; -} - -.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__rendered { - box-sizing: border-box; - list-style: none; - margin: 0; - padding: 0 10px 5px 5px; - width: 100%; - display: flex; - flex-wrap: wrap; -} - -.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__rendered li { - list-style: none; -} - -.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__placeholder { - color: var(--body-quiet-color); - margin-top: 5px; - float: left; -} - -.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__clear { - cursor: pointer; - float: right; - font-weight: bold; - margin: 5px; - position: absolute; - right: 0; -} - -.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice { - background-color: var(--darkened-bg); - border: 1px solid var(--border-color); - border-radius: 4px; - cursor: default; - float: left; - margin-right: 5px; - margin-top: 5px; - padding: 0 5px; -} - -.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice__remove { - color: var(--body-quiet-color); - cursor: pointer; - display: inline-block; - font-weight: bold; - margin-right: 2px; -} - -.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice__remove:hover { - color: var(--body-fg); -} - -.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-search--inline { - float: right; -} - -.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__choice { - margin-left: 5px; - margin-right: auto; -} - -.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { - margin-left: 2px; - margin-right: auto; -} - -.select2-container--admin-autocomplete.select2-container--focus .select2-selection--multiple { - border: solid var(--body-quiet-color) 1px; - outline: 0; -} - -.select2-container--admin-autocomplete.select2-container--disabled .select2-selection--multiple { - background-color: var(--darkened-bg); - cursor: default; -} - -.select2-container--admin-autocomplete.select2-container--disabled .select2-selection__choice__remove { - display: none; -} - -.select2-container--admin-autocomplete.select2-container--open.select2-container--above .select2-selection--single, .select2-container--admin-autocomplete.select2-container--open.select2-container--above .select2-selection--multiple { - border-top-left-radius: 0; - border-top-right-radius: 0; -} - -.select2-container--admin-autocomplete.select2-container--open.select2-container--below .select2-selection--single, .select2-container--admin-autocomplete.select2-container--open.select2-container--below .select2-selection--multiple { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; -} - -.select2-container--admin-autocomplete .select2-search--dropdown { - background: var(--darkened-bg); -} - -.select2-container--admin-autocomplete .select2-search--dropdown .select2-search__field { - background: var(--body-bg); - color: var(--body-fg); - border: 1px solid var(--border-color); - border-radius: 4px; -} - -.select2-container--admin-autocomplete .select2-search--inline .select2-search__field { - background: transparent; - color: var(--body-fg); - border: none; - outline: 0; - box-shadow: none; - -webkit-appearance: textfield; -} - -.select2-container--admin-autocomplete .select2-results > .select2-results__options { - max-height: 200px; - overflow-y: auto; - color: var(--body-fg); - background: var(--body-bg); -} - -.select2-container--admin-autocomplete .select2-results__option[role=group] { - padding: 0; -} - -.select2-container--admin-autocomplete .select2-results__option[aria-disabled=true] { - color: var(--body-quiet-color); -} - -.select2-container--admin-autocomplete .select2-results__option[aria-selected=true] { - background-color: var(--selected-bg); - color: var(--body-fg); -} - -.select2-container--admin-autocomplete .select2-results__option .select2-results__option { - padding-left: 1em; -} - -.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__group { - padding-left: 0; -} - -.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option { - margin-left: -1em; - padding-left: 2em; -} - -.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option { - margin-left: -2em; - padding-left: 3em; -} - -.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { - margin-left: -3em; - padding-left: 4em; -} - -.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { - margin-left: -4em; - padding-left: 5em; -} - -.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { - margin-left: -5em; - padding-left: 6em; -} - -.select2-container--admin-autocomplete .select2-results__option--highlighted[aria-selected] { - background-color: var(--primary); - color: var(--primary-fg); -} - -.select2-container--admin-autocomplete .select2-results__group { - cursor: default; - display: block; - padding: 6px; -} diff --git a/OneCprogsite/static/admin/css/base.css b/OneCprogsite/static/admin/css/base.css deleted file mode 100644 index 72f4ae1..0000000 --- a/OneCprogsite/static/admin/css/base.css +++ /dev/null @@ -1,1138 +0,0 @@ -/* - DJANGO Admin styles -*/ - -/* VARIABLE DEFINITIONS */ -html[data-theme="light"], -:root { - --primary: #79aec8; - --secondary: #417690; - --accent: #f5dd5d; - --primary-fg: #fff; - - --body-fg: #333; - --body-bg: #fff; - --body-quiet-color: #666; - --body-loud-color: #000; - - --header-color: #ffc; - --header-branding-color: var(--accent); - --header-bg: var(--secondary); - --header-link-color: var(--primary-fg); - - --breadcrumbs-fg: #c4dce8; - --breadcrumbs-link-fg: var(--body-bg); - --breadcrumbs-bg: var(--primary); - - --link-fg: #417893; - --link-hover-color: #036; - --link-selected-fg: #5b80b2; - - --hairline-color: #e8e8e8; - --border-color: #ccc; - - --error-fg: #ba2121; - - --message-success-bg: #dfd; - --message-warning-bg: #ffc; - --message-error-bg: #ffefef; - - --darkened-bg: #f8f8f8; /* A bit darker than --body-bg */ - --selected-bg: #e4e4e4; /* E.g. selected table cells */ - --selected-row: #ffc; - - --button-fg: #fff; - --button-bg: var(--primary); - --button-hover-bg: #609ab6; - --default-button-bg: var(--secondary); - --default-button-hover-bg: #205067; - --close-button-bg: #747474; - --close-button-hover-bg: #333; - --delete-button-bg: #ba2121; - --delete-button-hover-bg: #a41515; - - --object-tools-fg: var(--button-fg); - --object-tools-bg: var(--close-button-bg); - --object-tools-hover-bg: var(--close-button-hover-bg); - - --font-family-primary: - -apple-system, - BlinkMacSystemFont, - "Segoe UI", - system-ui, - Roboto, - "Helvetica Neue", - Arial, - sans-serif, - "Apple Color Emoji", - "Segoe UI Emoji", - "Segoe UI Symbol", - "Noto Color Emoji"; - --font-family-monospace: - ui-monospace, - Menlo, - Monaco, - "Cascadia Mono", - "Segoe UI Mono", - "Roboto Mono", - "Oxygen Mono", - "Ubuntu Monospace", - "Source Code Pro", - "Fira Mono", - "Droid Sans Mono", - "Courier New", - monospace, - "Apple Color Emoji", - "Segoe UI Emoji", - "Segoe UI Symbol", - "Noto Color Emoji"; -} - -html, body { - height: 100%; -} - -body { - margin: 0; - padding: 0; - font-size: 0.875rem; - font-family: var(--font-family-primary); - color: var(--body-fg); - background: var(--body-bg); -} - -/* LINKS */ - -a:link, a:visited { - color: var(--link-fg); - text-decoration: none; - transition: color 0.15s, background 0.15s; -} - -a:focus, a:hover { - color: var(--link-hover-color); -} - -a:focus { - text-decoration: underline; -} - -a img { - border: none; -} - -a.section:link, a.section:visited { - color: var(--header-link-color); - text-decoration: none; -} - -a.section:focus, a.section:hover { - text-decoration: underline; -} - -/* GLOBAL DEFAULTS */ - -p, ol, ul, dl { - margin: .2em 0 .8em 0; -} - -p { - padding: 0; - line-height: 140%; -} - -h1,h2,h3,h4,h5 { - font-weight: bold; -} - -h1 { - margin: 0 0 20px; - font-weight: 300; - font-size: 1.25rem; - color: var(--body-quiet-color); -} - -h2 { - font-size: 1rem; - margin: 1em 0 .5em 0; -} - -h2.subhead { - font-weight: normal; - margin-top: 0; -} - -h3 { - font-size: 0.875rem; - margin: .8em 0 .3em 0; - color: var(--body-quiet-color); - font-weight: bold; -} - -h4 { - font-size: 0.75rem; - margin: 1em 0 .8em 0; - padding-bottom: 3px; -} - -h5 { - font-size: 0.625rem; - margin: 1.5em 0 .5em 0; - color: var(--body-quiet-color); - text-transform: uppercase; - letter-spacing: 1px; -} - -ul > li { - list-style-type: square; - padding: 1px 0; -} - -li ul { - margin-bottom: 0; -} - -li, dt, dd { - font-size: 0.8125rem; - line-height: 1.25rem; -} - -dt { - font-weight: bold; - margin-top: 4px; -} - -dd { - margin-left: 0; -} - -form { - margin: 0; - padding: 0; -} - -fieldset { - margin: 0; - min-width: 0; - padding: 0; - border: none; - border-top: 1px solid var(--hairline-color); -} - -blockquote { - font-size: 0.6875rem; - color: #777; - margin-left: 2px; - padding-left: 10px; - border-left: 5px solid #ddd; -} - -code, pre { - font-family: var(--font-family-monospace); - color: var(--body-quiet-color); - font-size: 0.75rem; - overflow-x: auto; -} - -pre.literal-block { - margin: 10px; - background: var(--darkened-bg); - padding: 6px 8px; -} - -code strong { - color: #930; -} - -hr { - clear: both; - color: var(--hairline-color); - background-color: var(--hairline-color); - height: 1px; - border: none; - margin: 0; - padding: 0; - line-height: 1px; -} - -/* TEXT STYLES & MODIFIERS */ - -.small { - font-size: 0.6875rem; -} - -.mini { - font-size: 0.625rem; -} - -.help, p.help, form p.help, div.help, form div.help, div.help li { - font-size: 0.6875rem; - color: var(--body-quiet-color); -} - -div.help ul { - margin-bottom: 0; -} - -.help-tooltip { - cursor: help; -} - -p img, h1 img, h2 img, h3 img, h4 img, td img { - vertical-align: middle; -} - -.quiet, a.quiet:link, a.quiet:visited { - color: var(--body-quiet-color); - font-weight: normal; -} - -.clear { - clear: both; -} - -.nowrap { - white-space: nowrap; -} - -.hidden { - display: none !important; -} - -/* TABLES */ - -table { - border-collapse: collapse; - border-color: var(--border-color); -} - -td, th { - font-size: 0.8125rem; - line-height: 1rem; - border-bottom: 1px solid var(--hairline-color); - vertical-align: top; - padding: 8px; -} - -th { - font-weight: 600; - text-align: left; -} - -thead th, -tfoot td { - color: var(--body-quiet-color); - padding: 5px 10px; - font-size: 0.6875rem; - background: var(--body-bg); - border: none; - border-top: 1px solid var(--hairline-color); - border-bottom: 1px solid var(--hairline-color); -} - -tfoot td { - border-bottom: none; - border-top: 1px solid var(--hairline-color); -} - -thead th.required { - color: var(--body-loud-color); -} - -tr.alt { - background: var(--darkened-bg); -} - -tr:nth-child(odd), .row-form-errors { - background: var(--body-bg); -} - -tr:nth-child(even), -tr:nth-child(even) .errorlist, -tr:nth-child(odd) + .row-form-errors, -tr:nth-child(odd) + .row-form-errors .errorlist { - background: var(--darkened-bg); -} - -/* SORTABLE TABLES */ - -thead th { - padding: 5px 10px; - line-height: normal; - text-transform: uppercase; - background: var(--darkened-bg); -} - -thead th a:link, thead th a:visited { - color: var(--body-quiet-color); -} - -thead th.sorted { - background: var(--selected-bg); -} - -thead th.sorted .text { - padding-right: 42px; -} - -table thead th .text span { - padding: 8px 10px; - display: block; -} - -table thead th .text a { - display: block; - cursor: pointer; - padding: 8px 10px; -} - -table thead th .text a:focus, table thead th .text a:hover { - background: var(--selected-bg); -} - -thead th.sorted a.sortremove { - visibility: hidden; -} - -table thead th.sorted:hover a.sortremove { - visibility: visible; -} - -table thead th.sorted .sortoptions { - display: block; - padding: 9px 5px 0 5px; - float: right; - text-align: right; -} - -table thead th.sorted .sortpriority { - font-size: .8em; - min-width: 12px; - text-align: center; - vertical-align: 3px; - margin-left: 2px; - margin-right: 2px; -} - -table thead th.sorted .sortoptions a { - position: relative; - width: 14px; - height: 14px; - display: inline-block; - background: url(../img/sorting-icons.svg) 0 0 no-repeat; - background-size: 14px auto; -} - -table thead th.sorted .sortoptions a.sortremove { - background-position: 0 0; -} - -table thead th.sorted .sortoptions a.sortremove:after { - content: '\\'; - position: absolute; - top: -6px; - left: 3px; - font-weight: 200; - font-size: 1.125rem; - color: var(--body-quiet-color); -} - -table thead th.sorted .sortoptions a.sortremove:focus:after, -table thead th.sorted .sortoptions a.sortremove:hover:after { - color: var(--link-fg); -} - -table thead th.sorted .sortoptions a.sortremove:focus, -table thead th.sorted .sortoptions a.sortremove:hover { - background-position: 0 -14px; -} - -table thead th.sorted .sortoptions a.ascending { - background-position: 0 -28px; -} - -table thead th.sorted .sortoptions a.ascending:focus, -table thead th.sorted .sortoptions a.ascending:hover { - background-position: 0 -42px; -} - -table thead th.sorted .sortoptions a.descending { - top: 1px; - background-position: 0 -56px; -} - -table thead th.sorted .sortoptions a.descending:focus, -table thead th.sorted .sortoptions a.descending:hover { - background-position: 0 -70px; -} - -/* FORM DEFAULTS */ - -input, textarea, select, .form-row p, form .button { - margin: 2px 0; - padding: 2px 3px; - vertical-align: middle; - font-family: var(--font-family-primary); - font-weight: normal; - font-size: 0.8125rem; -} -.form-row div.help { - padding: 2px 3px; -} - -textarea { - vertical-align: top; -} - -input[type=text], input[type=password], input[type=email], input[type=url], -input[type=number], input[type=tel], textarea, select, .vTextField { - border: 1px solid var(--border-color); - border-radius: 4px; - padding: 5px 6px; - margin-top: 0; - color: var(--body-fg); - background-color: var(--body-bg); -} - -input[type=text]:focus, input[type=password]:focus, input[type=email]:focus, -input[type=url]:focus, input[type=number]:focus, input[type=tel]:focus, -textarea:focus, select:focus, .vTextField:focus { - border-color: var(--body-quiet-color); -} - -select { - height: 1.875rem; -} - -select[multiple] { - /* Allow HTML size attribute to override the height in the rule above. */ - height: auto; - min-height: 150px; -} - -/* FORM BUTTONS */ - -.button, input[type=submit], input[type=button], .submit-row input, a.button { - background: var(--button-bg); - padding: 10px 15px; - border: none; - border-radius: 4px; - color: var(--button-fg); - cursor: pointer; - transition: background 0.15s; -} - -a.button { - padding: 4px 5px; -} - -.button:active, input[type=submit]:active, input[type=button]:active, -.button:focus, input[type=submit]:focus, input[type=button]:focus, -.button:hover, input[type=submit]:hover, input[type=button]:hover { - background: var(--button-hover-bg); -} - -.button[disabled], input[type=submit][disabled], input[type=button][disabled] { - opacity: 0.4; -} - -.button.default, input[type=submit].default, .submit-row input.default { - border: none; - font-weight: 400; - background: var(--default-button-bg); -} - -.button.default:active, input[type=submit].default:active, -.button.default:focus, input[type=submit].default:focus, -.button.default:hover, input[type=submit].default:hover { - background: var(--default-button-hover-bg); -} - -.button[disabled].default, -input[type=submit][disabled].default, -input[type=button][disabled].default { - opacity: 0.4; -} - - -/* MODULES */ - -.module { - border: none; - margin-bottom: 30px; - background: var(--body-bg); -} - -.module p, .module ul, .module h3, .module h4, .module dl, .module pre { - padding-left: 10px; - padding-right: 10px; -} - -.module blockquote { - margin-left: 12px; -} - -.module ul, .module ol { - margin-left: 1.5em; -} - -.module h3 { - margin-top: .6em; -} - -.module h2, .module caption, .inline-group h2 { - margin: 0; - padding: 8px; - font-weight: 400; - font-size: 0.8125rem; - text-align: left; - background: var(--primary); - color: var(--header-link-color); -} - -.module caption, -.inline-group h2 { - font-size: 0.75rem; - letter-spacing: 0.5px; - text-transform: uppercase; -} - -.module table { - border-collapse: collapse; -} - -/* MESSAGES & ERRORS */ - -ul.messagelist { - padding: 0; - margin: 0; -} - -ul.messagelist li { - display: block; - font-weight: 400; - font-size: 0.8125rem; - padding: 10px 10px 10px 65px; - margin: 0 0 10px 0; - background: var(--message-success-bg) url(../img/icon-yes.svg) 40px 12px no-repeat; - background-size: 16px auto; - color: var(--body-fg); - word-break: break-word; -} - -ul.messagelist li.warning { - background: var(--message-warning-bg) url(../img/icon-alert.svg) 40px 14px no-repeat; - background-size: 14px auto; -} - -ul.messagelist li.error { - background: var(--message-error-bg) url(../img/icon-no.svg) 40px 12px no-repeat; - background-size: 16px auto; -} - -.errornote { - font-size: 0.875rem; - font-weight: 700; - display: block; - padding: 10px 12px; - margin: 0 0 10px 0; - color: var(--error-fg); - border: 1px solid var(--error-fg); - border-radius: 4px; - background-color: var(--body-bg); - background-position: 5px 12px; - overflow-wrap: break-word; -} - -ul.errorlist { - margin: 0 0 4px; - padding: 0; - color: var(--error-fg); - background: var(--body-bg); -} - -ul.errorlist li { - font-size: 0.8125rem; - display: block; - margin-bottom: 4px; - overflow-wrap: break-word; -} - -ul.errorlist li:first-child { - margin-top: 0; -} - -ul.errorlist li a { - color: inherit; - text-decoration: underline; -} - -td ul.errorlist { - margin: 0; - padding: 0; -} - -td ul.errorlist li { - margin: 0; -} - -.form-row.errors { - margin: 0; - border: none; - border-bottom: 1px solid var(--hairline-color); - background: none; -} - -.form-row.errors ul.errorlist li { - padding-left: 0; -} - -.errors input, .errors select, .errors textarea, -td ul.errorlist + input, td ul.errorlist + select, td ul.errorlist + textarea { - border: 1px solid var(--error-fg); -} - -.description { - font-size: 0.75rem; - padding: 5px 0 0 12px; -} - -/* BREADCRUMBS */ - -div.breadcrumbs { - background: var(--breadcrumbs-bg); - padding: 10px 40px; - border: none; - color: var(--breadcrumbs-fg); - text-align: left; -} - -div.breadcrumbs a { - color: var(--breadcrumbs-link-fg); -} - -div.breadcrumbs a:focus, div.breadcrumbs a:hover { - color: var(--breadcrumbs-fg); -} - -/* ACTION ICONS */ - -.viewlink, .inlineviewlink { - padding-left: 16px; - background: url(../img/icon-viewlink.svg) 0 1px no-repeat; -} - -.addlink { - padding-left: 16px; - background: url(../img/icon-addlink.svg) 0 1px no-repeat; -} - -.changelink, .inlinechangelink { - padding-left: 16px; - background: url(../img/icon-changelink.svg) 0 1px no-repeat; -} - -.deletelink { - padding-left: 16px; - background: url(../img/icon-deletelink.svg) 0 1px no-repeat; -} - -a.deletelink:link, a.deletelink:visited { - color: #CC3434; /* XXX Probably unused? */ -} - -a.deletelink:focus, a.deletelink:hover { - color: #993333; /* XXX Probably unused? */ - text-decoration: none; -} - -/* OBJECT TOOLS */ - -.object-tools { - font-size: 0.625rem; - font-weight: bold; - padding-left: 0; - float: right; - position: relative; - margin-top: -48px; -} - -.object-tools li { - display: block; - float: left; - margin-left: 5px; - height: 1rem; -} - -.object-tools a { - border-radius: 15px; -} - -.object-tools a:link, .object-tools a:visited { - display: block; - float: left; - padding: 3px 12px; - background: var(--object-tools-bg); - color: var(--object-tools-fg); - font-weight: 400; - font-size: 0.6875rem; - text-transform: uppercase; - letter-spacing: 0.5px; -} - -.object-tools a:focus, .object-tools a:hover { - background-color: var(--object-tools-hover-bg); -} - -.object-tools a:focus{ - text-decoration: none; -} - -.object-tools a.viewsitelink, .object-tools a.addlink { - background-repeat: no-repeat; - background-position: right 7px center; - padding-right: 26px; -} - -.object-tools a.viewsitelink { - background-image: url(../img/tooltag-arrowright.svg); -} - -.object-tools a.addlink { - background-image: url(../img/tooltag-add.svg); -} - -/* OBJECT HISTORY */ - -#change-history table { - width: 100%; -} - -#change-history table tbody th { - width: 16em; -} - -#change-history .paginator { - color: var(--body-quiet-color); - border-bottom: 1px solid var(--hairline-color); - background: var(--body-bg); - overflow: hidden; -} - -/* PAGE STRUCTURE */ - -#container { - position: relative; - width: 100%; - min-width: 980px; - padding: 0; - display: flex; - flex-direction: column; - height: 100%; -} - -#container > div { - flex-shrink: 0; -} - -#container > .main { - display: flex; - flex: 1 0 auto; -} - -.main > .content { - flex: 1 0; - max-width: 100%; -} - -.skip-to-content-link { - position: absolute; - top: -999px; - margin: 5px; - padding: 5px; - background: var(--body-bg); - z-index: 1; -} - -.skip-to-content-link:focus { - left: 0px; - top: 0px; -} - -#content { - padding: 20px 40px; -} - -.dashboard #content { - width: 600px; -} - -#content-main { - float: left; - width: 100%; -} - -#content-related { - float: right; - width: 260px; - position: relative; - margin-right: -300px; -} - -#footer { - clear: both; - padding: 10px; -} - -/* COLUMN TYPES */ - -.colMS { - margin-right: 300px; -} - -.colSM { - margin-left: 300px; -} - -.colSM #content-related { - float: left; - margin-right: 0; - margin-left: -300px; -} - -.colSM #content-main { - float: right; -} - -.popup .colM { - width: auto; -} - -/* HEADER */ - -#header { - width: auto; - height: auto; - display: flex; - justify-content: space-between; - align-items: center; - padding: 10px 40px; - background: var(--header-bg); - color: var(--header-color); - overflow: hidden; -} - -#header a:link, #header a:visited, #logout-form button { - color: var(--header-link-color); -} - -#header a:focus , #header a:hover { - text-decoration: underline; -} - -#branding { - display: flex; -} - -#branding h1 { - padding: 0; - margin: 0; - margin-inline-end: 20px; - font-weight: 300; - font-size: 1.5rem; - color: var(--header-branding-color); -} - -#branding h1 a:link, #branding h1 a:visited { - color: var(--accent); -} - -#branding h2 { - padding: 0 10px; - font-size: 0.875rem; - margin: -8px 0 8px 0; - font-weight: normal; - color: var(--header-color); -} - -#branding a:hover { - text-decoration: none; -} - -#logout-form { - display: inline; -} - -#logout-form button { - background: none; - border: 0; - cursor: pointer; - font-family: var(--font-family-primary); -} - -#user-tools { - float: right; - margin: 0 0 0 20px; - text-align: right; -} - -#user-tools, #logout-form button{ - padding: 0; - font-weight: 300; - font-size: 0.6875rem; - letter-spacing: 0.5px; - text-transform: uppercase; -} - -#user-tools a, #logout-form button { - border-bottom: 1px solid rgba(255, 255, 255, 0.25); -} - -#user-tools a:focus, #user-tools a:hover, -#logout-form button:active, #logout-form button:hover { - text-decoration: none; - border-bottom: 0; -} - -#logout-form button:active, #logout-form button:hover { - margin-bottom: 1px; -} - -/* SIDEBAR */ - -#content-related { - background: var(--darkened-bg); -} - -#content-related .module { - background: none; -} - -#content-related h3 { - color: var(--body-quiet-color); - padding: 0 16px; - margin: 0 0 16px; -} - -#content-related h4 { - font-size: 0.8125rem; -} - -#content-related p { - padding-left: 16px; - padding-right: 16px; -} - -#content-related .actionlist { - padding: 0; - margin: 16px; -} - -#content-related .actionlist li { - line-height: 1.2; - margin-bottom: 10px; - padding-left: 18px; -} - -#content-related .module h2 { - background: none; - padding: 16px; - margin-bottom: 16px; - border-bottom: 1px solid var(--hairline-color); - font-size: 1.125rem; - color: var(--body-fg); -} - -.delete-confirmation form input[type="submit"] { - background: var(--delete-button-bg); - border-radius: 4px; - padding: 10px 15px; - color: var(--button-fg); -} - -.delete-confirmation form input[type="submit"]:active, -.delete-confirmation form input[type="submit"]:focus, -.delete-confirmation form input[type="submit"]:hover { - background: var(--delete-button-hover-bg); -} - -.delete-confirmation form .cancel-link { - display: inline-block; - vertical-align: middle; - height: 0.9375rem; - line-height: 0.9375rem; - border-radius: 4px; - padding: 10px 15px; - color: var(--button-fg); - background: var(--close-button-bg); - margin: 0 0 0 10px; -} - -.delete-confirmation form .cancel-link:active, -.delete-confirmation form .cancel-link:focus, -.delete-confirmation form .cancel-link:hover { - background: var(--close-button-hover-bg); -} - -/* POPUP */ -.popup #content { - padding: 20px; -} - -.popup #container { - min-width: 0; -} - -.popup #header { - padding: 10px 20px; -} - -/* PAGINATOR */ - -.paginator { - font-size: 0.8125rem; - padding-top: 10px; - padding-bottom: 10px; - line-height: 22px; - margin: 0; - border-top: 1px solid var(--hairline-color); - width: 100%; -} - -.paginator a:link, .paginator a:visited { - padding: 2px 6px; - background: var(--button-bg); - text-decoration: none; - color: var(--button-fg); -} - -.paginator a.showall { - border: none; - background: none; - color: var(--link-fg); -} - -.paginator a.showall:focus, .paginator a.showall:hover { - background: none; - color: var(--link-hover-color); -} - -.paginator .end { - margin-right: 6px; -} - -.paginator .this-page { - padding: 2px 6px; - font-weight: bold; - font-size: 0.8125rem; - vertical-align: top; -} - -.paginator a:focus, .paginator a:hover { - color: white; - background: var(--link-hover-color); -} - -.base-svgs { - display: none; -} diff --git a/OneCprogsite/static/admin/css/changelists.css b/OneCprogsite/static/admin/css/changelists.css deleted file mode 100644 index a754513..0000000 --- a/OneCprogsite/static/admin/css/changelists.css +++ /dev/null @@ -1,328 +0,0 @@ -/* CHANGELISTS */ - -#changelist { - display: flex; - align-items: flex-start; - justify-content: space-between; -} - -#changelist .changelist-form-container { - flex: 1 1 auto; - min-width: 0; -} - -#changelist table { - width: 100%; -} - -.change-list .hiddenfields { display:none; } - -.change-list .filtered table { - border-right: none; -} - -.change-list .filtered { - min-height: 400px; -} - -.change-list .filtered .results, .change-list .filtered .paginator, -.filtered #toolbar, .filtered div.xfull { - width: auto; -} - -.change-list .filtered table tbody th { - padding-right: 1em; -} - -#changelist-form .results { - overflow-x: auto; - width: 100%; -} - -#changelist .toplinks { - border-bottom: 1px solid var(--hairline-color); -} - -#changelist .paginator { - color: var(--body-quiet-color); - border-bottom: 1px solid var(--hairline-color); - background: var(--body-bg); - overflow: hidden; -} - -/* CHANGELIST TABLES */ - -#changelist table thead th { - padding: 0; - white-space: nowrap; - vertical-align: middle; -} - -#changelist table thead th.action-checkbox-column { - width: 1.5em; - text-align: center; -} - -#changelist table tbody td.action-checkbox { - text-align: center; -} - -#changelist table tfoot { - color: var(--body-quiet-color); -} - -/* TOOLBAR */ - -#toolbar { - padding: 8px 10px; - margin-bottom: 15px; - border-top: 1px solid var(--hairline-color); - border-bottom: 1px solid var(--hairline-color); - background: var(--darkened-bg); - color: var(--body-quiet-color); -} - -#toolbar form input { - border-radius: 4px; - font-size: 0.875rem; - padding: 5px; - color: var(--body-fg); -} - -#toolbar #searchbar { - height: 1.1875rem; - border: 1px solid var(--border-color); - padding: 2px 5px; - margin: 0; - vertical-align: top; - font-size: 0.8125rem; - max-width: 100%; -} - -#toolbar #searchbar:focus { - border-color: var(--body-quiet-color); -} - -#toolbar form input[type="submit"] { - border: 1px solid var(--border-color); - font-size: 0.8125rem; - padding: 4px 8px; - margin: 0; - vertical-align: middle; - background: var(--body-bg); - box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset; - cursor: pointer; - color: var(--body-fg); -} - -#toolbar form input[type="submit"]:focus, -#toolbar form input[type="submit"]:hover { - border-color: var(--body-quiet-color); -} - -#changelist-search img { - vertical-align: middle; - margin-right: 4px; -} - -#changelist-search .help { - word-break: break-word; -} - -/* FILTER COLUMN */ - -#changelist-filter { - flex: 0 0 240px; - order: 1; - background: var(--darkened-bg); - border-left: none; - margin: 0 0 0 30px; -} - -#changelist-filter h2 { - font-size: 0.875rem; - text-transform: uppercase; - letter-spacing: 0.5px; - padding: 5px 15px; - margin-bottom: 12px; - border-bottom: none; -} - -#changelist-filter h3, -#changelist-filter details summary { - font-weight: 400; - padding: 0 15px; - margin-bottom: 10px; -} - -#changelist-filter details summary > * { - display: inline; -} - -#changelist-filter details > summary { - list-style-type: none; -} - -#changelist-filter details > summary::-webkit-details-marker { - display: none; -} - -#changelist-filter details > summary::before { - content: '→'; - font-weight: bold; - color: var(--link-hover-color); -} - -#changelist-filter details[open] > summary::before { - content: '↓'; -} - -#changelist-filter ul { - margin: 5px 0; - padding: 0 15px 15px; - border-bottom: 1px solid var(--hairline-color); -} - -#changelist-filter ul:last-child { - border-bottom: none; -} - -#changelist-filter li { - list-style-type: none; - margin-left: 0; - padding-left: 0; -} - -#changelist-filter a { - display: block; - color: var(--body-quiet-color); - word-break: break-word; -} - -#changelist-filter li.selected { - border-left: 5px solid var(--hairline-color); - padding-left: 10px; - margin-left: -15px; -} - -#changelist-filter li.selected a { - color: var(--link-selected-fg); -} - -#changelist-filter a:focus, #changelist-filter a:hover, -#changelist-filter li.selected a:focus, -#changelist-filter li.selected a:hover { - color: var(--link-hover-color); -} - -#changelist-filter #changelist-filter-clear a { - font-size: 0.8125rem; - padding-bottom: 10px; - border-bottom: 1px solid var(--hairline-color); -} - -/* DATE DRILLDOWN */ - -.change-list .toplinks { - display: flex; - padding-bottom: 5px; - flex-wrap: wrap; - gap: 3px 17px; - font-weight: bold; -} - -.change-list .toplinks a { - font-size: 0.8125rem; -} - -.change-list .toplinks .date-back { - color: var(--body-quiet-color); -} - -.change-list .toplinks .date-back:focus, -.change-list .toplinks .date-back:hover { - color: var(--link-hover-color); -} - -/* ACTIONS */ - -.filtered .actions { - border-right: none; -} - -#changelist table input { - margin: 0; - vertical-align: baseline; -} - -/* Once the :has() pseudo-class is supported by all browsers, the tr.selected - selector and the JS adding the class can be removed. */ -#changelist tbody tr.selected { - background-color: var(--selected-row); -} - -#changelist tbody tr:has(.action-select:checked) { - background-color: var(--selected-row); -} - -#changelist .actions { - padding: 10px; - background: var(--body-bg); - border-top: none; - border-bottom: none; - line-height: 1.5rem; - color: var(--body-quiet-color); - width: 100%; -} - -#changelist .actions span.all, -#changelist .actions span.action-counter, -#changelist .actions span.clear, -#changelist .actions span.question { - font-size: 0.8125rem; - margin: 0 0.5em; -} - -#changelist .actions:last-child { - border-bottom: none; -} - -#changelist .actions select { - vertical-align: top; - height: 1.5rem; - color: var(--body-fg); - border: 1px solid var(--border-color); - border-radius: 4px; - font-size: 0.875rem; - padding: 0 0 0 4px; - margin: 0; - margin-left: 10px; -} - -#changelist .actions select:focus { - border-color: var(--body-quiet-color); -} - -#changelist .actions label { - display: inline-block; - vertical-align: middle; - font-size: 0.8125rem; -} - -#changelist .actions .button { - font-size: 0.8125rem; - border: 1px solid var(--border-color); - border-radius: 4px; - background: var(--body-bg); - box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset; - cursor: pointer; - height: 1.5rem; - line-height: 1; - padding: 4px 8px; - margin: 0; - color: var(--body-fg); -} - -#changelist .actions .button:focus, #changelist .actions .button:hover { - border-color: var(--body-quiet-color); -} diff --git a/OneCprogsite/static/admin/css/dark_mode.css b/OneCprogsite/static/admin/css/dark_mode.css deleted file mode 100644 index 6d08233..0000000 --- a/OneCprogsite/static/admin/css/dark_mode.css +++ /dev/null @@ -1,137 +0,0 @@ -@media (prefers-color-scheme: dark) { - :root { - --primary: #264b5d; - --primary-fg: #f7f7f7; - - --body-fg: #eeeeee; - --body-bg: #121212; - --body-quiet-color: #e0e0e0; - --body-loud-color: #ffffff; - - --breadcrumbs-link-fg: #e0e0e0; - --breadcrumbs-bg: var(--primary); - - --link-fg: #81d4fa; - --link-hover-color: #4ac1f7; - --link-selected-fg: #6f94c6; - - --hairline-color: #272727; - --border-color: #353535; - - --error-fg: #e35f5f; - --message-success-bg: #006b1b; - --message-warning-bg: #583305; - --message-error-bg: #570808; - - --darkened-bg: #212121; - --selected-bg: #1b1b1b; - --selected-row: #00363a; - - --close-button-bg: #333333; - --close-button-hover-bg: #666666; - } - } - - -html[data-theme="dark"] { - --primary: #264b5d; - --primary-fg: #f7f7f7; - - --body-fg: #eeeeee; - --body-bg: #121212; - --body-quiet-color: #e0e0e0; - --body-loud-color: #ffffff; - - --breadcrumbs-link-fg: #e0e0e0; - --breadcrumbs-bg: var(--primary); - - --link-fg: #81d4fa; - --link-hover-color: #4ac1f7; - --link-selected-fg: #6f94c6; - - --hairline-color: #272727; - --border-color: #353535; - - --error-fg: #e35f5f; - --message-success-bg: #006b1b; - --message-warning-bg: #583305; - --message-error-bg: #570808; - - --darkened-bg: #212121; - --selected-bg: #1b1b1b; - --selected-row: #00363a; - - --close-button-bg: #333333; - --close-button-hover-bg: #666666; -} - -/* THEME SWITCH */ -.theme-toggle { - cursor: pointer; - border: none; - padding: 0; - background: transparent; - vertical-align: middle; - margin-inline-start: 5px; - margin-top: -1px; -} - -.theme-toggle svg { - vertical-align: middle; - height: 1rem; - width: 1rem; - display: none; -} - -/* -Fully hide screen reader text so we only show the one matching the current -theme. -*/ -.theme-toggle .visually-hidden { - display: none; -} - -html[data-theme="auto"] .theme-toggle .theme-label-when-auto { - display: block; -} - -html[data-theme="dark"] .theme-toggle .theme-label-when-dark { - display: block; -} - -html[data-theme="light"] .theme-toggle .theme-label-when-light { - display: block; -} - -/* ICONS */ -.theme-toggle svg.theme-icon-when-auto, -.theme-toggle svg.theme-icon-when-dark, -.theme-toggle svg.theme-icon-when-light { - fill: var(--header-link-color); - color: var(--header-bg); -} - -html[data-theme="auto"] .theme-toggle svg.theme-icon-when-auto { - display: block; -} - -html[data-theme="dark"] .theme-toggle svg.theme-icon-when-dark { - display: block; -} - -html[data-theme="light"] .theme-toggle svg.theme-icon-when-light { - display: block; -} - -.visually-hidden { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - overflow: hidden; - clip: rect(0,0,0,0); - white-space: nowrap; - border: 0; - color: var(--body-fg); - background-color: var(--body-bg); -} diff --git a/OneCprogsite/static/admin/css/dashboard.css b/OneCprogsite/static/admin/css/dashboard.css deleted file mode 100644 index 242b81a..0000000 --- a/OneCprogsite/static/admin/css/dashboard.css +++ /dev/null @@ -1,29 +0,0 @@ -/* DASHBOARD */ -.dashboard td, .dashboard th { - word-break: break-word; -} - -.dashboard .module table th { - width: 100%; -} - -.dashboard .module table td { - white-space: nowrap; -} - -.dashboard .module table td a { - display: block; - padding-right: .6em; -} - -/* RECENT ACTIONS MODULE */ - -.module ul.actionlist { - margin-left: 0; -} - -ul.actionlist li { - list-style-type: none; - overflow: hidden; - text-overflow: ellipsis; -} diff --git a/OneCprogsite/static/admin/css/forms.css b/OneCprogsite/static/admin/css/forms.css deleted file mode 100644 index e45abe1..0000000 --- a/OneCprogsite/static/admin/css/forms.css +++ /dev/null @@ -1,530 +0,0 @@ -@import url('widgets.css'); - -/* FORM ROWS */ - -.form-row { - overflow: hidden; - padding: 10px; - font-size: 0.8125rem; - border-bottom: 1px solid var(--hairline-color); -} - -.form-row img, .form-row input { - vertical-align: middle; -} - -.form-row label input[type="checkbox"] { - margin-top: 0; - vertical-align: 0; -} - -form .form-row p { - padding-left: 0; -} - -.flex-container { - display: flex; - flex-wrap: wrap; -} - -.form-multiline > div { - padding-bottom: 10px; -} - -/* FORM LABELS */ - -label { - font-weight: normal; - color: var(--body-quiet-color); - font-size: 0.8125rem; -} - -.required label, label.required { - font-weight: bold; - color: var(--body-fg); -} - -/* RADIO BUTTONS */ - -form div.radiolist div { - padding-right: 7px; -} - -form div.radiolist.inline div { - display: inline-block; -} - -form div.radiolist label { - width: auto; -} - -form div.radiolist input[type="radio"] { - margin: -2px 4px 0 0; - padding: 0; -} - -form ul.inline { - margin-left: 0; - padding: 0; -} - -form ul.inline li { - float: left; - padding-right: 7px; -} - -/* ALIGNED FIELDSETS */ - -.aligned label { - display: block; - padding: 4px 10px 0 0; - width: 160px; - word-wrap: break-word; - line-height: 1; -} - -.aligned label:not(.vCheckboxLabel):after { - content: ''; - display: inline-block; - vertical-align: middle; - height: 1.625rem; -} - -.aligned label + p, .aligned .checkbox-row + div.help, .aligned label + div.readonly { - padding: 6px 0; - margin-top: 0; - margin-bottom: 0; - margin-left: 0; - overflow-wrap: break-word; -} - -.aligned ul label { - display: inline; - float: none; - width: auto; -} - -.aligned .form-row input { - margin-bottom: 0; -} - -.colMS .aligned .vLargeTextField, .colMS .aligned .vXMLLargeTextField { - width: 350px; -} - -form .aligned ul { - margin-left: 160px; - padding-left: 10px; -} - -form .aligned div.radiolist { - display: inline-block; - margin: 0; - padding: 0; -} - -form .aligned p.help, -form .aligned div.help { - margin-top: 0; - margin-left: 160px; - padding-left: 10px; -} - -form .aligned p.date div.help.timezonewarning, -form .aligned p.datetime div.help.timezonewarning, -form .aligned p.time div.help.timezonewarning { - margin-left: 0; - padding-left: 0; - font-weight: normal; -} - -form .aligned p.help:last-child, -form .aligned div.help:last-child { - margin-bottom: 0; - padding-bottom: 0; -} - -form .aligned input + p.help, -form .aligned textarea + p.help, -form .aligned select + p.help, -form .aligned input + div.help, -form .aligned textarea + div.help, -form .aligned select + div.help { - margin-left: 160px; - padding-left: 10px; -} - -form .aligned ul li { - list-style: none; -} - -form .aligned table p { - margin-left: 0; - padding-left: 0; -} - -.aligned .vCheckboxLabel { - float: none; - width: auto; - display: inline-block; - vertical-align: -3px; - padding: 0 0 5px 5px; -} - -.aligned .vCheckboxLabel + p.help, -.aligned .vCheckboxLabel + div.help { - margin-top: -4px; -} - -.colM .aligned .vLargeTextField, .colM .aligned .vXMLLargeTextField { - width: 610px; -} - -fieldset .fieldBox { - margin-right: 20px; -} - -/* WIDE FIELDSETS */ - -.wide label { - width: 200px; -} - -form .wide p, -form .wide ul.errorlist, -form .wide input + p.help, -form .wide input + div.help { - margin-left: 200px; -} - -form .wide p.help, -form .wide div.help { - padding-left: 50px; -} - -form div.help ul { - padding-left: 0; - margin-left: 0; -} - -.colM fieldset.wide .vLargeTextField, .colM fieldset.wide .vXMLLargeTextField { - width: 450px; -} - -/* COLLAPSED FIELDSETS */ - -fieldset.collapsed * { - display: none; -} - -fieldset.collapsed h2, fieldset.collapsed { - display: block; -} - -fieldset.collapsed { - border: 1px solid var(--hairline-color); - border-radius: 4px; - overflow: hidden; -} - -fieldset.collapsed h2 { - background: var(--darkened-bg); - color: var(--body-quiet-color); -} - -fieldset .collapse-toggle { - color: var(--header-link-color); -} - -fieldset.collapsed .collapse-toggle { - background: transparent; - display: inline; - color: var(--link-fg); -} - -/* MONOSPACE TEXTAREAS */ - -fieldset.monospace textarea { - font-family: var(--font-family-monospace); -} - -/* SUBMIT ROW */ - -.submit-row { - padding: 12px 14px 12px; - margin: 0 0 20px; - background: var(--darkened-bg); - border: 1px solid var(--hairline-color); - border-radius: 4px; - overflow: hidden; - display: flex; - gap: 10px; - flex-wrap: wrap; -} - -body.popup .submit-row { - overflow: auto; -} - -.submit-row input { - height: 2.1875rem; - line-height: 0.9375rem; -} - -.submit-row input, .submit-row a { - margin: 0; -} - -.submit-row input.default { - text-transform: uppercase; -} - -.submit-row a.deletelink { - margin-left: auto; -} - -.submit-row a.deletelink { - display: block; - background: var(--delete-button-bg); - border-radius: 4px; - padding: 0.625rem 0.9375rem; - height: 0.9375rem; - line-height: 0.9375rem; - color: var(--button-fg); -} - -.submit-row a.closelink { - display: inline-block; - background: var(--close-button-bg); - border-radius: 4px; - padding: 10px 15px; - height: 0.9375rem; - line-height: 0.9375rem; - color: var(--button-fg); -} - -.submit-row a.deletelink:focus, -.submit-row a.deletelink:hover, -.submit-row a.deletelink:active { - background: var(--delete-button-hover-bg); - text-decoration: none; -} - -.submit-row a.closelink:focus, -.submit-row a.closelink:hover, -.submit-row a.closelink:active { - background: var(--close-button-hover-bg); - text-decoration: none; -} - -/* CUSTOM FORM FIELDS */ - -.vSelectMultipleField { - vertical-align: top; -} - -.vCheckboxField { - border: none; -} - -.vDateField, .vTimeField { - margin-right: 2px; - margin-bottom: 4px; -} - -.vDateField { - min-width: 6.85em; -} - -.vTimeField { - min-width: 4.7em; -} - -.vURLField { - width: 30em; -} - -.vLargeTextField, .vXMLLargeTextField { - width: 48em; -} - -.flatpages-flatpage #id_content { - height: 40.2em; -} - -.module table .vPositiveSmallIntegerField { - width: 2.2em; -} - -.vIntegerField { - width: 5em; -} - -.vBigIntegerField { - width: 10em; -} - -.vForeignKeyRawIdAdminField { - width: 5em; -} - -.vTextField, .vUUIDField { - width: 20em; -} - -/* INLINES */ - -.inline-group { - padding: 0; - margin: 0 0 30px; -} - -.inline-group thead th { - padding: 8px 10px; -} - -.inline-group .aligned label { - width: 160px; -} - -.inline-related { - position: relative; -} - -.inline-related h3 { - margin: 0; - color: var(--body-quiet-color); - padding: 5px; - font-size: 0.8125rem; - background: var(--darkened-bg); - border-top: 1px solid var(--hairline-color); - border-bottom: 1px solid var(--hairline-color); -} - -.inline-related h3 span.delete { - float: right; -} - -.inline-related h3 span.delete label { - margin-left: 2px; - font-size: 0.6875rem; -} - -.inline-related fieldset { - margin: 0; - background: var(--body-bg); - border: none; - width: 100%; -} - -.inline-related fieldset.module h3 { - margin: 0; - padding: 2px 5px 3px 5px; - font-size: 0.6875rem; - text-align: left; - font-weight: bold; - background: #bcd; - color: var(--body-bg); -} - -.inline-group .tabular fieldset.module { - border: none; -} - -.inline-related.tabular fieldset.module table { - width: 100%; - overflow-x: scroll; -} - -.last-related fieldset { - border: none; -} - -.inline-group .tabular tr.has_original td { - padding-top: 2em; -} - -.inline-group .tabular tr td.original { - padding: 2px 0 0 0; - width: 0; - _position: relative; -} - -.inline-group .tabular th.original { - width: 0px; - padding: 0; -} - -.inline-group .tabular td.original p { - position: absolute; - left: 0; - height: 1.1em; - padding: 2px 9px; - overflow: hidden; - font-size: 0.5625rem; - font-weight: bold; - color: var(--body-quiet-color); - _width: 700px; -} - -.inline-group ul.tools { - padding: 0; - margin: 0; - list-style: none; -} - -.inline-group ul.tools li { - display: inline; - padding: 0 5px; -} - -.inline-group div.add-row, -.inline-group .tabular tr.add-row td { - color: var(--body-quiet-color); - background: var(--darkened-bg); - padding: 8px 10px; - border-bottom: 1px solid var(--hairline-color); -} - -.inline-group .tabular tr.add-row td { - padding: 8px 10px; - border-bottom: 1px solid var(--hairline-color); -} - -.inline-group ul.tools a.add, -.inline-group div.add-row a, -.inline-group .tabular tr.add-row td a { - background: url(../img/icon-addlink.svg) 0 1px no-repeat; - padding-left: 16px; - font-size: 0.75rem; -} - -.empty-form { - display: none; -} - -/* RELATED FIELD ADD ONE / LOOKUP */ - -.related-lookup { - margin-left: 5px; - display: inline-block; - vertical-align: middle; - background-repeat: no-repeat; - background-size: 14px; -} - -.related-lookup { - width: 1rem; - height: 1rem; - background-image: url(../img/search.svg); -} - -form .related-widget-wrapper ul { - display: inline-block; - margin-left: 0; - padding-left: 0; -} - -.clearable-file-input input { - margin-top: 0; -} diff --git a/OneCprogsite/static/admin/css/login.css b/OneCprogsite/static/admin/css/login.css deleted file mode 100644 index 389772f..0000000 --- a/OneCprogsite/static/admin/css/login.css +++ /dev/null @@ -1,61 +0,0 @@ -/* LOGIN FORM */ - -.login { - background: var(--darkened-bg); - height: auto; -} - -.login #header { - height: auto; - padding: 15px 16px; - justify-content: center; -} - -.login #header h1 { - font-size: 1.125rem; - margin: 0; -} - -.login #header h1 a { - color: var(--header-link-color); -} - -.login #content { - padding: 20px 20px 0; -} - -.login #container { - background: var(--body-bg); - border: 1px solid var(--hairline-color); - border-radius: 4px; - overflow: hidden; - width: 28em; - min-width: 300px; - margin: 100px auto; - height: auto; -} - -.login .form-row { - padding: 4px 0; -} - -.login .form-row label { - display: block; - line-height: 2em; -} - -.login .form-row #id_username, .login .form-row #id_password { - padding: 8px; - width: 100%; - box-sizing: border-box; -} - -.login .submit-row { - padding: 1em 0 0 0; - margin: 0; - text-align: center; -} - -.login .password-reset-link { - text-align: center; -} diff --git a/OneCprogsite/static/admin/css/nav_sidebar.css b/OneCprogsite/static/admin/css/nav_sidebar.css deleted file mode 100644 index f76e6ce..0000000 --- a/OneCprogsite/static/admin/css/nav_sidebar.css +++ /dev/null @@ -1,144 +0,0 @@ -.sticky { - position: sticky; - top: 0; - max-height: 100vh; -} - -.toggle-nav-sidebar { - z-index: 20; - left: 0; - display: flex; - align-items: center; - justify-content: center; - flex: 0 0 23px; - width: 23px; - border: 0; - border-right: 1px solid var(--hairline-color); - background-color: var(--body-bg); - cursor: pointer; - font-size: 1.25rem; - color: var(--link-fg); - padding: 0; -} - -[dir="rtl"] .toggle-nav-sidebar { - border-left: 1px solid var(--hairline-color); - border-right: 0; -} - -.toggle-nav-sidebar:hover, -.toggle-nav-sidebar:focus { - background-color: var(--darkened-bg); -} - -#nav-sidebar { - z-index: 15; - flex: 0 0 275px; - left: -276px; - margin-left: -276px; - border-top: 1px solid transparent; - border-right: 1px solid var(--hairline-color); - background-color: var(--body-bg); - overflow: auto; -} - -[dir="rtl"] #nav-sidebar { - border-left: 1px solid var(--hairline-color); - border-right: 0; - left: 0; - margin-left: 0; - right: -276px; - margin-right: -276px; -} - -.toggle-nav-sidebar::before { - content: '\00BB'; -} - -.main.shifted .toggle-nav-sidebar::before { - content: '\00AB'; -} - -.main > #nav-sidebar { - visibility: hidden; -} - -.main.shifted > #nav-sidebar { - margin-left: 0; - visibility: visible; -} - -[dir="rtl"] .main.shifted > #nav-sidebar { - margin-right: 0; -} - -#nav-sidebar .module th { - width: 100%; - overflow-wrap: anywhere; -} - -#nav-sidebar .module th, -#nav-sidebar .module caption { - padding-left: 16px; -} - -#nav-sidebar .module td { - white-space: nowrap; -} - -[dir="rtl"] #nav-sidebar .module th, -[dir="rtl"] #nav-sidebar .module caption { - padding-left: 8px; - padding-right: 16px; -} - -#nav-sidebar .current-app .section:link, -#nav-sidebar .current-app .section:visited { - color: var(--header-color); - font-weight: bold; -} - -#nav-sidebar .current-model { - background: var(--selected-row); -} - -.main > #nav-sidebar + .content { - max-width: calc(100% - 23px); -} - -.main.shifted > #nav-sidebar + .content { - max-width: calc(100% - 299px); -} - -@media (max-width: 767px) { - #nav-sidebar, #toggle-nav-sidebar { - display: none; - } - - .main > #nav-sidebar + .content, - .main.shifted > #nav-sidebar + .content { - max-width: 100%; - } -} - -#nav-filter { - width: 100%; - box-sizing: border-box; - padding: 2px 5px; - margin: 5px 0; - border: 1px solid var(--border-color); - background-color: var(--darkened-bg); - color: var(--body-fg); -} - -#nav-filter:focus { - border-color: var(--body-quiet-color); -} - -#nav-filter.no-results { - background: var(--message-error-bg); -} - -#nav-sidebar table { - width: 100%; -} diff --git a/OneCprogsite/static/admin/css/responsive.css b/OneCprogsite/static/admin/css/responsive.css deleted file mode 100644 index 9ce4f67..0000000 --- a/OneCprogsite/static/admin/css/responsive.css +++ /dev/null @@ -1,998 +0,0 @@ -/* Tablets */ - -input[type="submit"], button { - -webkit-appearance: none; - appearance: none; -} - -@media (max-width: 1024px) { - /* Basic */ - - html { - -webkit-text-size-adjust: 100%; - } - - td, th { - padding: 10px; - font-size: 0.875rem; - } - - .small { - font-size: 0.75rem; - } - - /* Layout */ - - #container { - min-width: 0; - } - - #content { - padding: 15px 20px 20px; - } - - div.breadcrumbs { - padding: 10px 30px; - } - - /* Header */ - - #header { - flex-direction: column; - padding: 15px 30px; - justify-content: flex-start; - } - - #branding h1 { - margin: 0 0 8px; - line-height: 1.2; - } - - #user-tools { - margin: 0; - font-weight: 400; - line-height: 1.85; - text-align: left; - } - - #user-tools a { - display: inline-block; - line-height: 1.4; - } - - /* Dashboard */ - - .dashboard #content { - width: auto; - } - - #content-related { - margin-right: -290px; - } - - .colSM #content-related { - margin-left: -290px; - } - - .colMS { - margin-right: 290px; - } - - .colSM { - margin-left: 290px; - } - - .dashboard .module table td a { - padding-right: 0; - } - - td .changelink, td .addlink { - font-size: 0.8125rem; - } - - /* Changelist */ - - #toolbar { - border: none; - padding: 15px; - } - - #changelist-search > div { - display: flex; - flex-wrap: nowrap; - max-width: 480px; - } - - #changelist-search label { - line-height: 1.375rem; - } - - #toolbar form #searchbar { - flex: 1 0 auto; - width: 0; - height: 1.375rem; - margin: 0 10px 0 6px; - } - - #toolbar form input[type=submit] { - flex: 0 1 auto; - } - - #changelist-search .quiet { - width: 0; - flex: 1 0 auto; - margin: 5px 0 0 25px; - } - - #changelist .actions { - display: flex; - flex-wrap: wrap; - padding: 15px 0; - } - - #changelist .actions label { - display: flex; - } - - #changelist .actions select { - background: var(--body-bg); - } - - #changelist .actions .button { - min-width: 48px; - margin: 0 10px; - } - - #changelist .actions span.all, - #changelist .actions span.clear, - #changelist .actions span.question, - #changelist .actions span.action-counter { - font-size: 0.6875rem; - margin: 0 10px 0 0; - } - - #changelist-filter { - flex-basis: 200px; - } - - .change-list .filtered .results, - .change-list .filtered .paginator, - .filtered #toolbar, - .filtered .actions, - - #changelist .paginator { - border-top-color: var(--hairline-color); /* XXX Is this used at all? */ - } - - #changelist .results + .paginator { - border-top: none; - } - - /* Forms */ - - label { - font-size: 0.875rem; - } - - .form-row input[type=text], - .form-row input[type=password], - .form-row input[type=email], - .form-row input[type=url], - .form-row input[type=tel], - .form-row input[type=number], - .form-row textarea, - .form-row select, - .form-row .vTextField { - box-sizing: border-box; - margin: 0; - padding: 6px 8px; - min-height: 2.25rem; - font-size: 0.875rem; - } - - .form-row select { - height: 2.25rem; - } - - .form-row select[multiple] { - height: auto; - min-height: 0; - } - - fieldset .fieldBox + .fieldBox { - margin-top: 10px; - padding-top: 10px; - border-top: 1px solid var(--hairline-color); - } - - textarea { - max-width: 100%; - max-height: 120px; - } - - .aligned label { - padding-top: 6px; - } - - .aligned .related-lookup, - .aligned .datetimeshortcuts, - .aligned .related-lookup + strong { - align-self: center; - margin-left: 15px; - } - - form .aligned div.radiolist { - margin-left: 2px; - } - - .submit-row { - padding: 8px; - } - - .submit-row a.deletelink { - padding: 10px 7px; - } - - .button, input[type=submit], input[type=button], .submit-row input, a.button { - padding: 7px; - } - - /* Related widget */ - - .related-widget-wrapper { - float: none; - } - - .related-widget-wrapper-link + .selector { - max-width: calc(100% - 30px); - margin-right: 15px; - } - - select + .related-widget-wrapper-link, - .related-widget-wrapper-link + .related-widget-wrapper-link { - margin-left: 10px; - } - - /* Selector */ - - .selector { - display: flex; - width: 100%; - } - - .selector .selector-filter { - display: flex; - align-items: center; - } - - .selector .selector-filter label { - margin: 0 8px 0 0; - } - - .selector .selector-filter input { - width: auto; - min-height: 0; - flex: 1 1; - } - - .selector-available, .selector-chosen { - width: auto; - flex: 1 1; - display: flex; - flex-direction: column; - } - - .selector select { - width: 100%; - flex: 1 0 auto; - margin-bottom: 5px; - } - - .selector ul.selector-chooser { - width: 26px; - height: 52px; - padding: 2px 0; - margin: auto 15px; - border-radius: 20px; - transform: translateY(-10px); - } - - .selector-add, .selector-remove { - width: 20px; - height: 20px; - background-size: 20px auto; - } - - .selector-add { - background-position: 0 -120px; - } - - .selector-remove { - background-position: 0 -80px; - } - - a.selector-chooseall, a.selector-clearall { - align-self: center; - } - - .stacked { - flex-direction: column; - max-width: 480px; - } - - .stacked > * { - flex: 0 1 auto; - } - - .stacked select { - margin-bottom: 0; - } - - .stacked .selector-available, .stacked .selector-chosen { - width: auto; - } - - .stacked ul.selector-chooser { - width: 52px; - height: 26px; - padding: 0 2px; - margin: 15px auto; - transform: none; - } - - .stacked .selector-chooser li { - padding: 3px; - } - - .stacked .selector-add, .stacked .selector-remove { - background-size: 20px auto; - } - - .stacked .selector-add { - background-position: 0 -40px; - } - - .stacked .active.selector-add { - background-position: 0 -40px; - } - - .active.selector-add:focus, .active.selector-add:hover { - background-position: 0 -140px; - } - - .stacked .active.selector-add:focus, .stacked .active.selector-add:hover { - background-position: 0 -60px; - } - - .stacked .selector-remove { - background-position: 0 0; - } - - .stacked .active.selector-remove { - background-position: 0 0; - } - - .active.selector-remove:focus, .active.selector-remove:hover { - background-position: 0 -100px; - } - - .stacked .active.selector-remove:focus, .stacked .active.selector-remove:hover { - background-position: 0 -20px; - } - - .help-tooltip, .selector .help-icon { - display: none; - } - - .datetime input { - width: 50%; - max-width: 120px; - } - - .datetime span { - font-size: 0.8125rem; - } - - .datetime .timezonewarning { - display: block; - font-size: 0.6875rem; - color: var(--body-quiet-color); - } - - .datetimeshortcuts { - color: var(--border-color); /* XXX Redundant, .datetime span also sets #ccc */ - } - - .form-row .datetime input.vDateField, .form-row .datetime input.vTimeField { - width: 75%; - } - - .inline-group { - overflow: auto; - } - - /* Messages */ - - ul.messagelist li { - padding-left: 55px; - background-position: 30px 12px; - } - - ul.messagelist li.error { - background-position: 30px 12px; - } - - ul.messagelist li.warning { - background-position: 30px 14px; - } - - /* Login */ - - .login #header { - padding: 15px 20px; - } - - .login #branding h1 { - margin: 0; - } - - /* GIS */ - - div.olMap { - max-width: calc(100vw - 30px); - max-height: 300px; - } - - .olMap + .clear_features { - display: block; - margin-top: 10px; - } - - /* Docs */ - - .module table.xfull { - width: 100%; - } - - pre.literal-block { - overflow: auto; - } -} - -/* Mobile */ - -@media (max-width: 767px) { - /* Layout */ - - #header, #content, #footer { - padding: 15px; - } - - #footer:empty { - padding: 0; - } - - div.breadcrumbs { - padding: 10px 15px; - } - - /* Dashboard */ - - .colMS, .colSM { - margin: 0; - } - - #content-related, .colSM #content-related { - width: 100%; - margin: 0; - } - - #content-related .module { - margin-bottom: 0; - } - - #content-related .module h2 { - padding: 10px 15px; - font-size: 1rem; - } - - /* Changelist */ - - #changelist { - align-items: stretch; - flex-direction: column; - } - - #toolbar { - padding: 10px; - } - - #changelist-filter { - margin-left: 0; - } - - #changelist .actions label { - flex: 1 1; - } - - #changelist .actions select { - flex: 1 0; - width: 100%; - } - - #changelist .actions span { - flex: 1 0 100%; - } - - #changelist-filter { - position: static; - width: auto; - margin-top: 30px; - } - - .object-tools { - float: none; - margin: 0 0 15px; - padding: 0; - overflow: hidden; - } - - .object-tools li { - height: auto; - margin-left: 0; - } - - .object-tools li + li { - margin-left: 15px; - } - - /* Forms */ - - .form-row { - padding: 15px 0; - } - - .aligned .form-row, - .aligned .form-row > div { - max-width: 100vw; - } - - .aligned .form-row > div { - width: calc(100vw - 30px); - } - - .flex-container { - flex-flow: column; - } - - textarea { - max-width: none; - } - - .vURLField { - width: auto; - } - - fieldset .fieldBox + .fieldBox { - margin-top: 15px; - padding-top: 15px; - } - - fieldset.collapsed .form-row { - display: none; - } - - .aligned label { - width: 100%; - padding: 0 0 10px; - } - - .aligned label:after { - max-height: 0; - } - - .aligned .form-row input, - .aligned .form-row select, - .aligned .form-row textarea { - flex: 1 1 auto; - max-width: 100%; - } - - .aligned .checkbox-row { - align-items: center; - } - - .aligned .checkbox-row input { - flex: 0 1 auto; - margin: 0; - } - - .aligned .vCheckboxLabel { - flex: 1 0; - padding: 1px 0 0 5px; - } - - .aligned label + p, - .aligned label + div.help, - .aligned label + div.readonly { - padding: 0; - margin-left: 0; - } - - .aligned p.file-upload { - font-size: 0.8125rem; - } - - span.clearable-file-input { - margin-left: 15px; - } - - span.clearable-file-input label { - font-size: 0.8125rem; - padding-bottom: 0; - } - - .aligned .timezonewarning { - flex: 1 0 100%; - margin-top: 5px; - } - - form .aligned .form-row div.help { - width: 100%; - margin: 5px 0 0; - padding: 0; - } - - form .aligned ul, - form .aligned ul.errorlist { - margin-left: 0; - padding-left: 0; - } - - form .aligned div.radiolist { - margin-top: 5px; - margin-right: 15px; - margin-bottom: -3px; - } - - form .aligned div.radiolist:not(.inline) div + div { - margin-top: 5px; - } - - /* Related widget */ - - .related-widget-wrapper { - width: 100%; - display: flex; - align-items: flex-start; - } - - .related-widget-wrapper .selector { - order: 1; - } - - .related-widget-wrapper > a { - order: 2; - } - - .related-widget-wrapper .radiolist ~ a { - align-self: flex-end; - } - - .related-widget-wrapper > select ~ a { - align-self: center; - } - - select + .related-widget-wrapper-link, - .related-widget-wrapper-link + .related-widget-wrapper-link { - margin-left: 15px; - } - - /* Selector */ - - .selector { - flex-direction: column; - } - - .selector > * { - float: none; - } - - .selector-available, .selector-chosen { - margin-bottom: 0; - flex: 1 1 auto; - } - - .selector select { - max-height: 96px; - } - - .selector ul.selector-chooser { - display: block; - float: none; - width: 52px; - height: 26px; - padding: 0 2px; - margin: 15px auto 20px; - transform: none; - } - - .selector ul.selector-chooser li { - float: left; - } - - .selector-remove { - background-position: 0 0; - } - - .active.selector-remove:focus, .active.selector-remove:hover { - background-position: 0 -20px; - } - - .selector-add { - background-position: 0 -40px; - } - - .active.selector-add:focus, .active.selector-add:hover { - background-position: 0 -60px; - } - - /* Inlines */ - - .inline-group[data-inline-type="stacked"] .inline-related { - border: 1px solid var(--hairline-color); - border-radius: 4px; - margin-top: 15px; - overflow: auto; - } - - .inline-group[data-inline-type="stacked"] .inline-related > * { - box-sizing: border-box; - } - - .inline-group[data-inline-type="stacked"] .inline-related .module { - padding: 0 10px; - } - - .inline-group[data-inline-type="stacked"] .inline-related .module .form-row { - border-top: 1px solid var(--hairline-color); - border-bottom: none; - } - - .inline-group[data-inline-type="stacked"] .inline-related .module .form-row:first-child { - border-top: none; - } - - .inline-group[data-inline-type="stacked"] .inline-related h3 { - padding: 10px; - border-top-width: 0; - border-bottom-width: 2px; - display: flex; - flex-wrap: wrap; - align-items: center; - } - - .inline-group[data-inline-type="stacked"] .inline-related h3 .inline_label { - margin-right: auto; - } - - .inline-group[data-inline-type="stacked"] .inline-related h3 span.delete { - float: none; - flex: 1 1 100%; - margin-top: 5px; - } - - .inline-group[data-inline-type="stacked"] .aligned .form-row > div:not([class]) { - width: 100%; - } - - .inline-group[data-inline-type="stacked"] .aligned label { - width: 100%; - } - - .inline-group[data-inline-type="stacked"] div.add-row { - margin-top: 15px; - border: 1px solid var(--hairline-color); - border-radius: 4px; - } - - .inline-group div.add-row, - .inline-group .tabular tr.add-row td { - padding: 0; - } - - .inline-group div.add-row a, - .inline-group .tabular tr.add-row td a { - display: block; - padding: 8px 10px 8px 26px; - background-position: 8px 9px; - } - - /* Submit row */ - - .submit-row { - padding: 10px; - margin: 0 0 15px; - flex-direction: column; - gap: 8px; - } - - .submit-row input, .submit-row input.default, .submit-row a { - text-align: center; - } - - .submit-row a.closelink { - padding: 10px 0; - text-align: center; - } - - .submit-row a.deletelink { - margin: 0; - } - - /* Messages */ - - ul.messagelist li { - padding-left: 40px; - background-position: 15px 12px; - } - - ul.messagelist li.error { - background-position: 15px 12px; - } - - ul.messagelist li.warning { - background-position: 15px 14px; - } - - /* Paginator */ - - .paginator .this-page, .paginator a:link, .paginator a:visited { - padding: 4px 10px; - } - - /* Login */ - - body.login { - padding: 0 15px; - } - - .login #container { - width: auto; - max-width: 480px; - margin: 50px auto; - } - - .login #header, - .login #content { - padding: 15px; - } - - .login #content-main { - float: none; - } - - .login .form-row { - padding: 0; - } - - .login .form-row + .form-row { - margin-top: 15px; - } - - .login .form-row label { - margin: 0 0 5px; - line-height: 1.2; - } - - .login .submit-row { - padding: 15px 0 0; - } - - .login br { - display: none; - } - - .login .submit-row input { - margin: 0; - text-transform: uppercase; - } - - .errornote { - margin: 0 0 20px; - padding: 8px 12px; - font-size: 0.8125rem; - } - - /* Calendar and clock */ - - .calendarbox, .clockbox { - position: fixed !important; - top: 50% !important; - left: 50% !important; - transform: translate(-50%, -50%); - margin: 0; - border: none; - overflow: visible; - } - - .calendarbox:before, .clockbox:before { - content: ''; - position: fixed; - top: 50%; - left: 50%; - width: 100vw; - height: 100vh; - background: rgba(0, 0, 0, 0.75); - transform: translate(-50%, -50%); - } - - .calendarbox > *, .clockbox > * { - position: relative; - z-index: 1; - } - - .calendarbox > div:first-child { - z-index: 2; - } - - .calendarbox .calendar, .clockbox h2 { - border-radius: 4px 4px 0 0; - overflow: hidden; - } - - .calendarbox .calendar-cancel, .clockbox .calendar-cancel { - border-radius: 0 0 4px 4px; - overflow: hidden; - } - - .calendar-shortcuts { - padding: 10px 0; - font-size: 0.75rem; - line-height: 0.75rem; - } - - .calendar-shortcuts a { - margin: 0 4px; - } - - .timelist a { - background: var(--body-bg); - padding: 4px; - } - - .calendar-cancel { - padding: 8px 10px; - } - - .clockbox h2 { - padding: 8px 15px; - } - - .calendar caption { - padding: 10px; - } - - .calendarbox .calendarnav-previous, .calendarbox .calendarnav-next { - z-index: 1; - top: 10px; - } - - /* History */ - - table#change-history tbody th, table#change-history tbody td { - font-size: 0.8125rem; - word-break: break-word; - } - - table#change-history tbody th { - width: auto; - } - - /* Docs */ - - table.model tbody th, table.model tbody td { - font-size: 0.8125rem; - word-break: break-word; - } -} diff --git a/OneCprogsite/static/admin/css/responsive_rtl.css b/OneCprogsite/static/admin/css/responsive_rtl.css deleted file mode 100644 index 639e20b..0000000 --- a/OneCprogsite/static/admin/css/responsive_rtl.css +++ /dev/null @@ -1,81 +0,0 @@ -/* TABLETS */ - -@media (max-width: 1024px) { - [dir="rtl"] .colMS { - margin-right: 0; - } - - [dir="rtl"] #user-tools { - text-align: right; - } - - [dir="rtl"] #changelist .actions label { - padding-left: 10px; - padding-right: 0; - } - - [dir="rtl"] #changelist .actions select { - margin-left: 0; - margin-right: 15px; - } - - [dir="rtl"] .change-list .filtered .results, - [dir="rtl"] .change-list .filtered .paginator, - [dir="rtl"] .filtered #toolbar, - [dir="rtl"] .filtered div.xfull, - [dir="rtl"] .filtered .actions, - [dir="rtl"] #changelist-filter { - margin-left: 0; - } - - [dir="rtl"] .inline-group ul.tools a.add, - [dir="rtl"] .inline-group div.add-row a, - [dir="rtl"] .inline-group .tabular tr.add-row td a { - padding: 8px 26px 8px 10px; - background-position: calc(100% - 8px) 9px; - } - - [dir="rtl"] .related-widget-wrapper-link + .selector { - margin-right: 0; - margin-left: 15px; - } - - [dir="rtl"] .selector .selector-filter label { - margin-right: 0; - margin-left: 8px; - } - - [dir="rtl"] .object-tools li { - float: right; - } - - [dir="rtl"] .object-tools li + li { - margin-left: 0; - margin-right: 15px; - } - - [dir="rtl"] .dashboard .module table td a { - padding-left: 0; - padding-right: 16px; - } -} - -/* MOBILE */ - -@media (max-width: 767px) { - [dir="rtl"] .aligned .related-lookup, - [dir="rtl"] .aligned .datetimeshortcuts { - margin-left: 0; - margin-right: 15px; - } - - [dir="rtl"] .aligned ul, - [dir="rtl"] form .aligned ul.errorlist { - margin-right: 0; - } - - [dir="rtl"] #changelist-filter { - margin-left: 0; - margin-right: 0; - } -} diff --git a/OneCprogsite/static/admin/css/rtl.css b/OneCprogsite/static/admin/css/rtl.css deleted file mode 100644 index 53a6dd6..0000000 --- a/OneCprogsite/static/admin/css/rtl.css +++ /dev/null @@ -1,288 +0,0 @@ -/* GLOBAL */ - -th { - text-align: right; -} - -.module h2, .module caption { - text-align: right; -} - -.module ul, .module ol { - margin-left: 0; - margin-right: 1.5em; -} - -.viewlink, .addlink, .changelink { - padding-left: 0; - padding-right: 16px; - background-position: 100% 1px; -} - -.deletelink { - padding-left: 0; - padding-right: 16px; - background-position: 100% 1px; -} - -.object-tools { - float: left; -} - -thead th:first-child, -tfoot td:first-child { - border-left: none; -} - -/* LAYOUT */ - -#user-tools { - right: auto; - left: 0; - text-align: left; -} - -div.breadcrumbs { - text-align: right; -} - -#content-main { - float: right; -} - -#content-related { - float: left; - margin-left: -300px; - margin-right: auto; -} - -.colMS { - margin-left: 300px; - margin-right: 0; -} - -/* SORTABLE TABLES */ - -table thead th.sorted .sortoptions { - float: left; -} - -thead th.sorted .text { - padding-right: 0; - padding-left: 42px; -} - -/* dashboard styles */ - -.dashboard .module table td a { - padding-left: .6em; - padding-right: 16px; -} - -/* changelists styles */ - -.change-list .filtered table { - border-left: none; - border-right: 0px none; -} - -#changelist-filter { - border-left: none; - border-right: none; - margin-left: 0; - margin-right: 30px; -} - -#changelist-filter li.selected { - border-left: none; - padding-left: 10px; - margin-left: 0; - border-right: 5px solid var(--hairline-color); - padding-right: 10px; - margin-right: -15px; -} - -#changelist table tbody td:first-child, #changelist table tbody th:first-child { - border-right: none; - border-left: none; -} - -/* FORMS */ - -.aligned label { - padding: 0 0 3px 1em; -} - -.submit-row a.deletelink { - margin-left: 0; - margin-right: auto; -} - -.vDateField, .vTimeField { - margin-left: 2px; -} - -.aligned .form-row input { - margin-left: 5px; -} - -form .aligned ul { - margin-right: 163px; - padding-right: 10px; - margin-left: 0; - padding-left: 0; -} - -form ul.inline li { - float: right; - padding-right: 0; - padding-left: 7px; -} - -form .aligned p.help, -form .aligned div.help { - margin-right: 160px; - padding-right: 10px; -} - -form div.help ul, -form .aligned .checkbox-row + .help, -form .aligned p.date div.help.timezonewarning, -form .aligned p.datetime div.help.timezonewarning, -form .aligned p.time div.help.timezonewarning { - margin-right: 0; - padding-right: 0; -} - -form .wide p.help, form .wide div.help { - padding-left: 0; - padding-right: 50px; -} - -form .wide p, -form .wide ul.errorlist, -form .wide input + p.help, -form .wide input + div.help { - margin-right: 200px; - margin-left: 0px; -} - -.submit-row { - text-align: right; -} - -fieldset .fieldBox { - margin-left: 20px; - margin-right: 0; -} - -.errorlist li { - background-position: 100% 12px; - padding: 0; -} - -.errornote { - background-position: 100% 12px; - padding: 10px 12px; -} - -/* WIDGETS */ - -.calendarnav-previous { - top: 0; - left: auto; - right: 10px; - background: url(../img/calendar-icons.svg) 0 -30px no-repeat; -} - -.calendarbox .calendarnav-previous:focus, -.calendarbox .calendarnav-previous:hover { - background-position: 0 -45px; -} - -.calendarnav-next { - top: 0; - right: auto; - left: 10px; - background: url(../img/calendar-icons.svg) 0 0 no-repeat; -} - -.calendarbox .calendarnav-next:focus, -.calendarbox .calendarnav-next:hover { - background-position: 0 -15px; -} - -.calendar caption, .calendarbox h2 { - text-align: center; -} - -.selector { - float: right; -} - -.selector .selector-filter { - text-align: right; -} - -.selector-add { - background: url(../img/selector-icons.svg) 0 -64px no-repeat; -} - -.active.selector-add:focus, .active.selector-add:hover { - background-position: 0 -80px; -} - -.selector-remove { - background: url(../img/selector-icons.svg) 0 -96px no-repeat; -} - -.active.selector-remove:focus, .active.selector-remove:hover { - background-position: 0 -112px; -} - -a.selector-chooseall { - background: url(../img/selector-icons.svg) right -128px no-repeat; -} - -a.active.selector-chooseall:focus, a.active.selector-chooseall:hover { - background-position: 100% -144px; -} - -a.selector-clearall { - background: url(../img/selector-icons.svg) 0 -160px no-repeat; -} - -a.active.selector-clearall:focus, a.active.selector-clearall:hover { - background-position: 0 -176px; -} - -.inline-deletelink { - float: left; -} - -form .form-row p.datetime { - overflow: hidden; -} - -.related-widget-wrapper { - float: right; -} - -/* MISC */ - -.inline-related h2, .inline-group h2 { - text-align: right -} - -.inline-related h3 span.delete { - padding-right: 20px; - padding-left: inherit; - left: 10px; - right: inherit; - float:left; -} - -.inline-related h3 span.delete label { - margin-left: inherit; - margin-right: 2px; -} diff --git a/OneCprogsite/static/admin/css/vendor/select2/LICENSE-SELECT2.md b/OneCprogsite/static/admin/css/vendor/select2/LICENSE-SELECT2.md deleted file mode 100644 index 8cb8a2b..0000000 --- a/OneCprogsite/static/admin/css/vendor/select2/LICENSE-SELECT2.md +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2012-2017 Kevin Brown, Igor Vaynberg, and Select2 contributors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/OneCprogsite/static/admin/css/vendor/select2/select2.css b/OneCprogsite/static/admin/css/vendor/select2/select2.css deleted file mode 100644 index 750b320..0000000 --- a/OneCprogsite/static/admin/css/vendor/select2/select2.css +++ /dev/null @@ -1,481 +0,0 @@ -.select2-container { - box-sizing: border-box; - display: inline-block; - margin: 0; - position: relative; - vertical-align: middle; } - .select2-container .select2-selection--single { - box-sizing: border-box; - cursor: pointer; - display: block; - height: 28px; - user-select: none; - -webkit-user-select: none; } - .select2-container .select2-selection--single .select2-selection__rendered { - display: block; - padding-left: 8px; - padding-right: 20px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; } - .select2-container .select2-selection--single .select2-selection__clear { - position: relative; } - .select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered { - padding-right: 8px; - padding-left: 20px; } - .select2-container .select2-selection--multiple { - box-sizing: border-box; - cursor: pointer; - display: block; - min-height: 32px; - user-select: none; - -webkit-user-select: none; } - .select2-container .select2-selection--multiple .select2-selection__rendered { - display: inline-block; - overflow: hidden; - padding-left: 8px; - text-overflow: ellipsis; - white-space: nowrap; } - .select2-container .select2-search--inline { - float: left; } - .select2-container .select2-search--inline .select2-search__field { - box-sizing: border-box; - border: none; - font-size: 100%; - margin-top: 5px; - padding: 0; } - .select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button { - -webkit-appearance: none; } - -.select2-dropdown { - background-color: white; - border: 1px solid #aaa; - border-radius: 4px; - box-sizing: border-box; - display: block; - position: absolute; - left: -100000px; - width: 100%; - z-index: 1051; } - -.select2-results { - display: block; } - -.select2-results__options { - list-style: none; - margin: 0; - padding: 0; } - -.select2-results__option { - padding: 6px; - user-select: none; - -webkit-user-select: none; } - .select2-results__option[aria-selected] { - cursor: pointer; } - -.select2-container--open .select2-dropdown { - left: 0; } - -.select2-container--open .select2-dropdown--above { - border-bottom: none; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; } - -.select2-container--open .select2-dropdown--below { - border-top: none; - border-top-left-radius: 0; - border-top-right-radius: 0; } - -.select2-search--dropdown { - display: block; - padding: 4px; } - .select2-search--dropdown .select2-search__field { - padding: 4px; - width: 100%; - box-sizing: border-box; } - .select2-search--dropdown .select2-search__field::-webkit-search-cancel-button { - -webkit-appearance: none; } - .select2-search--dropdown.select2-search--hide { - display: none; } - -.select2-close-mask { - border: 0; - margin: 0; - padding: 0; - display: block; - position: fixed; - left: 0; - top: 0; - min-height: 100%; - min-width: 100%; - height: auto; - width: auto; - opacity: 0; - z-index: 99; - background-color: #fff; - filter: alpha(opacity=0); } - -.select2-hidden-accessible { - border: 0 !important; - clip: rect(0 0 0 0) !important; - -webkit-clip-path: inset(50%) !important; - clip-path: inset(50%) !important; - height: 1px !important; - overflow: hidden !important; - padding: 0 !important; - position: absolute !important; - width: 1px !important; - white-space: nowrap !important; } - -.select2-container--default .select2-selection--single { - background-color: #fff; - border: 1px solid #aaa; - border-radius: 4px; } - .select2-container--default .select2-selection--single .select2-selection__rendered { - color: #444; - line-height: 28px; } - .select2-container--default .select2-selection--single .select2-selection__clear { - cursor: pointer; - float: right; - font-weight: bold; } - .select2-container--default .select2-selection--single .select2-selection__placeholder { - color: #999; } - .select2-container--default .select2-selection--single .select2-selection__arrow { - height: 26px; - position: absolute; - top: 1px; - right: 1px; - width: 20px; } - .select2-container--default .select2-selection--single .select2-selection__arrow b { - border-color: #888 transparent transparent transparent; - border-style: solid; - border-width: 5px 4px 0 4px; - height: 0; - left: 50%; - margin-left: -4px; - margin-top: -2px; - position: absolute; - top: 50%; - width: 0; } - -.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear { - float: left; } - -.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow { - left: 1px; - right: auto; } - -.select2-container--default.select2-container--disabled .select2-selection--single { - background-color: #eee; - cursor: default; } - .select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear { - display: none; } - -.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b { - border-color: transparent transparent #888 transparent; - border-width: 0 4px 5px 4px; } - -.select2-container--default .select2-selection--multiple { - background-color: white; - border: 1px solid #aaa; - border-radius: 4px; - cursor: text; } - .select2-container--default .select2-selection--multiple .select2-selection__rendered { - box-sizing: border-box; - list-style: none; - margin: 0; - padding: 0 5px; - width: 100%; } - .select2-container--default .select2-selection--multiple .select2-selection__rendered li { - list-style: none; } - .select2-container--default .select2-selection--multiple .select2-selection__clear { - cursor: pointer; - float: right; - font-weight: bold; - margin-top: 5px; - margin-right: 10px; - padding: 1px; } - .select2-container--default .select2-selection--multiple .select2-selection__choice { - background-color: #e4e4e4; - border: 1px solid #aaa; - border-radius: 4px; - cursor: default; - float: left; - margin-right: 5px; - margin-top: 5px; - padding: 0 5px; } - .select2-container--default .select2-selection--multiple .select2-selection__choice__remove { - color: #999; - cursor: pointer; - display: inline-block; - font-weight: bold; - margin-right: 2px; } - .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover { - color: #333; } - -.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline { - float: right; } - -.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice { - margin-left: 5px; - margin-right: auto; } - -.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { - margin-left: 2px; - margin-right: auto; } - -.select2-container--default.select2-container--focus .select2-selection--multiple { - border: solid black 1px; - outline: 0; } - -.select2-container--default.select2-container--disabled .select2-selection--multiple { - background-color: #eee; - cursor: default; } - -.select2-container--default.select2-container--disabled .select2-selection__choice__remove { - display: none; } - -.select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple { - border-top-left-radius: 0; - border-top-right-radius: 0; } - -.select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; } - -.select2-container--default .select2-search--dropdown .select2-search__field { - border: 1px solid #aaa; } - -.select2-container--default .select2-search--inline .select2-search__field { - background: transparent; - border: none; - outline: 0; - box-shadow: none; - -webkit-appearance: textfield; } - -.select2-container--default .select2-results > .select2-results__options { - max-height: 200px; - overflow-y: auto; } - -.select2-container--default .select2-results__option[role=group] { - padding: 0; } - -.select2-container--default .select2-results__option[aria-disabled=true] { - color: #999; } - -.select2-container--default .select2-results__option[aria-selected=true] { - background-color: #ddd; } - -.select2-container--default .select2-results__option .select2-results__option { - padding-left: 1em; } - .select2-container--default .select2-results__option .select2-results__option .select2-results__group { - padding-left: 0; } - .select2-container--default .select2-results__option .select2-results__option .select2-results__option { - margin-left: -1em; - padding-left: 2em; } - .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option { - margin-left: -2em; - padding-left: 3em; } - .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { - margin-left: -3em; - padding-left: 4em; } - .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { - margin-left: -4em; - padding-left: 5em; } - .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { - margin-left: -5em; - padding-left: 6em; } - -.select2-container--default .select2-results__option--highlighted[aria-selected] { - background-color: #5897fb; - color: white; } - -.select2-container--default .select2-results__group { - cursor: default; - display: block; - padding: 6px; } - -.select2-container--classic .select2-selection--single { - background-color: #f7f7f7; - border: 1px solid #aaa; - border-radius: 4px; - outline: 0; - background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%); - background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%); - background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); } - .select2-container--classic .select2-selection--single:focus { - border: 1px solid #5897fb; } - .select2-container--classic .select2-selection--single .select2-selection__rendered { - color: #444; - line-height: 28px; } - .select2-container--classic .select2-selection--single .select2-selection__clear { - cursor: pointer; - float: right; - font-weight: bold; - margin-right: 10px; } - .select2-container--classic .select2-selection--single .select2-selection__placeholder { - color: #999; } - .select2-container--classic .select2-selection--single .select2-selection__arrow { - background-color: #ddd; - border: none; - border-left: 1px solid #aaa; - border-top-right-radius: 4px; - border-bottom-right-radius: 4px; - height: 26px; - position: absolute; - top: 1px; - right: 1px; - width: 20px; - background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%); - background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%); - background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); } - .select2-container--classic .select2-selection--single .select2-selection__arrow b { - border-color: #888 transparent transparent transparent; - border-style: solid; - border-width: 5px 4px 0 4px; - height: 0; - left: 50%; - margin-left: -4px; - margin-top: -2px; - position: absolute; - top: 50%; - width: 0; } - -.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear { - float: left; } - -.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow { - border: none; - border-right: 1px solid #aaa; - border-radius: 0; - border-top-left-radius: 4px; - border-bottom-left-radius: 4px; - left: 1px; - right: auto; } - -.select2-container--classic.select2-container--open .select2-selection--single { - border: 1px solid #5897fb; } - .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow { - background: transparent; - border: none; } - .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b { - border-color: transparent transparent #888 transparent; - border-width: 0 4px 5px 4px; } - -.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single { - border-top: none; - border-top-left-radius: 0; - border-top-right-radius: 0; - background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%); - background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%); - background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); } - -.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single { - border-bottom: none; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%); - background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%); - background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); } - -.select2-container--classic .select2-selection--multiple { - background-color: white; - border: 1px solid #aaa; - border-radius: 4px; - cursor: text; - outline: 0; } - .select2-container--classic .select2-selection--multiple:focus { - border: 1px solid #5897fb; } - .select2-container--classic .select2-selection--multiple .select2-selection__rendered { - list-style: none; - margin: 0; - padding: 0 5px; } - .select2-container--classic .select2-selection--multiple .select2-selection__clear { - display: none; } - .select2-container--classic .select2-selection--multiple .select2-selection__choice { - background-color: #e4e4e4; - border: 1px solid #aaa; - border-radius: 4px; - cursor: default; - float: left; - margin-right: 5px; - margin-top: 5px; - padding: 0 5px; } - .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove { - color: #888; - cursor: pointer; - display: inline-block; - font-weight: bold; - margin-right: 2px; } - .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover { - color: #555; } - -.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice { - float: right; - margin-left: 5px; - margin-right: auto; } - -.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { - margin-left: 2px; - margin-right: auto; } - -.select2-container--classic.select2-container--open .select2-selection--multiple { - border: 1px solid #5897fb; } - -.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple { - border-top: none; - border-top-left-radius: 0; - border-top-right-radius: 0; } - -.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple { - border-bottom: none; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; } - -.select2-container--classic .select2-search--dropdown .select2-search__field { - border: 1px solid #aaa; - outline: 0; } - -.select2-container--classic .select2-search--inline .select2-search__field { - outline: 0; - box-shadow: none; } - -.select2-container--classic .select2-dropdown { - background-color: white; - border: 1px solid transparent; } - -.select2-container--classic .select2-dropdown--above { - border-bottom: none; } - -.select2-container--classic .select2-dropdown--below { - border-top: none; } - -.select2-container--classic .select2-results > .select2-results__options { - max-height: 200px; - overflow-y: auto; } - -.select2-container--classic .select2-results__option[role=group] { - padding: 0; } - -.select2-container--classic .select2-results__option[aria-disabled=true] { - color: grey; } - -.select2-container--classic .select2-results__option--highlighted[aria-selected] { - background-color: #3875d7; - color: white; } - -.select2-container--classic .select2-results__group { - cursor: default; - display: block; - padding: 6px; } - -.select2-container--classic.select2-container--open .select2-dropdown { - border-color: #5897fb; } diff --git a/OneCprogsite/static/admin/css/vendor/select2/select2.min.css b/OneCprogsite/static/admin/css/vendor/select2/select2.min.css deleted file mode 100644 index 7c18ad5..0000000 --- a/OneCprogsite/static/admin/css/vendor/select2/select2.min.css +++ /dev/null @@ -1 +0,0 @@ -.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;height:1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important;white-space:nowrap !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px;padding:1px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right;margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb} diff --git a/OneCprogsite/static/admin/css/widgets.css b/OneCprogsite/static/admin/css/widgets.css deleted file mode 100644 index 5f7adcb..0000000 --- a/OneCprogsite/static/admin/css/widgets.css +++ /dev/null @@ -1,603 +0,0 @@ -/* SELECTOR (FILTER INTERFACE) */ - -.selector { - width: 800px; - float: left; - display: flex; -} - -.selector select { - width: 380px; - height: 17.2em; - flex: 1 0 auto; -} - -.selector-available, .selector-chosen { - width: 380px; - text-align: center; - margin-bottom: 5px; - display: flex; - flex-direction: column; -} - -.selector-available h2, .selector-chosen h2 { - border: 1px solid var(--border-color); - border-radius: 4px 4px 0 0; -} - -.selector-chosen .list-footer-display { - border: 1px solid var(--border-color); - border-top: none; - border-radius: 0 0 4px 4px; - margin: 0 0 10px; - padding: 8px; - text-align: center; - background: var(--primary); - color: var(--header-link-color); - cursor: pointer; -} -.selector-chosen .list-footer-display__clear { - color: var(--breadcrumbs-fg); -} - -.selector-chosen h2 { - background: var(--primary); - color: var(--header-link-color); -} - -.selector .selector-available h2 { - background: var(--darkened-bg); - color: var(--body-quiet-color); -} - -.selector .selector-filter { - border: 1px solid var(--border-color); - border-width: 0 1px; - padding: 8px; - color: var(--body-quiet-color); - font-size: 0.625rem; - margin: 0; - text-align: left; -} - -.selector .selector-filter label, -.inline-group .aligned .selector .selector-filter label { - float: left; - margin: 7px 0 0; - width: 18px; - height: 18px; - padding: 0; - overflow: hidden; - line-height: 1; -} - -.selector .selector-available input, -.selector .selector-chosen input { - width: 320px; - margin-left: 8px; -} - -.selector ul.selector-chooser { - align-self: center; - width: 22px; - background-color: var(--selected-bg); - border-radius: 10px; - margin: 0 5px; - padding: 0; - transform: translateY(-17px); -} - -.selector-chooser li { - margin: 0; - padding: 3px; - list-style-type: none; -} - -.selector select { - padding: 0 10px; - margin: 0 0 10px; - border-radius: 0 0 4px 4px; -} -.selector .selector-chosen--with-filtered select { - margin: 0; - border-radius: 0; - height: 14em; -} - -.selector .selector-chosen:not(.selector-chosen--with-filtered) .list-footer-display { - display: none; -} - -.selector-add, .selector-remove { - width: 16px; - height: 16px; - display: block; - text-indent: -3000px; - overflow: hidden; - cursor: default; - opacity: 0.55; -} - -.active.selector-add, .active.selector-remove { - opacity: 1; -} - -.active.selector-add:hover, .active.selector-remove:hover { - cursor: pointer; -} - -.selector-add { - background: url(../img/selector-icons.svg) 0 -96px no-repeat; -} - -.active.selector-add:focus, .active.selector-add:hover { - background-position: 0 -112px; -} - -.selector-remove { - background: url(../img/selector-icons.svg) 0 -64px no-repeat; -} - -.active.selector-remove:focus, .active.selector-remove:hover { - background-position: 0 -80px; -} - -a.selector-chooseall, a.selector-clearall { - display: inline-block; - height: 16px; - text-align: left; - margin: 1px auto 3px; - overflow: hidden; - font-weight: bold; - line-height: 16px; - color: var(--body-quiet-color); - text-decoration: none; - opacity: 0.55; -} - -a.active.selector-chooseall:focus, a.active.selector-clearall:focus, -a.active.selector-chooseall:hover, a.active.selector-clearall:hover { - color: var(--link-fg); -} - -a.active.selector-chooseall, a.active.selector-clearall { - opacity: 1; -} - -a.active.selector-chooseall:hover, a.active.selector-clearall:hover { - cursor: pointer; -} - -a.selector-chooseall { - padding: 0 18px 0 0; - background: url(../img/selector-icons.svg) right -160px no-repeat; - cursor: default; -} - -a.active.selector-chooseall:focus, a.active.selector-chooseall:hover { - background-position: 100% -176px; -} - -a.selector-clearall { - padding: 0 0 0 18px; - background: url(../img/selector-icons.svg) 0 -128px no-repeat; - cursor: default; -} - -a.active.selector-clearall:focus, a.active.selector-clearall:hover { - background-position: 0 -144px; -} - -/* STACKED SELECTORS */ - -.stacked { - float: left; - width: 490px; - display: block; -} - -.stacked select { - width: 480px; - height: 10.1em; -} - -.stacked .selector-available, .stacked .selector-chosen { - width: 480px; -} - -.stacked .selector-available { - margin-bottom: 0; -} - -.stacked .selector-available input { - width: 422px; -} - -.stacked ul.selector-chooser { - height: 22px; - width: 50px; - margin: 0 0 10px 40%; - background-color: #eee; - border-radius: 10px; - transform: none; -} - -.stacked .selector-chooser li { - float: left; - padding: 3px 3px 3px 5px; -} - -.stacked .selector-chooseall, .stacked .selector-clearall { - display: none; -} - -.stacked .selector-add { - background: url(../img/selector-icons.svg) 0 -32px no-repeat; - cursor: default; -} - -.stacked .active.selector-add { - background-position: 0 -32px; - cursor: pointer; -} - -.stacked .active.selector-add:focus, .stacked .active.selector-add:hover { - background-position: 0 -48px; - cursor: pointer; -} - -.stacked .selector-remove { - background: url(../img/selector-icons.svg) 0 0 no-repeat; - cursor: default; -} - -.stacked .active.selector-remove { - background-position: 0 0px; - cursor: pointer; -} - -.stacked .active.selector-remove:focus, .stacked .active.selector-remove:hover { - background-position: 0 -16px; - cursor: pointer; -} - -.selector .help-icon { - background: url(../img/icon-unknown.svg) 0 0 no-repeat; - display: inline-block; - vertical-align: middle; - margin: -2px 0 0 2px; - width: 13px; - height: 13px; -} - -.selector .selector-chosen .help-icon { - background: url(../img/icon-unknown-alt.svg) 0 0 no-repeat; -} - -.selector .search-label-icon { - background: url(../img/search.svg) 0 0 no-repeat; - display: inline-block; - height: 1.125rem; - width: 1.125rem; -} - -/* DATE AND TIME */ - -p.datetime { - line-height: 20px; - margin: 0; - padding: 0; - color: var(--body-quiet-color); - font-weight: bold; -} - -.datetime span { - white-space: nowrap; - font-weight: normal; - font-size: 0.6875rem; - color: var(--body-quiet-color); -} - -.datetime input, .form-row .datetime input.vDateField, .form-row .datetime input.vTimeField { - margin-left: 5px; - margin-bottom: 4px; -} - -table p.datetime { - font-size: 0.6875rem; - margin-left: 0; - padding-left: 0; -} - -.datetimeshortcuts .clock-icon, .datetimeshortcuts .date-icon { - position: relative; - display: inline-block; - vertical-align: middle; - height: 16px; - width: 16px; - overflow: hidden; -} - -.datetimeshortcuts .clock-icon { - background: url(../img/icon-clock.svg) 0 0 no-repeat; -} - -.datetimeshortcuts a:focus .clock-icon, -.datetimeshortcuts a:hover .clock-icon { - background-position: 0 -16px; -} - -.datetimeshortcuts .date-icon { - background: url(../img/icon-calendar.svg) 0 0 no-repeat; - top: -1px; -} - -.datetimeshortcuts a:focus .date-icon, -.datetimeshortcuts a:hover .date-icon { - background-position: 0 -16px; -} - -.timezonewarning { - font-size: 0.6875rem; - color: var(--body-quiet-color); -} - -/* URL */ - -p.url { - line-height: 20px; - margin: 0; - padding: 0; - color: var(--body-quiet-color); - font-size: 0.6875rem; - font-weight: bold; -} - -.url a { - font-weight: normal; -} - -/* FILE UPLOADS */ - -p.file-upload { - line-height: 20px; - margin: 0; - padding: 0; - color: var(--body-quiet-color); - font-size: 0.6875rem; - font-weight: bold; -} - -.file-upload a { - font-weight: normal; -} - -.file-upload .deletelink { - margin-left: 5px; -} - -span.clearable-file-input label { - color: var(--body-fg); - font-size: 0.6875rem; - display: inline; - float: none; -} - -/* CALENDARS & CLOCKS */ - -.calendarbox, .clockbox { - margin: 5px auto; - font-size: 0.75rem; - width: 19em; - text-align: center; - background: var(--body-bg); - color: var(--body-fg); - border: 1px solid var(--hairline-color); - border-radius: 4px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15); - overflow: hidden; - position: relative; -} - -.clockbox { - width: auto; -} - -.calendar { - margin: 0; - padding: 0; -} - -.calendar table { - margin: 0; - padding: 0; - border-collapse: collapse; - background: white; - width: 100%; -} - -.calendar caption, .calendarbox h2 { - margin: 0; - text-align: center; - border-top: none; - font-weight: 700; - font-size: 0.75rem; - color: #333; - background: var(--accent); -} - -.calendar th { - padding: 8px 5px; - background: var(--darkened-bg); - border-bottom: 1px solid var(--border-color); - font-weight: 400; - font-size: 0.75rem; - text-align: center; - color: var(--body-quiet-color); -} - -.calendar td { - font-weight: 400; - font-size: 0.75rem; - text-align: center; - padding: 0; - border-top: 1px solid var(--hairline-color); - border-bottom: none; -} - -.calendar td.selected a { - background: var(--primary); - color: var(--button-fg); -} - -.calendar td.nonday { - background: var(--darkened-bg); -} - -.calendar td.today a { - font-weight: 700; -} - -.calendar td a, .timelist a { - display: block; - font-weight: 400; - padding: 6px; - text-decoration: none; - color: var(--body-quiet-color); -} - -.calendar td a:focus, .timelist a:focus, -.calendar td a:hover, .timelist a:hover { - background: var(--primary); - color: white; -} - -.calendar td a:active, .timelist a:active { - background: var(--header-bg); - color: white; -} - -.calendarnav { - font-size: 0.625rem; - text-align: center; - color: #ccc; - margin: 0; - padding: 1px 3px; -} - -.calendarnav a:link, #calendarnav a:visited, -#calendarnav a:focus, #calendarnav a:hover { - color: var(--body-quiet-color); -} - -.calendar-shortcuts { - background: var(--body-bg); - color: var(--body-quiet-color); - font-size: 0.6875rem; - line-height: 0.6875rem; - border-top: 1px solid var(--hairline-color); - padding: 8px 0; -} - -.calendarbox .calendarnav-previous, .calendarbox .calendarnav-next { - display: block; - position: absolute; - top: 8px; - width: 15px; - height: 15px; - text-indent: -9999px; - padding: 0; -} - -.calendarnav-previous { - left: 10px; - background: url(../img/calendar-icons.svg) 0 0 no-repeat; -} - -.calendarbox .calendarnav-previous:focus, -.calendarbox .calendarnav-previous:hover { - background-position: 0 -15px; -} - -.calendarnav-next { - right: 10px; - background: url(../img/calendar-icons.svg) 0 -30px no-repeat; -} - -.calendarbox .calendarnav-next:focus, -.calendarbox .calendarnav-next:hover { - background-position: 0 -45px; -} - -.calendar-cancel { - margin: 0; - padding: 4px 0; - font-size: 0.75rem; - background: #eee; - border-top: 1px solid var(--border-color); - color: var(--body-fg); -} - -.calendar-cancel:focus, .calendar-cancel:hover { - background: #ddd; -} - -.calendar-cancel a { - color: black; - display: block; -} - -ul.timelist, .timelist li { - list-style-type: none; - margin: 0; - padding: 0; -} - -.timelist a { - padding: 2px; -} - -/* EDIT INLINE */ - -.inline-deletelink { - float: right; - text-indent: -9999px; - background: url(../img/inline-delete.svg) 0 0 no-repeat; - width: 16px; - height: 16px; - border: 0px none; -} - -.inline-deletelink:focus, .inline-deletelink:hover { - cursor: pointer; -} - -/* RELATED WIDGET WRAPPER */ -.related-widget-wrapper { - float: left; /* display properly in form rows with multiple fields */ - overflow: hidden; /* clear floated contents */ -} - -.related-widget-wrapper-link { - opacity: 0.3; -} - -.related-widget-wrapper-link:link { - opacity: .8; -} - -.related-widget-wrapper-link:link:focus, -.related-widget-wrapper-link:link:hover { - opacity: 1; -} - -select + .related-widget-wrapper-link, -.related-widget-wrapper-link + .related-widget-wrapper-link { - margin-left: 7px; -} - -/* GIS MAPS */ -.dj_map { - width: 600px; - height: 400px; -} diff --git a/OneCprogsite/static/admin/img/LICENSE b/OneCprogsite/static/admin/img/LICENSE deleted file mode 100644 index a4faaa1..0000000 --- a/OneCprogsite/static/admin/img/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Code Charm Ltd - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/OneCprogsite/static/admin/img/README.txt b/OneCprogsite/static/admin/img/README.txt deleted file mode 100644 index 4eb2e49..0000000 --- a/OneCprogsite/static/admin/img/README.txt +++ /dev/null @@ -1,7 +0,0 @@ -All icons are taken from Font Awesome (http://fontawesome.io/) project. -The Font Awesome font is licensed under the SIL OFL 1.1: -- https://scripts.sil.org/OFL - -SVG icons source: https://github.com/encharm/Font-Awesome-SVG-PNG -Font-Awesome-SVG-PNG is licensed under the MIT license (see file license -in current folder). diff --git a/OneCprogsite/static/admin/img/calendar-icons.svg b/OneCprogsite/static/admin/img/calendar-icons.svg deleted file mode 100644 index dbf21c3..0000000 --- a/OneCprogsite/static/admin/img/calendar-icons.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/OneCprogsite/static/admin/img/gis/move_vertex_off.svg b/OneCprogsite/static/admin/img/gis/move_vertex_off.svg deleted file mode 100644 index 228854f..0000000 --- a/OneCprogsite/static/admin/img/gis/move_vertex_off.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/OneCprogsite/static/admin/img/gis/move_vertex_on.svg b/OneCprogsite/static/admin/img/gis/move_vertex_on.svg deleted file mode 100644 index 96b87fd..0000000 --- a/OneCprogsite/static/admin/img/gis/move_vertex_on.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/OneCprogsite/static/admin/img/icon-addlink.svg b/OneCprogsite/static/admin/img/icon-addlink.svg deleted file mode 100644 index e004fb1..0000000 --- a/OneCprogsite/static/admin/img/icon-addlink.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/OneCprogsite/static/admin/img/icon-alert.svg b/OneCprogsite/static/admin/img/icon-alert.svg deleted file mode 100644 index e51ea83..0000000 --- a/OneCprogsite/static/admin/img/icon-alert.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/OneCprogsite/static/admin/img/icon-calendar.svg b/OneCprogsite/static/admin/img/icon-calendar.svg deleted file mode 100644 index 97910a9..0000000 --- a/OneCprogsite/static/admin/img/icon-calendar.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/OneCprogsite/static/admin/img/icon-changelink.svg b/OneCprogsite/static/admin/img/icon-changelink.svg deleted file mode 100644 index bbb137a..0000000 --- a/OneCprogsite/static/admin/img/icon-changelink.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/OneCprogsite/static/admin/img/icon-clock.svg b/OneCprogsite/static/admin/img/icon-clock.svg deleted file mode 100644 index bf9985d..0000000 --- a/OneCprogsite/static/admin/img/icon-clock.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/OneCprogsite/static/admin/img/icon-deletelink.svg b/OneCprogsite/static/admin/img/icon-deletelink.svg deleted file mode 100644 index 4059b15..0000000 --- a/OneCprogsite/static/admin/img/icon-deletelink.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/OneCprogsite/static/admin/img/icon-no.svg b/OneCprogsite/static/admin/img/icon-no.svg deleted file mode 100644 index 2e0d383..0000000 --- a/OneCprogsite/static/admin/img/icon-no.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/OneCprogsite/static/admin/img/icon-unknown-alt.svg b/OneCprogsite/static/admin/img/icon-unknown-alt.svg deleted file mode 100644 index 1c6b99f..0000000 --- a/OneCprogsite/static/admin/img/icon-unknown-alt.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/OneCprogsite/static/admin/img/icon-unknown.svg b/OneCprogsite/static/admin/img/icon-unknown.svg deleted file mode 100644 index 50b4f97..0000000 --- a/OneCprogsite/static/admin/img/icon-unknown.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/OneCprogsite/static/admin/img/icon-viewlink.svg b/OneCprogsite/static/admin/img/icon-viewlink.svg deleted file mode 100644 index a1ca1d3..0000000 --- a/OneCprogsite/static/admin/img/icon-viewlink.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/OneCprogsite/static/admin/img/icon-yes.svg b/OneCprogsite/static/admin/img/icon-yes.svg deleted file mode 100644 index 5883d87..0000000 --- a/OneCprogsite/static/admin/img/icon-yes.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/OneCprogsite/static/admin/img/inline-delete.svg b/OneCprogsite/static/admin/img/inline-delete.svg deleted file mode 100644 index 17d1ad6..0000000 --- a/OneCprogsite/static/admin/img/inline-delete.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/OneCprogsite/static/admin/img/search.svg b/OneCprogsite/static/admin/img/search.svg deleted file mode 100644 index c8c69b2..0000000 --- a/OneCprogsite/static/admin/img/search.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/OneCprogsite/static/admin/img/selector-icons.svg b/OneCprogsite/static/admin/img/selector-icons.svg deleted file mode 100644 index 926b8e2..0000000 --- a/OneCprogsite/static/admin/img/selector-icons.svg +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/OneCprogsite/static/admin/img/sorting-icons.svg b/OneCprogsite/static/admin/img/sorting-icons.svg deleted file mode 100644 index 7c31ec9..0000000 --- a/OneCprogsite/static/admin/img/sorting-icons.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/OneCprogsite/static/admin/img/tooltag-add.svg b/OneCprogsite/static/admin/img/tooltag-add.svg deleted file mode 100644 index 1ca64ae..0000000 --- a/OneCprogsite/static/admin/img/tooltag-add.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/OneCprogsite/static/admin/img/tooltag-arrowright.svg b/OneCprogsite/static/admin/img/tooltag-arrowright.svg deleted file mode 100644 index b664d61..0000000 --- a/OneCprogsite/static/admin/img/tooltag-arrowright.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/OneCprogsite/static/admin/js/SelectBox.js b/OneCprogsite/static/admin/js/SelectBox.js deleted file mode 100644 index 3db4ec7..0000000 --- a/OneCprogsite/static/admin/js/SelectBox.js +++ /dev/null @@ -1,116 +0,0 @@ -'use strict'; -{ - const SelectBox = { - cache: {}, - init: function(id) { - const box = document.getElementById(id); - SelectBox.cache[id] = []; - const cache = SelectBox.cache[id]; - for (const node of box.options) { - cache.push({value: node.value, text: node.text, displayed: 1}); - } - }, - redisplay: function(id) { - // Repopulate HTML select box from cache - const box = document.getElementById(id); - const scroll_value_from_top = box.scrollTop; - box.innerHTML = ''; - for (const node of SelectBox.cache[id]) { - if (node.displayed) { - const new_option = new Option(node.text, node.value, false, false); - // Shows a tooltip when hovering over the option - new_option.title = node.text; - box.appendChild(new_option); - } - } - box.scrollTop = scroll_value_from_top; - }, - filter: function(id, text) { - // Redisplay the HTML select box, displaying only the choices containing ALL - // the words in text. (It's an AND search.) - const tokens = text.toLowerCase().split(/\s+/); - for (const node of SelectBox.cache[id]) { - node.displayed = 1; - const node_text = node.text.toLowerCase(); - for (const token of tokens) { - if (!node_text.includes(token)) { - node.displayed = 0; - break; // Once the first token isn't found we're done - } - } - } - SelectBox.redisplay(id); - }, - get_hidden_node_count(id) { - const cache = SelectBox.cache[id] || []; - return cache.filter(node => node.displayed === 0).length; - }, - delete_from_cache: function(id, value) { - let delete_index = null; - const cache = SelectBox.cache[id]; - for (const [i, node] of cache.entries()) { - if (node.value === value) { - delete_index = i; - break; - } - } - cache.splice(delete_index, 1); - }, - add_to_cache: function(id, option) { - SelectBox.cache[id].push({value: option.value, text: option.text, displayed: 1}); - }, - cache_contains: function(id, value) { - // Check if an item is contained in the cache - for (const node of SelectBox.cache[id]) { - if (node.value === value) { - return true; - } - } - return false; - }, - move: function(from, to) { - const from_box = document.getElementById(from); - for (const option of from_box.options) { - const option_value = option.value; - if (option.selected && SelectBox.cache_contains(from, option_value)) { - SelectBox.add_to_cache(to, {value: option_value, text: option.text, displayed: 1}); - SelectBox.delete_from_cache(from, option_value); - } - } - SelectBox.redisplay(from); - SelectBox.redisplay(to); - }, - move_all: function(from, to) { - const from_box = document.getElementById(from); - for (const option of from_box.options) { - const option_value = option.value; - if (SelectBox.cache_contains(from, option_value)) { - SelectBox.add_to_cache(to, {value: option_value, text: option.text, displayed: 1}); - SelectBox.delete_from_cache(from, option_value); - } - } - SelectBox.redisplay(from); - SelectBox.redisplay(to); - }, - sort: function(id) { - SelectBox.cache[id].sort(function(a, b) { - a = a.text.toLowerCase(); - b = b.text.toLowerCase(); - if (a > b) { - return 1; - } - if (a < b) { - return -1; - } - return 0; - } ); - }, - select_all: function(id) { - const box = document.getElementById(id); - for (const option of box.options) { - option.selected = true; - } - } - }; - window.SelectBox = SelectBox; -} diff --git a/OneCprogsite/static/admin/js/SelectFilter2.js b/OneCprogsite/static/admin/js/SelectFilter2.js deleted file mode 100644 index 9a4e0a3..0000000 --- a/OneCprogsite/static/admin/js/SelectFilter2.js +++ /dev/null @@ -1,283 +0,0 @@ -/*global SelectBox, gettext, interpolate, quickElement, SelectFilter*/ -/* -SelectFilter2 - Turns a multiple-select box into a filter interface. - -Requires core.js and SelectBox.js. -*/ -'use strict'; -{ - window.SelectFilter = { - init: function(field_id, field_name, is_stacked) { - if (field_id.match(/__prefix__/)) { - // Don't initialize on empty forms. - return; - } - const from_box = document.getElementById(field_id); - from_box.id += '_from'; // change its ID - from_box.className = 'filtered'; - - for (const p of from_box.parentNode.getElementsByTagName('p')) { - if (p.classList.contains("info")) { - // Remove

    , because it just gets in the way. - from_box.parentNode.removeChild(p); - } else if (p.classList.contains("help")) { - // Move help text up to the top so it isn't below the select - // boxes or wrapped off on the side to the right of the add - // button: - from_box.parentNode.insertBefore(p, from_box.parentNode.firstChild); - } - } - - //

    or
    - const selector_div = quickElement('div', from_box.parentNode); - selector_div.className = is_stacked ? 'selector stacked' : 'selector'; - - //
    - const selector_available = quickElement('div', selector_div); - selector_available.className = 'selector-available'; - const title_available = quickElement('h2', selector_available, interpolate(gettext('Available %s') + ' ', [field_name])); - quickElement( - 'span', title_available, '', - 'class', 'help help-tooltip help-icon', - 'title', interpolate( - gettext( - 'This is the list of available %s. You may choose some by ' + - 'selecting them in the box below and then clicking the ' + - '"Choose" arrow between the two boxes.' - ), - [field_name] - ) - ); - - const filter_p = quickElement('p', selector_available, '', 'id', field_id + '_filter'); - filter_p.className = 'selector-filter'; - - const search_filter_label = quickElement('label', filter_p, '', 'for', field_id + '_input'); - - quickElement( - 'span', search_filter_label, '', - 'class', 'help-tooltip search-label-icon', - 'title', interpolate(gettext("Type into this box to filter down the list of available %s."), [field_name]) - ); - - filter_p.appendChild(document.createTextNode(' ')); - - const filter_input = quickElement('input', filter_p, '', 'type', 'text', 'placeholder', gettext("Filter")); - filter_input.id = field_id + '_input'; - - selector_available.appendChild(from_box); - const choose_all = quickElement('a', selector_available, gettext('Choose all'), 'title', interpolate(gettext('Click to choose all %s at once.'), [field_name]), 'href', '#', 'id', field_id + '_add_all_link'); - choose_all.className = 'selector-chooseall'; - - //
      - const selector_chooser = quickElement('ul', selector_div); - selector_chooser.className = 'selector-chooser'; - const add_link = quickElement('a', quickElement('li', selector_chooser), gettext('Choose'), 'title', gettext('Choose'), 'href', '#', 'id', field_id + '_add_link'); - add_link.className = 'selector-add'; - const remove_link = quickElement('a', quickElement('li', selector_chooser), gettext('Remove'), 'title', gettext('Remove'), 'href', '#', 'id', field_id + '_remove_link'); - remove_link.className = 'selector-remove'; - - //
      - const selector_chosen = quickElement('div', selector_div, '', 'id', field_id + '_selector_chosen'); - selector_chosen.className = 'selector-chosen'; - const title_chosen = quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s') + ' ', [field_name])); - quickElement( - 'span', title_chosen, '', - 'class', 'help help-tooltip help-icon', - 'title', interpolate( - gettext( - 'This is the list of chosen %s. You may remove some by ' + - 'selecting them in the box below and then clicking the ' + - '"Remove" arrow between the two boxes.' - ), - [field_name] - ) - ); - - const filter_selected_p = quickElement('p', selector_chosen, '', 'id', field_id + '_filter_selected'); - filter_selected_p.className = 'selector-filter'; - - const search_filter_selected_label = quickElement('label', filter_selected_p, '', 'for', field_id + '_selected_input'); - - quickElement( - 'span', search_filter_selected_label, '', - 'class', 'help-tooltip search-label-icon', - 'title', interpolate(gettext("Type into this box to filter down the list of selected %s."), [field_name]) - ); - - filter_selected_p.appendChild(document.createTextNode(' ')); - - const filter_selected_input = quickElement('input', filter_selected_p, '', 'type', 'text', 'placeholder', gettext("Filter")); - filter_selected_input.id = field_id + '_selected_input'; - - const to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', '', 'size', from_box.size, 'name', from_box.name); - to_box.className = 'filtered'; - - const warning_footer = quickElement('div', selector_chosen, '', 'class', 'list-footer-display'); - quickElement('span', warning_footer, '', 'id', field_id + '_list-footer-display-text'); - quickElement('span', warning_footer, ' (click to clear)', 'class', 'list-footer-display__clear'); - - const clear_all = quickElement('a', selector_chosen, gettext('Remove all'), 'title', interpolate(gettext('Click to remove all chosen %s at once.'), [field_name]), 'href', '#', 'id', field_id + '_remove_all_link'); - clear_all.className = 'selector-clearall'; - - from_box.name = from_box.name + '_old'; - - // Set up the JavaScript event handlers for the select box filter interface - const move_selection = function(e, elem, move_func, from, to) { - if (elem.classList.contains('active')) { - move_func(from, to); - SelectFilter.refresh_icons(field_id); - SelectFilter.refresh_filtered_selects(field_id); - SelectFilter.refresh_filtered_warning(field_id); - } - e.preventDefault(); - }; - choose_all.addEventListener('click', function(e) { - move_selection(e, this, SelectBox.move_all, field_id + '_from', field_id + '_to'); - }); - add_link.addEventListener('click', function(e) { - move_selection(e, this, SelectBox.move, field_id + '_from', field_id + '_to'); - }); - remove_link.addEventListener('click', function(e) { - move_selection(e, this, SelectBox.move, field_id + '_to', field_id + '_from'); - }); - clear_all.addEventListener('click', function(e) { - move_selection(e, this, SelectBox.move_all, field_id + '_to', field_id + '_from'); - }); - warning_footer.addEventListener('click', function(e) { - filter_selected_input.value = ''; - SelectBox.filter(field_id + '_to', ''); - SelectFilter.refresh_filtered_warning(field_id); - SelectFilter.refresh_icons(field_id); - }); - filter_input.addEventListener('keypress', function(e) { - SelectFilter.filter_key_press(e, field_id, '_from', '_to'); - }); - filter_input.addEventListener('keyup', function(e) { - SelectFilter.filter_key_up(e, field_id, '_from'); - }); - filter_input.addEventListener('keydown', function(e) { - SelectFilter.filter_key_down(e, field_id, '_from', '_to'); - }); - filter_selected_input.addEventListener('keypress', function(e) { - SelectFilter.filter_key_press(e, field_id, '_to', '_from'); - }); - filter_selected_input.addEventListener('keyup', function(e) { - SelectFilter.filter_key_up(e, field_id, '_to', '_selected_input'); - }); - filter_selected_input.addEventListener('keydown', function(e) { - SelectFilter.filter_key_down(e, field_id, '_to', '_from'); - }); - selector_div.addEventListener('change', function(e) { - if (e.target.tagName === 'SELECT') { - SelectFilter.refresh_icons(field_id); - } - }); - selector_div.addEventListener('dblclick', function(e) { - if (e.target.tagName === 'OPTION') { - if (e.target.closest('select').id === field_id + '_to') { - SelectBox.move(field_id + '_to', field_id + '_from'); - } else { - SelectBox.move(field_id + '_from', field_id + '_to'); - } - SelectFilter.refresh_icons(field_id); - } - }); - from_box.closest('form').addEventListener('submit', function() { - SelectBox.filter(field_id + '_to', ''); - SelectBox.select_all(field_id + '_to'); - }); - SelectBox.init(field_id + '_from'); - SelectBox.init(field_id + '_to'); - // Move selected from_box options to to_box - SelectBox.move(field_id + '_from', field_id + '_to'); - - // Initial icon refresh - SelectFilter.refresh_icons(field_id); - }, - any_selected: function(field) { - // Temporarily add the required attribute and check validity. - field.required = true; - const any_selected = field.checkValidity(); - field.required = false; - return any_selected; - }, - refresh_filtered_warning: function(field_id) { - const count = SelectBox.get_hidden_node_count(field_id + '_to'); - const selector = document.getElementById(field_id + '_selector_chosen'); - const warning = document.getElementById(field_id + '_list-footer-display-text'); - selector.className = selector.className.replace('selector-chosen--with-filtered', ''); - warning.textContent = interpolate(ngettext( - '%s selected option not visible', - '%s selected options not visible', - count - ), [count]); - if(count > 0) { - selector.className += ' selector-chosen--with-filtered'; - } - }, - refresh_filtered_selects: function(field_id) { - SelectBox.filter(field_id + '_from', document.getElementById(field_id + "_input").value); - SelectBox.filter(field_id + '_to', document.getElementById(field_id + "_selected_input").value); - }, - refresh_icons: function(field_id) { - const from = document.getElementById(field_id + '_from'); - const to = document.getElementById(field_id + '_to'); - // Active if at least one item is selected - document.getElementById(field_id + '_add_link').classList.toggle('active', SelectFilter.any_selected(from)); - document.getElementById(field_id + '_remove_link').classList.toggle('active', SelectFilter.any_selected(to)); - // Active if the corresponding box isn't empty - document.getElementById(field_id + '_add_all_link').classList.toggle('active', from.querySelector('option')); - document.getElementById(field_id + '_remove_all_link').classList.toggle('active', to.querySelector('option')); - SelectFilter.refresh_filtered_warning(field_id); - }, - filter_key_press: function(event, field_id, source, target) { - const source_box = document.getElementById(field_id + source); - // don't submit form if user pressed Enter - if ((event.which && event.which === 13) || (event.keyCode && event.keyCode === 13)) { - source_box.selectedIndex = 0; - SelectBox.move(field_id + source, field_id + target); - source_box.selectedIndex = 0; - event.preventDefault(); - } - }, - filter_key_up: function(event, field_id, source, filter_input) { - const input = filter_input || '_input'; - const source_box = document.getElementById(field_id + source); - const temp = source_box.selectedIndex; - SelectBox.filter(field_id + source, document.getElementById(field_id + input).value); - source_box.selectedIndex = temp; - SelectFilter.refresh_filtered_warning(field_id); - SelectFilter.refresh_icons(field_id); - }, - filter_key_down: function(event, field_id, source, target) { - const source_box = document.getElementById(field_id + source); - // right key (39) or left key (37) - const direction = source === '_from' ? 39 : 37; - // right arrow -- move across - if ((event.which && event.which === direction) || (event.keyCode && event.keyCode === direction)) { - const old_index = source_box.selectedIndex; - SelectBox.move(field_id + source, field_id + target); - SelectFilter.refresh_filtered_selects(field_id); - SelectFilter.refresh_filtered_warning(field_id); - source_box.selectedIndex = (old_index === source_box.length) ? source_box.length - 1 : old_index; - return; - } - // down arrow -- wrap around - if ((event.which && event.which === 40) || (event.keyCode && event.keyCode === 40)) { - source_box.selectedIndex = (source_box.length === source_box.selectedIndex + 1) ? 0 : source_box.selectedIndex + 1; - } - // up arrow -- wrap around - if ((event.which && event.which === 38) || (event.keyCode && event.keyCode === 38)) { - source_box.selectedIndex = (source_box.selectedIndex === 0) ? source_box.length - 1 : source_box.selectedIndex - 1; - } - } - }; - - window.addEventListener('load', function(e) { - document.querySelectorAll('select.selectfilter, select.selectfilterstacked').forEach(function(el) { - const data = el.dataset; - SelectFilter.init(el.id, data.fieldName, parseInt(data.isStacked, 10)); - }); - }); -} diff --git a/OneCprogsite/static/admin/js/actions.js b/OneCprogsite/static/admin/js/actions.js deleted file mode 100644 index 20a5c14..0000000 --- a/OneCprogsite/static/admin/js/actions.js +++ /dev/null @@ -1,201 +0,0 @@ -/*global gettext, interpolate, ngettext*/ -'use strict'; -{ - function show(selector) { - document.querySelectorAll(selector).forEach(function(el) { - el.classList.remove('hidden'); - }); - } - - function hide(selector) { - document.querySelectorAll(selector).forEach(function(el) { - el.classList.add('hidden'); - }); - } - - function showQuestion(options) { - hide(options.acrossClears); - show(options.acrossQuestions); - hide(options.allContainer); - } - - function showClear(options) { - show(options.acrossClears); - hide(options.acrossQuestions); - document.querySelector(options.actionContainer).classList.remove(options.selectedClass); - show(options.allContainer); - hide(options.counterContainer); - } - - function reset(options) { - hide(options.acrossClears); - hide(options.acrossQuestions); - hide(options.allContainer); - show(options.counterContainer); - } - - function clearAcross(options) { - reset(options); - const acrossInputs = document.querySelectorAll(options.acrossInput); - acrossInputs.forEach(function(acrossInput) { - acrossInput.value = 0; - }); - document.querySelector(options.actionContainer).classList.remove(options.selectedClass); - } - - function checker(actionCheckboxes, options, checked) { - if (checked) { - showQuestion(options); - } else { - reset(options); - } - actionCheckboxes.forEach(function(el) { - el.checked = checked; - el.closest('tr').classList.toggle(options.selectedClass, checked); - }); - } - - function updateCounter(actionCheckboxes, options) { - const sel = Array.from(actionCheckboxes).filter(function(el) { - return el.checked; - }).length; - const counter = document.querySelector(options.counterContainer); - // data-actions-icnt is defined in the generated HTML - // and contains the total amount of objects in the queryset - const actions_icnt = Number(counter.dataset.actionsIcnt); - counter.textContent = interpolate( - ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), { - sel: sel, - cnt: actions_icnt - }, true); - const allToggle = document.getElementById(options.allToggleId); - allToggle.checked = sel === actionCheckboxes.length; - if (allToggle.checked) { - showQuestion(options); - } else { - clearAcross(options); - } - } - - const defaults = { - actionContainer: "div.actions", - counterContainer: "span.action-counter", - allContainer: "div.actions span.all", - acrossInput: "div.actions input.select-across", - acrossQuestions: "div.actions span.question", - acrossClears: "div.actions span.clear", - allToggleId: "action-toggle", - selectedClass: "selected" - }; - - window.Actions = function(actionCheckboxes, options) { - options = Object.assign({}, defaults, options); - let list_editable_changed = false; - let lastChecked = null; - let shiftPressed = false; - - document.addEventListener('keydown', (event) => { - shiftPressed = event.shiftKey; - }); - - document.addEventListener('keyup', (event) => { - shiftPressed = event.shiftKey; - }); - - document.getElementById(options.allToggleId).addEventListener('click', function(event) { - checker(actionCheckboxes, options, this.checked); - updateCounter(actionCheckboxes, options); - }); - - document.querySelectorAll(options.acrossQuestions + " a").forEach(function(el) { - el.addEventListener('click', function(event) { - event.preventDefault(); - const acrossInputs = document.querySelectorAll(options.acrossInput); - acrossInputs.forEach(function(acrossInput) { - acrossInput.value = 1; - }); - showClear(options); - }); - }); - - document.querySelectorAll(options.acrossClears + " a").forEach(function(el) { - el.addEventListener('click', function(event) { - event.preventDefault(); - document.getElementById(options.allToggleId).checked = false; - clearAcross(options); - checker(actionCheckboxes, options, false); - updateCounter(actionCheckboxes, options); - }); - }); - - function affectedCheckboxes(target, withModifier) { - const multiSelect = (lastChecked && withModifier && lastChecked !== target); - if (!multiSelect) { - return [target]; - } - const checkboxes = Array.from(actionCheckboxes); - const targetIndex = checkboxes.findIndex(el => el === target); - const lastCheckedIndex = checkboxes.findIndex(el => el === lastChecked); - const startIndex = Math.min(targetIndex, lastCheckedIndex); - const endIndex = Math.max(targetIndex, lastCheckedIndex); - const filtered = checkboxes.filter((el, index) => (startIndex <= index) && (index <= endIndex)); - return filtered; - }; - - Array.from(document.getElementById('result_list').tBodies).forEach(function(el) { - el.addEventListener('change', function(event) { - const target = event.target; - if (target.classList.contains('action-select')) { - const checkboxes = affectedCheckboxes(target, shiftPressed); - checker(checkboxes, options, target.checked); - updateCounter(actionCheckboxes, options); - lastChecked = target; - } else { - list_editable_changed = true; - } - }); - }); - - document.querySelector('#changelist-form button[name=index]').addEventListener('click', function(event) { - if (list_editable_changed) { - const confirmed = confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost.")); - if (!confirmed) { - event.preventDefault(); - } - } - }); - - const el = document.querySelector('#changelist-form input[name=_save]'); - // The button does not exist if no fields are editable. - if (el) { - el.addEventListener('click', function(event) { - if (document.querySelector('[name=action]').value) { - const text = list_editable_changed - ? gettext("You have selected an action, but you haven’t saved your changes to individual fields yet. Please click OK to save. You’ll need to re-run the action.") - : gettext("You have selected an action, and you haven’t made any changes on individual fields. You’re probably looking for the Go button rather than the Save button."); - if (!confirm(text)) { - event.preventDefault(); - } - } - }); - } - }; - - // Call function fn when the DOM is loaded and ready. If it is already - // loaded, call the function now. - // http://youmightnotneedjquery.com/#ready - function ready(fn) { - if (document.readyState !== 'loading') { - fn(); - } else { - document.addEventListener('DOMContentLoaded', fn); - } - } - - ready(function() { - const actionsEls = document.querySelectorAll('tr input.action-select'); - if (actionsEls.length > 0) { - Actions(actionsEls); - } - }); -} diff --git a/OneCprogsite/static/admin/js/admin/DateTimeShortcuts.js b/OneCprogsite/static/admin/js/admin/DateTimeShortcuts.js deleted file mode 100644 index aa1cae9..0000000 --- a/OneCprogsite/static/admin/js/admin/DateTimeShortcuts.js +++ /dev/null @@ -1,408 +0,0 @@ -/*global Calendar, findPosX, findPosY, get_format, gettext, gettext_noop, interpolate, ngettext, quickElement*/ -// Inserts shortcut buttons after all of the following: -// -// -'use strict'; -{ - const DateTimeShortcuts = { - calendars: [], - calendarInputs: [], - clockInputs: [], - clockHours: { - default_: [ - [gettext_noop('Now'), -1], - [gettext_noop('Midnight'), 0], - [gettext_noop('6 a.m.'), 6], - [gettext_noop('Noon'), 12], - [gettext_noop('6 p.m.'), 18] - ] - }, - dismissClockFunc: [], - dismissCalendarFunc: [], - calendarDivName1: 'calendarbox', // name of calendar
      that gets toggled - calendarDivName2: 'calendarin', // name of
      that contains calendar - calendarLinkName: 'calendarlink', // name of the link that is used to toggle - clockDivName: 'clockbox', // name of clock
      that gets toggled - clockLinkName: 'clocklink', // name of the link that is used to toggle - shortCutsClass: 'datetimeshortcuts', // class of the clock and cal shortcuts - timezoneWarningClass: 'timezonewarning', // class of the warning for timezone mismatch - timezoneOffset: 0, - init: function() { - const serverOffset = document.body.dataset.adminUtcOffset; - if (serverOffset) { - const localOffset = new Date().getTimezoneOffset() * -60; - DateTimeShortcuts.timezoneOffset = localOffset - serverOffset; - } - - for (const inp of document.getElementsByTagName('input')) { - if (inp.type === 'text' && inp.classList.contains('vTimeField')) { - DateTimeShortcuts.addClock(inp); - DateTimeShortcuts.addTimezoneWarning(inp); - } - else if (inp.type === 'text' && inp.classList.contains('vDateField')) { - DateTimeShortcuts.addCalendar(inp); - DateTimeShortcuts.addTimezoneWarning(inp); - } - } - }, - // Return the current time while accounting for the server timezone. - now: function() { - const serverOffset = document.body.dataset.adminUtcOffset; - if (serverOffset) { - const localNow = new Date(); - const localOffset = localNow.getTimezoneOffset() * -60; - localNow.setTime(localNow.getTime() + 1000 * (serverOffset - localOffset)); - return localNow; - } else { - return new Date(); - } - }, - // Add a warning when the time zone in the browser and backend do not match. - addTimezoneWarning: function(inp) { - const warningClass = DateTimeShortcuts.timezoneWarningClass; - let timezoneOffset = DateTimeShortcuts.timezoneOffset / 3600; - - // Only warn if there is a time zone mismatch. - if (!timezoneOffset) { - return; - } - - // Check if warning is already there. - if (inp.parentNode.querySelectorAll('.' + warningClass).length) { - return; - } - - let message; - if (timezoneOffset > 0) { - message = ngettext( - 'Note: You are %s hour ahead of server time.', - 'Note: You are %s hours ahead of server time.', - timezoneOffset - ); - } - else { - timezoneOffset *= -1; - message = ngettext( - 'Note: You are %s hour behind server time.', - 'Note: You are %s hours behind server time.', - timezoneOffset - ); - } - message = interpolate(message, [timezoneOffset]); - - const warning = document.createElement('div'); - warning.classList.add('help', warningClass); - warning.textContent = message; - inp.parentNode.appendChild(warning); - }, - // Add clock widget to a given field - addClock: function(inp) { - const num = DateTimeShortcuts.clockInputs.length; - DateTimeShortcuts.clockInputs[num] = inp; - DateTimeShortcuts.dismissClockFunc[num] = function() { DateTimeShortcuts.dismissClock(num); return true; }; - - // Shortcut links (clock icon and "Now" link) - const shortcuts_span = document.createElement('span'); - shortcuts_span.className = DateTimeShortcuts.shortCutsClass; - inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling); - const now_link = document.createElement('a'); - now_link.href = "#"; - now_link.textContent = gettext('Now'); - now_link.addEventListener('click', function(e) { - e.preventDefault(); - DateTimeShortcuts.handleClockQuicklink(num, -1); - }); - const clock_link = document.createElement('a'); - clock_link.href = '#'; - clock_link.id = DateTimeShortcuts.clockLinkName + num; - clock_link.addEventListener('click', function(e) { - e.preventDefault(); - // avoid triggering the document click handler to dismiss the clock - e.stopPropagation(); - DateTimeShortcuts.openClock(num); - }); - - quickElement( - 'span', clock_link, '', - 'class', 'clock-icon', - 'title', gettext('Choose a Time') - ); - shortcuts_span.appendChild(document.createTextNode('\u00A0')); - shortcuts_span.appendChild(now_link); - shortcuts_span.appendChild(document.createTextNode('\u00A0|\u00A0')); - shortcuts_span.appendChild(clock_link); - - // Create clock link div - // - // Markup looks like: - //
      - //

      Choose a time

      - // - //

      Cancel

      - //
      - - const clock_box = document.createElement('div'); - clock_box.style.display = 'none'; - clock_box.style.position = 'absolute'; - clock_box.className = 'clockbox module'; - clock_box.id = DateTimeShortcuts.clockDivName + num; - document.body.appendChild(clock_box); - clock_box.addEventListener('click', function(e) { e.stopPropagation(); }); - - quickElement('h2', clock_box, gettext('Choose a time')); - const time_list = quickElement('ul', clock_box); - time_list.className = 'timelist'; - // The list of choices can be overridden in JavaScript like this: - // DateTimeShortcuts.clockHours.name = [['3 a.m.', 3]]; - // where name is the name attribute of the . - const name = typeof DateTimeShortcuts.clockHours[inp.name] === 'undefined' ? 'default_' : inp.name; - DateTimeShortcuts.clockHours[name].forEach(function(element) { - const time_link = quickElement('a', quickElement('li', time_list), gettext(element[0]), 'href', '#'); - time_link.addEventListener('click', function(e) { - e.preventDefault(); - DateTimeShortcuts.handleClockQuicklink(num, element[1]); - }); - }); - - const cancel_p = quickElement('p', clock_box); - cancel_p.className = 'calendar-cancel'; - const cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'href', '#'); - cancel_link.addEventListener('click', function(e) { - e.preventDefault(); - DateTimeShortcuts.dismissClock(num); - }); - - document.addEventListener('keyup', function(event) { - if (event.which === 27) { - // ESC key closes popup - DateTimeShortcuts.dismissClock(num); - event.preventDefault(); - } - }); - }, - openClock: function(num) { - const clock_box = document.getElementById(DateTimeShortcuts.clockDivName + num); - const clock_link = document.getElementById(DateTimeShortcuts.clockLinkName + num); - - // Recalculate the clockbox position - // is it left-to-right or right-to-left layout ? - if (window.getComputedStyle(document.body).direction !== 'rtl') { - clock_box.style.left = findPosX(clock_link) + 17 + 'px'; - } - else { - // since style's width is in em, it'd be tough to calculate - // px value of it. let's use an estimated px for now - clock_box.style.left = findPosX(clock_link) - 110 + 'px'; - } - clock_box.style.top = Math.max(0, findPosY(clock_link) - 30) + 'px'; - - // Show the clock box - clock_box.style.display = 'block'; - document.addEventListener('click', DateTimeShortcuts.dismissClockFunc[num]); - }, - dismissClock: function(num) { - document.getElementById(DateTimeShortcuts.clockDivName + num).style.display = 'none'; - document.removeEventListener('click', DateTimeShortcuts.dismissClockFunc[num]); - }, - handleClockQuicklink: function(num, val) { - let d; - if (val === -1) { - d = DateTimeShortcuts.now(); - } - else { - d = new Date(1970, 1, 1, val, 0, 0, 0); - } - DateTimeShortcuts.clockInputs[num].value = d.strftime(get_format('TIME_INPUT_FORMATS')[0]); - DateTimeShortcuts.clockInputs[num].focus(); - DateTimeShortcuts.dismissClock(num); - }, - // Add calendar widget to a given field. - addCalendar: function(inp) { - const num = DateTimeShortcuts.calendars.length; - - DateTimeShortcuts.calendarInputs[num] = inp; - DateTimeShortcuts.dismissCalendarFunc[num] = function() { DateTimeShortcuts.dismissCalendar(num); return true; }; - - // Shortcut links (calendar icon and "Today" link) - const shortcuts_span = document.createElement('span'); - shortcuts_span.className = DateTimeShortcuts.shortCutsClass; - inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling); - const today_link = document.createElement('a'); - today_link.href = '#'; - today_link.appendChild(document.createTextNode(gettext('Today'))); - today_link.addEventListener('click', function(e) { - e.preventDefault(); - DateTimeShortcuts.handleCalendarQuickLink(num, 0); - }); - const cal_link = document.createElement('a'); - cal_link.href = '#'; - cal_link.id = DateTimeShortcuts.calendarLinkName + num; - cal_link.addEventListener('click', function(e) { - e.preventDefault(); - // avoid triggering the document click handler to dismiss the calendar - e.stopPropagation(); - DateTimeShortcuts.openCalendar(num); - }); - quickElement( - 'span', cal_link, '', - 'class', 'date-icon', - 'title', gettext('Choose a Date') - ); - shortcuts_span.appendChild(document.createTextNode('\u00A0')); - shortcuts_span.appendChild(today_link); - shortcuts_span.appendChild(document.createTextNode('\u00A0|\u00A0')); - shortcuts_span.appendChild(cal_link); - - // Create calendarbox div. - // - // Markup looks like: - // - //
      - //

      - // - // February 2003 - //

      - //
      - // - //
      - //
      - // Yesterday | Today | Tomorrow - //
      - //

      Cancel

      - //
      - const cal_box = document.createElement('div'); - cal_box.style.display = 'none'; - cal_box.style.position = 'absolute'; - cal_box.className = 'calendarbox module'; - cal_box.id = DateTimeShortcuts.calendarDivName1 + num; - document.body.appendChild(cal_box); - cal_box.addEventListener('click', function(e) { e.stopPropagation(); }); - - // next-prev links - const cal_nav = quickElement('div', cal_box); - const cal_nav_prev = quickElement('a', cal_nav, '<', 'href', '#'); - cal_nav_prev.className = 'calendarnav-previous'; - cal_nav_prev.addEventListener('click', function(e) { - e.preventDefault(); - DateTimeShortcuts.drawPrev(num); - }); - - const cal_nav_next = quickElement('a', cal_nav, '>', 'href', '#'); - cal_nav_next.className = 'calendarnav-next'; - cal_nav_next.addEventListener('click', function(e) { - e.preventDefault(); - DateTimeShortcuts.drawNext(num); - }); - - // main box - const cal_main = quickElement('div', cal_box, '', 'id', DateTimeShortcuts.calendarDivName2 + num); - cal_main.className = 'calendar'; - DateTimeShortcuts.calendars[num] = new Calendar(DateTimeShortcuts.calendarDivName2 + num, DateTimeShortcuts.handleCalendarCallback(num)); - DateTimeShortcuts.calendars[num].drawCurrent(); - - // calendar shortcuts - const shortcuts = quickElement('div', cal_box); - shortcuts.className = 'calendar-shortcuts'; - let day_link = quickElement('a', shortcuts, gettext('Yesterday'), 'href', '#'); - day_link.addEventListener('click', function(e) { - e.preventDefault(); - DateTimeShortcuts.handleCalendarQuickLink(num, -1); - }); - shortcuts.appendChild(document.createTextNode('\u00A0|\u00A0')); - day_link = quickElement('a', shortcuts, gettext('Today'), 'href', '#'); - day_link.addEventListener('click', function(e) { - e.preventDefault(); - DateTimeShortcuts.handleCalendarQuickLink(num, 0); - }); - shortcuts.appendChild(document.createTextNode('\u00A0|\u00A0')); - day_link = quickElement('a', shortcuts, gettext('Tomorrow'), 'href', '#'); - day_link.addEventListener('click', function(e) { - e.preventDefault(); - DateTimeShortcuts.handleCalendarQuickLink(num, +1); - }); - - // cancel bar - const cancel_p = quickElement('p', cal_box); - cancel_p.className = 'calendar-cancel'; - const cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'href', '#'); - cancel_link.addEventListener('click', function(e) { - e.preventDefault(); - DateTimeShortcuts.dismissCalendar(num); - }); - document.addEventListener('keyup', function(event) { - if (event.which === 27) { - // ESC key closes popup - DateTimeShortcuts.dismissCalendar(num); - event.preventDefault(); - } - }); - }, - openCalendar: function(num) { - const cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1 + num); - const cal_link = document.getElementById(DateTimeShortcuts.calendarLinkName + num); - const inp = DateTimeShortcuts.calendarInputs[num]; - - // Determine if the current value in the input has a valid date. - // If so, draw the calendar with that date's year and month. - if (inp.value) { - const format = get_format('DATE_INPUT_FORMATS')[0]; - const selected = inp.value.strptime(format); - const year = selected.getUTCFullYear(); - const month = selected.getUTCMonth() + 1; - const re = /\d{4}/; - if (re.test(year.toString()) && month >= 1 && month <= 12) { - DateTimeShortcuts.calendars[num].drawDate(month, year, selected); - } - } - - // Recalculate the clockbox position - // is it left-to-right or right-to-left layout ? - if (window.getComputedStyle(document.body).direction !== 'rtl') { - cal_box.style.left = findPosX(cal_link) + 17 + 'px'; - } - else { - // since style's width is in em, it'd be tough to calculate - // px value of it. let's use an estimated px for now - cal_box.style.left = findPosX(cal_link) - 180 + 'px'; - } - cal_box.style.top = Math.max(0, findPosY(cal_link) - 75) + 'px'; - - cal_box.style.display = 'block'; - document.addEventListener('click', DateTimeShortcuts.dismissCalendarFunc[num]); - }, - dismissCalendar: function(num) { - document.getElementById(DateTimeShortcuts.calendarDivName1 + num).style.display = 'none'; - document.removeEventListener('click', DateTimeShortcuts.dismissCalendarFunc[num]); - }, - drawPrev: function(num) { - DateTimeShortcuts.calendars[num].drawPreviousMonth(); - }, - drawNext: function(num) { - DateTimeShortcuts.calendars[num].drawNextMonth(); - }, - handleCalendarCallback: function(num) { - const format = get_format('DATE_INPUT_FORMATS')[0]; - return function(y, m, d) { - DateTimeShortcuts.calendarInputs[num].value = new Date(y, m - 1, d).strftime(format); - DateTimeShortcuts.calendarInputs[num].focus(); - document.getElementById(DateTimeShortcuts.calendarDivName1 + num).style.display = 'none'; - }; - }, - handleCalendarQuickLink: function(num, offset) { - const d = DateTimeShortcuts.now(); - d.setDate(d.getDate() + offset); - DateTimeShortcuts.calendarInputs[num].value = d.strftime(get_format('DATE_INPUT_FORMATS')[0]); - DateTimeShortcuts.calendarInputs[num].focus(); - DateTimeShortcuts.dismissCalendar(num); - } - }; - - window.addEventListener('load', DateTimeShortcuts.init); - window.DateTimeShortcuts = DateTimeShortcuts; -} diff --git a/OneCprogsite/static/admin/js/admin/RelatedObjectLookups.js b/OneCprogsite/static/admin/js/admin/RelatedObjectLookups.js deleted file mode 100644 index afb6b66..0000000 --- a/OneCprogsite/static/admin/js/admin/RelatedObjectLookups.js +++ /dev/null @@ -1,238 +0,0 @@ -/*global SelectBox, interpolate*/ -// Handles related-objects functionality: lookup link for raw_id_fields -// and Add Another links. -'use strict'; -{ - const $ = django.jQuery; - let popupIndex = 0; - const relatedWindows = []; - - function dismissChildPopups() { - relatedWindows.forEach(function(win) { - if(!win.closed) { - win.dismissChildPopups(); - win.close(); - } - }); - } - - function setPopupIndex() { - if(document.getElementsByName("_popup").length > 0) { - const index = window.name.lastIndexOf("__") + 2; - popupIndex = parseInt(window.name.substring(index)); - } else { - popupIndex = 0; - } - } - - function addPopupIndex(name) { - return name + "__" + (popupIndex + 1); - } - - function removePopupIndex(name) { - return name.replace(new RegExp("__" + (popupIndex + 1) + "$"), ''); - } - - function showAdminPopup(triggeringLink, name_regexp, add_popup) { - const name = addPopupIndex(triggeringLink.id.replace(name_regexp, '')); - const href = new URL(triggeringLink.href); - if (add_popup) { - href.searchParams.set('_popup', 1); - } - const win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes'); - relatedWindows.push(win); - win.focus(); - return false; - } - - function showRelatedObjectLookupPopup(triggeringLink) { - return showAdminPopup(triggeringLink, /^lookup_/, true); - } - - function dismissRelatedLookupPopup(win, chosenId) { - const name = removePopupIndex(win.name); - const elem = document.getElementById(name); - if (elem.classList.contains('vManyToManyRawIdAdminField') && elem.value) { - elem.value += ',' + chosenId; - } else { - document.getElementById(name).value = chosenId; - } - const index = relatedWindows.indexOf(win); - if (index > -1) { - relatedWindows.splice(index, 1); - } - win.close(); - } - - function showRelatedObjectPopup(triggeringLink) { - return showAdminPopup(triggeringLink, /^(change|add|delete)_/, false); - } - - function updateRelatedObjectLinks(triggeringLink) { - const $this = $(triggeringLink); - const siblings = $this.nextAll('.view-related, .change-related, .delete-related'); - if (!siblings.length) { - return; - } - const value = $this.val(); - if (value) { - siblings.each(function() { - const elm = $(this); - elm.attr('href', elm.attr('data-href-template').replace('__fk__', value)); - }); - } else { - siblings.removeAttr('href'); - } - } - - function updateRelatedSelectsOptions(currentSelect, win, objId, newRepr, newId) { - // After create/edit a model from the options next to the current - // select (+ or :pencil:) update ForeignKey PK of the rest of selects - // in the page. - - const path = win.location.pathname; - // Extract the model from the popup url '...//add/' or - // '...///change/' depending the action (add or change). - const modelName = path.split('/')[path.split('/').length - (objId ? 4 : 3)]; - // Exclude autocomplete selects. - const selectsRelated = document.querySelectorAll(`[data-model-ref="${modelName}"] select:not(.admin-autocomplete)`); - - selectsRelated.forEach(function(select) { - if (currentSelect === select) { - return; - } - - let option = select.querySelector(`option[value="${objId}"]`); - - if (!option) { - option = new Option(newRepr, newId); - select.options.add(option); - return; - } - - option.textContent = newRepr; - option.value = newId; - }); - } - - function dismissAddRelatedObjectPopup(win, newId, newRepr) { - const name = removePopupIndex(win.name); - const elem = document.getElementById(name); - if (elem) { - const elemName = elem.nodeName.toUpperCase(); - if (elemName === 'SELECT') { - elem.options[elem.options.length] = new Option(newRepr, newId, true, true); - updateRelatedSelectsOptions(elem, win, null, newRepr, newId); - } else if (elemName === 'INPUT') { - if (elem.classList.contains('vManyToManyRawIdAdminField') && elem.value) { - elem.value += ',' + newId; - } else { - elem.value = newId; - } - } - // Trigger a change event to update related links if required. - $(elem).trigger('change'); - } else { - const toId = name + "_to"; - const o = new Option(newRepr, newId); - SelectBox.add_to_cache(toId, o); - SelectBox.redisplay(toId); - } - const index = relatedWindows.indexOf(win); - if (index > -1) { - relatedWindows.splice(index, 1); - } - win.close(); - } - - function dismissChangeRelatedObjectPopup(win, objId, newRepr, newId) { - const id = removePopupIndex(win.name.replace(/^edit_/, '')); - const selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]); - const selects = $(selectsSelector); - selects.find('option').each(function() { - if (this.value === objId) { - this.textContent = newRepr; - this.value = newId; - } - }).trigger('change'); - updateRelatedSelectsOptions(selects[0], win, objId, newRepr, newId); - selects.next().find('.select2-selection__rendered').each(function() { - // The element can have a clear button as a child. - // Use the lastChild to modify only the displayed value. - this.lastChild.textContent = newRepr; - this.title = newRepr; - }); - const index = relatedWindows.indexOf(win); - if (index > -1) { - relatedWindows.splice(index, 1); - } - win.close(); - } - - function dismissDeleteRelatedObjectPopup(win, objId) { - const id = removePopupIndex(win.name.replace(/^delete_/, '')); - const selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]); - const selects = $(selectsSelector); - selects.find('option').each(function() { - if (this.value === objId) { - $(this).remove(); - } - }).trigger('change'); - const index = relatedWindows.indexOf(win); - if (index > -1) { - relatedWindows.splice(index, 1); - } - win.close(); - } - - window.showRelatedObjectLookupPopup = showRelatedObjectLookupPopup; - window.dismissRelatedLookupPopup = dismissRelatedLookupPopup; - window.showRelatedObjectPopup = showRelatedObjectPopup; - window.updateRelatedObjectLinks = updateRelatedObjectLinks; - window.dismissAddRelatedObjectPopup = dismissAddRelatedObjectPopup; - window.dismissChangeRelatedObjectPopup = dismissChangeRelatedObjectPopup; - window.dismissDeleteRelatedObjectPopup = dismissDeleteRelatedObjectPopup; - window.dismissChildPopups = dismissChildPopups; - - // Kept for backward compatibility - window.showAddAnotherPopup = showRelatedObjectPopup; - window.dismissAddAnotherPopup = dismissAddRelatedObjectPopup; - - window.addEventListener('unload', function(evt) { - window.dismissChildPopups(); - }); - - $(document).ready(function() { - setPopupIndex(); - $("a[data-popup-opener]").on('click', function(event) { - event.preventDefault(); - opener.dismissRelatedLookupPopup(window, $(this).data("popup-opener")); - }); - $('body').on('click', '.related-widget-wrapper-link[data-popup="yes"]', function(e) { - e.preventDefault(); - if (this.href) { - const event = $.Event('django:show-related', {href: this.href}); - $(this).trigger(event); - if (!event.isDefaultPrevented()) { - showRelatedObjectPopup(this); - } - } - }); - $('body').on('change', '.related-widget-wrapper select', function(e) { - const event = $.Event('django:update-related'); - $(this).trigger(event); - if (!event.isDefaultPrevented()) { - updateRelatedObjectLinks(this); - } - }); - $('.related-widget-wrapper select').trigger('change'); - $('body').on('click', '.related-lookup', function(e) { - e.preventDefault(); - const event = $.Event('django:lookup-related'); - $(this).trigger(event); - if (!event.isDefaultPrevented()) { - showRelatedObjectLookupPopup(this); - } - }); - }); -} diff --git a/OneCprogsite/static/admin/js/autocomplete.js b/OneCprogsite/static/admin/js/autocomplete.js deleted file mode 100644 index d3daeab..0000000 --- a/OneCprogsite/static/admin/js/autocomplete.js +++ /dev/null @@ -1,33 +0,0 @@ -'use strict'; -{ - const $ = django.jQuery; - - $.fn.djangoAdminSelect2 = function() { - $.each(this, function(i, element) { - $(element).select2({ - ajax: { - data: (params) => { - return { - term: params.term, - page: params.page, - app_label: element.dataset.appLabel, - model_name: element.dataset.modelName, - field_name: element.dataset.fieldName - }; - } - } - }); - }); - return this; - }; - - $(function() { - // Initialize all autocomplete widgets except the one in the template - // form used when a new formset is added. - $('.admin-autocomplete').not('[name*=__prefix__]').djangoAdminSelect2(); - }); - - document.addEventListener('formset:added', (event) => { - $(event.target).find('.admin-autocomplete').djangoAdminSelect2(); - }); -} diff --git a/OneCprogsite/static/admin/js/calendar.js b/OneCprogsite/static/admin/js/calendar.js deleted file mode 100644 index a62d10a..0000000 --- a/OneCprogsite/static/admin/js/calendar.js +++ /dev/null @@ -1,221 +0,0 @@ -/*global gettext, pgettext, get_format, quickElement, removeChildren*/ -/* -calendar.js - Calendar functions by Adrian Holovaty -depends on core.js for utility functions like removeChildren or quickElement -*/ -'use strict'; -{ - // CalendarNamespace -- Provides a collection of HTML calendar-related helper functions - const CalendarNamespace = { - monthsOfYear: [ - gettext('January'), - gettext('February'), - gettext('March'), - gettext('April'), - gettext('May'), - gettext('June'), - gettext('July'), - gettext('August'), - gettext('September'), - gettext('October'), - gettext('November'), - gettext('December') - ], - monthsOfYearAbbrev: [ - pgettext('abbrev. month January', 'Jan'), - pgettext('abbrev. month February', 'Feb'), - pgettext('abbrev. month March', 'Mar'), - pgettext('abbrev. month April', 'Apr'), - pgettext('abbrev. month May', 'May'), - pgettext('abbrev. month June', 'Jun'), - pgettext('abbrev. month July', 'Jul'), - pgettext('abbrev. month August', 'Aug'), - pgettext('abbrev. month September', 'Sep'), - pgettext('abbrev. month October', 'Oct'), - pgettext('abbrev. month November', 'Nov'), - pgettext('abbrev. month December', 'Dec') - ], - daysOfWeek: [ - pgettext('one letter Sunday', 'S'), - pgettext('one letter Monday', 'M'), - pgettext('one letter Tuesday', 'T'), - pgettext('one letter Wednesday', 'W'), - pgettext('one letter Thursday', 'T'), - pgettext('one letter Friday', 'F'), - pgettext('one letter Saturday', 'S') - ], - firstDayOfWeek: parseInt(get_format('FIRST_DAY_OF_WEEK')), - isLeapYear: function(year) { - return (((year % 4) === 0) && ((year % 100) !== 0 ) || ((year % 400) === 0)); - }, - getDaysInMonth: function(month, year) { - let days; - if (month === 1 || month === 3 || month === 5 || month === 7 || month === 8 || month === 10 || month === 12) { - days = 31; - } - else if (month === 4 || month === 6 || month === 9 || month === 11) { - days = 30; - } - else if (month === 2 && CalendarNamespace.isLeapYear(year)) { - days = 29; - } - else { - days = 28; - } - return days; - }, - draw: function(month, year, div_id, callback, selected) { // month = 1-12, year = 1-9999 - const today = new Date(); - const todayDay = today.getDate(); - const todayMonth = today.getMonth() + 1; - const todayYear = today.getFullYear(); - let todayClass = ''; - - // Use UTC functions here because the date field does not contain time - // and using the UTC function variants prevent the local time offset - // from altering the date, specifically the day field. For example: - // - // ``` - // var x = new Date('2013-10-02'); - // var day = x.getDate(); - // ``` - // - // The day variable above will be 1 instead of 2 in, say, US Pacific time - // zone. - let isSelectedMonth = false; - if (typeof selected !== 'undefined') { - isSelectedMonth = (selected.getUTCFullYear() === year && (selected.getUTCMonth() + 1) === month); - } - - month = parseInt(month); - year = parseInt(year); - const calDiv = document.getElementById(div_id); - removeChildren(calDiv); - const calTable = document.createElement('table'); - quickElement('caption', calTable, CalendarNamespace.monthsOfYear[month - 1] + ' ' + year); - const tableBody = quickElement('tbody', calTable); - - // Draw days-of-week header - let tableRow = quickElement('tr', tableBody); - for (let i = 0; i < 7; i++) { - quickElement('th', tableRow, CalendarNamespace.daysOfWeek[(i + CalendarNamespace.firstDayOfWeek) % 7]); - } - - const startingPos = new Date(year, month - 1, 1 - CalendarNamespace.firstDayOfWeek).getDay(); - const days = CalendarNamespace.getDaysInMonth(month, year); - - let nonDayCell; - - // Draw blanks before first of month - tableRow = quickElement('tr', tableBody); - for (let i = 0; i < startingPos; i++) { - nonDayCell = quickElement('td', tableRow, ' '); - nonDayCell.className = "nonday"; - } - - function calendarMonth(y, m) { - function onClick(e) { - e.preventDefault(); - callback(y, m, this.textContent); - } - return onClick; - } - - // Draw days of month - let currentDay = 1; - for (let i = startingPos; currentDay <= days; i++) { - if (i % 7 === 0 && currentDay !== 1) { - tableRow = quickElement('tr', tableBody); - } - if ((currentDay === todayDay) && (month === todayMonth) && (year === todayYear)) { - todayClass = 'today'; - } else { - todayClass = ''; - } - - // use UTC function; see above for explanation. - if (isSelectedMonth && currentDay === selected.getUTCDate()) { - if (todayClass !== '') { - todayClass += " "; - } - todayClass += "selected"; - } - - const cell = quickElement('td', tableRow, '', 'class', todayClass); - const link = quickElement('a', cell, currentDay, 'href', '#'); - link.addEventListener('click', calendarMonth(year, month)); - currentDay++; - } - - // Draw blanks after end of month (optional, but makes for valid code) - while (tableRow.childNodes.length < 7) { - nonDayCell = quickElement('td', tableRow, ' '); - nonDayCell.className = "nonday"; - } - - calDiv.appendChild(calTable); - } - }; - - // Calendar -- A calendar instance - function Calendar(div_id, callback, selected) { - // div_id (string) is the ID of the element in which the calendar will - // be displayed - // callback (string) is the name of a JavaScript function that will be - // called with the parameters (year, month, day) when a day in the - // calendar is clicked - this.div_id = div_id; - this.callback = callback; - this.today = new Date(); - this.currentMonth = this.today.getMonth() + 1; - this.currentYear = this.today.getFullYear(); - if (typeof selected !== 'undefined') { - this.selected = selected; - } - } - Calendar.prototype = { - drawCurrent: function() { - CalendarNamespace.draw(this.currentMonth, this.currentYear, this.div_id, this.callback, this.selected); - }, - drawDate: function(month, year, selected) { - this.currentMonth = month; - this.currentYear = year; - - if(selected) { - this.selected = selected; - } - - this.drawCurrent(); - }, - drawPreviousMonth: function() { - if (this.currentMonth === 1) { - this.currentMonth = 12; - this.currentYear--; - } - else { - this.currentMonth--; - } - this.drawCurrent(); - }, - drawNextMonth: function() { - if (this.currentMonth === 12) { - this.currentMonth = 1; - this.currentYear++; - } - else { - this.currentMonth++; - } - this.drawCurrent(); - }, - drawPreviousYear: function() { - this.currentYear--; - this.drawCurrent(); - }, - drawNextYear: function() { - this.currentYear++; - this.drawCurrent(); - } - }; - window.Calendar = Calendar; - window.CalendarNamespace = CalendarNamespace; -} diff --git a/OneCprogsite/static/admin/js/cancel.js b/OneCprogsite/static/admin/js/cancel.js deleted file mode 100644 index 3069c6f..0000000 --- a/OneCprogsite/static/admin/js/cancel.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict'; -{ - // Call function fn when the DOM is loaded and ready. If it is already - // loaded, call the function now. - // http://youmightnotneedjquery.com/#ready - function ready(fn) { - if (document.readyState !== 'loading') { - fn(); - } else { - document.addEventListener('DOMContentLoaded', fn); - } - } - - ready(function() { - function handleClick(event) { - event.preventDefault(); - const params = new URLSearchParams(window.location.search); - if (params.has('_popup')) { - window.close(); // Close the popup. - } else { - window.history.back(); // Otherwise, go back. - } - } - - document.querySelectorAll('.cancel-link').forEach(function(el) { - el.addEventListener('click', handleClick); - }); - }); -} diff --git a/OneCprogsite/static/admin/js/change_form.js b/OneCprogsite/static/admin/js/change_form.js deleted file mode 100644 index 96a4c62..0000000 --- a/OneCprogsite/static/admin/js/change_form.js +++ /dev/null @@ -1,16 +0,0 @@ -'use strict'; -{ - const inputTags = ['BUTTON', 'INPUT', 'SELECT', 'TEXTAREA']; - const modelName = document.getElementById('django-admin-form-add-constants').dataset.modelName; - if (modelName) { - const form = document.getElementById(modelName + '_form'); - for (const element of form.elements) { - // HTMLElement.offsetParent returns null when the element is not - // rendered. - if (inputTags.includes(element.tagName) && !element.disabled && element.offsetParent) { - element.focus(); - break; - } - } - } -} diff --git a/OneCprogsite/static/admin/js/collapse.js b/OneCprogsite/static/admin/js/collapse.js deleted file mode 100644 index c6c7b0f..0000000 --- a/OneCprogsite/static/admin/js/collapse.js +++ /dev/null @@ -1,43 +0,0 @@ -/*global gettext*/ -'use strict'; -{ - window.addEventListener('load', function() { - // Add anchor tag for Show/Hide link - const fieldsets = document.querySelectorAll('fieldset.collapse'); - for (const [i, elem] of fieldsets.entries()) { - // Don't hide if fields in this fieldset have errors - if (elem.querySelectorAll('div.errors, ul.errorlist').length === 0) { - elem.classList.add('collapsed'); - const h2 = elem.querySelector('h2'); - const link = document.createElement('a'); - link.id = 'fieldsetcollapser' + i; - link.className = 'collapse-toggle'; - link.href = '#'; - link.textContent = gettext('Show'); - h2.appendChild(document.createTextNode(' (')); - h2.appendChild(link); - h2.appendChild(document.createTextNode(')')); - } - } - // Add toggle to hide/show anchor tag - const toggleFunc = function(ev) { - if (ev.target.matches('.collapse-toggle')) { - ev.preventDefault(); - ev.stopPropagation(); - const fieldset = ev.target.closest('fieldset'); - if (fieldset.classList.contains('collapsed')) { - // Show - ev.target.textContent = gettext('Hide'); - fieldset.classList.remove('collapsed'); - } else { - // Hide - ev.target.textContent = gettext('Show'); - fieldset.classList.add('collapsed'); - } - } - }; - document.querySelectorAll('fieldset.module').forEach(function(el) { - el.addEventListener('click', toggleFunc); - }); - }); -} diff --git a/OneCprogsite/static/admin/js/core.js b/OneCprogsite/static/admin/js/core.js deleted file mode 100644 index 0344a13..0000000 --- a/OneCprogsite/static/admin/js/core.js +++ /dev/null @@ -1,170 +0,0 @@ -// Core JavaScript helper functions -'use strict'; - -// quickElement(tagType, parentReference [, textInChildNode, attribute, attributeValue ...]); -function quickElement() { - const obj = document.createElement(arguments[0]); - if (arguments[2]) { - const textNode = document.createTextNode(arguments[2]); - obj.appendChild(textNode); - } - const len = arguments.length; - for (let i = 3; i < len; i += 2) { - obj.setAttribute(arguments[i], arguments[i + 1]); - } - arguments[1].appendChild(obj); - return obj; -} - -// "a" is reference to an object -function removeChildren(a) { - while (a.hasChildNodes()) { - a.removeChild(a.lastChild); - } -} - -// ---------------------------------------------------------------------------- -// Find-position functions by PPK -// See https://www.quirksmode.org/js/findpos.html -// ---------------------------------------------------------------------------- -function findPosX(obj) { - let curleft = 0; - if (obj.offsetParent) { - while (obj.offsetParent) { - curleft += obj.offsetLeft - obj.scrollLeft; - obj = obj.offsetParent; - } - } else if (obj.x) { - curleft += obj.x; - } - return curleft; -} - -function findPosY(obj) { - let curtop = 0; - if (obj.offsetParent) { - while (obj.offsetParent) { - curtop += obj.offsetTop - obj.scrollTop; - obj = obj.offsetParent; - } - } else if (obj.y) { - curtop += obj.y; - } - return curtop; -} - -//----------------------------------------------------------------------------- -// Date object extensions -// ---------------------------------------------------------------------------- -{ - Date.prototype.getTwelveHours = function() { - return this.getHours() % 12 || 12; - }; - - Date.prototype.getTwoDigitMonth = function() { - return (this.getMonth() < 9) ? '0' + (this.getMonth() + 1) : (this.getMonth() + 1); - }; - - Date.prototype.getTwoDigitDate = function() { - return (this.getDate() < 10) ? '0' + this.getDate() : this.getDate(); - }; - - Date.prototype.getTwoDigitTwelveHour = function() { - return (this.getTwelveHours() < 10) ? '0' + this.getTwelveHours() : this.getTwelveHours(); - }; - - Date.prototype.getTwoDigitHour = function() { - return (this.getHours() < 10) ? '0' + this.getHours() : this.getHours(); - }; - - Date.prototype.getTwoDigitMinute = function() { - return (this.getMinutes() < 10) ? '0' + this.getMinutes() : this.getMinutes(); - }; - - Date.prototype.getTwoDigitSecond = function() { - return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds(); - }; - - Date.prototype.getAbbrevMonthName = function() { - return typeof window.CalendarNamespace === "undefined" - ? this.getTwoDigitMonth() - : window.CalendarNamespace.monthsOfYearAbbrev[this.getMonth()]; - }; - - Date.prototype.getFullMonthName = function() { - return typeof window.CalendarNamespace === "undefined" - ? this.getTwoDigitMonth() - : window.CalendarNamespace.monthsOfYear[this.getMonth()]; - }; - - Date.prototype.strftime = function(format) { - const fields = { - b: this.getAbbrevMonthName(), - B: this.getFullMonthName(), - c: this.toString(), - d: this.getTwoDigitDate(), - H: this.getTwoDigitHour(), - I: this.getTwoDigitTwelveHour(), - m: this.getTwoDigitMonth(), - M: this.getTwoDigitMinute(), - p: (this.getHours() >= 12) ? 'PM' : 'AM', - S: this.getTwoDigitSecond(), - w: '0' + this.getDay(), - x: this.toLocaleDateString(), - X: this.toLocaleTimeString(), - y: ('' + this.getFullYear()).substr(2, 4), - Y: '' + this.getFullYear(), - '%': '%' - }; - let result = '', i = 0; - while (i < format.length) { - if (format.charAt(i) === '%') { - result += fields[format.charAt(i + 1)]; - ++i; - } - else { - result += format.charAt(i); - } - ++i; - } - return result; - }; - - // ---------------------------------------------------------------------------- - // String object extensions - // ---------------------------------------------------------------------------- - String.prototype.strptime = function(format) { - const split_format = format.split(/[.\-/]/); - const date = this.split(/[.\-/]/); - let i = 0; - let day, month, year; - while (i < split_format.length) { - switch (split_format[i]) { - case "%d": - day = date[i]; - break; - case "%m": - month = date[i] - 1; - break; - case "%Y": - year = date[i]; - break; - case "%y": - // A %y value in the range of [00, 68] is in the current - // century, while [69, 99] is in the previous century, - // according to the Open Group Specification. - if (parseInt(date[i], 10) >= 69) { - year = date[i]; - } else { - year = (new Date(Date.UTC(date[i], 0))).getUTCFullYear() + 100; - } - break; - } - ++i; - } - // Create Date object from UTC since the parsed value is supposed to be - // in UTC, not local time. Also, the calendar uses UTC functions for - // date extraction. - return new Date(Date.UTC(year, month, day)); - }; -} diff --git a/OneCprogsite/static/admin/js/filters.js b/OneCprogsite/static/admin/js/filters.js deleted file mode 100644 index f5536eb..0000000 --- a/OneCprogsite/static/admin/js/filters.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Persist changelist filters state (collapsed/expanded). - */ -'use strict'; -{ - // Init filters. - let filters = JSON.parse(sessionStorage.getItem('django.admin.filtersState')); - - if (!filters) { - filters = {}; - } - - Object.entries(filters).forEach(([key, value]) => { - const detailElement = document.querySelector(`[data-filter-title='${CSS.escape(key)}']`); - - // Check if the filter is present, it could be from other view. - if (detailElement) { - value ? detailElement.setAttribute('open', '') : detailElement.removeAttribute('open'); - } - }); - - // Save filter state when clicks. - const details = document.querySelectorAll('details'); - details.forEach(detail => { - detail.addEventListener('toggle', event => { - filters[`${event.target.dataset.filterTitle}`] = detail.open; - sessionStorage.setItem('django.admin.filtersState', JSON.stringify(filters)); - }); - }); -} diff --git a/OneCprogsite/static/admin/js/inlines.js b/OneCprogsite/static/admin/js/inlines.js deleted file mode 100644 index e9a1dfe..0000000 --- a/OneCprogsite/static/admin/js/inlines.js +++ /dev/null @@ -1,359 +0,0 @@ -/*global DateTimeShortcuts, SelectFilter*/ -/** - * Django admin inlines - * - * Based on jQuery Formset 1.1 - * @author Stanislaus Madueke (stan DOT madueke AT gmail DOT com) - * @requires jQuery 1.2.6 or later - * - * Copyright (c) 2009, Stanislaus Madueke - * All rights reserved. - * - * Spiced up with Code from Zain Memon's GSoC project 2009 - * and modified for Django by Jannis Leidel, Travis Swicegood and Julien Phalip. - * - * Licensed under the New BSD License - * See: https://opensource.org/licenses/bsd-license.php - */ -'use strict'; -{ - const $ = django.jQuery; - $.fn.formset = function(opts) { - const options = $.extend({}, $.fn.formset.defaults, opts); - const $this = $(this); - const $parent = $this.parent(); - const updateElementIndex = function(el, prefix, ndx) { - const id_regex = new RegExp("(" + prefix + "-(\\d+|__prefix__))"); - const replacement = prefix + "-" + ndx; - if ($(el).prop("for")) { - $(el).prop("for", $(el).prop("for").replace(id_regex, replacement)); - } - if (el.id) { - el.id = el.id.replace(id_regex, replacement); - } - if (el.name) { - el.name = el.name.replace(id_regex, replacement); - } - }; - const totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS").prop("autocomplete", "off"); - let nextIndex = parseInt(totalForms.val(), 10); - const maxForms = $("#id_" + options.prefix + "-MAX_NUM_FORMS").prop("autocomplete", "off"); - const minForms = $("#id_" + options.prefix + "-MIN_NUM_FORMS").prop("autocomplete", "off"); - let addButton; - - /** - * The "Add another MyModel" button below the inline forms. - */ - const addInlineAddButton = function() { - if (addButton === null) { - if ($this.prop("tagName") === "TR") { - // If forms are laid out as table rows, insert the - // "add" button in a new table row: - const numCols = $this.eq(-1).children().length; - $parent.append('' + options.addText + ""); - addButton = $parent.find("tr:last a"); - } else { - // Otherwise, insert it immediately after the last form: - $this.filter(":last").after('"); - addButton = $this.filter(":last").next().find("a"); - } - } - addButton.on('click', addInlineClickHandler); - }; - - const addInlineClickHandler = function(e) { - e.preventDefault(); - const template = $("#" + options.prefix + "-empty"); - const row = template.clone(true); - row.removeClass(options.emptyCssClass) - .addClass(options.formCssClass) - .attr("id", options.prefix + "-" + nextIndex); - addInlineDeleteButton(row); - row.find("*").each(function() { - updateElementIndex(this, options.prefix, totalForms.val()); - }); - // Insert the new form when it has been fully edited. - row.insertBefore($(template)); - // Update number of total forms. - $(totalForms).val(parseInt(totalForms.val(), 10) + 1); - nextIndex += 1; - // Hide the add button if there's a limit and it's been reached. - if ((maxForms.val() !== '') && (maxForms.val() - totalForms.val()) <= 0) { - addButton.parent().hide(); - } - // Show the remove buttons if there are more than min_num. - toggleDeleteButtonVisibility(row.closest('.inline-group')); - - // Pass the new form to the post-add callback, if provided. - if (options.added) { - options.added(row); - } - row.get(0).dispatchEvent(new CustomEvent("formset:added", { - bubbles: true, - detail: { - formsetName: options.prefix - } - })); - }; - - /** - * The "X" button that is part of every unsaved inline. - * (When saved, it is replaced with a "Delete" checkbox.) - */ - const addInlineDeleteButton = function(row) { - if (row.is("tr")) { - // If the forms are laid out in table rows, insert - // the remove button into the last table cell: - row.children(":last").append('"); - } else if (row.is("ul") || row.is("ol")) { - // If they're laid out as an ordered/unordered list, - // insert an
    • after the last list item: - row.append('
    • ' + options.deleteText + "
    • "); - } else { - // Otherwise, just insert the remove button as the - // last child element of the form's container: - row.children(":first").append('' + options.deleteText + ""); - } - // Add delete handler for each row. - row.find("a." + options.deleteCssClass).on('click', inlineDeleteHandler.bind(this)); - }; - - const inlineDeleteHandler = function(e1) { - e1.preventDefault(); - const deleteButton = $(e1.target); - const row = deleteButton.closest('.' + options.formCssClass); - const inlineGroup = row.closest('.inline-group'); - // Remove the parent form containing this button, - // and also remove the relevant row with non-field errors: - const prevRow = row.prev(); - if (prevRow.length && prevRow.hasClass('row-form-errors')) { - prevRow.remove(); - } - row.remove(); - nextIndex -= 1; - // Pass the deleted form to the post-delete callback, if provided. - if (options.removed) { - options.removed(row); - } - document.dispatchEvent(new CustomEvent("formset:removed", { - detail: { - formsetName: options.prefix - } - })); - // Update the TOTAL_FORMS form count. - const forms = $("." + options.formCssClass); - $("#id_" + options.prefix + "-TOTAL_FORMS").val(forms.length); - // Show add button again once below maximum number. - if ((maxForms.val() === '') || (maxForms.val() - forms.length) > 0) { - addButton.parent().show(); - } - // Hide the remove buttons if at min_num. - toggleDeleteButtonVisibility(inlineGroup); - // Also, update names and ids for all remaining form controls so - // they remain in sequence: - let i, formCount; - const updateElementCallback = function() { - updateElementIndex(this, options.prefix, i); - }; - for (i = 0, formCount = forms.length; i < formCount; i++) { - updateElementIndex($(forms).get(i), options.prefix, i); - $(forms.get(i)).find("*").each(updateElementCallback); - } - }; - - const toggleDeleteButtonVisibility = function(inlineGroup) { - if ((minForms.val() !== '') && (minForms.val() - totalForms.val()) >= 0) { - inlineGroup.find('.inline-deletelink').hide(); - } else { - inlineGroup.find('.inline-deletelink').show(); - } - }; - - $this.each(function(i) { - $(this).not("." + options.emptyCssClass).addClass(options.formCssClass); - }); - - // Create the delete buttons for all unsaved inlines: - $this.filter('.' + options.formCssClass + ':not(.has_original):not(.' + options.emptyCssClass + ')').each(function() { - addInlineDeleteButton($(this)); - }); - toggleDeleteButtonVisibility($this); - - // Create the add button, initially hidden. - addButton = options.addButton; - addInlineAddButton(); - - // Show the add button if allowed to add more items. - // Note that max_num = None translates to a blank string. - const showAddButton = maxForms.val() === '' || (maxForms.val() - totalForms.val()) > 0; - if ($this.length && showAddButton) { - addButton.parent().show(); - } else { - addButton.parent().hide(); - } - - return this; - }; - - /* Setup plugin defaults */ - $.fn.formset.defaults = { - prefix: "form", // The form prefix for your django formset - addText: "add another", // Text for the add link - deleteText: "remove", // Text for the delete link - addCssClass: "add-row", // CSS class applied to the add link - deleteCssClass: "delete-row", // CSS class applied to the delete link - emptyCssClass: "empty-row", // CSS class applied to the empty row - formCssClass: "dynamic-form", // CSS class applied to each form in a formset - added: null, // Function called each time a new form is added - removed: null, // Function called each time a form is deleted - addButton: null // Existing add button to use - }; - - - // Tabular inlines --------------------------------------------------------- - $.fn.tabularFormset = function(selector, options) { - const $rows = $(this); - - const reinitDateTimeShortCuts = function() { - // Reinitialize the calendar and clock widgets by force - if (typeof DateTimeShortcuts !== "undefined") { - $(".datetimeshortcuts").remove(); - DateTimeShortcuts.init(); - } - }; - - const updateSelectFilter = function() { - // If any SelectFilter widgets are a part of the new form, - // instantiate a new SelectFilter instance for it. - if (typeof SelectFilter !== 'undefined') { - $('.selectfilter').each(function(index, value) { - SelectFilter.init(value.id, this.dataset.fieldName, false); - }); - $('.selectfilterstacked').each(function(index, value) { - SelectFilter.init(value.id, this.dataset.fieldName, true); - }); - } - }; - - const initPrepopulatedFields = function(row) { - row.find('.prepopulated_field').each(function() { - const field = $(this), - input = field.find('input, select, textarea'), - dependency_list = input.data('dependency_list') || [], - dependencies = []; - $.each(dependency_list, function(i, field_name) { - dependencies.push('#' + row.find('.field-' + field_name).find('input, select, textarea').attr('id')); - }); - if (dependencies.length) { - input.prepopulate(dependencies, input.attr('maxlength')); - } - }); - }; - - $rows.formset({ - prefix: options.prefix, - addText: options.addText, - formCssClass: "dynamic-" + options.prefix, - deleteCssClass: "inline-deletelink", - deleteText: options.deleteText, - emptyCssClass: "empty-form", - added: function(row) { - initPrepopulatedFields(row); - reinitDateTimeShortCuts(); - updateSelectFilter(); - }, - addButton: options.addButton - }); - - return $rows; - }; - - // Stacked inlines --------------------------------------------------------- - $.fn.stackedFormset = function(selector, options) { - const $rows = $(this); - const updateInlineLabel = function(row) { - $(selector).find(".inline_label").each(function(i) { - const count = i + 1; - $(this).html($(this).html().replace(/(#\d+)/g, "#" + count)); - }); - }; - - const reinitDateTimeShortCuts = function() { - // Reinitialize the calendar and clock widgets by force, yuck. - if (typeof DateTimeShortcuts !== "undefined") { - $(".datetimeshortcuts").remove(); - DateTimeShortcuts.init(); - } - }; - - const updateSelectFilter = function() { - // If any SelectFilter widgets were added, instantiate a new instance. - if (typeof SelectFilter !== "undefined") { - $(".selectfilter").each(function(index, value) { - SelectFilter.init(value.id, this.dataset.fieldName, false); - }); - $(".selectfilterstacked").each(function(index, value) { - SelectFilter.init(value.id, this.dataset.fieldName, true); - }); - } - }; - - const initPrepopulatedFields = function(row) { - row.find('.prepopulated_field').each(function() { - const field = $(this), - input = field.find('input, select, textarea'), - dependency_list = input.data('dependency_list') || [], - dependencies = []; - $.each(dependency_list, function(i, field_name) { - // Dependency in a fieldset. - let field_element = row.find('.form-row .field-' + field_name); - // Dependency without a fieldset. - if (!field_element.length) { - field_element = row.find('.form-row.field-' + field_name); - } - dependencies.push('#' + field_element.find('input, select, textarea').attr('id')); - }); - if (dependencies.length) { - input.prepopulate(dependencies, input.attr('maxlength')); - } - }); - }; - - $rows.formset({ - prefix: options.prefix, - addText: options.addText, - formCssClass: "dynamic-" + options.prefix, - deleteCssClass: "inline-deletelink", - deleteText: options.deleteText, - emptyCssClass: "empty-form", - removed: updateInlineLabel, - added: function(row) { - initPrepopulatedFields(row); - reinitDateTimeShortCuts(); - updateSelectFilter(); - updateInlineLabel(row); - }, - addButton: options.addButton - }); - - return $rows; - }; - - $(document).ready(function() { - $(".js-inline-admin-formset").each(function() { - const data = $(this).data(), - inlineOptions = data.inlineFormset; - let selector; - switch(data.inlineType) { - case "stacked": - selector = inlineOptions.name + "-group .inline-related"; - $(selector).stackedFormset(selector, inlineOptions.options); - break; - case "tabular": - selector = inlineOptions.name + "-group .tabular.inline-related tbody:first > tr.form-row"; - $(selector).tabularFormset(selector, inlineOptions.options); - break; - } - }); - }); -} diff --git a/OneCprogsite/static/admin/js/jquery.init.js b/OneCprogsite/static/admin/js/jquery.init.js deleted file mode 100644 index f40b27f..0000000 --- a/OneCprogsite/static/admin/js/jquery.init.js +++ /dev/null @@ -1,8 +0,0 @@ -/*global jQuery:false*/ -'use strict'; -/* Puts the included jQuery into our own namespace using noConflict and passing - * it 'true'. This ensures that the included jQuery doesn't pollute the global - * namespace (i.e. this preserves pre-existing values for both window.$ and - * window.jQuery). - */ -window.django = {jQuery: jQuery.noConflict(true)}; diff --git a/OneCprogsite/static/admin/js/nav_sidebar.js b/OneCprogsite/static/admin/js/nav_sidebar.js deleted file mode 100644 index 7e735db..0000000 --- a/OneCprogsite/static/admin/js/nav_sidebar.js +++ /dev/null @@ -1,79 +0,0 @@ -'use strict'; -{ - const toggleNavSidebar = document.getElementById('toggle-nav-sidebar'); - if (toggleNavSidebar !== null) { - const navSidebar = document.getElementById('nav-sidebar'); - const main = document.getElementById('main'); - let navSidebarIsOpen = localStorage.getItem('django.admin.navSidebarIsOpen'); - if (navSidebarIsOpen === null) { - navSidebarIsOpen = 'true'; - } - main.classList.toggle('shifted', navSidebarIsOpen === 'true'); - navSidebar.setAttribute('aria-expanded', navSidebarIsOpen); - - toggleNavSidebar.addEventListener('click', function() { - if (navSidebarIsOpen === 'true') { - navSidebarIsOpen = 'false'; - } else { - navSidebarIsOpen = 'true'; - } - localStorage.setItem('django.admin.navSidebarIsOpen', navSidebarIsOpen); - main.classList.toggle('shifted'); - navSidebar.setAttribute('aria-expanded', navSidebarIsOpen); - }); - } - - function initSidebarQuickFilter() { - const options = []; - const navSidebar = document.getElementById('nav-sidebar'); - if (!navSidebar) { - return; - } - navSidebar.querySelectorAll('th[scope=row] a').forEach((container) => { - options.push({title: container.innerHTML, node: container}); - }); - - function checkValue(event) { - let filterValue = event.target.value; - if (filterValue) { - filterValue = filterValue.toLowerCase(); - } - if (event.key === 'Escape') { - filterValue = ''; - event.target.value = ''; // clear input - } - let matches = false; - for (const o of options) { - let displayValue = ''; - if (filterValue) { - if (o.title.toLowerCase().indexOf(filterValue) === -1) { - displayValue = 'none'; - } else { - matches = true; - } - } - // show/hide parent - o.node.parentNode.parentNode.style.display = displayValue; - } - if (!filterValue || matches) { - event.target.classList.remove('no-results'); - } else { - event.target.classList.add('no-results'); - } - sessionStorage.setItem('django.admin.navSidebarFilterValue', filterValue); - } - - const nav = document.getElementById('nav-filter'); - nav.addEventListener('change', checkValue, false); - nav.addEventListener('input', checkValue, false); - nav.addEventListener('keyup', checkValue, false); - - const storedValue = sessionStorage.getItem('django.admin.navSidebarFilterValue'); - if (storedValue) { - nav.value = storedValue; - checkValue({target: nav, key: ''}); - } - } - window.initSidebarQuickFilter = initSidebarQuickFilter; - initSidebarQuickFilter(); -} diff --git a/OneCprogsite/static/admin/js/popup_response.js b/OneCprogsite/static/admin/js/popup_response.js deleted file mode 100644 index 2b1d3dd..0000000 --- a/OneCprogsite/static/admin/js/popup_response.js +++ /dev/null @@ -1,16 +0,0 @@ -/*global opener */ -'use strict'; -{ - const initData = JSON.parse(document.getElementById('django-admin-popup-response-constants').dataset.popupResponse); - switch(initData.action) { - case 'change': - opener.dismissChangeRelatedObjectPopup(window, initData.value, initData.obj, initData.new_value); - break; - case 'delete': - opener.dismissDeleteRelatedObjectPopup(window, initData.value); - break; - default: - opener.dismissAddRelatedObjectPopup(window, initData.value, initData.obj); - break; - } -} diff --git a/OneCprogsite/static/admin/js/prepopulate.js b/OneCprogsite/static/admin/js/prepopulate.js deleted file mode 100644 index 89e95ab..0000000 --- a/OneCprogsite/static/admin/js/prepopulate.js +++ /dev/null @@ -1,43 +0,0 @@ -/*global URLify*/ -'use strict'; -{ - const $ = django.jQuery; - $.fn.prepopulate = function(dependencies, maxLength, allowUnicode) { - /* - Depends on urlify.js - Populates a selected field with the values of the dependent fields, - URLifies and shortens the string. - dependencies - array of dependent fields ids - maxLength - maximum length of the URLify'd string - allowUnicode - Unicode support of the URLify'd string - */ - return this.each(function() { - const prepopulatedField = $(this); - - const populate = function() { - // Bail if the field's value has been changed by the user - if (prepopulatedField.data('_changed')) { - return; - } - - const values = []; - $.each(dependencies, function(i, field) { - field = $(field); - if (field.val().length > 0) { - values.push(field.val()); - } - }); - prepopulatedField.val(URLify(values.join(' '), maxLength, allowUnicode)); - }; - - prepopulatedField.data('_changed', false); - prepopulatedField.on('change', function() { - prepopulatedField.data('_changed', true); - }); - - if (!prepopulatedField.val()) { - $(dependencies.join(',')).on('keyup change focus', populate); - } - }); - }; -} diff --git a/OneCprogsite/static/admin/js/prepopulate_init.js b/OneCprogsite/static/admin/js/prepopulate_init.js deleted file mode 100644 index a58841f..0000000 --- a/OneCprogsite/static/admin/js/prepopulate_init.js +++ /dev/null @@ -1,15 +0,0 @@ -'use strict'; -{ - const $ = django.jQuery; - const fields = $('#django-admin-prepopulated-fields-constants').data('prepopulatedFields'); - $.each(fields, function(index, field) { - $( - '.empty-form .form-row .field-' + field.name + - ', .empty-form.form-row .field-' + field.name + - ', .empty-form .form-row.field-' + field.name - ).addClass('prepopulated_field'); - $(field.id).data('dependency_list', field.dependency_list).prepopulate( - field.dependency_ids, field.maxLength, field.allowUnicode - ); - }); -} diff --git a/OneCprogsite/static/admin/js/theme.js b/OneCprogsite/static/admin/js/theme.js deleted file mode 100644 index 794cd15..0000000 --- a/OneCprogsite/static/admin/js/theme.js +++ /dev/null @@ -1,56 +0,0 @@ -'use strict'; -{ - window.addEventListener('load', function(e) { - - function setTheme(mode) { - if (mode !== "light" && mode !== "dark" && mode !== "auto") { - console.error(`Got invalid theme mode: ${mode}. Resetting to auto.`); - mode = "auto"; - } - document.documentElement.dataset.theme = mode; - localStorage.setItem("theme", mode); - } - - function cycleTheme() { - const currentTheme = localStorage.getItem("theme") || "auto"; - const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches; - - if (prefersDark) { - // Auto (dark) -> Light -> Dark - if (currentTheme === "auto") { - setTheme("light"); - } else if (currentTheme === "light") { - setTheme("dark"); - } else { - setTheme("auto"); - } - } else { - // Auto (light) -> Dark -> Light - if (currentTheme === "auto") { - setTheme("dark"); - } else if (currentTheme === "dark") { - setTheme("light"); - } else { - setTheme("auto"); - } - } - } - - function initTheme() { - // set theme defined in localStorage if there is one, or fallback to auto mode - const currentTheme = localStorage.getItem("theme"); - currentTheme ? setTheme(currentTheme) : setTheme("auto"); - } - - function setupTheme() { - // Attach event handlers for toggling themes - const buttons = document.getElementsByClassName("theme-toggle"); - Array.from(buttons).forEach((btn) => { - btn.addEventListener("click", cycleTheme); - }); - initTheme(); - } - - setupTheme(); - }); -} diff --git a/OneCprogsite/static/admin/js/urlify.js b/OneCprogsite/static/admin/js/urlify.js deleted file mode 100644 index 9fc0409..0000000 --- a/OneCprogsite/static/admin/js/urlify.js +++ /dev/null @@ -1,169 +0,0 @@ -/*global XRegExp*/ -'use strict'; -{ - const LATIN_MAP = { - 'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE', - 'Ç': 'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I', - 'Î': 'I', 'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O', - 'Õ': 'O', 'Ö': 'O', 'Ő': 'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U', - 'Ü': 'U', 'Ű': 'U', 'Ý': 'Y', 'Þ': 'TH', 'Ÿ': 'Y', 'ß': 'ss', 'à': 'a', - 'á': 'a', 'â': 'a', 'ã': 'a', 'ä': 'a', 'å': 'a', 'æ': 'ae', 'ç': 'c', - 'è': 'e', 'é': 'e', 'ê': 'e', 'ë': 'e', 'ì': 'i', 'í': 'i', 'î': 'i', - 'ï': 'i', 'ð': 'd', 'ñ': 'n', 'ò': 'o', 'ó': 'o', 'ô': 'o', 'õ': 'o', - 'ö': 'o', 'ő': 'o', 'ø': 'o', 'ù': 'u', 'ú': 'u', 'û': 'u', 'ü': 'u', - 'ű': 'u', 'ý': 'y', 'þ': 'th', 'ÿ': 'y' - }; - const LATIN_SYMBOLS_MAP = { - '©': '(c)' - }; - const GREEK_MAP = { - 'α': 'a', 'β': 'b', 'γ': 'g', 'δ': 'd', 'ε': 'e', 'ζ': 'z', 'η': 'h', - 'θ': '8', 'ι': 'i', 'κ': 'k', 'λ': 'l', 'μ': 'm', 'ν': 'n', 'ξ': '3', - 'ο': 'o', 'π': 'p', 'ρ': 'r', 'σ': 's', 'τ': 't', 'υ': 'y', 'φ': 'f', - 'χ': 'x', 'ψ': 'ps', 'ω': 'w', 'ά': 'a', 'έ': 'e', 'ί': 'i', 'ό': 'o', - 'ύ': 'y', 'ή': 'h', 'ώ': 'w', 'ς': 's', 'ϊ': 'i', 'ΰ': 'y', 'ϋ': 'y', - 'ΐ': 'i', 'Α': 'A', 'Β': 'B', 'Γ': 'G', 'Δ': 'D', 'Ε': 'E', 'Ζ': 'Z', - 'Η': 'H', 'Θ': '8', 'Ι': 'I', 'Κ': 'K', 'Λ': 'L', 'Μ': 'M', 'Ν': 'N', - 'Ξ': '3', 'Ο': 'O', 'Π': 'P', 'Ρ': 'R', 'Σ': 'S', 'Τ': 'T', 'Υ': 'Y', - 'Φ': 'F', 'Χ': 'X', 'Ψ': 'PS', 'Ω': 'W', 'Ά': 'A', 'Έ': 'E', 'Ί': 'I', - 'Ό': 'O', 'Ύ': 'Y', 'Ή': 'H', 'Ώ': 'W', 'Ϊ': 'I', 'Ϋ': 'Y' - }; - const TURKISH_MAP = { - 'ş': 's', 'Ş': 'S', 'ı': 'i', 'İ': 'I', 'ç': 'c', 'Ç': 'C', 'ü': 'u', - 'Ü': 'U', 'ö': 'o', 'Ö': 'O', 'ğ': 'g', 'Ğ': 'G' - }; - const ROMANIAN_MAP = { - 'ă': 'a', 'î': 'i', 'ș': 's', 'ț': 't', 'â': 'a', - 'Ă': 'A', 'Î': 'I', 'Ș': 'S', 'Ț': 'T', 'Â': 'A' - }; - const RUSSIAN_MAP = { - 'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd', 'е': 'e', 'ё': 'yo', - 'ж': 'zh', 'з': 'z', 'и': 'i', 'й': 'j', 'к': 'k', 'л': 'l', 'м': 'm', - 'н': 'n', 'о': 'o', 'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u', - 'ф': 'f', 'х': 'h', 'ц': 'c', 'ч': 'ch', 'ш': 'sh', 'щ': 'sh', 'ъ': '', - 'ы': 'y', 'ь': '', 'э': 'e', 'ю': 'yu', 'я': 'ya', - 'А': 'A', 'Б': 'B', 'В': 'V', 'Г': 'G', 'Д': 'D', 'Е': 'E', 'Ё': 'Yo', - 'Ж': 'Zh', 'З': 'Z', 'И': 'I', 'Й': 'J', 'К': 'K', 'Л': 'L', 'М': 'M', - 'Н': 'N', 'О': 'O', 'П': 'P', 'Р': 'R', 'С': 'S', 'Т': 'T', 'У': 'U', - 'Ф': 'F', 'Х': 'H', 'Ц': 'C', 'Ч': 'Ch', 'Ш': 'Sh', 'Щ': 'Sh', 'Ъ': '', - 'Ы': 'Y', 'Ь': '', 'Э': 'E', 'Ю': 'Yu', 'Я': 'Ya' - }; - const UKRAINIAN_MAP = { - 'Є': 'Ye', 'І': 'I', 'Ї': 'Yi', 'Ґ': 'G', 'є': 'ye', 'і': 'i', - 'ї': 'yi', 'ґ': 'g' - }; - const CZECH_MAP = { - 'č': 'c', 'ď': 'd', 'ě': 'e', 'ň': 'n', 'ř': 'r', 'š': 's', 'ť': 't', - 'ů': 'u', 'ž': 'z', 'Č': 'C', 'Ď': 'D', 'Ě': 'E', 'Ň': 'N', 'Ř': 'R', - 'Š': 'S', 'Ť': 'T', 'Ů': 'U', 'Ž': 'Z' - }; - const SLOVAK_MAP = { - 'á': 'a', 'ä': 'a', 'č': 'c', 'ď': 'd', 'é': 'e', 'í': 'i', 'ľ': 'l', - 'ĺ': 'l', 'ň': 'n', 'ó': 'o', 'ô': 'o', 'ŕ': 'r', 'š': 's', 'ť': 't', - 'ú': 'u', 'ý': 'y', 'ž': 'z', - 'Á': 'a', 'Ä': 'A', 'Č': 'C', 'Ď': 'D', 'É': 'E', 'Í': 'I', 'Ľ': 'L', - 'Ĺ': 'L', 'Ň': 'N', 'Ó': 'O', 'Ô': 'O', 'Ŕ': 'R', 'Š': 'S', 'Ť': 'T', - 'Ú': 'U', 'Ý': 'Y', 'Ž': 'Z' - }; - const POLISH_MAP = { - 'ą': 'a', 'ć': 'c', 'ę': 'e', 'ł': 'l', 'ń': 'n', 'ó': 'o', 'ś': 's', - 'ź': 'z', 'ż': 'z', - 'Ą': 'A', 'Ć': 'C', 'Ę': 'E', 'Ł': 'L', 'Ń': 'N', 'Ó': 'O', 'Ś': 'S', - 'Ź': 'Z', 'Ż': 'Z' - }; - const LATVIAN_MAP = { - 'ā': 'a', 'č': 'c', 'ē': 'e', 'ģ': 'g', 'ī': 'i', 'ķ': 'k', 'ļ': 'l', - 'ņ': 'n', 'š': 's', 'ū': 'u', 'ž': 'z', - 'Ā': 'A', 'Č': 'C', 'Ē': 'E', 'Ģ': 'G', 'Ī': 'I', 'Ķ': 'K', 'Ļ': 'L', - 'Ņ': 'N', 'Š': 'S', 'Ū': 'U', 'Ž': 'Z' - }; - const ARABIC_MAP = { - 'أ': 'a', 'ب': 'b', 'ت': 't', 'ث': 'th', 'ج': 'g', 'ح': 'h', 'خ': 'kh', 'د': 'd', - 'ذ': 'th', 'ر': 'r', 'ز': 'z', 'س': 's', 'ش': 'sh', 'ص': 's', 'ض': 'd', 'ط': 't', - 'ظ': 'th', 'ع': 'aa', 'غ': 'gh', 'ف': 'f', 'ق': 'k', 'ك': 'k', 'ل': 'l', 'م': 'm', - 'ن': 'n', 'ه': 'h', 'و': 'o', 'ي': 'y' - }; - const LITHUANIAN_MAP = { - 'ą': 'a', 'č': 'c', 'ę': 'e', 'ė': 'e', 'į': 'i', 'š': 's', 'ų': 'u', - 'ū': 'u', 'ž': 'z', - 'Ą': 'A', 'Č': 'C', 'Ę': 'E', 'Ė': 'E', 'Į': 'I', 'Š': 'S', 'Ų': 'U', - 'Ū': 'U', 'Ž': 'Z' - }; - const SERBIAN_MAP = { - 'ђ': 'dj', 'ј': 'j', 'љ': 'lj', 'њ': 'nj', 'ћ': 'c', 'џ': 'dz', - 'đ': 'dj', 'Ђ': 'Dj', 'Ј': 'j', 'Љ': 'Lj', 'Њ': 'Nj', 'Ћ': 'C', - 'Џ': 'Dz', 'Đ': 'Dj' - }; - const AZERBAIJANI_MAP = { - 'ç': 'c', 'ə': 'e', 'ğ': 'g', 'ı': 'i', 'ö': 'o', 'ş': 's', 'ü': 'u', - 'Ç': 'C', 'Ə': 'E', 'Ğ': 'G', 'İ': 'I', 'Ö': 'O', 'Ş': 'S', 'Ü': 'U' - }; - const GEORGIAN_MAP = { - 'ა': 'a', 'ბ': 'b', 'გ': 'g', 'დ': 'd', 'ე': 'e', 'ვ': 'v', 'ზ': 'z', - 'თ': 't', 'ი': 'i', 'კ': 'k', 'ლ': 'l', 'მ': 'm', 'ნ': 'n', 'ო': 'o', - 'პ': 'p', 'ჟ': 'j', 'რ': 'r', 'ს': 's', 'ტ': 't', 'უ': 'u', 'ფ': 'f', - 'ქ': 'q', 'ღ': 'g', 'ყ': 'y', 'შ': 'sh', 'ჩ': 'ch', 'ც': 'c', 'ძ': 'dz', - 'წ': 'w', 'ჭ': 'ch', 'ხ': 'x', 'ჯ': 'j', 'ჰ': 'h' - }; - - const ALL_DOWNCODE_MAPS = [ - LATIN_MAP, - LATIN_SYMBOLS_MAP, - GREEK_MAP, - TURKISH_MAP, - ROMANIAN_MAP, - RUSSIAN_MAP, - UKRAINIAN_MAP, - CZECH_MAP, - SLOVAK_MAP, - POLISH_MAP, - LATVIAN_MAP, - ARABIC_MAP, - LITHUANIAN_MAP, - SERBIAN_MAP, - AZERBAIJANI_MAP, - GEORGIAN_MAP - ]; - - const Downcoder = { - 'Initialize': function() { - if (Downcoder.map) { // already made - return; - } - Downcoder.map = {}; - for (const lookup of ALL_DOWNCODE_MAPS) { - Object.assign(Downcoder.map, lookup); - } - Downcoder.regex = new RegExp(Object.keys(Downcoder.map).join('|'), 'g'); - } - }; - - function downcode(slug) { - Downcoder.Initialize(); - return slug.replace(Downcoder.regex, function(m) { - return Downcoder.map[m]; - }); - } - - - function URLify(s, num_chars, allowUnicode) { - // changes, e.g., "Petty theft" to "petty-theft" - if (!allowUnicode) { - s = downcode(s); - } - s = s.toLowerCase(); // convert to lowercase - // if downcode doesn't hit, the char will be stripped here - if (allowUnicode) { - // Keep Unicode letters including both lowercase and uppercase - // characters, whitespace, and dash; remove other characters. - s = XRegExp.replace(s, XRegExp('[^-_\\p{L}\\p{N}\\s]', 'g'), ''); - } else { - s = s.replace(/[^-\w\s]/g, ''); // remove unneeded chars - } - s = s.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces - s = s.replace(/[-\s]+/g, '-'); // convert spaces to hyphens - s = s.substring(0, num_chars); // trim to first num_chars chars - return s.replace(/-+$/g, ''); // trim any trailing hyphens - } - window.URLify = URLify; -} diff --git a/OneCprogsite/static/admin/js/vendor/jquery/LICENSE.txt b/OneCprogsite/static/admin/js/vendor/jquery/LICENSE.txt deleted file mode 100644 index f642c3f..0000000 --- a/OneCprogsite/static/admin/js/vendor/jquery/LICENSE.txt +++ /dev/null @@ -1,20 +0,0 @@ -Copyright OpenJS Foundation and other contributors, https://openjsf.org/ - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/OneCprogsite/static/admin/js/vendor/jquery/jquery.js b/OneCprogsite/static/admin/js/vendor/jquery/jquery.js deleted file mode 100644 index 7f35c11..0000000 --- a/OneCprogsite/static/admin/js/vendor/jquery/jquery.js +++ /dev/null @@ -1,10965 +0,0 @@ -/*! - * jQuery JavaScript Library v3.6.4 - * https://jquery.com/ - * - * Includes Sizzle.js - * https://sizzlejs.com/ - * - * Copyright OpenJS Foundation and other contributors - * Released under the MIT license - * https://jquery.org/license - * - * Date: 2023-03-08T15:28Z - */ -( function( global, factory ) { - - "use strict"; - - if ( typeof module === "object" && typeof module.exports === "object" ) { - - // For CommonJS and CommonJS-like environments where a proper `window` - // is present, execute the factory and get jQuery. - // For environments that do not have a `window` with a `document` - // (such as Node.js), expose a factory as module.exports. - // This accentuates the need for the creation of a real `window`. - // e.g. var jQuery = require("jquery")(window); - // See ticket trac-14549 for more info. - module.exports = global.document ? - factory( global, true ) : - function( w ) { - if ( !w.document ) { - throw new Error( "jQuery requires a window with a document" ); - } - return factory( w ); - }; - } else { - factory( global ); - } - -// Pass this if window is not defined yet -} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { - -// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 -// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode -// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common -// enough that all such attempts are guarded in a try block. -"use strict"; - -var arr = []; - -var getProto = Object.getPrototypeOf; - -var slice = arr.slice; - -var flat = arr.flat ? function( array ) { - return arr.flat.call( array ); -} : function( array ) { - return arr.concat.apply( [], array ); -}; - - -var push = arr.push; - -var indexOf = arr.indexOf; - -var class2type = {}; - -var toString = class2type.toString; - -var hasOwn = class2type.hasOwnProperty; - -var fnToString = hasOwn.toString; - -var ObjectFunctionString = fnToString.call( Object ); - -var support = {}; - -var isFunction = function isFunction( obj ) { - - // Support: Chrome <=57, Firefox <=52 - // In some browsers, typeof returns "function" for HTML elements - // (i.e., `typeof document.createElement( "object" ) === "function"`). - // We don't want to classify *any* DOM node as a function. - // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5 - // Plus for old WebKit, typeof returns "function" for HTML collections - // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756) - return typeof obj === "function" && typeof obj.nodeType !== "number" && - typeof obj.item !== "function"; - }; - - -var isWindow = function isWindow( obj ) { - return obj != null && obj === obj.window; - }; - - -var document = window.document; - - - - var preservedScriptAttributes = { - type: true, - src: true, - nonce: true, - noModule: true - }; - - function DOMEval( code, node, doc ) { - doc = doc || document; - - var i, val, - script = doc.createElement( "script" ); - - script.text = code; - if ( node ) { - for ( i in preservedScriptAttributes ) { - - // Support: Firefox 64+, Edge 18+ - // Some browsers don't support the "nonce" property on scripts. - // On the other hand, just using `getAttribute` is not enough as - // the `nonce` attribute is reset to an empty string whenever it - // becomes browsing-context connected. - // See https://github.com/whatwg/html/issues/2369 - // See https://html.spec.whatwg.org/#nonce-attributes - // The `node.getAttribute` check was added for the sake of - // `jQuery.globalEval` so that it can fake a nonce-containing node - // via an object. - val = node[ i ] || node.getAttribute && node.getAttribute( i ); - if ( val ) { - script.setAttribute( i, val ); - } - } - } - doc.head.appendChild( script ).parentNode.removeChild( script ); - } - - -function toType( obj ) { - if ( obj == null ) { - return obj + ""; - } - - // Support: Android <=2.3 only (functionish RegExp) - return typeof obj === "object" || typeof obj === "function" ? - class2type[ toString.call( obj ) ] || "object" : - typeof obj; -} -/* global Symbol */ -// Defining this global in .eslintrc.json would create a danger of using the global -// unguarded in another place, it seems safer to define global only for this module - - - -var - version = "3.6.4", - - // Define a local copy of jQuery - jQuery = function( selector, context ) { - - // The jQuery object is actually just the init constructor 'enhanced' - // Need init if jQuery is called (just allow error to be thrown if not included) - return new jQuery.fn.init( selector, context ); - }; - -jQuery.fn = jQuery.prototype = { - - // The current version of jQuery being used - jquery: version, - - constructor: jQuery, - - // The default length of a jQuery object is 0 - length: 0, - - toArray: function() { - return slice.call( this ); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - - // Return all the elements in a clean array - if ( num == null ) { - return slice.call( this ); - } - - // Return just the one element from the set - return num < 0 ? this[ num + this.length ] : this[ num ]; - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems ) { - - // Build a new jQuery matched element set - var ret = jQuery.merge( this.constructor(), elems ); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - - // Return the newly-formed element set - return ret; - }, - - // Execute a callback for every element in the matched set. - each: function( callback ) { - return jQuery.each( this, callback ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map( this, function( elem, i ) { - return callback.call( elem, i, elem ); - } ) ); - }, - - slice: function() { - return this.pushStack( slice.apply( this, arguments ) ); - }, - - first: function() { - return this.eq( 0 ); - }, - - last: function() { - return this.eq( -1 ); - }, - - even: function() { - return this.pushStack( jQuery.grep( this, function( _elem, i ) { - return ( i + 1 ) % 2; - } ) ); - }, - - odd: function() { - return this.pushStack( jQuery.grep( this, function( _elem, i ) { - return i % 2; - } ) ); - }, - - eq: function( i ) { - var len = this.length, - j = +i + ( i < 0 ? len : 0 ); - return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); - }, - - end: function() { - return this.prevObject || this.constructor(); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: arr.sort, - splice: arr.splice -}; - -jQuery.extend = jQuery.fn.extend = function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[ 0 ] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - - // Skip the boolean and the target - target = arguments[ i ] || {}; - i++; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !isFunction( target ) ) { - target = {}; - } - - // Extend jQuery itself if only one argument is passed - if ( i === length ) { - target = this; - i--; - } - - for ( ; i < length; i++ ) { - - // Only deal with non-null/undefined values - if ( ( options = arguments[ i ] ) != null ) { - - // Extend the base object - for ( name in options ) { - copy = options[ name ]; - - // Prevent Object.prototype pollution - // Prevent never-ending loop - if ( name === "__proto__" || target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject( copy ) || - ( copyIsArray = Array.isArray( copy ) ) ) ) { - src = target[ name ]; - - // Ensure proper type for the source value - if ( copyIsArray && !Array.isArray( src ) ) { - clone = []; - } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { - clone = {}; - } else { - clone = src; - } - copyIsArray = false; - - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - -jQuery.extend( { - - // Unique for each copy of jQuery on the page - expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), - - // Assume jQuery is ready without the ready module - isReady: true, - - error: function( msg ) { - throw new Error( msg ); - }, - - noop: function() {}, - - isPlainObject: function( obj ) { - var proto, Ctor; - - // Detect obvious negatives - // Use toString instead of jQuery.type to catch host objects - if ( !obj || toString.call( obj ) !== "[object Object]" ) { - return false; - } - - proto = getProto( obj ); - - // Objects with no prototype (e.g., `Object.create( null )`) are plain - if ( !proto ) { - return true; - } - - // Objects with prototype are plain iff they were constructed by a global Object function - Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; - return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; - }, - - isEmptyObject: function( obj ) { - var name; - - for ( name in obj ) { - return false; - } - return true; - }, - - // Evaluates a script in a provided context; falls back to the global one - // if not specified. - globalEval: function( code, options, doc ) { - DOMEval( code, { nonce: options && options.nonce }, doc ); - }, - - each: function( obj, callback ) { - var length, i = 0; - - if ( isArrayLike( obj ) ) { - length = obj.length; - for ( ; i < length; i++ ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } else { - for ( i in obj ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } - - return obj; - }, - - // results is for internal usage only - makeArray: function( arr, results ) { - var ret = results || []; - - if ( arr != null ) { - if ( isArrayLike( Object( arr ) ) ) { - jQuery.merge( ret, - typeof arr === "string" ? - [ arr ] : arr - ); - } else { - push.call( ret, arr ); - } - } - - return ret; - }, - - inArray: function( elem, arr, i ) { - return arr == null ? -1 : indexOf.call( arr, elem, i ); - }, - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - merge: function( first, second ) { - var len = +second.length, - j = 0, - i = first.length; - - for ( ; j < len; j++ ) { - first[ i++ ] = second[ j ]; - } - - first.length = i; - - return first; - }, - - grep: function( elems, callback, invert ) { - var callbackInverse, - matches = [], - i = 0, - length = elems.length, - callbackExpect = !invert; - - // Go through the array, only saving the items - // that pass the validator function - for ( ; i < length; i++ ) { - callbackInverse = !callback( elems[ i ], i ); - if ( callbackInverse !== callbackExpect ) { - matches.push( elems[ i ] ); - } - } - - return matches; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - var length, value, - i = 0, - ret = []; - - // Go through the array, translating each of the items to their new values - if ( isArrayLike( elems ) ) { - length = elems.length; - for ( ; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - - // Go through every key on the object, - } else { - for ( i in elems ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - } - - // Flatten any nested arrays - return flat( ret ); - }, - - // A global GUID counter for objects - guid: 1, - - // jQuery.support is not used in Core but other projects attach their - // properties to it so it needs to exist. - support: support -} ); - -if ( typeof Symbol === "function" ) { - jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; -} - -// Populate the class2type map -jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), - function( _i, name ) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); - } ); - -function isArrayLike( obj ) { - - // Support: real iOS 8.2 only (not reproducible in simulator) - // `in` check used to prevent JIT error (gh-2145) - // hasOwn isn't used here due to false negatives - // regarding Nodelist length in IE - var length = !!obj && "length" in obj && obj.length, - type = toType( obj ); - - if ( isFunction( obj ) || isWindow( obj ) ) { - return false; - } - - return type === "array" || length === 0 || - typeof length === "number" && length > 0 && ( length - 1 ) in obj; -} -var Sizzle = -/*! - * Sizzle CSS Selector Engine v2.3.10 - * https://sizzlejs.com/ - * - * Copyright JS Foundation and other contributors - * Released under the MIT license - * https://js.foundation/ - * - * Date: 2023-02-14 - */ -( function( window ) { -var i, - support, - Expr, - getText, - isXML, - tokenize, - compile, - select, - outermostContext, - sortInput, - hasDuplicate, - - // Local document vars - setDocument, - document, - docElem, - documentIsHTML, - rbuggyQSA, - rbuggyMatches, - matches, - contains, - - // Instance-specific data - expando = "sizzle" + 1 * new Date(), - preferredDoc = window.document, - dirruns = 0, - done = 0, - classCache = createCache(), - tokenCache = createCache(), - compilerCache = createCache(), - nonnativeSelectorCache = createCache(), - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - } - return 0; - }, - - // Instance methods - hasOwn = ( {} ).hasOwnProperty, - arr = [], - pop = arr.pop, - pushNative = arr.push, - push = arr.push, - slice = arr.slice, - - // Use a stripped-down indexOf as it's faster than native - // https://jsperf.com/thor-indexof-vs-for/5 - indexOf = function( list, elem ) { - var i = 0, - len = list.length; - for ( ; i < len; i++ ) { - if ( list[ i ] === elem ) { - return i; - } - } - return -1; - }, - - booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + - "ismap|loop|multiple|open|readonly|required|scoped", - - // Regular expressions - - // http://www.w3.org/TR/css3-selectors/#whitespace - whitespace = "[\\x20\\t\\r\\n\\f]", - - // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram - identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + - "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", - - // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors - attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + - - // Operator (capture 2) - "*([*^$|!~]?=)" + whitespace + - - // "Attribute values must be CSS identifiers [capture 5] - // or strings [capture 3 or capture 4]" - "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + - whitespace + "*\\]", - - pseudos = ":(" + identifier + ")(?:\\((" + - - // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: - // 1. quoted (capture 3; capture 4 or capture 5) - "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + - - // 2. simple (capture 6) - "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + - - // 3. anything else (capture 2) - ".*" + - ")\\)|)", - - // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter - rwhitespace = new RegExp( whitespace + "+", "g" ), - rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + - whitespace + "+$", "g" ), - - rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), - rleadingCombinator = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + - "*" ), - rdescend = new RegExp( whitespace + "|>" ), - - rpseudo = new RegExp( pseudos ), - ridentifier = new RegExp( "^" + identifier + "$" ), - - matchExpr = { - "ID": new RegExp( "^#(" + identifier + ")" ), - "CLASS": new RegExp( "^\\.(" + identifier + ")" ), - "TAG": new RegExp( "^(" + identifier + "|[*])" ), - "ATTR": new RegExp( "^" + attributes ), - "PSEUDO": new RegExp( "^" + pseudos ), - "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + - whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + - whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), - "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), - - // For use in libraries implementing .is() - // We use this for POS matching in `select` - "needsContext": new RegExp( "^" + whitespace + - "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + - "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) - }, - - rhtml = /HTML$/i, - rinputs = /^(?:input|select|textarea|button)$/i, - rheader = /^h\d$/i, - - rnative = /^[^{]+\{\s*\[native \w/, - - // Easily-parseable/retrievable ID or TAG or CLASS selectors - rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - - rsibling = /[+~]/, - - // CSS escapes - // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters - runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), - funescape = function( escape, nonHex ) { - var high = "0x" + escape.slice( 1 ) - 0x10000; - - return nonHex ? - - // Strip the backslash prefix from a non-hex escape sequence - nonHex : - - // Replace a hexadecimal escape sequence with the encoded Unicode code point - // Support: IE <=11+ - // For values outside the Basic Multilingual Plane (BMP), manually construct a - // surrogate pair - high < 0 ? - String.fromCharCode( high + 0x10000 ) : - String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); - }, - - // CSS string/identifier serialization - // https://drafts.csswg.org/cssom/#common-serializing-idioms - rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, - fcssescape = function( ch, asCodePoint ) { - if ( asCodePoint ) { - - // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER - if ( ch === "\0" ) { - return "\uFFFD"; - } - - // Control characters and (dependent upon position) numbers get escaped as code points - return ch.slice( 0, -1 ) + "\\" + - ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; - } - - // Other potentially-special ASCII characters get backslash-escaped - return "\\" + ch; - }, - - // Used for iframes - // See setDocument() - // Removing the function wrapper causes a "Permission Denied" - // error in IE - unloadHandler = function() { - setDocument(); - }, - - inDisabledFieldset = addCombinator( - function( elem ) { - return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; - }, - { dir: "parentNode", next: "legend" } - ); - -// Optimize for push.apply( _, NodeList ) -try { - push.apply( - ( arr = slice.call( preferredDoc.childNodes ) ), - preferredDoc.childNodes - ); - - // Support: Android<4.0 - // Detect silently failing push.apply - // eslint-disable-next-line no-unused-expressions - arr[ preferredDoc.childNodes.length ].nodeType; -} catch ( e ) { - push = { apply: arr.length ? - - // Leverage slice if possible - function( target, els ) { - pushNative.apply( target, slice.call( els ) ); - } : - - // Support: IE<9 - // Otherwise append directly - function( target, els ) { - var j = target.length, - i = 0; - - // Can't trust NodeList.length - while ( ( target[ j++ ] = els[ i++ ] ) ) {} - target.length = j - 1; - } - }; -} - -function Sizzle( selector, context, results, seed ) { - var m, i, elem, nid, match, groups, newSelector, - newContext = context && context.ownerDocument, - - // nodeType defaults to 9, since context defaults to document - nodeType = context ? context.nodeType : 9; - - results = results || []; - - // Return early from calls with invalid selector or context - if ( typeof selector !== "string" || !selector || - nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { - - return results; - } - - // Try to shortcut find operations (as opposed to filters) in HTML documents - if ( !seed ) { - setDocument( context ); - context = context || document; - - if ( documentIsHTML ) { - - // If the selector is sufficiently simple, try using a "get*By*" DOM method - // (excepting DocumentFragment context, where the methods don't exist) - if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { - - // ID selector - if ( ( m = match[ 1 ] ) ) { - - // Document context - if ( nodeType === 9 ) { - if ( ( elem = context.getElementById( m ) ) ) { - - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if ( elem.id === m ) { - results.push( elem ); - return results; - } - } else { - return results; - } - - // Element context - } else { - - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if ( newContext && ( elem = newContext.getElementById( m ) ) && - contains( context, elem ) && - elem.id === m ) { - - results.push( elem ); - return results; - } - } - - // Type selector - } else if ( match[ 2 ] ) { - push.apply( results, context.getElementsByTagName( selector ) ); - return results; - - // Class selector - } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && - context.getElementsByClassName ) { - - push.apply( results, context.getElementsByClassName( m ) ); - return results; - } - } - - // Take advantage of querySelectorAll - if ( support.qsa && - !nonnativeSelectorCache[ selector + " " ] && - ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && - - // Support: IE 8 only - // Exclude object elements - ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { - - newSelector = selector; - newContext = context; - - // qSA considers elements outside a scoping root when evaluating child or - // descendant combinators, which is not what we want. - // In such cases, we work around the behavior by prefixing every selector in the - // list with an ID selector referencing the scope context. - // The technique has to be used as well when a leading combinator is used - // as such selectors are not recognized by querySelectorAll. - // Thanks to Andrew Dupont for this technique. - if ( nodeType === 1 && - ( rdescend.test( selector ) || rleadingCombinator.test( selector ) ) ) { - - // Expand context for sibling selectors - newContext = rsibling.test( selector ) && testContext( context.parentNode ) || - context; - - // We can use :scope instead of the ID hack if the browser - // supports it & if we're not changing the context. - if ( newContext !== context || !support.scope ) { - - // Capture the context ID, setting it first if necessary - if ( ( nid = context.getAttribute( "id" ) ) ) { - nid = nid.replace( rcssescape, fcssescape ); - } else { - context.setAttribute( "id", ( nid = expando ) ); - } - } - - // Prefix every selector in the list - groups = tokenize( selector ); - i = groups.length; - while ( i-- ) { - groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + - toSelector( groups[ i ] ); - } - newSelector = groups.join( "," ); - } - - try { - push.apply( results, - newContext.querySelectorAll( newSelector ) - ); - return results; - } catch ( qsaError ) { - nonnativeSelectorCache( selector, true ); - } finally { - if ( nid === expando ) { - context.removeAttribute( "id" ); - } - } - } - } - } - - // All others - return select( selector.replace( rtrim, "$1" ), context, results, seed ); -} - -/** - * Create key-value caches of limited size - * @returns {function(string, object)} Returns the Object data after storing it on itself with - * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) - * deleting the oldest entry - */ -function createCache() { - var keys = []; - - function cache( key, value ) { - - // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) - if ( keys.push( key + " " ) > Expr.cacheLength ) { - - // Only keep the most recent entries - delete cache[ keys.shift() ]; - } - return ( cache[ key + " " ] = value ); - } - return cache; -} - -/** - * Mark a function for special use by Sizzle - * @param {Function} fn The function to mark - */ -function markFunction( fn ) { - fn[ expando ] = true; - return fn; -} - -/** - * Support testing using an element - * @param {Function} fn Passed the created element and returns a boolean result - */ -function assert( fn ) { - var el = document.createElement( "fieldset" ); - - try { - return !!fn( el ); - } catch ( e ) { - return false; - } finally { - - // Remove from its parent by default - if ( el.parentNode ) { - el.parentNode.removeChild( el ); - } - - // release memory in IE - el = null; - } -} - -/** - * Adds the same handler for all of the specified attrs - * @param {String} attrs Pipe-separated list of attributes - * @param {Function} handler The method that will be applied - */ -function addHandle( attrs, handler ) { - var arr = attrs.split( "|" ), - i = arr.length; - - while ( i-- ) { - Expr.attrHandle[ arr[ i ] ] = handler; - } -} - -/** - * Checks document order of two siblings - * @param {Element} a - * @param {Element} b - * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b - */ -function siblingCheck( a, b ) { - var cur = b && a, - diff = cur && a.nodeType === 1 && b.nodeType === 1 && - a.sourceIndex - b.sourceIndex; - - // Use IE sourceIndex if available on both nodes - if ( diff ) { - return diff; - } - - // Check if b follows a - if ( cur ) { - while ( ( cur = cur.nextSibling ) ) { - if ( cur === b ) { - return -1; - } - } - } - - return a ? 1 : -1; -} - -/** - * Returns a function to use in pseudos for input types - * @param {String} type - */ -function createInputPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for buttons - * @param {String} type - */ -function createButtonPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return ( name === "input" || name === "button" ) && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for :enabled/:disabled - * @param {Boolean} disabled true for :disabled; false for :enabled - */ -function createDisabledPseudo( disabled ) { - - // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable - return function( elem ) { - - // Only certain elements can match :enabled or :disabled - // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled - // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled - if ( "form" in elem ) { - - // Check for inherited disabledness on relevant non-disabled elements: - // * listed form-associated elements in a disabled fieldset - // https://html.spec.whatwg.org/multipage/forms.html#category-listed - // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled - // * option elements in a disabled optgroup - // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled - // All such elements have a "form" property. - if ( elem.parentNode && elem.disabled === false ) { - - // Option elements defer to a parent optgroup if present - if ( "label" in elem ) { - if ( "label" in elem.parentNode ) { - return elem.parentNode.disabled === disabled; - } else { - return elem.disabled === disabled; - } - } - - // Support: IE 6 - 11 - // Use the isDisabled shortcut property to check for disabled fieldset ancestors - return elem.isDisabled === disabled || - - // Where there is no isDisabled, check manually - /* jshint -W018 */ - elem.isDisabled !== !disabled && - inDisabledFieldset( elem ) === disabled; - } - - return elem.disabled === disabled; - - // Try to winnow out elements that can't be disabled before trusting the disabled property. - // Some victims get caught in our net (label, legend, menu, track), but it shouldn't - // even exist on them, let alone have a boolean value. - } else if ( "label" in elem ) { - return elem.disabled === disabled; - } - - // Remaining elements are neither :enabled nor :disabled - return false; - }; -} - -/** - * Returns a function to use in pseudos for positionals - * @param {Function} fn - */ -function createPositionalPseudo( fn ) { - return markFunction( function( argument ) { - argument = +argument; - return markFunction( function( seed, matches ) { - var j, - matchIndexes = fn( [], seed.length, argument ), - i = matchIndexes.length; - - // Match elements found at the specified indexes - while ( i-- ) { - if ( seed[ ( j = matchIndexes[ i ] ) ] ) { - seed[ j ] = !( matches[ j ] = seed[ j ] ); - } - } - } ); - } ); -} - -/** - * Checks a node for validity as a Sizzle context - * @param {Element|Object=} context - * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value - */ -function testContext( context ) { - return context && typeof context.getElementsByTagName !== "undefined" && context; -} - -// Expose support vars for convenience -support = Sizzle.support = {}; - -/** - * Detects XML nodes - * @param {Element|Object} elem An element or a document - * @returns {Boolean} True iff elem is a non-HTML XML node - */ -isXML = Sizzle.isXML = function( elem ) { - var namespace = elem && elem.namespaceURI, - docElem = elem && ( elem.ownerDocument || elem ).documentElement; - - // Support: IE <=8 - // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes - // https://bugs.jquery.com/ticket/4833 - return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); -}; - -/** - * Sets document-related variables once based on the current document - * @param {Element|Object} [doc] An element or document object to use to set the document - * @returns {Object} Returns the current document - */ -setDocument = Sizzle.setDocument = function( node ) { - var hasCompare, subWindow, - doc = node ? node.ownerDocument || node : preferredDoc; - - // Return early if doc is invalid or already selected - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { - return document; - } - - // Update global variables - document = doc; - docElem = document.documentElement; - documentIsHTML = !isXML( document ); - - // Support: IE 9 - 11+, Edge 12 - 18+ - // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( preferredDoc != document && - ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { - - // Support: IE 11, Edge - if ( subWindow.addEventListener ) { - subWindow.addEventListener( "unload", unloadHandler, false ); - - // Support: IE 9 - 10 only - } else if ( subWindow.attachEvent ) { - subWindow.attachEvent( "onunload", unloadHandler ); - } - } - - // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, - // Safari 4 - 5 only, Opera <=11.6 - 12.x only - // IE/Edge & older browsers don't support the :scope pseudo-class. - // Support: Safari 6.0 only - // Safari 6.0 supports :scope but it's an alias of :root there. - support.scope = assert( function( el ) { - docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); - return typeof el.querySelectorAll !== "undefined" && - !el.querySelectorAll( ":scope fieldset div" ).length; - } ); - - // Support: Chrome 105 - 110+, Safari 15.4 - 16.3+ - // Make sure the the `:has()` argument is parsed unforgivingly. - // We include `*` in the test to detect buggy implementations that are - // _selectively_ forgiving (specifically when the list includes at least - // one valid selector). - // Note that we treat complete lack of support for `:has()` as if it were - // spec-compliant support, which is fine because use of `:has()` in such - // environments will fail in the qSA path and fall back to jQuery traversal - // anyway. - support.cssHas = assert( function() { - try { - document.querySelector( ":has(*,:jqfake)" ); - return false; - } catch ( e ) { - return true; - } - } ); - - /* Attributes - ---------------------------------------------------------------------- */ - - // Support: IE<8 - // Verify that getAttribute really returns attributes and not properties - // (excepting IE8 booleans) - support.attributes = assert( function( el ) { - el.className = "i"; - return !el.getAttribute( "className" ); - } ); - - /* getElement(s)By* - ---------------------------------------------------------------------- */ - - // Check if getElementsByTagName("*") returns only elements - support.getElementsByTagName = assert( function( el ) { - el.appendChild( document.createComment( "" ) ); - return !el.getElementsByTagName( "*" ).length; - } ); - - // Support: IE<9 - support.getElementsByClassName = rnative.test( document.getElementsByClassName ); - - // Support: IE<10 - // Check if getElementById returns elements by name - // The broken getElementById methods don't pick up programmatically-set names, - // so use a roundabout getElementsByName test - support.getById = assert( function( el ) { - docElem.appendChild( el ).id = expando; - return !document.getElementsByName || !document.getElementsByName( expando ).length; - } ); - - // ID filter and find - if ( support.getById ) { - Expr.filter[ "ID" ] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - return elem.getAttribute( "id" ) === attrId; - }; - }; - Expr.find[ "ID" ] = function( id, context ) { - if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { - var elem = context.getElementById( id ); - return elem ? [ elem ] : []; - } - }; - } else { - Expr.filter[ "ID" ] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - var node = typeof elem.getAttributeNode !== "undefined" && - elem.getAttributeNode( "id" ); - return node && node.value === attrId; - }; - }; - - // Support: IE 6 - 7 only - // getElementById is not reliable as a find shortcut - Expr.find[ "ID" ] = function( id, context ) { - if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { - var node, i, elems, - elem = context.getElementById( id ); - - if ( elem ) { - - // Verify the id attribute - node = elem.getAttributeNode( "id" ); - if ( node && node.value === id ) { - return [ elem ]; - } - - // Fall back on getElementsByName - elems = context.getElementsByName( id ); - i = 0; - while ( ( elem = elems[ i++ ] ) ) { - node = elem.getAttributeNode( "id" ); - if ( node && node.value === id ) { - return [ elem ]; - } - } - } - - return []; - } - }; - } - - // Tag - Expr.find[ "TAG" ] = support.getElementsByTagName ? - function( tag, context ) { - if ( typeof context.getElementsByTagName !== "undefined" ) { - return context.getElementsByTagName( tag ); - - // DocumentFragment nodes don't have gEBTN - } else if ( support.qsa ) { - return context.querySelectorAll( tag ); - } - } : - - function( tag, context ) { - var elem, - tmp = [], - i = 0, - - // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too - results = context.getElementsByTagName( tag ); - - // Filter out possible comments - if ( tag === "*" ) { - while ( ( elem = results[ i++ ] ) ) { - if ( elem.nodeType === 1 ) { - tmp.push( elem ); - } - } - - return tmp; - } - return results; - }; - - // Class - Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { - if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { - return context.getElementsByClassName( className ); - } - }; - - /* QSA/matchesSelector - ---------------------------------------------------------------------- */ - - // QSA and matchesSelector support - - // matchesSelector(:active) reports false when true (IE9/Opera 11.5) - rbuggyMatches = []; - - // qSa(:focus) reports false when true (Chrome 21) - // We allow this because of a bug in IE8/9 that throws an error - // whenever `document.activeElement` is accessed on an iframe - // So, we allow :focus to pass through QSA all the time to avoid the IE error - // See https://bugs.jquery.com/ticket/13378 - rbuggyQSA = []; - - if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { - - // Build QSA regex - // Regex strategy adopted from Diego Perini - assert( function( el ) { - - var input; - - // Select is set to empty string on purpose - // This is to test IE's treatment of not explicitly - // setting a boolean content attribute, - // since its presence should be enough - // https://bugs.jquery.com/ticket/12359 - docElem.appendChild( el ).innerHTML = "" + - ""; - - // Support: IE8, Opera 11-12.16 - // Nothing should be selected when empty strings follow ^= or $= or *= - // The test attribute must be unknown in Opera but "safe" for WinRT - // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section - if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { - rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); - } - - // Support: IE8 - // Boolean attributes and "value" are not treated correctly - if ( !el.querySelectorAll( "[selected]" ).length ) { - rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); - } - - // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ - if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { - rbuggyQSA.push( "~=" ); - } - - // Support: IE 11+, Edge 15 - 18+ - // IE 11/Edge don't find elements on a `[name='']` query in some cases. - // Adding a temporary attribute to the document before the selection works - // around the issue. - // Interestingly, IE 10 & older don't seem to have the issue. - input = document.createElement( "input" ); - input.setAttribute( "name", "" ); - el.appendChild( input ); - if ( !el.querySelectorAll( "[name='']" ).length ) { - rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + - whitespace + "*(?:''|\"\")" ); - } - - // Webkit/Opera - :checked should return selected option elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - // IE8 throws error here and will not see later tests - if ( !el.querySelectorAll( ":checked" ).length ) { - rbuggyQSA.push( ":checked" ); - } - - // Support: Safari 8+, iOS 8+ - // https://bugs.webkit.org/show_bug.cgi?id=136851 - // In-page `selector#id sibling-combinator selector` fails - if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { - rbuggyQSA.push( ".#.+[+~]" ); - } - - // Support: Firefox <=3.6 - 5 only - // Old Firefox doesn't throw on a badly-escaped identifier. - el.querySelectorAll( "\\\f" ); - rbuggyQSA.push( "[\\r\\n\\f]" ); - } ); - - assert( function( el ) { - el.innerHTML = "" + - ""; - - // Support: Windows 8 Native Apps - // The type and name attributes are restricted during .innerHTML assignment - var input = document.createElement( "input" ); - input.setAttribute( "type", "hidden" ); - el.appendChild( input ).setAttribute( "name", "D" ); - - // Support: IE8 - // Enforce case-sensitivity of name attribute - if ( el.querySelectorAll( "[name=d]" ).length ) { - rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); - } - - // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) - // IE8 throws error here and will not see later tests - if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { - rbuggyQSA.push( ":enabled", ":disabled" ); - } - - // Support: IE9-11+ - // IE's :disabled selector does not pick up the children of disabled fieldsets - docElem.appendChild( el ).disabled = true; - if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { - rbuggyQSA.push( ":enabled", ":disabled" ); - } - - // Support: Opera 10 - 11 only - // Opera 10-11 does not throw on post-comma invalid pseudos - el.querySelectorAll( "*,:x" ); - rbuggyQSA.push( ",.*:" ); - } ); - } - - if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || - docElem.webkitMatchesSelector || - docElem.mozMatchesSelector || - docElem.oMatchesSelector || - docElem.msMatchesSelector ) ) ) ) { - - assert( function( el ) { - - // Check to see if it's possible to do matchesSelector - // on a disconnected node (IE 9) - support.disconnectedMatch = matches.call( el, "*" ); - - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call( el, "[s!='']:x" ); - rbuggyMatches.push( "!=", pseudos ); - } ); - } - - if ( !support.cssHas ) { - - // Support: Chrome 105 - 110+, Safari 15.4 - 16.3+ - // Our regular `try-catch` mechanism fails to detect natively-unsupported - // pseudo-classes inside `:has()` (such as `:has(:contains("Foo"))`) - // in browsers that parse the `:has()` argument as a forgiving selector list. - // https://drafts.csswg.org/selectors/#relational now requires the argument - // to be parsed unforgivingly, but browsers have not yet fully adjusted. - rbuggyQSA.push( ":has" ); - } - - rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); - rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); - - /* Contains - ---------------------------------------------------------------------- */ - hasCompare = rnative.test( docElem.compareDocumentPosition ); - - // Element contains another - // Purposefully self-exclusive - // As in, an element does not contain itself - contains = hasCompare || rnative.test( docElem.contains ) ? - function( a, b ) { - - // Support: IE <9 only - // IE doesn't have `contains` on `document` so we need to check for - // `documentElement` presence. - // We need to fall back to `a` when `documentElement` is missing - // as `ownerDocument` of elements within `