diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000..06baa5e --- /dev/null +++ b/app/__init__.py @@ -0,0 +1,82 @@ +import logging +from flask import Flask, request, jsonify, redirect, url_for, session + +from app.extensions.db import db +from app.extensions.audit_logger import AuditLogger +from app.models import * +from app.models.user import User +from app.routes import register_blueprints +from app.extensions.auth_ext import init_auth, login_manager + +import config +from app.routes.dashboard import dashboard_bp +# from backend.api import bp_api + +from config import TZ + + +# noinspection SpellCheckingInspection +def create_app(): + app = Flask(__name__, static_url_path='/telezab/static', template_folder='templates') + app.config['SQLALCHEMY_DATABASE_URI'] = config.SQLALCHEMY_DATABASE_URI + app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False + app.config['SECRET_KEY'] = config.SECRET_KEY # Замените на надежный секретный ключ + app.config['SESSION_COOKIE_SECURE'] = config.SESSION_COOKIE_SECURE # Убедитесь, что установлено значение True + app.config['SESSION_COOKIE_HTTPONLY'] = config.SESSION_COOKIE_HTTPONLY # Убедитесь, что установлено значение True + app.config['SESSION_COOKIE_SAMESITE'] = config.SESSION_COOKIE_SAMESITE + app.config['SESSION_REFRESH_EACH_REQUEST'] = False + app.config['PERMANENT_SESSION_LIFETIME'] = config.PERMANENT_SESSION_LIFETIME + app.config['SESSION_COOKIE_MAX_AGE'] = 3600 + app.config['TIMEZONE'] = TZ + + # Инициализация расширений + db.init_app(app) + login_manager.init_app(app) + init_auth(app) + + # Инициализация AuditLogger с передачей db.session + app.audit_logger = AuditLogger(db.session) + + # Регистрируем блюпринты + register_blueprints(app) + + # Создаем таблицы (если нужно) + with app.app_context(): + db.create_all() + + + + + @login_manager.unauthorized_handler + def unauthorized(): + logging.debug("Unauthorized access detected") + if request.path.startswith('/telezab/rest/api'): + return jsonify({'error': 'Не авторизован'}), 401 + else: + return redirect(url_for('auth.login')) + + @login_manager.user_loader + def load_user(user_id): + user_data = session.get('user_data', {}) + + display_name = user_data.get('display_name') + if not display_name: + display_name = " ".join(filter(None, [ + user_data.get('user_surname'), + user_data.get('user_name'), + user_data.get('user_middle_name') + ])) + + return User( + user_id, + user_name=user_data.get('user_name'), + user_surname=user_data.get('user_surname'), + user_middle_name=user_data.get('user_middle_name'), + display_name=display_name, + email=user_data.get('email') + ) + + return app + +app = create_app() + diff --git a/app/bot/__init__.py b/app/bot/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/bot/config.py b/app/bot/config.py new file mode 100644 index 0000000..6be2774 --- /dev/null +++ b/app/bot/config.py @@ -0,0 +1,17 @@ +import os + +#Дебаг режим +DEV = os.getenv('DEV') +#Токены и URL'ы +BOT_TOKEN = os.getenv('TELEGRAM_TOKEN') +ZABBIX_API_TOKEN = os.getenv('ZABBIX_API_TOKEN') +ZABBIX_URL = os.getenv('ZABBIX_URL') +SUPPORT_EMAIL = "shiftsupport-rtmis@rtmis.ru" +HELP_URL = "https://confluence.is-mis.ru/pages/viewpage.action?pageId=416785183" +DB_PATH = 'db/telezab.db' + +RABBITMQ_HOST = os.getenv('RABBITMQ_HOST') +RABBITMQ_LOGIN = os.getenv('RABBITMQ_LOGIN') +RABBITMQ_PASS = os.getenv('RABBITMQ_PASS') +RABBITMQ_QUEUE = 'telegram_notifications' +RABBITMQ_URL_FULL = f"amqp://{RABBITMQ_LOGIN}:{RABBITMQ_PASS}@{RABBITMQ_HOST}/" diff --git a/app/bot/handlers/__init__.py b/app/bot/handlers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/bot/handlers/help.py b/app/bot/handlers/help.py new file mode 100644 index 0000000..67dd053 --- /dev/null +++ b/app/bot/handlers/help.py @@ -0,0 +1,15 @@ +# app/bot/handlers/help.py +from telebot.types import Message +from app.bot.config import HELP_URL + +def register_handlers(bot): + @bot.message_handler(commands=['help']) + @bot.message_handler(func=lambda msg: msg.text == "Помощь") + def handle_help(message: Message): + help_text = ( + '/start - Показать меню бота\n' + 'Настройки - Перейти в режим настроек и управления подписками\n' + 'Активные события - Получение всех нерешённых событий мониторинга по выбранным сервисам выбранного региона\n' + f'Помощь - Описание всех возможностей бота' + ) + bot.send_message(message.chat.id, help_text, parse_mode="HTML") diff --git a/app/bot/handlers/main_menu.py b/app/bot/handlers/main_menu.py new file mode 100644 index 0000000..9749e5e --- /dev/null +++ b/app/bot/handlers/main_menu.py @@ -0,0 +1,13 @@ +# app/bot/handlers/main_menu.py +from telebot.types import Message +from app.bot.keyboards.settings_menu import get_settings_menu + +def register_handlers(bot): + @bot.message_handler(func=lambda msg: msg.text == "Настройки") + + def handle_settings_menu(message: Message): + bot.send_message( + message.chat.id, + "Меню настроек:", + reply_markup=get_settings_menu() + ) diff --git a/app/bot/handlers/registration.py b/app/bot/handlers/registration.py new file mode 100644 index 0000000..c2eb17b --- /dev/null +++ b/app/bot/handlers/registration.py @@ -0,0 +1,21 @@ +from telebot.types import Message +from app.bot.config import SUPPORT_EMAIL + + +def register_handlers(bot): + @bot.message_handler(func=lambda msg: msg.text == "Регистрация") + def handle_registration(message: Message): + chat_id = message.chat.id + username = message.from_user.username + if username: + username = f"@{username}" + else: + username = "N/A" + text = ( + f'Для продолжения регистрации необходимо отправить с корпоративного почтового адреса "РТ МИС" письмо на адрес {SUPPORT_EMAIL}\n' + f'В теме письма указать "Подтверждение регистрации в телеграм-боте TeleZab".\n' + f'В теле письма указать:\n' + f'1. ФИО\n' + f'2. Ваш Chat ID: {chat_id}\n' + f'3. Ваше имя пользователя: {username}') + bot.send_message(chat_id, text, parse_mode="HTML") \ No newline at end of file diff --git a/app/bot/handlers/settings.py b/app/bot/handlers/settings.py new file mode 100644 index 0000000..d2960a1 --- /dev/null +++ b/app/bot/handlers/settings.py @@ -0,0 +1,25 @@ +# app/bot/handlers/settings.py +from telebot.types import Message +from app.bot.keyboards.main_menu import get_main_menu +from app.bot.keyboards.settings_menu import get_settings_menu + +def register_handlers(bot): + @bot.message_handler(func=lambda msg: msg.text == "Подписаться") + def handle_subscribe(message: Message): + bot.send_message(message.chat.id, "🔔 Функция подписки ещё не реализована.") + + @bot.message_handler(func=lambda msg: msg.text == "Отписаться") + def handle_unsubscribe(message: Message): + bot.send_message(message.chat.id, "🔕 Функция отписки ещё не реализована.") + + @bot.message_handler(func=lambda msg: msg.text == "Мои подписки") + def handle_my_subscriptions(message: Message): + bot.send_message(message.chat.id, "📄 Отображение подписок пока не реализовано.") + + @bot.message_handler(func=lambda msg: msg.text == "Режим уведомлений") + def handle_notify_mode(message: Message): + bot.send_message(message.chat.id, "⚙️ Настройка режима уведомлений пока не реализована.") + + @bot.message_handler(func=lambda msg: msg.text == "Назад") + def handle_back(message: Message): + bot.send_message(message.chat.id, "Возврат в главное меню", reply_markup=get_main_menu()) diff --git a/app/bot/handlers/start.py b/app/bot/handlers/start.py new file mode 100644 index 0000000..d47cc9c --- /dev/null +++ b/app/bot/handlers/start.py @@ -0,0 +1,41 @@ +# app/bot/handlers/start.py +from telebot.types import Message, ReplyKeyboardMarkup, KeyboardButton +from app.bot.keyboards.main_menu import get_main_menu + +def register_handlers(bot): + @bot.message_handler(commands=['start']) + def start_handler(message, data=None): + chat_id = message.chat.id + + if data: + if data.get('user_verified'): + user = data['user'] + bot.send_message( + chat_id, + f"👋 Привет, {user.user_email}!\nВыберите действие из меню:", + reply_markup=get_main_menu() + ) + return + + elif data.get('user_blocked'): + bot.send_message( + chat_id, + "🚫 Ваш аккаунт заблокирован.\n" + "Пожалуйста, обратитесь к администратору." + ) + return + + elif data.get('user_not_found'): + keyboard = ReplyKeyboardMarkup(resize_keyboard=True) + keyboard.add(KeyboardButton("Регистрация")) + bot.send_message( + chat_id, + "👋 Добро пожаловать!\n\n" + "❗ Вы не зарегистрированы в системе.\n" + "Пожалуйста, нажмите кнопку ниже для регистрации.", + reply_markup=keyboard + ) + return + + # fallback + bot.send_message(chat_id, "Произошла ошибка. Попробуйте позже.") diff --git a/app/bot/keyboards/__init__.py b/app/bot/keyboards/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/bot/keyboards/main_menu.py b/app/bot/keyboards/main_menu.py new file mode 100644 index 0000000..d507252 --- /dev/null +++ b/app/bot/keyboards/main_menu.py @@ -0,0 +1,11 @@ +# app/bot/keyboards/main_menu.py +from telebot.types import ReplyKeyboardMarkup, KeyboardButton + +def get_main_menu(): + markup = ReplyKeyboardMarkup(resize_keyboard=True) + markup.add( + KeyboardButton("Настройки"), + KeyboardButton("Активные проблемы"), + KeyboardButton("Помощь") + ) + return markup diff --git a/app/bot/keyboards/settings_menu.py b/app/bot/keyboards/settings_menu.py new file mode 100644 index 0000000..f84f710 --- /dev/null +++ b/app/bot/keyboards/settings_menu.py @@ -0,0 +1,9 @@ +# app/bot/keyboards/settings_menu.py +from telebot.types import ReplyKeyboardMarkup, KeyboardButton + +def get_settings_menu(): + markup = ReplyKeyboardMarkup(resize_keyboard=True) + markup.add(KeyboardButton("Подписаться"),KeyboardButton("Отписаться")) + markup.add(KeyboardButton("Мои подписки"),KeyboardButton("Режим уведомлений")) + markup.add(KeyboardButton("Назад")) + return markup diff --git a/app/bot/middlewares/__init__.py b/app/bot/middlewares/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/bot/middlewares/user_access.py b/app/bot/middlewares/user_access.py new file mode 100644 index 0000000..eced72b --- /dev/null +++ b/app/bot/middlewares/user_access.py @@ -0,0 +1,49 @@ +# app/bot/middlewares/user_middleware.py +from telebot.handler_backends import BaseMiddleware +from app.models.users import Users +from app.extensions.db import db + + +class UserVerificationMiddleware(BaseMiddleware): + """ + Middleware: проверяет наличие пользователя и флаги, работает в контексте Flask-приложения + """ + + def __init__(self, bot, flask_app): + super().__init__() + self.update_types = ['message', 'callback_query'] + self.bot = bot + self.app = flask_app # Сохраняем ссылку на Flask app + + def pre_process(self, message, data): + if hasattr(message, 'chat'): + chat_id = message.chat.id + elif hasattr(message, 'message') and hasattr(message.message, 'chat'): + chat_id = message.message.chat.id + else: + return + + try: + with self.app.app_context(): + user = db.session.query(Users).filter_by(chat_id=chat_id).first() + + if user is None: + data['user_not_found'] = True + return + + if user.is_blocked: + data['user_blocked'] = True + return + + data['user'] = user + data['user_verified'] = True + + except Exception as e: + print(f"Ошибка при проверке пользователя: {e}") + + def post_process(self, message, data, exception=None): + if exception: + print(f"Exception in handler: {exception}") + elif data.get('user_verified'): + user = data.get('user') + print(f"✅ Пользователь chat_id={user.chat_id} прошёл проверку") diff --git a/app/bot/states.py b/app/bot/states.py new file mode 100644 index 0000000..e69de29 diff --git a/app/bot/telezab_bot.py b/app/bot/telezab_bot.py new file mode 100644 index 0000000..18e4a3d --- /dev/null +++ b/app/bot/telezab_bot.py @@ -0,0 +1,24 @@ +# app/bot/telezab_bot.py +import telebot +from app.bot.config import BOT_TOKEN +from app.bot.handlers import start, main_menu, settings, help, registration +from app.bot.middlewares.user_access import UserVerificationMiddleware +from app import create_app + + +bot = telebot.TeleBot(BOT_TOKEN, use_class_middlewares=True, parse_mode='HTML') +flask_app = create_app() + +# Регистрируем обработчики +start.register_handlers(bot) +main_menu.register_handlers(bot) +settings.register_handlers(bot) +help.register_handlers(bot) +registration.register_handlers(bot) + +# Потом подключаем middleware +user_verification_middleware = UserVerificationMiddleware(bot, flask_app) +bot.setup_middleware(user_verification_middleware) + +def run_bot(): + bot.infinity_polling() diff --git a/app/extensions/__init__.py b/app/extensions/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/extensions/audit_logger.py b/app/extensions/audit_logger.py new file mode 100644 index 0000000..e1cb54e --- /dev/null +++ b/app/extensions/audit_logger.py @@ -0,0 +1,190 @@ +from typing import Optional + +from flask import request +from flask_login import current_user + +from app.models import AuditLog + + +class AuditLogger: + def __init__(self, session): + self.session = session + + def _save_log(self, ldap_user_id, username, action, details, ipaddress=None): + username = username or "Anonymous" + ldap_user_id = ldap_user_id or "anonymous" + ipaddress = ipaddress or request.headers.get('X-Forwarded-For', request.remote_addr) + + log_entry = AuditLog( + ldap_user_id=ldap_user_id, + username=username, + action=action, + details=details, + ipaddress=ipaddress + ) + self.session.add(log_entry) + self.session.commit() + + def auth(self, username_attempted, success: bool, ldap_user_id=None, display_name=None, error=None): + action = "Авторизация" if success else "Ошибка авторизации" + details = f"{'Успешный вход' if success else 'Неудачная попытка входа'}: {display_name or username_attempted}" + if error: + details += f". Ошибка: {error}" + self._save_log( + ldap_user_id=ldap_user_id or username_attempted, + username=display_name if success else "Anonymous", + action=action, + details=details + ) + + def users(self, action_type: str, actor_display_name: Optional[str], ldap_user_id: str, + affected_chat_id: Optional[int] = None, email: Optional[str] = None, + telegram_id: Optional[str] = None, error: Optional[str] = None): + action_map = { + "add": "Добавление пользователя", + "delete": "Удаление пользователя", + "block": "Блокировка пользователя", + "unblock": "Разблокировка пользователя" + } + if action_type not in action_map: + raise ValueError(f"Недопустимое действие логирования: {action_type}") + + details = self._compose_details( + telegram_id=telegram_id, + affected_chat_id=affected_chat_id, + email=email, + error=error, + fallback="Данные пользователя отсутствуют" if not current_user.is_authenticated else None + ) + + self._save_log( + ldap_user_id=ldap_user_id, + username=actor_display_name, + action=action_map[action_type], + details=details + ) + + def systems(self, action_type: str, actor_display_name: Optional[str], ldap_user_id: str, + system_id: Optional[str] = None, name: Optional[str] = None, error: Optional[str] = None): + action_map = { + "add": "Добавление системы", + "update": "Изменение имени системы", + "delete": "Удаление системы" + } + if action_type not in action_map: + raise ValueError(f"Недопустимое действие логирования: {action_type}") + + details = self._compose_details( + system_id=system_id, + name=name, + error=error + ) + + self._save_log( + ldap_user_id=ldap_user_id, + username=actor_display_name, + action=action_map[action_type], + details=details + ) + + def regions(self, + action_type: str, + actor_display_name: Optional[str], + ldap_user_id: str, + region_id: Optional[str] = None, + name: Optional[str] = None, + new_name: Optional[str] = None, + old_name: Optional[str] = None, + active: Optional[bool] = None, + old_active: Optional[bool] = None, + error: Optional[str] = None, + ): + action_map = { + "add": "Добавление региона", + "rename": "Изменение имени региона", + "toggle": "Изменение статуса региона", + "delete": "Удаление региона" + } + + if action_type not in action_map: + raise ValueError(f"Недопустимое действие логирования: {action_type}") + + if action_type == "rename": + if old_name is not None and new_name is not None: + details = f"Region id: {region_id}; Rename: {old_name} → {new_name}" + else: + details = self._compose_details( + region_id=region_id, + new_name=new_name, + old_name=old_name, + error=error + ) + + elif action_type == "toggle": + if old_active is not None and active is not None: + old_status_str = "Активен" if old_active else "Отключён" + new_status_str = "Активен" if active else "Отключён" + details = f"Region id: {region_id}; Status: {old_status_str} → {new_status_str}" + else: + status_str = "Активен" if active else "Отключён" if active is not None else None + details = self._compose_details( + region_id=region_id, + status=status_str, + error=error + ) + + else: + status_str = "Активен" if active else "Отключён" if active is not None else None + details = self._compose_details( + region_id=region_id, + name=name, + status=status_str, + error=error + ) + + self._save_log( + ldap_user_id=ldap_user_id, + username=actor_display_name, + action=action_map[action_type], + details=details + ) + + + def get_web_action_logs(self, page, per_page, ldap_user_id_filter=None, action_filter=None): + query = AuditLog.query.order_by(AuditLog.timestamp.desc()) + + if ldap_user_id_filter: + query = query.filter_by(ldap_user_id=ldap_user_id_filter) + if action_filter: + query = query.filter(AuditLog.action.like(f'%{action_filter}%')) + + pagination = query.paginate(page=page, per_page=per_page) + return { + 'logs': [ + { + 'id': log.id, + 'ldap_user_id': log.ldap_user_id, + 'username': log.username, + 'timestamp': log.timestamp.isoformat(), + 'action': log.action, + 'details': log.details + } for log in pagination.items + ], + 'total': pagination.total, + 'pages': pagination.pages, + 'current_page': pagination.page, + 'per_page': pagination.per_page + } + + @staticmethod + def _compose_details(**kwargs) -> str: + parts = [] + for key, value in kwargs.items(): + if value is None: + continue + if key == "fallback": + parts.append(value) + else: + key_display = key.replace("_", " ").capitalize() + parts.append(f"{key_display}: {value}") + return "; ".join(parts) diff --git a/app/extensions/auth_ext.py b/app/extensions/auth_ext.py new file mode 100644 index 0000000..e0124cd --- /dev/null +++ b/app/extensions/auth_ext.py @@ -0,0 +1,10 @@ +# backend/ext/auth_ext.py (опционально, если хочешь инициализировать через factory) +from flask_login import LoginManager +from app.services.auth_service import init_ldap + +login_manager = LoginManager() + +def init_auth(app): + login_manager.init_app(app) + login_manager.login_view = 'auth.login' + init_ldap(app) \ No newline at end of file diff --git a/app/extensions/db.py b/app/extensions/db.py new file mode 100644 index 0000000..f758333 --- /dev/null +++ b/app/extensions/db.py @@ -0,0 +1,3 @@ +from flask_sqlalchemy import SQLAlchemy + +db: SQLAlchemy = SQLAlchemy() \ No newline at end of file diff --git a/app/models/__init__.py b/app/models/__init__.py new file mode 100644 index 0000000..2d80f85 --- /dev/null +++ b/app/models/__init__.py @@ -0,0 +1,8 @@ +from .users import Users +from .regions import Regions +from .subscriptions import Subscriptions +from .userevents import UserEvents +from .auditlog import AuditLog +from .systems import Systems +from .user import User +from .state import UserState \ No newline at end of file diff --git a/app/models/auditlog.py b/app/models/auditlog.py new file mode 100644 index 0000000..eb4d694 --- /dev/null +++ b/app/models/auditlog.py @@ -0,0 +1,19 @@ +from datetime import datetime + +from sqlalchemy import Integer, String, DateTime +from sqlalchemy.orm import Mapped, mapped_column + +from app.extensions.db import db + +class AuditLog(db.Model): + __tablename__ = 'auditlog' + + id: Mapped[int] = mapped_column(Integer, primary_key=True) + ldap_user_id: Mapped[str] = mapped_column(String(255), nullable=False) + username: Mapped[str | None] = mapped_column(String(255)) + action: Mapped[str] = mapped_column(String(255), nullable=False) + details: Mapped[str | None] = mapped_column(String(1024)) + timestamp: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) + ipaddress: Mapped[str] = mapped_column(String(255), nullable=False) + def __repr__(self): + return f"" \ No newline at end of file diff --git a/app/models/regions.py b/app/models/regions.py new file mode 100644 index 0000000..dc51bd8 --- /dev/null +++ b/app/models/regions.py @@ -0,0 +1,6 @@ +from app.extensions.db import db + +class Regions(db.Model): + region_id = db.Column(db.Integer, primary_key=True) + region_name = db.Column(db.String(255), nullable=False) + active = db.Column(db.Boolean, default=True) \ No newline at end of file diff --git a/app/models/state.py b/app/models/state.py new file mode 100644 index 0000000..c3ecc0a --- /dev/null +++ b/app/models/state.py @@ -0,0 +1,10 @@ +from app.extensions.db import db + +class UserState(db.Model): + __tablename__ = "user_states" + + chat_id = db.Column(db.BigInteger, primary_key=True) + state = db.Column(db.String(64), nullable=False) + + def __repr__(self): + return f"" \ No newline at end of file diff --git a/app/models/subscriptions.py b/app/models/subscriptions.py new file mode 100644 index 0000000..63fca9b --- /dev/null +++ b/app/models/subscriptions.py @@ -0,0 +1,13 @@ +from sqlalchemy import ForeignKey, PrimaryKeyConstraint + +from app.extensions.db import db + +class Subscriptions(db.Model): + chat_id = db.Column(db.Integer, ForeignKey('users.chat_id', ondelete='CASCADE'), nullable=False) #Добавляем внешний ключ с ondelete + region_id = db.Column(db.Integer, nullable=False) + active = db.Column(db.Boolean, default=True) + skip = db.Column(db.Boolean, default=False) + disaster_only = db.Column(db.Boolean, default=False) + __table_args__ = ( + PrimaryKeyConstraint('chat_id', 'region_id'), + ) \ No newline at end of file diff --git a/app/models/systems.py b/app/models/systems.py new file mode 100644 index 0000000..32a70a5 --- /dev/null +++ b/app/models/systems.py @@ -0,0 +1,10 @@ +from app.extensions.db import db + +class Systems(db.Model): + __tablename__ = 'systems' + system_id = db.Column(db.Integer, primary_key=True) + system_name = db.Column(db.String(255), nullable=False) + name = db.Column(db.String(255), nullable=False) + + def __repr__(self): + return f'' \ No newline at end of file diff --git a/app/models/user.py b/app/models/user.py new file mode 100644 index 0000000..d8657fa --- /dev/null +++ b/app/models/user.py @@ -0,0 +1,17 @@ +from flask_login import UserMixin + + +class User(UserMixin): + def __init__(self, user_id, + user_name=None, + user_surname=None, + user_middle_name=None, + display_name=None, + email=None + ): + self.id = str(user_id) + self.user_name = user_name + self.user_surname = user_surname + self.user_middle_name = user_middle_name + self.display_name = display_name + self.email = email \ No newline at end of file diff --git a/app/models/userevents.py b/app/models/userevents.py new file mode 100644 index 0000000..0c2807f --- /dev/null +++ b/app/models/userevents.py @@ -0,0 +1,9 @@ +from app.extensions.db import db + + +class UserEvents(db.Model): + id = db.Column(db.Integer, primary_key=True) + chat_id = db.Column(db.Integer, nullable=False) + telegram_id = db.Column(db.String(80), nullable=False) + action = db.Column(db.String(500), nullable=False) + timestamp = db.Column(db.DateTime, default=db.func.current_timestamp()) \ No newline at end of file diff --git a/app/models/users.py b/app/models/users.py new file mode 100644 index 0000000..66d51b0 --- /dev/null +++ b/app/models/users.py @@ -0,0 +1,10 @@ +from sqlalchemy.orm import relationship + +from app.extensions.db import db + +class Users(db.Model): + chat_id = db.Column(db.Integer, primary_key=True) + telegram_id = db.Column(db.String(80), unique=True, nullable=False) + user_email = db.Column(db.String(255), unique=True, nullable=False) + is_blocked = db.Column(db.Boolean, default=False) + subscriptions = relationship("Subscriptions", backref="user", cascade="all, delete-orphan") # Добавлено cascade \ No newline at end of file diff --git a/app/routes/__init__.py b/app/routes/__init__.py new file mode 100644 index 0000000..ca32d54 --- /dev/null +++ b/app/routes/__init__.py @@ -0,0 +1,8 @@ +from .auth import auth_bp +from .dashboard import dashboard_bp +from .api import api_bp + +def register_blueprints(app): + app.register_blueprint(auth_bp) + app.register_blueprint(dashboard_bp) + app.register_blueprint(api_bp) diff --git a/app/routes/api/__init__.py b/app/routes/api/__init__.py new file mode 100644 index 0000000..dace9f7 --- /dev/null +++ b/app/routes/api/__init__.py @@ -0,0 +1,14 @@ +from flask import Blueprint + +api_bp = Blueprint('api', __name__, url_prefix='/telezab/rest/api') + +from .regions import region_bp +from .users import users_bp +from .systems import system_bp +from .notifications import notification_bp + +# Регистрируем вложенные блюпринты с url_prefix +api_bp.register_blueprint(region_bp, url_prefix='/regions') +api_bp.register_blueprint(users_bp, url_prefix='/users') +api_bp.register_blueprint(system_bp, url_prefix='/systems') +api_bp.register_blueprint(notification_bp, url_prefix='/notifications') diff --git a/app/routes/api/notifications.py b/app/routes/api/notifications.py new file mode 100644 index 0000000..c9e9476 --- /dev/null +++ b/app/routes/api/notifications.py @@ -0,0 +1,12 @@ +from flask import Blueprint, request, jsonify +from app.services.notifications_service import NotificationService + +notification_bp = Blueprint('notification', __name__,url_prefix='/notifications') + + +@notification_bp.route('/', methods=['POST'], strict_slashes=False) +def notification(): + service = NotificationService() + data = request.get_json() + result, status = service.process_notification(data) + return jsonify(result), status diff --git a/app/routes/api/regions.py b/app/routes/api/regions.py new file mode 100644 index 0000000..93ab64f --- /dev/null +++ b/app/routes/api/regions.py @@ -0,0 +1,42 @@ +from flask import Blueprint, request, jsonify +from flask_login import current_user, login_required + +from app.services.regions_service import RegionService + +region_bp = Blueprint('region', __name__,url_prefix='/regions') +region = RegionService() + +@region_bp.route('/', methods=['GET'], strict_slashes=False) +@login_required +def list_regions(): + return jsonify(region.get_regions( + page=request.args.get('page', 1, type=int), + per_page=request.args.get('per_page', 10, type=int), + sort_field=request.args.get('sort_field', 'region_id'), + sort_order=request.args.get('sort_order', 'asc') + )) + +@region_bp.route('/', methods=['POST'], strict_slashes=False) +@login_required +def add_region(): + return region.add_region(request.json, current_user) + +@region_bp.route('/', methods=['DELETE']) +@login_required +def delete_region(region_id): + return region.delete_region(region_id, current_user) + +@region_bp.route('/name', methods=['PUT']) +@login_required +def update_name(): + return region.update_region_name(request.json, current_user) + +@region_bp.route('/status', methods=['PUT']) +@login_required +def update_status(): + return region.update_region_status(request.json, current_user) + +@region_bp.route('//subscribers', methods=['GET']) +@login_required +def region_subscribers(region_id): + return region.get_region_subscribers(region_id) \ No newline at end of file diff --git a/app/routes/api/systems.py b/app/routes/api/systems.py new file mode 100644 index 0000000..9b0b0fd --- /dev/null +++ b/app/routes/api/systems.py @@ -0,0 +1,31 @@ +from flask import Blueprint, request, jsonify +from flask_login import login_required +from app.services.systems_service import SystemService + +system_bp = Blueprint('system', __name__,url_prefix='/systems') +system = SystemService() + +@system_bp.route('/', methods=['GET'], strict_slashes=False) +@login_required +def list_systems(): + return jsonify(system.get_systems( + page=request.args.get('page', 1, type=int), + per_page=request.args.get('per_page', 10, type=int), + sort_field=request.args.get('sort_field', 'system_id'), + sort_order=request.args.get('sort_order', 'asc') + )) + +@system_bp.route('/', methods=['POST'],strict_slashes=False) +@login_required +def add_system(): + return system.add_system(request.json) + +@system_bp.route('/', methods=['PUT'],strict_slashes=False) +@login_required +def update_system(): + return system.update_system_name(request.json) + +@system_bp.route('/', methods=['DELETE'],strict_slashes=False) +@login_required +def delete_system(system_id): + return system.delete_system(system_id) diff --git a/app/routes/api/users.py b/app/routes/api/users.py new file mode 100644 index 0000000..fd60d91 --- /dev/null +++ b/app/routes/api/users.py @@ -0,0 +1,68 @@ +# app/routes/users.py + +from flask import Blueprint, jsonify, request +from flask_login import login_required, current_user + +# Импортируем функции сервисов напрямую +from app.services.users_service import get_users, get_user, toggle_block_user, delete_user, add_user, search_users +from app.services.users_event_service import log_user_action, get_user_events # Импортируем функции + +users_bp = Blueprint('users', __name__, url_prefix='/users') + +@users_bp.route('/', methods=['GET', 'POST'], strict_slashes=False) +@login_required +def manage_users_route(): + if request.method == 'GET': + page = request.args.get('page', 1, type=int) + per_page = request.args.get('per_page', 20, type=int) + return jsonify(get_users(page, per_page)) + elif request.method == 'POST': + user_data = request.get_json() + result, status_code = add_user(user_data, current_user) + return jsonify(result), status_code + return None + + +@users_bp.route('/', methods=['GET']) +@login_required +def get_user_route(chat_id): + user = get_user(chat_id) + if not user: + return jsonify({'error': 'Пользователь не найден'}), 404 + return jsonify(user) + +@users_bp.route('//block', methods=['POST']) +@login_required +def block_user_route(chat_id): + result, status_code = toggle_block_user(chat_id, current_user) + return jsonify(result), status_code + +@users_bp.route('/', methods=['DELETE']) +@login_required +def delete_user_route(chat_id): + result, status_code = delete_user(chat_id, current_user) + return jsonify(result), status_code + +@users_bp.route('//log', methods=['POST']) +@login_required +def log_user_action_route(chat_id): + action = request.json.get('action') + if action: + result, status_code = log_user_action(chat_id, action) # Вызываем функцию напрямую + return jsonify(result), status_code + else: + return jsonify({'error': 'Не указано действие'}), 400 + +@users_bp.route('/search', methods=['GET']) +@login_required +def search_users_route(): + telegram_id = request.args.get('telegram_id') + email = request.args.get('email') + users = search_users(telegram_id, email) + return jsonify(users) + +@users_bp.route('//user_events', methods=['GET']) +@login_required +def handle_user_events_route(chat_id): + result, status_code = get_user_events(chat_id) # Вызываем функцию напрямую + return jsonify(result), status_code \ No newline at end of file diff --git a/app/routes/auth.py b/app/routes/auth.py new file mode 100644 index 0000000..7fbbc9a --- /dev/null +++ b/app/routes/auth.py @@ -0,0 +1,59 @@ +from flask import Blueprint, render_template, request, redirect, url_for, flash, session, current_app +from flask_login import login_user, login_required, logout_user + +from app.extensions.db import db +from app.extensions.audit_logger import AuditLogger +from app.services.auth_service import authenticate_user, parse_ldap_user +from app.models import User + + +auditlog = AuditLogger(db.session) + +auth_bp = Blueprint('auth', __name__, url_prefix='/telezab/') + +@auth_bp.route('/login', methods=['GET', 'POST']) +def login(): + if 'user_id' in session: + return redirect(url_for('dashboard.dashboard')) + + if request.method == 'POST': + username = request.form['username'] + password = request.form['password'] + + success, user_info, error = authenticate_user(username, password) + + if not success: + flash(error, 'danger') + auditlog.auth(username_attempted=username, success=False, error=error) + return render_template("login.html") + + data = parse_ldap_user(user_info) + display_name = (f"{data['user_surname']} {data['user_name']} {data['user_middle_name']}").strip() + user = User( + user_id=data['sam_account_name'], + user_name=data['user_name'], + user_surname=data['user_surname'], + user_middle_name=data['user_middle_name'], + display_name=display_name, + email=data['email'] + ) + + session.permanent = True + session['username'] = data['sam_account_name'] + session['display_name'] = display_name + session['user_data'] = data + login_user(user) + + auditlog.auth(username_attempted=username, success=True, ldap_user_id=data['sam_account_name'], display_name=display_name) + flash("Logged in successfully!", "success") + return redirect(url_for("dashboard.dashboard")) + + return render_template("login.html") + + +@auth_bp.route('/logout') +@login_required +def logout(): + logout_user() + session.clear() + return redirect(url_for('auth.login')) diff --git a/app/routes/dashboard.py b/app/routes/dashboard.py new file mode 100644 index 0000000..caef6a9 --- /dev/null +++ b/app/routes/dashboard.py @@ -0,0 +1,92 @@ +from flask import Blueprint, render_template, request + +from app.models import AuditLog +from app.models import Users +from flask_login import login_required + +# Создаём Blueprint +dashboard_bp = Blueprint('dashboard', __name__, url_prefix='/telezab/') + + + +# Роуты для отображения страниц +@dashboard_bp.route('/') +@login_required +def dashboard(): + return render_template('index.html') + +@dashboard_bp.route('/users') +@login_required +def users_page(): + users = Users.query.all() + return render_template('users.html', user=users) + +@dashboard_bp.route('/logs') +@login_required +def logs_page(): + # Получаем параметры фильтрации из query string + action = request.args.get('action', type=str) + username = request.args.get('username', type=str) + timestamp_from = request.args.get('timestamp_from', type=str) + timestamp_to = request.args.get('timestamp_to', type=str) + order = request.args.get('order', 'asc').lower() + page = request.args.get('page', 1, type=int) + per_page = 20 + + query = AuditLog.query + + # Фильтрация по action + if action: + query = query.filter(AuditLog.action.ilike(f'%{action}%')) + + # Фильтрация по username + if username: + query = query.filter(AuditLog.username.ilike(f'%{username}%')) + + # Фильтрация по дате (начало) + if timestamp_from: + try: + from datetime import datetime + dt_from = datetime.strptime(timestamp_from, '%Y-%m-%d') + query = query.filter(AuditLog.timestamp >= dt_from) + except ValueError: + pass # Игнорируем неверный формат + + # Фильтрация по дате (конец) + if timestamp_to: + try: + from datetime import datetime, timedelta + dt_to = datetime.strptime(timestamp_to, '%Y-%m-%d') + timedelta(days=1) + query = query.filter(AuditLog.timestamp < dt_to) + except ValueError: + pass + + # Сортировка + if order == 'asc': + query = query.order_by(AuditLog.timestamp.asc()) + else: + query = query.order_by(AuditLog.timestamp.desc()) + + # Пагинация + logs = query.paginate(page=page, per_page=per_page, error_out=False) + + # Передаем текущие фильтры и сортировку в шаблон для отображения и генерации ссылок + filters = { + 'action': action, + 'username': username, + 'timestamp_from': timestamp_from, + 'timestamp_to': timestamp_to, + 'order': order + } + + return render_template('logs.html', logs=logs, filters=filters) + +@dashboard_bp.route('/regions') +@login_required +def regions_page(): + return render_template('regions.html') + +@dashboard_bp.route('/health') +def healthcheck(): + pass + diff --git a/app/services/auth_service.py b/app/services/auth_service.py new file mode 100644 index 0000000..39d047c --- /dev/null +++ b/app/services/auth_service.py @@ -0,0 +1,53 @@ + +from flask import current_app +from flask_ldap3_login import LDAP3LoginManager, AuthenticationResponseStatus +from werkzeug.middleware.proxy_fix import ProxyFix +import config + +def init_ldap(app): + app.config['LDAP_HOST'] = config.LDAP_HOST + app.config['LDAP_PORT'] = config.LDAP_PORT + app.config['LDAP_USE_SSL'] = config.LDAP_USE_SSL + app.config['LDAP_BASE_DN'] = config.LDAP_BASE_DN + app.config['LDAP_BIND_DIRECT_CREDENTIALS'] = False + app.config['LDAP_BIND_USER_DN'] = config.LDAP_BIND_USER_DN + app.config['LDAP_BIND_USER_PASSWORD'] = config.LDAP_USER_PASSWORD + app.config['LDAP_USER_DN'] = config.LDAP_USER_DN + app.config['LDAP_USER_PASSWORD'] = config.LDAP_USER_PASSWORD + app.config['LDAP_USER_OBJECT_FILTER'] = config.LDAP_USER_OBJECT_FILTER + app.config['LDAP_USER_LOGIN_ATTR'] = config.LDAP_USER_LOGIN_ATTR + app.config['LDAP_USER_SEARCH_SCOPE'] = config.LDAP_USER_SEARCH_SCOPE + app.config['LDAP_SCHEMA'] = config.LDAP_SCHEMA + + ldap_manager = LDAP3LoginManager(app) + app.extensions['ldap3_login'] = ldap_manager + ldap_manager.init_app(app) + app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1) + +def authenticate_user(username, password): + ldap_manager = current_app.extensions['ldap3_login'] + response = ldap_manager.authenticate(username, password) + if response.status == AuthenticationResponseStatus.success: + return True, response.user_info, None + elif response.status == AuthenticationResponseStatus.fail: + return False, None, "Invalid username or password." + else: + return False, None, f"LDAP Error: {response.status}" + +def parse_ldap_user(user_info): + def get(attr): + value = user_info.get(attr) + if isinstance(value, list) and value: + return str(value[0]) + elif value: + return str(value) + else: + return None + + return { + 'sam_account_name': get("sAMAccountName"), + 'email': get("mail"), + 'user_name': get("givenName"), + 'user_middle_name': get("middleName"), + 'user_surname': get("sn"), + } diff --git a/app/services/bot/bot_database.py b/app/services/bot/bot_database.py new file mode 100644 index 0000000..5134cf1 --- /dev/null +++ b/app/services/bot/bot_database.py @@ -0,0 +1,72 @@ +from datetime import datetime, timezone + +from app.extensions.db import db +from app.models import Users, Regions, Subscriptions, UserEvents + +import telebot # Для логов, можно заменить на кастомный логгер + + +def is_whitelisted(chat_id): + """Проверяет, есть ли пользователь с заданным chat_id в базе данных и не заблокирован ли он.""" + try: + user = Users.query.filter_by(chat_id=chat_id).first() + if user: + if user.is_blocked: + return False, "Ваш доступ заблокирован." + return True, None + return False, None + except Exception as e: + telebot.logger.error(f"Ошибка при проверке пользователя: {e}") + return False, "Произошла ошибка при проверке доступа." + + +def get_sorted_regions(): + """Получить список активных регионов, отсортированных по region_id.""" + return ( + Regions.query + .filter_by(active=True) + .order_by(Regions.region_id.asc()) + .with_entities(Regions.region_id, Regions.region_name) + .all() + ) + + +def get_user_subscribed_regions(chat_id): + """Получить список регионов, на которые подписан пользователь.""" + return ( + Regions.query + .join(Subscriptions, Subscriptions.region_id == Regions.region_id) + .filter( + Subscriptions.chat_id == chat_id, + Subscriptions.active.is_(True), + Subscriptions.skip.is_(False) + ) + .order_by(Regions.region_id.asc()) + .with_entities(Regions.region_id, Regions.region_name) + .all() + ) + + +def format_regions_list(regions): + """Сформировать строку для отображения списка регионов.""" + return '\n'.join([f"{region_id} - {region_name}" for region_id, region_name in regions]) + + +def log_user_event(chat_id, username, action): + """Логирует действие пользователя.""" + try: + timestamp = datetime.now(timezone.utc) + event = UserEvents( + chat_id=chat_id, + telegram_id=username, + action=action, + timestamp=timestamp + ) + db.session.add(event) + db.session.commit() + + formatted_time = timestamp.strftime('%Y-%m-%d %H:%M:%S') + telebot.logger.info(f"User event logged: {chat_id} ({username}) - {action} at {formatted_time}.") + except Exception as e: + db.session.rollback() + telebot.logger.error(f"Error logging user event: {e}") diff --git a/app/services/notifications_service.py b/app/services/notifications_service.py new file mode 100644 index 0000000..02c4b5a --- /dev/null +++ b/app/services/notifications_service.py @@ -0,0 +1,28 @@ +from utilities.notification_manager import NotificationManager +from utilities.telegram_utilities import extract_region_number, format_message +from flask import current_app + + + +class NotificationService: + def __init__(self): + self.logger = current_app.logger + self.manager = NotificationManager(self.logger) + + def process_notification(self, data): + self.logger.info(f"Получены данные уведомления: {data}") + + region_id = extract_region_number(data.get("host")) + if region_id is None: + self.logger.error(f"Не удалось извлечь номер региона из host: {data.get('host')}") + return {"status": "error", "message": "Invalid host format"}, 400 + + self.logger.debug(f"Извлечён номер региона: {region_id}") + + subscribers = self.manager.get_subscribers(region_id, data['severity']) + + if self.manager.is_region_active(region_id): + message = format_message(data) + self.manager.send_notifications(subscribers, message) + + return {"status": "success"}, 200 diff --git a/app/services/rabbitmq_service.py b/app/services/rabbitmq_service.py new file mode 100644 index 0000000..707f8b2 --- /dev/null +++ b/app/services/rabbitmq_service.py @@ -0,0 +1,86 @@ +import asyncio +import json +import logging +from app import app, Users +import aio_pika +import pika + +from config import RABBITMQ_LOGIN, RABBITMQ_PASS, RABBITMQ_HOST, RABBITMQ_QUEUE, RABBITMQ_URL_FULL + +logger = logging.getLogger(__name__) + +rate_limit_semaphore = asyncio.Semaphore(25) + +def rabbitmq_connection(): + credentials = pika.PlainCredentials(RABBITMQ_LOGIN, RABBITMQ_PASS) + parameters = pika.ConnectionParameters( + host=RABBITMQ_HOST, + credentials=credentials, + heartbeat=600, + blocked_connection_timeout=300 + ) + connection = pika.BlockingConnection(parameters) + channel = connection.channel() + channel.queue_declare(queue=RABBITMQ_QUEUE, durable=True) + return connection, channel + +def send_to_queue(message): + connection, channel = rabbitmq_connection() + channel.basic_publish( + exchange='', + routing_key=RABBITMQ_QUEUE, + body=json.dumps(message), + properties=pika.BasicProperties( + delivery_mode=2, + )) + connection.close() + +async def send_message(chat_id, message, backend_bot, is_notification=False): + telegram_id = "unknown" + try: + if is_notification: + await rate_limit_semaphore.acquire() + + def get_user(): + with app.app_context(): + user = Users.query.get(chat_id) + return user.telegram_id if user else "unknown" + + telegram_id = await asyncio.to_thread(get_user) + + await asyncio.to_thread(backend_bot.bot.send_message, chat_id, message, parse_mode='HTML') + + formatted_message = message.replace('\n', ' ').replace('\r', '') + logger.info(f'Send notification to {telegram_id} ({chat_id}) from RabbitMQ [{formatted_message}]') + + except Exception as e: + logger.error(f"Error sending message to {telegram_id} ({chat_id}): {e}") + finally: + if is_notification: + rate_limit_semaphore.release() + +async def consume_from_queue(backend_bot): + while True: + try: + connection = await aio_pika.connect_robust(RABBITMQ_URL_FULL) + async with connection: + channel = await connection.channel() + queue = await channel.declare_queue(RABBITMQ_QUEUE, durable=True) + + async for message in queue: + async with message.process(): + try: + data = json.loads(message.body.decode('utf-8')) + chat_id = data["chat_id"] + message_text = data["message"] + await send_message(chat_id, message_text, backend_bot, is_notification=True) + except (json.JSONDecodeError, KeyError) as e: + logger.error(f"Error processing message: {e}") + except Exception as e: + logger.error(f"Error sending message: {e}") + except aio_pika.exceptions.AMQPError as e: + logger.error(f"RabbitMQ error: {e}") + except Exception as e: + logger.error(f"Critical error: {e}") + finally: + await asyncio.sleep(5) diff --git a/app/services/regions_service.py b/app/services/regions_service.py new file mode 100644 index 0000000..39806a3 --- /dev/null +++ b/app/services/regions_service.py @@ -0,0 +1,299 @@ +from flask import current_app +from sqlalchemy import desc, asc +import logging +from app import Regions, db, Users, Subscriptions +from app.extensions.audit_logger import AuditLogger + + +auditlog = AuditLogger(db.session) +logger = logging.getLogger(__name__) +logger.setLevel(logging.DEBUG) + +class RegionService: + def __init__(self): + self.db = db + self.auditlog = auditlog + self.logger = logger + + def get_regions(self, page=1, per_page=10, sort_field='region_id', sort_order='asc'): + self.logger.info(f"Получение регионов: page={page}, per_page={per_page}, sort_field={sort_field}, sort_order={sort_order}") + + # Определение порядка сортировки + sort_func = asc if sort_order == 'asc' else desc + + # Получение атрибута модели для сортировки + if sort_field: + sort_attr = getattr(Regions, sort_field, Regions.region_id) # По умолчанию сортируем по region_id + else: + sort_attr = Regions.region_id + + # Запрос к базе данных с учетом сортировки и пагинации + if sort_field == 'region_id': + regions_query = Regions.query.order_by(sort_func(Regions.region_id.cast(db.Integer))).paginate(page=page, per_page=per_page, error_out=False) + elif sort_field == 'name': + regions_query = Regions.query.order_by(sort_func(Regions.region_name)).paginate(page=page, per_page=per_page, error_out=False) + else: + regions_query = Regions.query.order_by(sort_func(sort_attr)).paginate(page=page, per_page=per_page, error_out=False) + + regions_list = [{ + 'region_id': r.region_id, + 'name': r.region_name, + 'active': r.active + } for r in regions_query.items] + + # bf.app.logger.info(f"Получены регионы: {len(regions_list)} элементов") + + return { + 'regions': regions_list, + 'total_regions': regions_query.total, + 'total_pages': regions_query.pages, + 'current_page': regions_query.page, + 'per_page': regions_query.per_page + } + + def get_region_by_id(self, region_id): + # bf.app.logger.info(f"Поиск региона по ID: {region_id}") + + # Получение региона по его ID + region = Regions.query.filter_by(region_id=region_id).first() + + if region: + # bf.app.logger.info(f"Найден регион: {region.region_name}") + return region.region_name + else: + # bf.app.logger.warning(f"Регион с ID {region_id} не найден.") + return None + + def get_region_subscribers(self, region_id): + # bf.app.logger.info(f"Получение подписчиков региона: region_id={region_id}") + + try: + region = Regions.query.get(region_id) + if not region: + # bf.app.logger.warning(f"Регион с ID {region_id} не найден") + return {'status': 'error', 'message': 'Регион не найден'}, 404 + + subscribers = self.db.session.query( + Users).join(Subscriptions).filter(Subscriptions.region_id == region_id).all() + + subscribers_list = [{ + 'chat_id': user.chat_id, + 'telegram_id': user.telegram_id, + 'email': user.user_email + } for user in subscribers] + + # bf.app.logger.info(f"Получены подписчики региона {region_id}: {len(subscribers_list)} элементов") + + return {'status': 'success', 'subscribers': subscribers_list}, 200 + except Exception as e: + # bf.app.logger.error(f"Ошибка при получении подписчиков региона: {e}") + return {'status': 'error', 'message': str(e)}, 500 + + def add_region(self, data, user): + region_id = data.get('region_id') + name = data.get('name') + active = data.get('active', True) + + self.logger.info(f"Добавление региона: region_id={region_id}, name={name}, active={active}") + + try: + if not region_id.isdigit(): + self.logger.warning(f"ID региона {region_id} содержит нечисловые символы") + error_msg = 'ID региона должен содержать только числа.' + self.auditlog.regions( + action_type="add", + actor_display_name=user.display_name, + ldap_user_id=user.id, + name=name, + region_id=region_id, + error=error_msg + ) + return {'status': 'error', 'message': error_msg}, 400 + + existing_region = Regions.query.get(region_id) + if existing_region: + self.logger.warning(f"Регион с ID {region_id} уже существует") + error_msg = 'Регион с таким ID уже существует' + self.auditlog.regions( + action_type="add", + actor_display_name=user.display_name, + ldap_user_id=user.id, + name=name, + region_id=region_id, + error=error_msg + ) + return {'status': 'error', 'message': error_msg}, 409 + + region = Regions(region_id=region_id, region_name=name, active=active) + self.db.session.add(region) + self.db.session.commit() + + self.logger.info(f"Регион {region_id} успешно добавлен") + self.auditlog.regions( + action_type="add", + actor_display_name=user.display_name, + ldap_user_id=user.id, + name=name, + region_id=region_id + ) + return {'status': 'success', 'message': 'Регион добавлен'}, 201 + + except Exception as e: + self.db.session.rollback() + error_msg = str(e) + self.logger.error(f"Ошибка при добавлении региона: {error_msg}") + self.auditlog.regions( + action_type="add", + actor_display_name=user.display_name, + ldap_user_id=user.id, + name=name, + region_id=region_id, + error=error_msg + ) + return {'status': 'error', 'message': error_msg}, 500 + + def update_region_status(self, data, user): + region_id = data.get('region_id') + new_status = data.get('active') + + self.logger.info(f"Изменение статуса региона: region_id={region_id}, new_status={new_status}") + + try: + region = Regions.query.get(region_id) + if region: + old_status = region.active + region.active = new_status + self.db.session.commit() + + self.logger.info(f"Статус региона {region_id} изменён: {old_status} → {new_status}") + self.auditlog.regions( + action_type="toggle", + actor_display_name=user.display_name, + ldap_user_id=user.id, + region_id=region_id, + old_active=old_status, + active=new_status + ) + + return {'status': 'success', 'message': 'Статус региона обновлён'}, 200 + else: + error_msg = f"Регион с ID {region_id} не найден" + self.logger.warning(error_msg) + self.auditlog.regions( + action_type="toggle", + actor_display_name=user.display_name, + ldap_user_id=user.id, + region_id=region_id, + active=new_status, + error=error_msg + ) + return {'status': 'error', 'message': 'Регион не найден'}, 404 + except Exception as e: + self.db.session.rollback() + error_msg = str(e) + self.logger.error(f"Ошибка при изменении статуса региона: {error_msg}") + self.auditlog.regions( + action_type="toggle", + actor_display_name=user.display_name, + ldap_user_id=user.id, + region_id=region_id, + active=new_status, + error=error_msg + ) + return {'status': 'error', 'message': error_msg}, 500 + + + + def update_region_name(self, data, user): + region_id = data.get('region_id') + name = data.get('name') + + self.logger.info(f"Изменение названия региона: region_id={region_id}, name={name}") + + try: + region = Regions.query.get(region_id) + if region: + old_name = region.region_name + region.region_name = name + self.db.session.commit() + + self.logger.info(f"Название региона {region_id} изменено с {old_name} на {name}") + self.auditlog.regions( + action_type="rename", + actor_display_name=user.display_name, + ldap_user_id=user.id, + region_id=region_id, + new_name=name, + old_name=old_name + ) + + return {'status': 'success', 'message': 'Название региона изменено'}, 200 + else: + error_msg = f"Регион с ID {region_id} не найден" + self.logger.warning(error_msg) + self.auditlog.regions( + action_type="rename", + actor_display_name=user.display_name, + ldap_user_id=user.id, + region_id=region_id, + new_name=name, + error=error_msg + ) + return {'status': 'error', 'message': 'Регион не найден'}, 404 + except Exception as e: + self.db.session.rollback() + error_msg = str(e) + self.logger.error(f"Ошибка при изменении названия региона: {error_msg}") + self.auditlog.regions( + action_type="rename", + actor_display_name=user.display_name, + ldap_user_id=user.id, + region_id=region_id, + new_name=name, + error=error_msg + ) + return {'status': 'error', 'message': error_msg}, 500 + + def delete_region(self, region_id, user): + self.logger.info(f"Удаление региона: region_id={region_id}") + + try: + region = Regions.query.get(region_id) + if region: + name = region.region_name + self.db.session.delete(region) + self.db.session.commit() + + self.logger.info(f"Регион {region_id} успешно удалён") + self.auditlog.regions( + action_type="delete", + actor_display_name=user.display_name, + ldap_user_id=user.id, + region_id=region_id, + new_name=name + ) + + return {'status': 'success', 'message': 'Регион удалён'}, 200 + else: + error_msg = f"Регион с ID {region_id} не найден" + self.logger.warning(error_msg) + self.auditlog.regions( + action_type="delete", + actor_display_name=user.display_name, + ldap_user_id=user.id, + region_id=region_id, + error=error_msg + ) + return {'status': 'error', 'message': 'Регион не найден'}, 404 + except Exception as e: + self.db.session.rollback() + error_msg = str(e) + self.logger.error(f"Ошибка при удалении региона: {error_msg}") + self.auditlog.regions( + action_type="delete", + actor_display_name=user.display_name, + ldap_user_id=user.id, + region_id=region_id, + error=error_msg + ) + return {'status': 'error', 'message': error_msg}, 500 diff --git a/app/services/systems_service.py b/app/services/systems_service.py new file mode 100644 index 0000000..94878cf --- /dev/null +++ b/app/services/systems_service.py @@ -0,0 +1,171 @@ + +from app import AuditLogger +from app.models import Systems +from app.extensions.db import db +from flask_login import current_user +from sqlalchemy import asc, desc + +auditlog = AuditLogger(db.session) + +class SystemService: + def __init__(self): + self.auditlog = auditlog + + + def get_systems(self, page=1, per_page=10, sort_field='system_id', sort_order='asc'): + """ + + :param page: + :param per_page: + :param sort_field: + :param sort_order: + :return: + """ + sort_func = asc if sort_order == 'asc' else desc + sort_attr = getattr(Systems, sort_field, Systems.system_id) + + if sort_field == 'system_id': + query = Systems.query.order_by(sort_func(Systems.system_id.cast(db.Integer))) + else: + query = Systems.query.order_by(sort_func(sort_attr)) + + systems_query = query.paginate(page=page, per_page=per_page, error_out=False) + + return { + 'systems': [{ + 'system_id': s.system_id, + 'system_name': s.system_name, + 'name': s.name, + } for s in systems_query.items], + 'total_systems': systems_query.total, + 'total_pages': systems_query.pages, + 'current_page': systems_query.page, + 'per_page': systems_query.per_page + } + + def get_system_by_id(self, system_id): + """ + + :param system_id: + :return: + """ + return Systems.query.filter_by(system_id=system_id).first() + + def add_system(self, data): + """ + + :param data: + :return: + """ + system_id = data.get('system_id') + system_name = data.get('system_name') + name = data.get('name') + error = None + + if not system_id.isdigit(): + error = 'ID системы должен содержать только числа.' + status = 400 + elif Systems.query.get(system_id): + error = 'Система с таким ID уже существует' + status = 409 + else: + try: + system = Systems(system_id=system_id, system_name=system_name, name=name) + db.session.add(system) + db.session.commit() + status = 201 + except Exception as e: + db.session.rollback() + error = str(e) + status = 500 + + self.auditlog.systems( + action_type="add", + actor_display_name=current_user.display_name, + ldap_user_id=current_user.id, + system_id=system_id, + name=f'{system_name}; ({name})', + error=error + ) + + return {'status': 'error' if error else 'success', 'message': error or 'Система добавлена'}, status + + def update_system_name(self, data): + system_id = data.get('system_id') + system_name = data.get('system_name') + name = data.get('name') + error = None + + if system_id is None: + return {'status': 'error', 'message': 'system_id обязателен'}, 400 + if system_name is None or name is None: + return {'status': 'error', 'message': 'Поля system_name и name обязательны'}, 400 + + try: + system = Systems.query.get(system_id) + if system: + old_name = system.name # Старое имя + system.system_name = system_name + system.name = name + db.session.commit() + status = 200 + else: + error = 'Система не найдена' + status = 404 + except Exception as e: + db.session.rollback() + error = str(e) + status = 500 + + # Формируем отображение вида "старое_имя → новое_имя" + if not error and system: + log_name = f"{old_name} → {name}" + else: + log_name = name # Если ошибка, логируем только новое имя + + self.auditlog.systems( + action_type="update", + actor_display_name=current_user.display_name, + ldap_user_id=current_user.id, + system_id=system_id, + name=log_name, + error=error + ) + + return {'status': 'error' if error else 'success', 'message': error or 'Название системы изменено'}, status + + + + + def delete_system(self, system_id): + """ + + :param system_id: + :return: + """ + error = None + system = Systems.query.get(system_id) + + if not system: + error = 'Система не найдена' + status = 404 + else: + try: + db.session.delete(system) + db.session.commit() + status = 200 + except Exception as e: + db.session.rollback() + error = str(e) + status = 500 + + self.auditlog.systems( + action_type="delete", + actor_display_name=current_user.display_name, + ldap_user_id=current_user.id, + system_id=system_id, + name=f'{system.system_name}; ({system.name})' if system else None, + error=error + ) + + return {'status': 'error' if error else 'success', 'message': error or 'Система удалена'}, status diff --git a/app/services/users_event_service.py b/app/services/users_event_service.py new file mode 100644 index 0000000..2708ee7 --- /dev/null +++ b/app/services/users_event_service.py @@ -0,0 +1,37 @@ +# app/services/user_event_service.py + +from typing import Dict, Any, Tuple +from app.extensions.db import db +from app.models import UserEvents, Users # Импортируем модель Users для получения telegram_id + + +def log_user_action(chat_id: int, action: str) -> Tuple[Dict[str, str], int]: + try: + # Получаем telegram_id пользователя по chat_id + user = Users.query.filter_by(chat_id=chat_id).first() + if not user: + return {'error': f'Пользователь с chat_id {chat_id} не найден для логирования действия.'}, 404 + + new_event = UserEvents( + chat_id=chat_id, + telegram_id=user.telegram_id, # Добавляем telegram_id из найденного пользователя + action=action, + # timestamp генерируется автоматически по default=db.func.current_timestamp() + ) + db.session.add(new_event) + db.session.commit() + return {'message': 'Действие сохранено'}, 200 + except Exception as e: + db.session.rollback() + return {'error': str(e)}, 500 + +def get_user_events(chat_id: int) -> tuple[list[dict[str, Any | None]], int]: + # Предполагаем, что у UserEvents есть поля 'id' и 'timestamp' + events = UserEvents.query.filter_by(chat_id=chat_id).order_by(UserEvents.timestamp.desc()).all() + events_list = [{ + 'event_id': e.id, + 'chat_id': e.chat_id, + 'event_type': e.action, # Используем 'action', как в модели UserEvents + 'timestamp': e.timestamp.isoformat() if e.timestamp else None # Форматируем дату + } for e in events] + return events_list, 200 \ No newline at end of file diff --git a/app/services/users_service.py b/app/services/users_service.py new file mode 100644 index 0000000..4d0af21 --- /dev/null +++ b/app/services/users_service.py @@ -0,0 +1,232 @@ +# app/services/user_service.py + +import logging +import re +from typing import Dict, List, Optional, Tuple, Any + +from sqlalchemy.exc import IntegrityError +from sqlalchemy.orm import joinedload +from sqlalchemy import or_ + +from app import db +from app.models import Users # Предполагаем, что app.models/__init__.py экспортирует Users +from app.extensions.audit_logger import AuditLogger + +logger = logging.getLogger(__name__) + +auditlog = AuditLogger(db.session) + +def get_users(page: int, per_page: int) -> Dict[str, Any]: + logger.debug(f"Получение пользователей: page={page}, per_page={per_page}") + users_query = Users.query.options(joinedload(Users.subscriptions)) + users_paginated = users_query.paginate(page=page, per_page=per_page, error_out=False) + + users_list: List[Dict[str, Any]] = [] + for user in users_paginated.items: + user_data: Dict[str, Any] = { + 'chat_id': user.chat_id, + 'telegram_id': user.telegram_id, + 'email': user.user_email, + 'subscriptions': [], + 'disaster_only': "Все уведомления", + 'status': "Активен" if not user.is_blocked else "Заблокирован", + 'blocked': user.is_blocked + } + + if user.subscriptions: + for subscription in user.subscriptions: + if subscription.active and not subscription.skip: + user_data['subscriptions'].append(subscription.region_id) + if subscription.disaster_only: + user_data['disaster_only'] = "Только критические уведомления" + + users_list.append(user_data) + logger.debug(f"Получено пользователей: {len(users_list)} элементов") + return { + 'users': users_list, + 'total_users': users_paginated.total, + 'total_pages': users_paginated.pages, + 'current_page': users_paginated.page, + 'per_page': users_paginated.per_page + } + +def get_user(chat_id: int) -> Optional[Dict[str, Any]]: + logger.debug(f"Получение пользователя: chat_id={chat_id}") + user: Optional[Users] = Users.query.filter_by(chat_id=chat_id).first() + if user: + user_data: Dict[str, Any] = { + 'chat_id': user.chat_id, + 'telegram_id': user.telegram_id, + 'email': user.user_email, + 'blocked': user.is_blocked + } + logger.debug(f"Пользователь найден: chat_id={chat_id}") + return user_data + else: + logger.warning(f"Пользователь не найден: chat_id={chat_id}") + return None + +def toggle_block_user(chat_id: int, actor_user: Any) -> Tuple[Dict[str, Any], int]: + logger.debug(f"Переключение блокировки пользователя: chat_id={chat_id}") + user: Optional[Users] = Users.query.filter_by(chat_id=chat_id).first() + if not user: + error_msg = "Пользователь не найден" + auditlog.users(action_type="toggle_block", actor_display_name=actor_user.display_name, + ldap_user_id=actor_user.id, affected_chat_id=chat_id, error=error_msg) + logger.warning(f"{error_msg}: chat_id={chat_id}") + return {'status': 'error', 'message': error_msg}, 404 + try: + user.is_blocked = not user.is_blocked + db.session.commit() + status_text = "заблокирован" if user.is_blocked else "разблокирован" + logger.info(f"Пользователь {chat_id} {status_text}") + + action_type = "block" if user.is_blocked else "unblock" + auditlog.users( + action_type=action_type, + actor_display_name=actor_user.display_name, + ldap_user_id=actor_user.id, + affected_chat_id=chat_id, + email=user.user_email, + telegram_id=user.telegram_id, + ) + return {'status': 'updated', 'new_status': user.is_blocked}, 200 + except Exception as e: + db.session.rollback() + error_msg = str(e) + logger.error(f"Ошибка при переключении блокировки пользователя {chat_id}: {error_msg}") + auditlog.users(action_type="toggle_block", actor_display_name=actor_user.display_name, + ldap_user_id=actor_user.id, affected_chat_id=chat_id, error=error_msg) + return {'status': 'error', 'message': error_msg}, 500 + + +def delete_user(chat_id: int, actor_user: Any) -> Tuple[Dict[str, Any], int]: + logger.info(f"Удаление пользователя: chat_id={chat_id}") + user: Optional[Users] = Users.query.filter_by(chat_id=chat_id).first() + if not user: + error_msg = "Пользователь не найден" + auditlog.users(action_type="delete", actor_display_name=actor_user.display_name, + ldap_user_id=actor_user.id, affected_chat_id=chat_id, error=error_msg) + logger.warning(f"{error_msg}: chat_id={chat_id}") + return {'status': 'error', 'message': error_msg}, 404 + try: + db.session.delete(user) + db.session.commit() + logger.info(f"Пользователь удален: chat_id={chat_id}") + auditlog.users( + action_type="delete", + actor_display_name=actor_user.display_name, + ldap_user_id=actor_user.id, + affected_chat_id=chat_id, + email=user.user_email, + telegram_id=user.telegram_id, + ) + return {'status': 'deleted', 'message': 'Пользователь удален'}, 200 + except Exception as e: + db.session.rollback() + error_msg = str(e) + logger.error(f"Ошибка при удалении пользователя {chat_id}: {error_msg}") + auditlog.users(action_type="delete", actor_display_name=actor_user.display_name, + ldap_user_id=actor_user.id, affected_chat_id=chat_id, error=error_msg) + return {'status': 'error', 'message': error_msg}, 500 + +def add_user(user_data: Dict[str, Any], actor_user: Any) -> Tuple[Dict[str, str], int]: + logger.info(f"Добавление пользователя: {user_data}") + chat_id = None + telegram_id = user_data.get('telegram_id') + user_email = user_data.get('user_email') + + try: + try: + chat_id = int(user_data.get('chat_id')) + except (ValueError, TypeError): + error_msg = 'Chat ID должен быть числом' + auditlog.users(action_type="add", actor_display_name=actor_user.display_name, + ldap_user_id=actor_user.id, affected_chat_id=chat_id, + telegram_id=telegram_id, email=user_email, error=error_msg) + logger.warning(error_msg) + return {'error': error_msg}, 400 + + if not telegram_id or not re.match(r'^@.*$', telegram_id): + error_msg = "Telegram ID должен начинаться с символа @" + auditlog.users(action_type="add", actor_display_name=actor_user.display_name, + ldap_user_id=actor_user.id, affected_chat_id=chat_id, + telegram_id=telegram_id, email=user_email, error=error_msg) + logger.warning(error_msg) + return {'error': error_msg}, 400 + if not user_email or not re.match(r'.*@rtmis.ru$', user_email): + error_msg = "Email должен содержать домен @rtmis.ru" + auditlog.users(action_type="add", actor_display_name=actor_user.display_name, + ldap_user_id=actor_user.id, affected_chat_id=chat_id, + telegram_id=telegram_id, email=user_email, error=error_msg) + logger.warning(error_msg) + return {'error': error_msg}, 400 + + existing_user = Users.query.filter( + (Users.user_email == user_email) | + (Users.telegram_id == telegram_id) | + (Users.chat_id == chat_id) + ).first() + + if existing_user: + error_msg = 'Пользователь с таким Chat ID, Telegram ID или Email уже существует.' + auditlog.users(action_type="add", actor_display_name=actor_user.display_name, + ldap_user_id=actor_user.id, affected_chat_id=chat_id, + telegram_id=telegram_id, email=user_email, error=error_msg) + logger.warning(error_msg) + return {'error': error_msg}, 409 + + new_user: Users = Users( + chat_id=chat_id, + telegram_id=telegram_id, + user_email=user_email, + is_blocked=user_data.get('is_blocked', False) + ) + db.session.add(new_user) + db.session.commit() + logger.info(f"Пользователь добавлен успешно: {new_user.user_email}") + auditlog.users(action_type="add", actor_display_name=actor_user.display_name, + ldap_user_id=actor_user.id, affected_chat_id=chat_id, + telegram_id=telegram_id, email=user_email) + return {'message': 'Пользователь добавлен успешно'}, 201 + except IntegrityError as e: + db.session.rollback() + error_msg = 'Ошибка уникальности данных' + logger.error(f"Ошибка уникальности при добавлении пользователя: {e}") + auditlog.users(action_type="add", actor_display_name=actor_user.display_name, + ldap_user_id=actor_user.id, affected_chat_id=chat_id, + telegram_id=telegram_id, email=user_email, error=error_msg) + return {'error': error_msg}, 409 + except Exception as e: + db.session.rollback() + error_msg = f'Ошибка при добавлении пользователя: {type(e).__name__}: {e}' + logger.error(error_msg) + auditlog.users(action_type="add", actor_display_name=actor_user.display_name, + ldap_user_id=actor_user.id, affected_chat_id=chat_id, + telegram_id=telegram_id, email=user_email, error=error_msg) + return {'error': 'Ошибка при добавлении пользователя'}, 500 + +def search_users(telegram_id: Optional[str] = None, email: Optional[str] = None) -> List[Dict[str, Any]]: + logger.debug(f"Поиск пользователей: telegram_id={telegram_id}, email={email}") + + query = db.session.query(Users) + if telegram_id: + query = query.filter(Users.telegram_id.ilike(f"%{telegram_id}%")) + if email: + query = query.filter(Users.user_email.ilike(f"%{email}%")) + + users: List[Users] = query.all() + + users_list: List[Dict[str, Any]] = [] + for user in users: + # Используем названия полей модели напрямую + user_data: Dict[str, Any] = { + 'chat_id': user.chat_id, + 'telegram_id': user.telegram_id, + 'email': user.user_email, + 'blocked': user.is_blocked + } + users_list.append(user_data) + + logger.debug(f"Найдено пользователей: {len(users_list)}") + return users_list \ No newline at end of file diff --git a/static/css/bootstrap-grid.css b/app/static/css/bootstrap-grid.css similarity index 100% rename from static/css/bootstrap-grid.css rename to app/static/css/bootstrap-grid.css diff --git a/static/css/bootstrap-grid.css.map b/app/static/css/bootstrap-grid.css.map similarity index 100% rename from static/css/bootstrap-grid.css.map rename to app/static/css/bootstrap-grid.css.map diff --git a/static/css/bootstrap-grid.min.css b/app/static/css/bootstrap-grid.min.css similarity index 100% rename from static/css/bootstrap-grid.min.css rename to app/static/css/bootstrap-grid.min.css diff --git a/static/css/bootstrap-grid.min.css.map b/app/static/css/bootstrap-grid.min.css.map similarity index 100% rename from static/css/bootstrap-grid.min.css.map rename to app/static/css/bootstrap-grid.min.css.map diff --git a/static/css/bootstrap-grid.rtl.css b/app/static/css/bootstrap-grid.rtl.css similarity index 100% rename from static/css/bootstrap-grid.rtl.css rename to app/static/css/bootstrap-grid.rtl.css diff --git a/static/css/bootstrap-grid.rtl.css.map b/app/static/css/bootstrap-grid.rtl.css.map similarity index 100% rename from static/css/bootstrap-grid.rtl.css.map rename to app/static/css/bootstrap-grid.rtl.css.map diff --git a/static/css/bootstrap-grid.rtl.min.css b/app/static/css/bootstrap-grid.rtl.min.css similarity index 100% rename from static/css/bootstrap-grid.rtl.min.css rename to app/static/css/bootstrap-grid.rtl.min.css diff --git a/static/css/bootstrap-grid.rtl.min.css.map b/app/static/css/bootstrap-grid.rtl.min.css.map similarity index 100% rename from static/css/bootstrap-grid.rtl.min.css.map rename to app/static/css/bootstrap-grid.rtl.min.css.map diff --git a/static/css/bootstrap-icons-1.11.3/0-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/0-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/0-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/0-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/0-circle.svg b/app/static/css/bootstrap-icons-1.11.3/0-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/0-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/0-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/0-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/0-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/0-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/0-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/0-square.svg b/app/static/css/bootstrap-icons-1.11.3/0-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/0-square.svg rename to app/static/css/bootstrap-icons-1.11.3/0-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/1-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/1-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/1-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/1-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/1-circle.svg b/app/static/css/bootstrap-icons-1.11.3/1-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/1-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/1-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/1-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/1-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/1-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/1-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/1-square.svg b/app/static/css/bootstrap-icons-1.11.3/1-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/1-square.svg rename to app/static/css/bootstrap-icons-1.11.3/1-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/123.svg b/app/static/css/bootstrap-icons-1.11.3/123.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/123.svg rename to app/static/css/bootstrap-icons-1.11.3/123.svg diff --git a/static/css/bootstrap-icons-1.11.3/2-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/2-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/2-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/2-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/2-circle.svg b/app/static/css/bootstrap-icons-1.11.3/2-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/2-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/2-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/2-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/2-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/2-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/2-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/2-square.svg b/app/static/css/bootstrap-icons-1.11.3/2-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/2-square.svg rename to app/static/css/bootstrap-icons-1.11.3/2-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/3-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/3-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/3-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/3-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/3-circle.svg b/app/static/css/bootstrap-icons-1.11.3/3-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/3-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/3-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/3-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/3-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/3-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/3-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/3-square.svg b/app/static/css/bootstrap-icons-1.11.3/3-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/3-square.svg rename to app/static/css/bootstrap-icons-1.11.3/3-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/4-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/4-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/4-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/4-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/4-circle.svg b/app/static/css/bootstrap-icons-1.11.3/4-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/4-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/4-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/4-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/4-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/4-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/4-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/4-square.svg b/app/static/css/bootstrap-icons-1.11.3/4-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/4-square.svg rename to app/static/css/bootstrap-icons-1.11.3/4-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/5-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/5-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/5-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/5-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/5-circle.svg b/app/static/css/bootstrap-icons-1.11.3/5-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/5-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/5-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/5-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/5-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/5-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/5-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/5-square.svg b/app/static/css/bootstrap-icons-1.11.3/5-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/5-square.svg rename to app/static/css/bootstrap-icons-1.11.3/5-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/6-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/6-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/6-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/6-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/6-circle.svg b/app/static/css/bootstrap-icons-1.11.3/6-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/6-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/6-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/6-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/6-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/6-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/6-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/6-square.svg b/app/static/css/bootstrap-icons-1.11.3/6-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/6-square.svg rename to app/static/css/bootstrap-icons-1.11.3/6-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/7-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/7-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/7-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/7-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/7-circle.svg b/app/static/css/bootstrap-icons-1.11.3/7-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/7-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/7-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/7-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/7-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/7-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/7-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/7-square.svg b/app/static/css/bootstrap-icons-1.11.3/7-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/7-square.svg rename to app/static/css/bootstrap-icons-1.11.3/7-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/8-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/8-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/8-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/8-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/8-circle.svg b/app/static/css/bootstrap-icons-1.11.3/8-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/8-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/8-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/8-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/8-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/8-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/8-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/8-square.svg b/app/static/css/bootstrap-icons-1.11.3/8-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/8-square.svg rename to app/static/css/bootstrap-icons-1.11.3/8-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/9-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/9-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/9-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/9-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/9-circle.svg b/app/static/css/bootstrap-icons-1.11.3/9-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/9-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/9-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/9-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/9-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/9-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/9-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/9-square.svg b/app/static/css/bootstrap-icons-1.11.3/9-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/9-square.svg rename to app/static/css/bootstrap-icons-1.11.3/9-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/activity.svg b/app/static/css/bootstrap-icons-1.11.3/activity.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/activity.svg rename to app/static/css/bootstrap-icons-1.11.3/activity.svg diff --git a/static/css/bootstrap-icons-1.11.3/airplane-engines-fill.svg b/app/static/css/bootstrap-icons-1.11.3/airplane-engines-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/airplane-engines-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/airplane-engines-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/airplane-engines.svg b/app/static/css/bootstrap-icons-1.11.3/airplane-engines.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/airplane-engines.svg rename to app/static/css/bootstrap-icons-1.11.3/airplane-engines.svg diff --git a/static/css/bootstrap-icons-1.11.3/airplane-fill.svg b/app/static/css/bootstrap-icons-1.11.3/airplane-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/airplane-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/airplane-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/airplane.svg b/app/static/css/bootstrap-icons-1.11.3/airplane.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/airplane.svg rename to app/static/css/bootstrap-icons-1.11.3/airplane.svg diff --git a/static/css/bootstrap-icons-1.11.3/alarm-fill.svg b/app/static/css/bootstrap-icons-1.11.3/alarm-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/alarm-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/alarm-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/alarm.svg b/app/static/css/bootstrap-icons-1.11.3/alarm.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/alarm.svg rename to app/static/css/bootstrap-icons-1.11.3/alarm.svg diff --git a/static/css/bootstrap-icons-1.11.3/alexa.svg b/app/static/css/bootstrap-icons-1.11.3/alexa.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/alexa.svg rename to app/static/css/bootstrap-icons-1.11.3/alexa.svg diff --git a/static/css/bootstrap-icons-1.11.3/align-bottom.svg b/app/static/css/bootstrap-icons-1.11.3/align-bottom.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/align-bottom.svg rename to app/static/css/bootstrap-icons-1.11.3/align-bottom.svg diff --git a/static/css/bootstrap-icons-1.11.3/align-center.svg b/app/static/css/bootstrap-icons-1.11.3/align-center.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/align-center.svg rename to app/static/css/bootstrap-icons-1.11.3/align-center.svg diff --git a/static/css/bootstrap-icons-1.11.3/align-end.svg b/app/static/css/bootstrap-icons-1.11.3/align-end.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/align-end.svg rename to app/static/css/bootstrap-icons-1.11.3/align-end.svg diff --git a/static/css/bootstrap-icons-1.11.3/align-middle.svg b/app/static/css/bootstrap-icons-1.11.3/align-middle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/align-middle.svg rename to app/static/css/bootstrap-icons-1.11.3/align-middle.svg diff --git a/static/css/bootstrap-icons-1.11.3/align-start.svg b/app/static/css/bootstrap-icons-1.11.3/align-start.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/align-start.svg rename to app/static/css/bootstrap-icons-1.11.3/align-start.svg diff --git a/static/css/bootstrap-icons-1.11.3/align-top.svg b/app/static/css/bootstrap-icons-1.11.3/align-top.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/align-top.svg rename to app/static/css/bootstrap-icons-1.11.3/align-top.svg diff --git a/static/css/bootstrap-icons-1.11.3/alipay.svg b/app/static/css/bootstrap-icons-1.11.3/alipay.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/alipay.svg rename to app/static/css/bootstrap-icons-1.11.3/alipay.svg diff --git a/static/css/bootstrap-icons-1.11.3/alphabet-uppercase.svg b/app/static/css/bootstrap-icons-1.11.3/alphabet-uppercase.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/alphabet-uppercase.svg rename to app/static/css/bootstrap-icons-1.11.3/alphabet-uppercase.svg diff --git a/static/css/bootstrap-icons-1.11.3/alphabet.svg b/app/static/css/bootstrap-icons-1.11.3/alphabet.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/alphabet.svg rename to app/static/css/bootstrap-icons-1.11.3/alphabet.svg diff --git a/static/css/bootstrap-icons-1.11.3/alt.svg b/app/static/css/bootstrap-icons-1.11.3/alt.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/alt.svg rename to app/static/css/bootstrap-icons-1.11.3/alt.svg diff --git a/static/css/bootstrap-icons-1.11.3/amazon.svg b/app/static/css/bootstrap-icons-1.11.3/amazon.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/amazon.svg rename to app/static/css/bootstrap-icons-1.11.3/amazon.svg diff --git a/static/css/bootstrap-icons-1.11.3/amd.svg b/app/static/css/bootstrap-icons-1.11.3/amd.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/amd.svg rename to app/static/css/bootstrap-icons-1.11.3/amd.svg diff --git a/static/css/bootstrap-icons-1.11.3/android.svg b/app/static/css/bootstrap-icons-1.11.3/android.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/android.svg rename to app/static/css/bootstrap-icons-1.11.3/android.svg diff --git a/static/css/bootstrap-icons-1.11.3/android2.svg b/app/static/css/bootstrap-icons-1.11.3/android2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/android2.svg rename to app/static/css/bootstrap-icons-1.11.3/android2.svg diff --git a/static/css/bootstrap-icons-1.11.3/app-indicator.svg b/app/static/css/bootstrap-icons-1.11.3/app-indicator.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/app-indicator.svg rename to app/static/css/bootstrap-icons-1.11.3/app-indicator.svg diff --git a/static/css/bootstrap-icons-1.11.3/app.svg b/app/static/css/bootstrap-icons-1.11.3/app.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/app.svg rename to app/static/css/bootstrap-icons-1.11.3/app.svg diff --git a/static/css/bootstrap-icons-1.11.3/apple.svg b/app/static/css/bootstrap-icons-1.11.3/apple.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/apple.svg rename to app/static/css/bootstrap-icons-1.11.3/apple.svg diff --git a/static/css/bootstrap-icons-1.11.3/archive-fill.svg b/app/static/css/bootstrap-icons-1.11.3/archive-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/archive-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/archive-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/archive.svg b/app/static/css/bootstrap-icons-1.11.3/archive.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/archive.svg rename to app/static/css/bootstrap-icons-1.11.3/archive.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-90deg-down.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-90deg-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-90deg-down.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-90deg-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-90deg-left.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-90deg-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-90deg-left.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-90deg-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-90deg-right.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-90deg-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-90deg-right.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-90deg-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-90deg-up.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-90deg-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-90deg-up.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-90deg-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-bar-down.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-bar-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-bar-down.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-bar-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-bar-left.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-bar-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-bar-left.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-bar-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-bar-right.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-bar-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-bar-right.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-bar-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-bar-up.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-bar-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-bar-up.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-bar-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-clockwise.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-clockwise.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-clockwise.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-clockwise.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-counterclockwise.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-counterclockwise.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-counterclockwise.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-counterclockwise.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-down-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-down-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-down-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-down-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-down-circle.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-down-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-down-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-down-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-down-left-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-down-left-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-down-left-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-down-left-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-down-left-circle.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-down-left-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-down-left-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-down-left-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-down-left-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-down-left-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-down-left-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-down-left-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-down-left-square.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-down-left-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-down-left-square.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-down-left-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-down-left.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-down-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-down-left.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-down-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-down-right-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-down-right-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-down-right-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-down-right-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-down-right-circle.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-down-right-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-down-right-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-down-right-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-down-right-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-down-right-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-down-right-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-down-right-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-down-right-square.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-down-right-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-down-right-square.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-down-right-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-down-right.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-down-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-down-right.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-down-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-down-short.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-down-short.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-down-short.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-down-short.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-down-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-down-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-down-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-down-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-down-square.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-down-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-down-square.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-down-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-down-up.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-down-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-down-up.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-down-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-down.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-down.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-left-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-left-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-left-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-left-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-left-circle.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-left-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-left-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-left-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-left-right.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-left-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-left-right.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-left-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-left-short.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-left-short.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-left-short.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-left-short.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-left-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-left-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-left-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-left-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-left-square.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-left-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-left-square.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-left-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-left.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-left.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-repeat.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-repeat.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-repeat.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-repeat.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-return-left.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-return-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-return-left.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-return-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-return-right.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-return-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-return-right.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-return-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-right-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-right-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-right-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-right-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-right-circle.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-right-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-right-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-right-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-right-short.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-right-short.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-right-short.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-right-short.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-right-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-right-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-right-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-right-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-right-square.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-right-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-right-square.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-right-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-right.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-right.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-through-heart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-through-heart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-through-heart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-through-heart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-through-heart.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-through-heart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-through-heart.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-through-heart.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-up-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-up-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-up-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-up-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-up-circle.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-up-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-up-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-up-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-up-left-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-up-left-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-up-left-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-up-left-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-up-left-circle.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-up-left-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-up-left-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-up-left-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-up-left-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-up-left-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-up-left-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-up-left-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-up-left-square.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-up-left-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-up-left-square.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-up-left-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-up-left.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-up-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-up-left.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-up-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-up-right-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-up-right-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-up-right-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-up-right-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-up-right-circle.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-up-right-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-up-right-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-up-right-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-up-right-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-up-right-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-up-right-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-up-right-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-up-right-square.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-up-right-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-up-right-square.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-up-right-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-up-right.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-up-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-up-right.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-up-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-up-short.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-up-short.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-up-short.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-up-short.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-up-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-up-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-up-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-up-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-up-square.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-up-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-up-square.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-up-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrow-up.svg b/app/static/css/bootstrap-icons-1.11.3/arrow-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrow-up.svg rename to app/static/css/bootstrap-icons-1.11.3/arrow-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrows-angle-contract.svg b/app/static/css/bootstrap-icons-1.11.3/arrows-angle-contract.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrows-angle-contract.svg rename to app/static/css/bootstrap-icons-1.11.3/arrows-angle-contract.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrows-angle-expand.svg b/app/static/css/bootstrap-icons-1.11.3/arrows-angle-expand.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrows-angle-expand.svg rename to app/static/css/bootstrap-icons-1.11.3/arrows-angle-expand.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrows-collapse-vertical.svg b/app/static/css/bootstrap-icons-1.11.3/arrows-collapse-vertical.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrows-collapse-vertical.svg rename to app/static/css/bootstrap-icons-1.11.3/arrows-collapse-vertical.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrows-collapse.svg b/app/static/css/bootstrap-icons-1.11.3/arrows-collapse.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrows-collapse.svg rename to app/static/css/bootstrap-icons-1.11.3/arrows-collapse.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrows-expand-vertical.svg b/app/static/css/bootstrap-icons-1.11.3/arrows-expand-vertical.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrows-expand-vertical.svg rename to app/static/css/bootstrap-icons-1.11.3/arrows-expand-vertical.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrows-expand.svg b/app/static/css/bootstrap-icons-1.11.3/arrows-expand.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrows-expand.svg rename to app/static/css/bootstrap-icons-1.11.3/arrows-expand.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrows-fullscreen.svg b/app/static/css/bootstrap-icons-1.11.3/arrows-fullscreen.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrows-fullscreen.svg rename to app/static/css/bootstrap-icons-1.11.3/arrows-fullscreen.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrows-move.svg b/app/static/css/bootstrap-icons-1.11.3/arrows-move.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrows-move.svg rename to app/static/css/bootstrap-icons-1.11.3/arrows-move.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrows-vertical.svg b/app/static/css/bootstrap-icons-1.11.3/arrows-vertical.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrows-vertical.svg rename to app/static/css/bootstrap-icons-1.11.3/arrows-vertical.svg diff --git a/static/css/bootstrap-icons-1.11.3/arrows.svg b/app/static/css/bootstrap-icons-1.11.3/arrows.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/arrows.svg rename to app/static/css/bootstrap-icons-1.11.3/arrows.svg diff --git a/static/css/bootstrap-icons-1.11.3/aspect-ratio-fill.svg b/app/static/css/bootstrap-icons-1.11.3/aspect-ratio-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/aspect-ratio-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/aspect-ratio-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/aspect-ratio.svg b/app/static/css/bootstrap-icons-1.11.3/aspect-ratio.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/aspect-ratio.svg rename to app/static/css/bootstrap-icons-1.11.3/aspect-ratio.svg diff --git a/static/css/bootstrap-icons-1.11.3/asterisk.svg b/app/static/css/bootstrap-icons-1.11.3/asterisk.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/asterisk.svg rename to app/static/css/bootstrap-icons-1.11.3/asterisk.svg diff --git a/static/css/bootstrap-icons-1.11.3/at.svg b/app/static/css/bootstrap-icons-1.11.3/at.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/at.svg rename to app/static/css/bootstrap-icons-1.11.3/at.svg diff --git a/static/css/bootstrap-icons-1.11.3/award-fill.svg b/app/static/css/bootstrap-icons-1.11.3/award-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/award-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/award-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/award.svg b/app/static/css/bootstrap-icons-1.11.3/award.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/award.svg rename to app/static/css/bootstrap-icons-1.11.3/award.svg diff --git a/static/css/bootstrap-icons-1.11.3/back.svg b/app/static/css/bootstrap-icons-1.11.3/back.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/back.svg rename to app/static/css/bootstrap-icons-1.11.3/back.svg diff --git a/static/css/bootstrap-icons-1.11.3/backpack-fill.svg b/app/static/css/bootstrap-icons-1.11.3/backpack-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/backpack-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/backpack-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/backpack.svg b/app/static/css/bootstrap-icons-1.11.3/backpack.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/backpack.svg rename to app/static/css/bootstrap-icons-1.11.3/backpack.svg diff --git a/static/css/bootstrap-icons-1.11.3/backpack2-fill.svg b/app/static/css/bootstrap-icons-1.11.3/backpack2-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/backpack2-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/backpack2-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/backpack2.svg b/app/static/css/bootstrap-icons-1.11.3/backpack2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/backpack2.svg rename to app/static/css/bootstrap-icons-1.11.3/backpack2.svg diff --git a/static/css/bootstrap-icons-1.11.3/backpack3-fill.svg b/app/static/css/bootstrap-icons-1.11.3/backpack3-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/backpack3-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/backpack3-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/backpack3.svg b/app/static/css/bootstrap-icons-1.11.3/backpack3.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/backpack3.svg rename to app/static/css/bootstrap-icons-1.11.3/backpack3.svg diff --git a/static/css/bootstrap-icons-1.11.3/backpack4-fill.svg b/app/static/css/bootstrap-icons-1.11.3/backpack4-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/backpack4-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/backpack4-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/backpack4.svg b/app/static/css/bootstrap-icons-1.11.3/backpack4.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/backpack4.svg rename to app/static/css/bootstrap-icons-1.11.3/backpack4.svg diff --git a/static/css/bootstrap-icons-1.11.3/backspace-fill.svg b/app/static/css/bootstrap-icons-1.11.3/backspace-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/backspace-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/backspace-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/backspace-reverse-fill.svg b/app/static/css/bootstrap-icons-1.11.3/backspace-reverse-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/backspace-reverse-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/backspace-reverse-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/backspace-reverse.svg b/app/static/css/bootstrap-icons-1.11.3/backspace-reverse.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/backspace-reverse.svg rename to app/static/css/bootstrap-icons-1.11.3/backspace-reverse.svg diff --git a/static/css/bootstrap-icons-1.11.3/backspace.svg b/app/static/css/bootstrap-icons-1.11.3/backspace.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/backspace.svg rename to app/static/css/bootstrap-icons-1.11.3/backspace.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-3d-fill.svg b/app/static/css/bootstrap-icons-1.11.3/badge-3d-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-3d-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-3d-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-3d.svg b/app/static/css/bootstrap-icons-1.11.3/badge-3d.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-3d.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-3d.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-4k-fill.svg b/app/static/css/bootstrap-icons-1.11.3/badge-4k-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-4k-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-4k-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-4k.svg b/app/static/css/bootstrap-icons-1.11.3/badge-4k.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-4k.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-4k.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-8k-fill.svg b/app/static/css/bootstrap-icons-1.11.3/badge-8k-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-8k-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-8k-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-8k.svg b/app/static/css/bootstrap-icons-1.11.3/badge-8k.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-8k.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-8k.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-ad-fill.svg b/app/static/css/bootstrap-icons-1.11.3/badge-ad-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-ad-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-ad-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-ad.svg b/app/static/css/bootstrap-icons-1.11.3/badge-ad.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-ad.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-ad.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-ar-fill.svg b/app/static/css/bootstrap-icons-1.11.3/badge-ar-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-ar-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-ar-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-ar.svg b/app/static/css/bootstrap-icons-1.11.3/badge-ar.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-ar.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-ar.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-cc-fill.svg b/app/static/css/bootstrap-icons-1.11.3/badge-cc-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-cc-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-cc-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-cc.svg b/app/static/css/bootstrap-icons-1.11.3/badge-cc.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-cc.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-cc.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-hd-fill.svg b/app/static/css/bootstrap-icons-1.11.3/badge-hd-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-hd-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-hd-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-hd.svg b/app/static/css/bootstrap-icons-1.11.3/badge-hd.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-hd.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-hd.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-sd-fill.svg b/app/static/css/bootstrap-icons-1.11.3/badge-sd-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-sd-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-sd-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-sd.svg b/app/static/css/bootstrap-icons-1.11.3/badge-sd.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-sd.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-sd.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-tm-fill.svg b/app/static/css/bootstrap-icons-1.11.3/badge-tm-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-tm-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-tm-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-tm.svg b/app/static/css/bootstrap-icons-1.11.3/badge-tm.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-tm.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-tm.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-vo-fill.svg b/app/static/css/bootstrap-icons-1.11.3/badge-vo-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-vo-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-vo-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-vo.svg b/app/static/css/bootstrap-icons-1.11.3/badge-vo.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-vo.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-vo.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-vr-fill.svg b/app/static/css/bootstrap-icons-1.11.3/badge-vr-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-vr-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-vr-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-vr.svg b/app/static/css/bootstrap-icons-1.11.3/badge-vr.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-vr.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-vr.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-wc-fill.svg b/app/static/css/bootstrap-icons-1.11.3/badge-wc-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-wc-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-wc-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/badge-wc.svg b/app/static/css/bootstrap-icons-1.11.3/badge-wc.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/badge-wc.svg rename to app/static/css/bootstrap-icons-1.11.3/badge-wc.svg diff --git a/static/css/bootstrap-icons-1.11.3/bag-check-fill.svg b/app/static/css/bootstrap-icons-1.11.3/bag-check-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bag-check-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/bag-check-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/bag-check.svg b/app/static/css/bootstrap-icons-1.11.3/bag-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bag-check.svg rename to app/static/css/bootstrap-icons-1.11.3/bag-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/bag-dash-fill.svg b/app/static/css/bootstrap-icons-1.11.3/bag-dash-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bag-dash-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/bag-dash-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/bag-dash.svg b/app/static/css/bootstrap-icons-1.11.3/bag-dash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bag-dash.svg rename to app/static/css/bootstrap-icons-1.11.3/bag-dash.svg diff --git a/static/css/bootstrap-icons-1.11.3/bag-fill.svg b/app/static/css/bootstrap-icons-1.11.3/bag-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bag-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/bag-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/bag-heart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/bag-heart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bag-heart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/bag-heart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/bag-heart.svg b/app/static/css/bootstrap-icons-1.11.3/bag-heart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bag-heart.svg rename to app/static/css/bootstrap-icons-1.11.3/bag-heart.svg diff --git a/static/css/bootstrap-icons-1.11.3/bag-plus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/bag-plus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bag-plus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/bag-plus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/bag-plus.svg b/app/static/css/bootstrap-icons-1.11.3/bag-plus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bag-plus.svg rename to app/static/css/bootstrap-icons-1.11.3/bag-plus.svg diff --git a/static/css/bootstrap-icons-1.11.3/bag-x-fill.svg b/app/static/css/bootstrap-icons-1.11.3/bag-x-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bag-x-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/bag-x-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/bag-x.svg b/app/static/css/bootstrap-icons-1.11.3/bag-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bag-x.svg rename to app/static/css/bootstrap-icons-1.11.3/bag-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/bag.svg b/app/static/css/bootstrap-icons-1.11.3/bag.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bag.svg rename to app/static/css/bootstrap-icons-1.11.3/bag.svg diff --git a/static/css/bootstrap-icons-1.11.3/balloon-fill.svg b/app/static/css/bootstrap-icons-1.11.3/balloon-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/balloon-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/balloon-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/balloon-heart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/balloon-heart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/balloon-heart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/balloon-heart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/balloon-heart.svg b/app/static/css/bootstrap-icons-1.11.3/balloon-heart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/balloon-heart.svg rename to app/static/css/bootstrap-icons-1.11.3/balloon-heart.svg diff --git a/static/css/bootstrap-icons-1.11.3/balloon.svg b/app/static/css/bootstrap-icons-1.11.3/balloon.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/balloon.svg rename to app/static/css/bootstrap-icons-1.11.3/balloon.svg diff --git a/static/css/bootstrap-icons-1.11.3/ban-fill.svg b/app/static/css/bootstrap-icons-1.11.3/ban-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/ban-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/ban-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/ban.svg b/app/static/css/bootstrap-icons-1.11.3/ban.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/ban.svg rename to app/static/css/bootstrap-icons-1.11.3/ban.svg diff --git a/static/css/bootstrap-icons-1.11.3/bandaid-fill.svg b/app/static/css/bootstrap-icons-1.11.3/bandaid-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bandaid-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/bandaid-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/bandaid.svg b/app/static/css/bootstrap-icons-1.11.3/bandaid.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bandaid.svg rename to app/static/css/bootstrap-icons-1.11.3/bandaid.svg diff --git a/static/css/bootstrap-icons-1.11.3/bank.svg b/app/static/css/bootstrap-icons-1.11.3/bank.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bank.svg rename to app/static/css/bootstrap-icons-1.11.3/bank.svg diff --git a/static/css/bootstrap-icons-1.11.3/bank2.svg b/app/static/css/bootstrap-icons-1.11.3/bank2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bank2.svg rename to app/static/css/bootstrap-icons-1.11.3/bank2.svg diff --git a/static/css/bootstrap-icons-1.11.3/bar-chart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/bar-chart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bar-chart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/bar-chart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/bar-chart-line-fill.svg b/app/static/css/bootstrap-icons-1.11.3/bar-chart-line-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bar-chart-line-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/bar-chart-line-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/bar-chart-line.svg b/app/static/css/bootstrap-icons-1.11.3/bar-chart-line.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bar-chart-line.svg rename to app/static/css/bootstrap-icons-1.11.3/bar-chart-line.svg diff --git a/static/css/bootstrap-icons-1.11.3/bar-chart-steps.svg b/app/static/css/bootstrap-icons-1.11.3/bar-chart-steps.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bar-chart-steps.svg rename to app/static/css/bootstrap-icons-1.11.3/bar-chart-steps.svg diff --git a/static/css/bootstrap-icons-1.11.3/bar-chart.svg b/app/static/css/bootstrap-icons-1.11.3/bar-chart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bar-chart.svg rename to app/static/css/bootstrap-icons-1.11.3/bar-chart.svg diff --git a/static/css/bootstrap-icons-1.11.3/basket-fill.svg b/app/static/css/bootstrap-icons-1.11.3/basket-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/basket-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/basket-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/basket.svg b/app/static/css/bootstrap-icons-1.11.3/basket.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/basket.svg rename to app/static/css/bootstrap-icons-1.11.3/basket.svg diff --git a/static/css/bootstrap-icons-1.11.3/basket2-fill.svg b/app/static/css/bootstrap-icons-1.11.3/basket2-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/basket2-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/basket2-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/basket2.svg b/app/static/css/bootstrap-icons-1.11.3/basket2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/basket2.svg rename to app/static/css/bootstrap-icons-1.11.3/basket2.svg diff --git a/static/css/bootstrap-icons-1.11.3/basket3-fill.svg b/app/static/css/bootstrap-icons-1.11.3/basket3-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/basket3-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/basket3-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/basket3.svg b/app/static/css/bootstrap-icons-1.11.3/basket3.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/basket3.svg rename to app/static/css/bootstrap-icons-1.11.3/basket3.svg diff --git a/static/css/bootstrap-icons-1.11.3/battery-charging.svg b/app/static/css/bootstrap-icons-1.11.3/battery-charging.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/battery-charging.svg rename to app/static/css/bootstrap-icons-1.11.3/battery-charging.svg diff --git a/static/css/bootstrap-icons-1.11.3/battery-full.svg b/app/static/css/bootstrap-icons-1.11.3/battery-full.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/battery-full.svg rename to app/static/css/bootstrap-icons-1.11.3/battery-full.svg diff --git a/static/css/bootstrap-icons-1.11.3/battery-half.svg b/app/static/css/bootstrap-icons-1.11.3/battery-half.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/battery-half.svg rename to app/static/css/bootstrap-icons-1.11.3/battery-half.svg diff --git a/static/css/bootstrap-icons-1.11.3/battery.svg b/app/static/css/bootstrap-icons-1.11.3/battery.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/battery.svg rename to app/static/css/bootstrap-icons-1.11.3/battery.svg diff --git a/static/css/bootstrap-icons-1.11.3/behance.svg b/app/static/css/bootstrap-icons-1.11.3/behance.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/behance.svg rename to app/static/css/bootstrap-icons-1.11.3/behance.svg diff --git a/static/css/bootstrap-icons-1.11.3/bell-fill.svg b/app/static/css/bootstrap-icons-1.11.3/bell-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bell-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/bell-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/bell-slash-fill.svg b/app/static/css/bootstrap-icons-1.11.3/bell-slash-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bell-slash-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/bell-slash-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/bell-slash.svg b/app/static/css/bootstrap-icons-1.11.3/bell-slash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bell-slash.svg rename to app/static/css/bootstrap-icons-1.11.3/bell-slash.svg diff --git a/static/css/bootstrap-icons-1.11.3/bell.svg b/app/static/css/bootstrap-icons-1.11.3/bell.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bell.svg rename to app/static/css/bootstrap-icons-1.11.3/bell.svg diff --git a/static/css/bootstrap-icons-1.11.3/bezier.svg b/app/static/css/bootstrap-icons-1.11.3/bezier.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bezier.svg rename to app/static/css/bootstrap-icons-1.11.3/bezier.svg diff --git a/static/css/bootstrap-icons-1.11.3/bezier2.svg b/app/static/css/bootstrap-icons-1.11.3/bezier2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bezier2.svg rename to app/static/css/bootstrap-icons-1.11.3/bezier2.svg diff --git a/static/css/bootstrap-icons-1.11.3/bicycle.svg b/app/static/css/bootstrap-icons-1.11.3/bicycle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bicycle.svg rename to app/static/css/bootstrap-icons-1.11.3/bicycle.svg diff --git a/static/css/bootstrap-icons-1.11.3/bing.svg b/app/static/css/bootstrap-icons-1.11.3/bing.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bing.svg rename to app/static/css/bootstrap-icons-1.11.3/bing.svg diff --git a/static/css/bootstrap-icons-1.11.3/binoculars-fill.svg b/app/static/css/bootstrap-icons-1.11.3/binoculars-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/binoculars-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/binoculars-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/binoculars.svg b/app/static/css/bootstrap-icons-1.11.3/binoculars.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/binoculars.svg rename to app/static/css/bootstrap-icons-1.11.3/binoculars.svg diff --git a/static/css/bootstrap-icons-1.11.3/blockquote-left.svg b/app/static/css/bootstrap-icons-1.11.3/blockquote-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/blockquote-left.svg rename to app/static/css/bootstrap-icons-1.11.3/blockquote-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/blockquote-right.svg b/app/static/css/bootstrap-icons-1.11.3/blockquote-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/blockquote-right.svg rename to app/static/css/bootstrap-icons-1.11.3/blockquote-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/bluetooth.svg b/app/static/css/bootstrap-icons-1.11.3/bluetooth.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bluetooth.svg rename to app/static/css/bootstrap-icons-1.11.3/bluetooth.svg diff --git a/static/css/bootstrap-icons-1.11.3/body-text.svg b/app/static/css/bootstrap-icons-1.11.3/body-text.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/body-text.svg rename to app/static/css/bootstrap-icons-1.11.3/body-text.svg diff --git a/static/css/bootstrap-icons-1.11.3/book-fill.svg b/app/static/css/bootstrap-icons-1.11.3/book-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/book-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/book-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/book-half.svg b/app/static/css/bootstrap-icons-1.11.3/book-half.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/book-half.svg rename to app/static/css/bootstrap-icons-1.11.3/book-half.svg diff --git a/static/css/bootstrap-icons-1.11.3/book.svg b/app/static/css/bootstrap-icons-1.11.3/book.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/book.svg rename to app/static/css/bootstrap-icons-1.11.3/book.svg diff --git a/static/css/bootstrap-icons-1.11.3/bookmark-check-fill.svg b/app/static/css/bootstrap-icons-1.11.3/bookmark-check-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bookmark-check-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/bookmark-check-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/bookmark-check.svg b/app/static/css/bootstrap-icons-1.11.3/bookmark-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bookmark-check.svg rename to app/static/css/bootstrap-icons-1.11.3/bookmark-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/bookmark-dash-fill.svg b/app/static/css/bootstrap-icons-1.11.3/bookmark-dash-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bookmark-dash-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/bookmark-dash-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/bookmark-dash.svg b/app/static/css/bootstrap-icons-1.11.3/bookmark-dash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bookmark-dash.svg rename to app/static/css/bootstrap-icons-1.11.3/bookmark-dash.svg diff --git a/static/css/bootstrap-icons-1.11.3/bookmark-fill.svg b/app/static/css/bootstrap-icons-1.11.3/bookmark-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bookmark-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/bookmark-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/bookmark-heart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/bookmark-heart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bookmark-heart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/bookmark-heart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/bookmark-heart.svg b/app/static/css/bootstrap-icons-1.11.3/bookmark-heart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bookmark-heart.svg rename to app/static/css/bootstrap-icons-1.11.3/bookmark-heart.svg diff --git a/static/css/bootstrap-icons-1.11.3/bookmark-plus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/bookmark-plus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bookmark-plus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/bookmark-plus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/bookmark-plus.svg b/app/static/css/bootstrap-icons-1.11.3/bookmark-plus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bookmark-plus.svg rename to app/static/css/bootstrap-icons-1.11.3/bookmark-plus.svg diff --git a/static/css/bootstrap-icons-1.11.3/bookmark-star-fill.svg b/app/static/css/bootstrap-icons-1.11.3/bookmark-star-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bookmark-star-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/bookmark-star-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/bookmark-star.svg b/app/static/css/bootstrap-icons-1.11.3/bookmark-star.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bookmark-star.svg rename to app/static/css/bootstrap-icons-1.11.3/bookmark-star.svg diff --git a/static/css/bootstrap-icons-1.11.3/bookmark-x-fill.svg b/app/static/css/bootstrap-icons-1.11.3/bookmark-x-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bookmark-x-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/bookmark-x-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/bookmark-x.svg b/app/static/css/bootstrap-icons-1.11.3/bookmark-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bookmark-x.svg rename to app/static/css/bootstrap-icons-1.11.3/bookmark-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/bookmark.svg b/app/static/css/bootstrap-icons-1.11.3/bookmark.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bookmark.svg rename to app/static/css/bootstrap-icons-1.11.3/bookmark.svg diff --git a/static/css/bootstrap-icons-1.11.3/bookmarks-fill.svg b/app/static/css/bootstrap-icons-1.11.3/bookmarks-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bookmarks-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/bookmarks-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/bookmarks.svg b/app/static/css/bootstrap-icons-1.11.3/bookmarks.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bookmarks.svg rename to app/static/css/bootstrap-icons-1.11.3/bookmarks.svg diff --git a/static/css/bootstrap-icons-1.11.3/bookshelf.svg b/app/static/css/bootstrap-icons-1.11.3/bookshelf.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bookshelf.svg rename to app/static/css/bootstrap-icons-1.11.3/bookshelf.svg diff --git a/static/css/bootstrap-icons-1.11.3/boombox-fill.svg b/app/static/css/bootstrap-icons-1.11.3/boombox-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/boombox-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/boombox-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/boombox.svg b/app/static/css/bootstrap-icons-1.11.3/boombox.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/boombox.svg rename to app/static/css/bootstrap-icons-1.11.3/boombox.svg diff --git a/static/css/bootstrap-icons-1.11.3/bootstrap-fill.svg b/app/static/css/bootstrap-icons-1.11.3/bootstrap-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bootstrap-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/bootstrap-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/bootstrap-icons.svg b/app/static/css/bootstrap-icons-1.11.3/bootstrap-icons.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bootstrap-icons.svg rename to app/static/css/bootstrap-icons-1.11.3/bootstrap-icons.svg diff --git a/static/css/bootstrap-icons-1.11.3/bootstrap-reboot.svg b/app/static/css/bootstrap-icons-1.11.3/bootstrap-reboot.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bootstrap-reboot.svg rename to app/static/css/bootstrap-icons-1.11.3/bootstrap-reboot.svg diff --git a/static/css/bootstrap-icons-1.11.3/bootstrap.svg b/app/static/css/bootstrap-icons-1.11.3/bootstrap.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bootstrap.svg rename to app/static/css/bootstrap-icons-1.11.3/bootstrap.svg diff --git a/static/css/bootstrap-icons-1.11.3/border-all.svg b/app/static/css/bootstrap-icons-1.11.3/border-all.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/border-all.svg rename to app/static/css/bootstrap-icons-1.11.3/border-all.svg diff --git a/static/css/bootstrap-icons-1.11.3/border-bottom.svg b/app/static/css/bootstrap-icons-1.11.3/border-bottom.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/border-bottom.svg rename to app/static/css/bootstrap-icons-1.11.3/border-bottom.svg diff --git a/static/css/bootstrap-icons-1.11.3/border-center.svg b/app/static/css/bootstrap-icons-1.11.3/border-center.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/border-center.svg rename to app/static/css/bootstrap-icons-1.11.3/border-center.svg diff --git a/static/css/bootstrap-icons-1.11.3/border-inner.svg b/app/static/css/bootstrap-icons-1.11.3/border-inner.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/border-inner.svg rename to app/static/css/bootstrap-icons-1.11.3/border-inner.svg diff --git a/static/css/bootstrap-icons-1.11.3/border-left.svg b/app/static/css/bootstrap-icons-1.11.3/border-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/border-left.svg rename to app/static/css/bootstrap-icons-1.11.3/border-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/border-middle.svg b/app/static/css/bootstrap-icons-1.11.3/border-middle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/border-middle.svg rename to app/static/css/bootstrap-icons-1.11.3/border-middle.svg diff --git a/static/css/bootstrap-icons-1.11.3/border-outer.svg b/app/static/css/bootstrap-icons-1.11.3/border-outer.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/border-outer.svg rename to app/static/css/bootstrap-icons-1.11.3/border-outer.svg diff --git a/static/css/bootstrap-icons-1.11.3/border-right.svg b/app/static/css/bootstrap-icons-1.11.3/border-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/border-right.svg rename to app/static/css/bootstrap-icons-1.11.3/border-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/border-style.svg b/app/static/css/bootstrap-icons-1.11.3/border-style.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/border-style.svg rename to app/static/css/bootstrap-icons-1.11.3/border-style.svg diff --git a/static/css/bootstrap-icons-1.11.3/border-top.svg b/app/static/css/bootstrap-icons-1.11.3/border-top.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/border-top.svg rename to app/static/css/bootstrap-icons-1.11.3/border-top.svg diff --git a/static/css/bootstrap-icons-1.11.3/border-width.svg b/app/static/css/bootstrap-icons-1.11.3/border-width.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/border-width.svg rename to app/static/css/bootstrap-icons-1.11.3/border-width.svg diff --git a/static/css/bootstrap-icons-1.11.3/border.svg b/app/static/css/bootstrap-icons-1.11.3/border.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/border.svg rename to app/static/css/bootstrap-icons-1.11.3/border.svg diff --git a/static/css/bootstrap-icons-1.11.3/bounding-box-circles.svg b/app/static/css/bootstrap-icons-1.11.3/bounding-box-circles.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bounding-box-circles.svg rename to app/static/css/bootstrap-icons-1.11.3/bounding-box-circles.svg diff --git a/static/css/bootstrap-icons-1.11.3/bounding-box.svg b/app/static/css/bootstrap-icons-1.11.3/bounding-box.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bounding-box.svg rename to app/static/css/bootstrap-icons-1.11.3/bounding-box.svg diff --git a/static/css/bootstrap-icons-1.11.3/box-arrow-down-left.svg b/app/static/css/bootstrap-icons-1.11.3/box-arrow-down-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box-arrow-down-left.svg rename to app/static/css/bootstrap-icons-1.11.3/box-arrow-down-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/box-arrow-down-right.svg b/app/static/css/bootstrap-icons-1.11.3/box-arrow-down-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box-arrow-down-right.svg rename to app/static/css/bootstrap-icons-1.11.3/box-arrow-down-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/box-arrow-down.svg b/app/static/css/bootstrap-icons-1.11.3/box-arrow-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box-arrow-down.svg rename to app/static/css/bootstrap-icons-1.11.3/box-arrow-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/box-arrow-in-down-left.svg b/app/static/css/bootstrap-icons-1.11.3/box-arrow-in-down-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box-arrow-in-down-left.svg rename to app/static/css/bootstrap-icons-1.11.3/box-arrow-in-down-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/box-arrow-in-down-right.svg b/app/static/css/bootstrap-icons-1.11.3/box-arrow-in-down-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box-arrow-in-down-right.svg rename to app/static/css/bootstrap-icons-1.11.3/box-arrow-in-down-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/box-arrow-in-down.svg b/app/static/css/bootstrap-icons-1.11.3/box-arrow-in-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box-arrow-in-down.svg rename to app/static/css/bootstrap-icons-1.11.3/box-arrow-in-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/box-arrow-in-left.svg b/app/static/css/bootstrap-icons-1.11.3/box-arrow-in-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box-arrow-in-left.svg rename to app/static/css/bootstrap-icons-1.11.3/box-arrow-in-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/box-arrow-in-right.svg b/app/static/css/bootstrap-icons-1.11.3/box-arrow-in-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box-arrow-in-right.svg rename to app/static/css/bootstrap-icons-1.11.3/box-arrow-in-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/box-arrow-in-up-left.svg b/app/static/css/bootstrap-icons-1.11.3/box-arrow-in-up-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box-arrow-in-up-left.svg rename to app/static/css/bootstrap-icons-1.11.3/box-arrow-in-up-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/box-arrow-in-up-right.svg b/app/static/css/bootstrap-icons-1.11.3/box-arrow-in-up-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box-arrow-in-up-right.svg rename to app/static/css/bootstrap-icons-1.11.3/box-arrow-in-up-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/box-arrow-in-up.svg b/app/static/css/bootstrap-icons-1.11.3/box-arrow-in-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box-arrow-in-up.svg rename to app/static/css/bootstrap-icons-1.11.3/box-arrow-in-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/box-arrow-left.svg b/app/static/css/bootstrap-icons-1.11.3/box-arrow-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box-arrow-left.svg rename to app/static/css/bootstrap-icons-1.11.3/box-arrow-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/box-arrow-right.svg b/app/static/css/bootstrap-icons-1.11.3/box-arrow-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box-arrow-right.svg rename to app/static/css/bootstrap-icons-1.11.3/box-arrow-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/box-arrow-up-left.svg b/app/static/css/bootstrap-icons-1.11.3/box-arrow-up-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box-arrow-up-left.svg rename to app/static/css/bootstrap-icons-1.11.3/box-arrow-up-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/box-arrow-up-right.svg b/app/static/css/bootstrap-icons-1.11.3/box-arrow-up-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box-arrow-up-right.svg rename to app/static/css/bootstrap-icons-1.11.3/box-arrow-up-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/box-arrow-up.svg b/app/static/css/bootstrap-icons-1.11.3/box-arrow-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box-arrow-up.svg rename to app/static/css/bootstrap-icons-1.11.3/box-arrow-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/box-fill.svg b/app/static/css/bootstrap-icons-1.11.3/box-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/box-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/box-seam-fill.svg b/app/static/css/bootstrap-icons-1.11.3/box-seam-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box-seam-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/box-seam-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/box-seam.svg b/app/static/css/bootstrap-icons-1.11.3/box-seam.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box-seam.svg rename to app/static/css/bootstrap-icons-1.11.3/box-seam.svg diff --git a/static/css/bootstrap-icons-1.11.3/box.svg b/app/static/css/bootstrap-icons-1.11.3/box.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box.svg rename to app/static/css/bootstrap-icons-1.11.3/box.svg diff --git a/static/css/bootstrap-icons-1.11.3/box2-fill.svg b/app/static/css/bootstrap-icons-1.11.3/box2-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box2-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/box2-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/box2-heart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/box2-heart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box2-heart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/box2-heart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/box2-heart.svg b/app/static/css/bootstrap-icons-1.11.3/box2-heart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box2-heart.svg rename to app/static/css/bootstrap-icons-1.11.3/box2-heart.svg diff --git a/static/css/bootstrap-icons-1.11.3/box2.svg b/app/static/css/bootstrap-icons-1.11.3/box2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/box2.svg rename to app/static/css/bootstrap-icons-1.11.3/box2.svg diff --git a/static/css/bootstrap-icons-1.11.3/boxes.svg b/app/static/css/bootstrap-icons-1.11.3/boxes.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/boxes.svg rename to app/static/css/bootstrap-icons-1.11.3/boxes.svg diff --git a/static/css/bootstrap-icons-1.11.3/braces-asterisk.svg b/app/static/css/bootstrap-icons-1.11.3/braces-asterisk.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/braces-asterisk.svg rename to app/static/css/bootstrap-icons-1.11.3/braces-asterisk.svg diff --git a/static/css/bootstrap-icons-1.11.3/braces.svg b/app/static/css/bootstrap-icons-1.11.3/braces.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/braces.svg rename to app/static/css/bootstrap-icons-1.11.3/braces.svg diff --git a/static/css/bootstrap-icons-1.11.3/bricks.svg b/app/static/css/bootstrap-icons-1.11.3/bricks.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bricks.svg rename to app/static/css/bootstrap-icons-1.11.3/bricks.svg diff --git a/static/css/bootstrap-icons-1.11.3/briefcase-fill.svg b/app/static/css/bootstrap-icons-1.11.3/briefcase-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/briefcase-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/briefcase-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/briefcase.svg b/app/static/css/bootstrap-icons-1.11.3/briefcase.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/briefcase.svg rename to app/static/css/bootstrap-icons-1.11.3/briefcase.svg diff --git a/static/css/bootstrap-icons-1.11.3/brightness-alt-high-fill.svg b/app/static/css/bootstrap-icons-1.11.3/brightness-alt-high-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/brightness-alt-high-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/brightness-alt-high-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/brightness-alt-high.svg b/app/static/css/bootstrap-icons-1.11.3/brightness-alt-high.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/brightness-alt-high.svg rename to app/static/css/bootstrap-icons-1.11.3/brightness-alt-high.svg diff --git a/static/css/bootstrap-icons-1.11.3/brightness-alt-low-fill.svg b/app/static/css/bootstrap-icons-1.11.3/brightness-alt-low-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/brightness-alt-low-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/brightness-alt-low-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/brightness-alt-low.svg b/app/static/css/bootstrap-icons-1.11.3/brightness-alt-low.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/brightness-alt-low.svg rename to app/static/css/bootstrap-icons-1.11.3/brightness-alt-low.svg diff --git a/static/css/bootstrap-icons-1.11.3/brightness-high-fill.svg b/app/static/css/bootstrap-icons-1.11.3/brightness-high-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/brightness-high-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/brightness-high-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/brightness-high.svg b/app/static/css/bootstrap-icons-1.11.3/brightness-high.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/brightness-high.svg rename to app/static/css/bootstrap-icons-1.11.3/brightness-high.svg diff --git a/static/css/bootstrap-icons-1.11.3/brightness-low-fill.svg b/app/static/css/bootstrap-icons-1.11.3/brightness-low-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/brightness-low-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/brightness-low-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/brightness-low.svg b/app/static/css/bootstrap-icons-1.11.3/brightness-low.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/brightness-low.svg rename to app/static/css/bootstrap-icons-1.11.3/brightness-low.svg diff --git a/static/css/bootstrap-icons-1.11.3/brilliance.svg b/app/static/css/bootstrap-icons-1.11.3/brilliance.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/brilliance.svg rename to app/static/css/bootstrap-icons-1.11.3/brilliance.svg diff --git a/static/css/bootstrap-icons-1.11.3/broadcast-pin.svg b/app/static/css/bootstrap-icons-1.11.3/broadcast-pin.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/broadcast-pin.svg rename to app/static/css/bootstrap-icons-1.11.3/broadcast-pin.svg diff --git a/static/css/bootstrap-icons-1.11.3/broadcast.svg b/app/static/css/bootstrap-icons-1.11.3/broadcast.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/broadcast.svg rename to app/static/css/bootstrap-icons-1.11.3/broadcast.svg diff --git a/static/css/bootstrap-icons-1.11.3/browser-chrome.svg b/app/static/css/bootstrap-icons-1.11.3/browser-chrome.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/browser-chrome.svg rename to app/static/css/bootstrap-icons-1.11.3/browser-chrome.svg diff --git a/static/css/bootstrap-icons-1.11.3/browser-edge.svg b/app/static/css/bootstrap-icons-1.11.3/browser-edge.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/browser-edge.svg rename to app/static/css/bootstrap-icons-1.11.3/browser-edge.svg diff --git a/static/css/bootstrap-icons-1.11.3/browser-firefox.svg b/app/static/css/bootstrap-icons-1.11.3/browser-firefox.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/browser-firefox.svg rename to app/static/css/bootstrap-icons-1.11.3/browser-firefox.svg diff --git a/static/css/bootstrap-icons-1.11.3/browser-safari.svg b/app/static/css/bootstrap-icons-1.11.3/browser-safari.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/browser-safari.svg rename to app/static/css/bootstrap-icons-1.11.3/browser-safari.svg diff --git a/static/css/bootstrap-icons-1.11.3/brush-fill.svg b/app/static/css/bootstrap-icons-1.11.3/brush-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/brush-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/brush-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/brush.svg b/app/static/css/bootstrap-icons-1.11.3/brush.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/brush.svg rename to app/static/css/bootstrap-icons-1.11.3/brush.svg diff --git a/static/css/bootstrap-icons-1.11.3/bucket-fill.svg b/app/static/css/bootstrap-icons-1.11.3/bucket-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bucket-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/bucket-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/bucket.svg b/app/static/css/bootstrap-icons-1.11.3/bucket.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bucket.svg rename to app/static/css/bootstrap-icons-1.11.3/bucket.svg diff --git a/static/css/bootstrap-icons-1.11.3/bug-fill.svg b/app/static/css/bootstrap-icons-1.11.3/bug-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bug-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/bug-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/bug.svg b/app/static/css/bootstrap-icons-1.11.3/bug.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bug.svg rename to app/static/css/bootstrap-icons-1.11.3/bug.svg diff --git a/static/css/bootstrap-icons-1.11.3/building-add.svg b/app/static/css/bootstrap-icons-1.11.3/building-add.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/building-add.svg rename to app/static/css/bootstrap-icons-1.11.3/building-add.svg diff --git a/static/css/bootstrap-icons-1.11.3/building-check.svg b/app/static/css/bootstrap-icons-1.11.3/building-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/building-check.svg rename to app/static/css/bootstrap-icons-1.11.3/building-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/building-dash.svg b/app/static/css/bootstrap-icons-1.11.3/building-dash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/building-dash.svg rename to app/static/css/bootstrap-icons-1.11.3/building-dash.svg diff --git a/static/css/bootstrap-icons-1.11.3/building-down.svg b/app/static/css/bootstrap-icons-1.11.3/building-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/building-down.svg rename to app/static/css/bootstrap-icons-1.11.3/building-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/building-exclamation.svg b/app/static/css/bootstrap-icons-1.11.3/building-exclamation.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/building-exclamation.svg rename to app/static/css/bootstrap-icons-1.11.3/building-exclamation.svg diff --git a/static/css/bootstrap-icons-1.11.3/building-fill-add.svg b/app/static/css/bootstrap-icons-1.11.3/building-fill-add.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/building-fill-add.svg rename to app/static/css/bootstrap-icons-1.11.3/building-fill-add.svg diff --git a/static/css/bootstrap-icons-1.11.3/building-fill-check.svg b/app/static/css/bootstrap-icons-1.11.3/building-fill-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/building-fill-check.svg rename to app/static/css/bootstrap-icons-1.11.3/building-fill-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/building-fill-dash.svg b/app/static/css/bootstrap-icons-1.11.3/building-fill-dash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/building-fill-dash.svg rename to app/static/css/bootstrap-icons-1.11.3/building-fill-dash.svg diff --git a/static/css/bootstrap-icons-1.11.3/building-fill-down.svg b/app/static/css/bootstrap-icons-1.11.3/building-fill-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/building-fill-down.svg rename to app/static/css/bootstrap-icons-1.11.3/building-fill-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/building-fill-exclamation.svg b/app/static/css/bootstrap-icons-1.11.3/building-fill-exclamation.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/building-fill-exclamation.svg rename to app/static/css/bootstrap-icons-1.11.3/building-fill-exclamation.svg diff --git a/static/css/bootstrap-icons-1.11.3/building-fill-gear.svg b/app/static/css/bootstrap-icons-1.11.3/building-fill-gear.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/building-fill-gear.svg rename to app/static/css/bootstrap-icons-1.11.3/building-fill-gear.svg diff --git a/static/css/bootstrap-icons-1.11.3/building-fill-lock.svg b/app/static/css/bootstrap-icons-1.11.3/building-fill-lock.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/building-fill-lock.svg rename to app/static/css/bootstrap-icons-1.11.3/building-fill-lock.svg diff --git a/static/css/bootstrap-icons-1.11.3/building-fill-slash.svg b/app/static/css/bootstrap-icons-1.11.3/building-fill-slash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/building-fill-slash.svg rename to app/static/css/bootstrap-icons-1.11.3/building-fill-slash.svg diff --git a/static/css/bootstrap-icons-1.11.3/building-fill-up.svg b/app/static/css/bootstrap-icons-1.11.3/building-fill-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/building-fill-up.svg rename to app/static/css/bootstrap-icons-1.11.3/building-fill-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/building-fill-x.svg b/app/static/css/bootstrap-icons-1.11.3/building-fill-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/building-fill-x.svg rename to app/static/css/bootstrap-icons-1.11.3/building-fill-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/building-fill.svg b/app/static/css/bootstrap-icons-1.11.3/building-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/building-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/building-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/building-gear.svg b/app/static/css/bootstrap-icons-1.11.3/building-gear.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/building-gear.svg rename to app/static/css/bootstrap-icons-1.11.3/building-gear.svg diff --git a/static/css/bootstrap-icons-1.11.3/building-lock.svg b/app/static/css/bootstrap-icons-1.11.3/building-lock.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/building-lock.svg rename to app/static/css/bootstrap-icons-1.11.3/building-lock.svg diff --git a/static/css/bootstrap-icons-1.11.3/building-slash.svg b/app/static/css/bootstrap-icons-1.11.3/building-slash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/building-slash.svg rename to app/static/css/bootstrap-icons-1.11.3/building-slash.svg diff --git a/static/css/bootstrap-icons-1.11.3/building-up.svg b/app/static/css/bootstrap-icons-1.11.3/building-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/building-up.svg rename to app/static/css/bootstrap-icons-1.11.3/building-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/building-x.svg b/app/static/css/bootstrap-icons-1.11.3/building-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/building-x.svg rename to app/static/css/bootstrap-icons-1.11.3/building-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/building.svg b/app/static/css/bootstrap-icons-1.11.3/building.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/building.svg rename to app/static/css/bootstrap-icons-1.11.3/building.svg diff --git a/static/css/bootstrap-icons-1.11.3/buildings-fill.svg b/app/static/css/bootstrap-icons-1.11.3/buildings-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/buildings-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/buildings-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/buildings.svg b/app/static/css/bootstrap-icons-1.11.3/buildings.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/buildings.svg rename to app/static/css/bootstrap-icons-1.11.3/buildings.svg diff --git a/static/css/bootstrap-icons-1.11.3/bullseye.svg b/app/static/css/bootstrap-icons-1.11.3/bullseye.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bullseye.svg rename to app/static/css/bootstrap-icons-1.11.3/bullseye.svg diff --git a/static/css/bootstrap-icons-1.11.3/bus-front-fill.svg b/app/static/css/bootstrap-icons-1.11.3/bus-front-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bus-front-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/bus-front-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/bus-front.svg b/app/static/css/bootstrap-icons-1.11.3/bus-front.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/bus-front.svg rename to app/static/css/bootstrap-icons-1.11.3/bus-front.svg diff --git a/static/css/bootstrap-icons-1.11.3/c-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/c-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/c-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/c-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/c-circle.svg b/app/static/css/bootstrap-icons-1.11.3/c-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/c-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/c-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/c-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/c-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/c-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/c-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/c-square.svg b/app/static/css/bootstrap-icons-1.11.3/c-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/c-square.svg rename to app/static/css/bootstrap-icons-1.11.3/c-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/cake-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cake-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cake-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cake-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cake.svg b/app/static/css/bootstrap-icons-1.11.3/cake.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cake.svg rename to app/static/css/bootstrap-icons-1.11.3/cake.svg diff --git a/static/css/bootstrap-icons-1.11.3/cake2-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cake2-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cake2-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cake2-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cake2.svg b/app/static/css/bootstrap-icons-1.11.3/cake2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cake2.svg rename to app/static/css/bootstrap-icons-1.11.3/cake2.svg diff --git a/static/css/bootstrap-icons-1.11.3/calculator-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calculator-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calculator-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calculator-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calculator.svg b/app/static/css/bootstrap-icons-1.11.3/calculator.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calculator.svg rename to app/static/css/bootstrap-icons-1.11.3/calculator.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar-check-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar-check-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar-check-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar-check-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar-check.svg b/app/static/css/bootstrap-icons-1.11.3/calendar-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar-check.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar-date-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar-date-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar-date-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar-date-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar-date.svg b/app/static/css/bootstrap-icons-1.11.3/calendar-date.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar-date.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar-date.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar-day-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar-day-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar-day-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar-day-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar-day.svg b/app/static/css/bootstrap-icons-1.11.3/calendar-day.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar-day.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar-day.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar-event-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar-event-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar-event-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar-event-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar-event.svg b/app/static/css/bootstrap-icons-1.11.3/calendar-event.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar-event.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar-event.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar-heart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar-heart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar-heart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar-heart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar-heart.svg b/app/static/css/bootstrap-icons-1.11.3/calendar-heart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar-heart.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar-heart.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar-minus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar-minus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar-minus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar-minus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar-minus.svg b/app/static/css/bootstrap-icons-1.11.3/calendar-minus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar-minus.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar-minus.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar-month-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar-month-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar-month-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar-month-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar-month.svg b/app/static/css/bootstrap-icons-1.11.3/calendar-month.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar-month.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar-month.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar-plus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar-plus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar-plus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar-plus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar-plus.svg b/app/static/css/bootstrap-icons-1.11.3/calendar-plus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar-plus.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar-plus.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar-range-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar-range-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar-range-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar-range-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar-range.svg b/app/static/css/bootstrap-icons-1.11.3/calendar-range.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar-range.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar-range.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar-week-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar-week-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar-week-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar-week-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar-week.svg b/app/static/css/bootstrap-icons-1.11.3/calendar-week.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar-week.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar-week.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar-x-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar-x-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar-x-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar-x-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar-x.svg b/app/static/css/bootstrap-icons-1.11.3/calendar-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar-x.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar.svg b/app/static/css/bootstrap-icons-1.11.3/calendar.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2-check-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2-check-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2-check-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2-check-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2-check.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2-check.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2-date-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2-date-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2-date-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2-date-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2-date.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2-date.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2-date.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2-date.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2-day-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2-day-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2-day-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2-day-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2-day.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2-day.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2-day.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2-day.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2-event-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2-event-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2-event-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2-event-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2-event.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2-event.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2-event.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2-event.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2-heart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2-heart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2-heart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2-heart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2-heart.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2-heart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2-heart.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2-heart.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2-minus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2-minus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2-minus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2-minus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2-minus.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2-minus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2-minus.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2-minus.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2-month-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2-month-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2-month-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2-month-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2-month.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2-month.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2-month.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2-month.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2-plus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2-plus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2-plus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2-plus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2-plus.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2-plus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2-plus.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2-plus.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2-range-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2-range-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2-range-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2-range-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2-range.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2-range.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2-range.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2-range.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2-week-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2-week-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2-week-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2-week-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2-week.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2-week.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2-week.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2-week.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2-x-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2-x-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2-x-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2-x-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2-x.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2-x.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar2.svg b/app/static/css/bootstrap-icons-1.11.3/calendar2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar2.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar2.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar3-event-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar3-event-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar3-event-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar3-event-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar3-event.svg b/app/static/css/bootstrap-icons-1.11.3/calendar3-event.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar3-event.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar3-event.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar3-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar3-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar3-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar3-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar3-range-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar3-range-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar3-range-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar3-range-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar3-range.svg b/app/static/css/bootstrap-icons-1.11.3/calendar3-range.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar3-range.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar3-range.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar3-week-fill.svg b/app/static/css/bootstrap-icons-1.11.3/calendar3-week-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar3-week-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar3-week-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar3-week.svg b/app/static/css/bootstrap-icons-1.11.3/calendar3-week.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar3-week.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar3-week.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar3.svg b/app/static/css/bootstrap-icons-1.11.3/calendar3.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar3.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar3.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar4-event.svg b/app/static/css/bootstrap-icons-1.11.3/calendar4-event.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar4-event.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar4-event.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar4-range.svg b/app/static/css/bootstrap-icons-1.11.3/calendar4-range.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar4-range.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar4-range.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar4-week.svg b/app/static/css/bootstrap-icons-1.11.3/calendar4-week.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar4-week.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar4-week.svg diff --git a/static/css/bootstrap-icons-1.11.3/calendar4.svg b/app/static/css/bootstrap-icons-1.11.3/calendar4.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/calendar4.svg rename to app/static/css/bootstrap-icons-1.11.3/calendar4.svg diff --git a/static/css/bootstrap-icons-1.11.3/camera-fill.svg b/app/static/css/bootstrap-icons-1.11.3/camera-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/camera-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/camera-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/camera-reels-fill.svg b/app/static/css/bootstrap-icons-1.11.3/camera-reels-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/camera-reels-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/camera-reels-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/camera-reels.svg b/app/static/css/bootstrap-icons-1.11.3/camera-reels.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/camera-reels.svg rename to app/static/css/bootstrap-icons-1.11.3/camera-reels.svg diff --git a/static/css/bootstrap-icons-1.11.3/camera-video-fill.svg b/app/static/css/bootstrap-icons-1.11.3/camera-video-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/camera-video-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/camera-video-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/camera-video-off-fill.svg b/app/static/css/bootstrap-icons-1.11.3/camera-video-off-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/camera-video-off-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/camera-video-off-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/camera-video-off.svg b/app/static/css/bootstrap-icons-1.11.3/camera-video-off.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/camera-video-off.svg rename to app/static/css/bootstrap-icons-1.11.3/camera-video-off.svg diff --git a/static/css/bootstrap-icons-1.11.3/camera-video.svg b/app/static/css/bootstrap-icons-1.11.3/camera-video.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/camera-video.svg rename to app/static/css/bootstrap-icons-1.11.3/camera-video.svg diff --git a/static/css/bootstrap-icons-1.11.3/camera.svg b/app/static/css/bootstrap-icons-1.11.3/camera.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/camera.svg rename to app/static/css/bootstrap-icons-1.11.3/camera.svg diff --git a/static/css/bootstrap-icons-1.11.3/camera2.svg b/app/static/css/bootstrap-icons-1.11.3/camera2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/camera2.svg rename to app/static/css/bootstrap-icons-1.11.3/camera2.svg diff --git a/static/css/bootstrap-icons-1.11.3/capslock-fill.svg b/app/static/css/bootstrap-icons-1.11.3/capslock-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/capslock-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/capslock-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/capslock.svg b/app/static/css/bootstrap-icons-1.11.3/capslock.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/capslock.svg rename to app/static/css/bootstrap-icons-1.11.3/capslock.svg diff --git a/static/css/bootstrap-icons-1.11.3/capsule-pill.svg b/app/static/css/bootstrap-icons-1.11.3/capsule-pill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/capsule-pill.svg rename to app/static/css/bootstrap-icons-1.11.3/capsule-pill.svg diff --git a/static/css/bootstrap-icons-1.11.3/capsule.svg b/app/static/css/bootstrap-icons-1.11.3/capsule.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/capsule.svg rename to app/static/css/bootstrap-icons-1.11.3/capsule.svg diff --git a/static/css/bootstrap-icons-1.11.3/car-front-fill.svg b/app/static/css/bootstrap-icons-1.11.3/car-front-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/car-front-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/car-front-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/car-front.svg b/app/static/css/bootstrap-icons-1.11.3/car-front.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/car-front.svg rename to app/static/css/bootstrap-icons-1.11.3/car-front.svg diff --git a/static/css/bootstrap-icons-1.11.3/card-checklist.svg b/app/static/css/bootstrap-icons-1.11.3/card-checklist.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/card-checklist.svg rename to app/static/css/bootstrap-icons-1.11.3/card-checklist.svg diff --git a/static/css/bootstrap-icons-1.11.3/card-heading.svg b/app/static/css/bootstrap-icons-1.11.3/card-heading.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/card-heading.svg rename to app/static/css/bootstrap-icons-1.11.3/card-heading.svg diff --git a/static/css/bootstrap-icons-1.11.3/card-image.svg b/app/static/css/bootstrap-icons-1.11.3/card-image.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/card-image.svg rename to app/static/css/bootstrap-icons-1.11.3/card-image.svg diff --git a/static/css/bootstrap-icons-1.11.3/card-list.svg b/app/static/css/bootstrap-icons-1.11.3/card-list.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/card-list.svg rename to app/static/css/bootstrap-icons-1.11.3/card-list.svg diff --git a/static/css/bootstrap-icons-1.11.3/card-text.svg b/app/static/css/bootstrap-icons-1.11.3/card-text.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/card-text.svg rename to app/static/css/bootstrap-icons-1.11.3/card-text.svg diff --git a/static/css/bootstrap-icons-1.11.3/caret-down-fill.svg b/app/static/css/bootstrap-icons-1.11.3/caret-down-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/caret-down-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/caret-down-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/caret-down-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/caret-down-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/caret-down-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/caret-down-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/caret-down-square.svg b/app/static/css/bootstrap-icons-1.11.3/caret-down-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/caret-down-square.svg rename to app/static/css/bootstrap-icons-1.11.3/caret-down-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/caret-down.svg b/app/static/css/bootstrap-icons-1.11.3/caret-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/caret-down.svg rename to app/static/css/bootstrap-icons-1.11.3/caret-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/caret-left-fill.svg b/app/static/css/bootstrap-icons-1.11.3/caret-left-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/caret-left-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/caret-left-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/caret-left-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/caret-left-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/caret-left-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/caret-left-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/caret-left-square.svg b/app/static/css/bootstrap-icons-1.11.3/caret-left-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/caret-left-square.svg rename to app/static/css/bootstrap-icons-1.11.3/caret-left-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/caret-left.svg b/app/static/css/bootstrap-icons-1.11.3/caret-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/caret-left.svg rename to app/static/css/bootstrap-icons-1.11.3/caret-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/caret-right-fill.svg b/app/static/css/bootstrap-icons-1.11.3/caret-right-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/caret-right-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/caret-right-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/caret-right-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/caret-right-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/caret-right-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/caret-right-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/caret-right-square.svg b/app/static/css/bootstrap-icons-1.11.3/caret-right-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/caret-right-square.svg rename to app/static/css/bootstrap-icons-1.11.3/caret-right-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/caret-right.svg b/app/static/css/bootstrap-icons-1.11.3/caret-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/caret-right.svg rename to app/static/css/bootstrap-icons-1.11.3/caret-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/caret-up-fill.svg b/app/static/css/bootstrap-icons-1.11.3/caret-up-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/caret-up-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/caret-up-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/caret-up-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/caret-up-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/caret-up-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/caret-up-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/caret-up-square.svg b/app/static/css/bootstrap-icons-1.11.3/caret-up-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/caret-up-square.svg rename to app/static/css/bootstrap-icons-1.11.3/caret-up-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/caret-up.svg b/app/static/css/bootstrap-icons-1.11.3/caret-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/caret-up.svg rename to app/static/css/bootstrap-icons-1.11.3/caret-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/cart-check-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cart-check-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cart-check-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cart-check-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cart-check.svg b/app/static/css/bootstrap-icons-1.11.3/cart-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cart-check.svg rename to app/static/css/bootstrap-icons-1.11.3/cart-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/cart-dash-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cart-dash-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cart-dash-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cart-dash-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cart-dash.svg b/app/static/css/bootstrap-icons-1.11.3/cart-dash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cart-dash.svg rename to app/static/css/bootstrap-icons-1.11.3/cart-dash.svg diff --git a/static/css/bootstrap-icons-1.11.3/cart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cart-plus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cart-plus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cart-plus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cart-plus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cart-plus.svg b/app/static/css/bootstrap-icons-1.11.3/cart-plus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cart-plus.svg rename to app/static/css/bootstrap-icons-1.11.3/cart-plus.svg diff --git a/static/css/bootstrap-icons-1.11.3/cart-x-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cart-x-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cart-x-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cart-x-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cart-x.svg b/app/static/css/bootstrap-icons-1.11.3/cart-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cart-x.svg rename to app/static/css/bootstrap-icons-1.11.3/cart-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/cart.svg b/app/static/css/bootstrap-icons-1.11.3/cart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cart.svg rename to app/static/css/bootstrap-icons-1.11.3/cart.svg diff --git a/static/css/bootstrap-icons-1.11.3/cart2.svg b/app/static/css/bootstrap-icons-1.11.3/cart2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cart2.svg rename to app/static/css/bootstrap-icons-1.11.3/cart2.svg diff --git a/static/css/bootstrap-icons-1.11.3/cart3.svg b/app/static/css/bootstrap-icons-1.11.3/cart3.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cart3.svg rename to app/static/css/bootstrap-icons-1.11.3/cart3.svg diff --git a/static/css/bootstrap-icons-1.11.3/cart4.svg b/app/static/css/bootstrap-icons-1.11.3/cart4.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cart4.svg rename to app/static/css/bootstrap-icons-1.11.3/cart4.svg diff --git a/static/css/bootstrap-icons-1.11.3/cash-coin.svg b/app/static/css/bootstrap-icons-1.11.3/cash-coin.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cash-coin.svg rename to app/static/css/bootstrap-icons-1.11.3/cash-coin.svg diff --git a/static/css/bootstrap-icons-1.11.3/cash-stack.svg b/app/static/css/bootstrap-icons-1.11.3/cash-stack.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cash-stack.svg rename to app/static/css/bootstrap-icons-1.11.3/cash-stack.svg diff --git a/static/css/bootstrap-icons-1.11.3/cash.svg b/app/static/css/bootstrap-icons-1.11.3/cash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cash.svg rename to app/static/css/bootstrap-icons-1.11.3/cash.svg diff --git a/static/css/bootstrap-icons-1.11.3/cassette-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cassette-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cassette-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cassette-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cassette.svg b/app/static/css/bootstrap-icons-1.11.3/cassette.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cassette.svg rename to app/static/css/bootstrap-icons-1.11.3/cassette.svg diff --git a/static/css/bootstrap-icons-1.11.3/cast.svg b/app/static/css/bootstrap-icons-1.11.3/cast.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cast.svg rename to app/static/css/bootstrap-icons-1.11.3/cast.svg diff --git a/static/css/bootstrap-icons-1.11.3/cc-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cc-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cc-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cc-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cc-circle.svg b/app/static/css/bootstrap-icons-1.11.3/cc-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cc-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/cc-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/cc-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cc-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cc-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cc-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cc-square.svg b/app/static/css/bootstrap-icons-1.11.3/cc-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cc-square.svg rename to app/static/css/bootstrap-icons-1.11.3/cc-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-dots-fill.svg b/app/static/css/bootstrap-icons-1.11.3/chat-dots-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-dots-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-dots-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-dots.svg b/app/static/css/bootstrap-icons-1.11.3/chat-dots.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-dots.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-dots.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-fill.svg b/app/static/css/bootstrap-icons-1.11.3/chat-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-heart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/chat-heart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-heart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-heart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-heart.svg b/app/static/css/bootstrap-icons-1.11.3/chat-heart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-heart.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-heart.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-left-dots-fill.svg b/app/static/css/bootstrap-icons-1.11.3/chat-left-dots-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-left-dots-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-left-dots-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-left-dots.svg b/app/static/css/bootstrap-icons-1.11.3/chat-left-dots.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-left-dots.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-left-dots.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-left-fill.svg b/app/static/css/bootstrap-icons-1.11.3/chat-left-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-left-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-left-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-left-heart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/chat-left-heart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-left-heart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-left-heart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-left-heart.svg b/app/static/css/bootstrap-icons-1.11.3/chat-left-heart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-left-heart.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-left-heart.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-left-quote-fill.svg b/app/static/css/bootstrap-icons-1.11.3/chat-left-quote-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-left-quote-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-left-quote-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-left-quote.svg b/app/static/css/bootstrap-icons-1.11.3/chat-left-quote.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-left-quote.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-left-quote.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-left-text-fill.svg b/app/static/css/bootstrap-icons-1.11.3/chat-left-text-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-left-text-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-left-text-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-left-text.svg b/app/static/css/bootstrap-icons-1.11.3/chat-left-text.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-left-text.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-left-text.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-left.svg b/app/static/css/bootstrap-icons-1.11.3/chat-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-left.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-quote-fill.svg b/app/static/css/bootstrap-icons-1.11.3/chat-quote-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-quote-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-quote-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-quote.svg b/app/static/css/bootstrap-icons-1.11.3/chat-quote.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-quote.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-quote.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-right-dots-fill.svg b/app/static/css/bootstrap-icons-1.11.3/chat-right-dots-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-right-dots-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-right-dots-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-right-dots.svg b/app/static/css/bootstrap-icons-1.11.3/chat-right-dots.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-right-dots.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-right-dots.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-right-fill.svg b/app/static/css/bootstrap-icons-1.11.3/chat-right-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-right-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-right-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-right-heart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/chat-right-heart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-right-heart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-right-heart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-right-heart.svg b/app/static/css/bootstrap-icons-1.11.3/chat-right-heart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-right-heart.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-right-heart.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-right-quote-fill.svg b/app/static/css/bootstrap-icons-1.11.3/chat-right-quote-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-right-quote-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-right-quote-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-right-quote.svg b/app/static/css/bootstrap-icons-1.11.3/chat-right-quote.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-right-quote.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-right-quote.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-right-text-fill.svg b/app/static/css/bootstrap-icons-1.11.3/chat-right-text-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-right-text-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-right-text-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-right-text.svg b/app/static/css/bootstrap-icons-1.11.3/chat-right-text.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-right-text.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-right-text.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-right.svg b/app/static/css/bootstrap-icons-1.11.3/chat-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-right.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-square-dots-fill.svg b/app/static/css/bootstrap-icons-1.11.3/chat-square-dots-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-square-dots-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-square-dots-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-square-dots.svg b/app/static/css/bootstrap-icons-1.11.3/chat-square-dots.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-square-dots.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-square-dots.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/chat-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-square-heart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/chat-square-heart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-square-heart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-square-heart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-square-heart.svg b/app/static/css/bootstrap-icons-1.11.3/chat-square-heart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-square-heart.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-square-heart.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-square-quote-fill.svg b/app/static/css/bootstrap-icons-1.11.3/chat-square-quote-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-square-quote-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-square-quote-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-square-quote.svg b/app/static/css/bootstrap-icons-1.11.3/chat-square-quote.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-square-quote.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-square-quote.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-square-text-fill.svg b/app/static/css/bootstrap-icons-1.11.3/chat-square-text-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-square-text-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-square-text-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-square-text.svg b/app/static/css/bootstrap-icons-1.11.3/chat-square-text.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-square-text.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-square-text.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-square.svg b/app/static/css/bootstrap-icons-1.11.3/chat-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-square.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-text-fill.svg b/app/static/css/bootstrap-icons-1.11.3/chat-text-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-text-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-text-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat-text.svg b/app/static/css/bootstrap-icons-1.11.3/chat-text.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat-text.svg rename to app/static/css/bootstrap-icons-1.11.3/chat-text.svg diff --git a/static/css/bootstrap-icons-1.11.3/chat.svg b/app/static/css/bootstrap-icons-1.11.3/chat.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chat.svg rename to app/static/css/bootstrap-icons-1.11.3/chat.svg diff --git a/static/css/bootstrap-icons-1.11.3/check-all.svg b/app/static/css/bootstrap-icons-1.11.3/check-all.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/check-all.svg rename to app/static/css/bootstrap-icons-1.11.3/check-all.svg diff --git a/static/css/bootstrap-icons-1.11.3/check-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/check-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/check-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/check-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/check-circle.svg b/app/static/css/bootstrap-icons-1.11.3/check-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/check-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/check-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/check-lg.svg b/app/static/css/bootstrap-icons-1.11.3/check-lg.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/check-lg.svg rename to app/static/css/bootstrap-icons-1.11.3/check-lg.svg diff --git a/static/css/bootstrap-icons-1.11.3/check-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/check-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/check-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/check-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/check-square.svg b/app/static/css/bootstrap-icons-1.11.3/check-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/check-square.svg rename to app/static/css/bootstrap-icons-1.11.3/check-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/check.svg b/app/static/css/bootstrap-icons-1.11.3/check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/check.svg rename to app/static/css/bootstrap-icons-1.11.3/check.svg diff --git a/static/css/bootstrap-icons-1.11.3/check2-all.svg b/app/static/css/bootstrap-icons-1.11.3/check2-all.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/check2-all.svg rename to app/static/css/bootstrap-icons-1.11.3/check2-all.svg diff --git a/static/css/bootstrap-icons-1.11.3/check2-circle.svg b/app/static/css/bootstrap-icons-1.11.3/check2-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/check2-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/check2-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/check2-square.svg b/app/static/css/bootstrap-icons-1.11.3/check2-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/check2-square.svg rename to app/static/css/bootstrap-icons-1.11.3/check2-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/check2.svg b/app/static/css/bootstrap-icons-1.11.3/check2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/check2.svg rename to app/static/css/bootstrap-icons-1.11.3/check2.svg diff --git a/static/css/bootstrap-icons-1.11.3/chevron-bar-contract.svg b/app/static/css/bootstrap-icons-1.11.3/chevron-bar-contract.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chevron-bar-contract.svg rename to app/static/css/bootstrap-icons-1.11.3/chevron-bar-contract.svg diff --git a/static/css/bootstrap-icons-1.11.3/chevron-bar-down.svg b/app/static/css/bootstrap-icons-1.11.3/chevron-bar-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chevron-bar-down.svg rename to app/static/css/bootstrap-icons-1.11.3/chevron-bar-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/chevron-bar-expand.svg b/app/static/css/bootstrap-icons-1.11.3/chevron-bar-expand.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chevron-bar-expand.svg rename to app/static/css/bootstrap-icons-1.11.3/chevron-bar-expand.svg diff --git a/static/css/bootstrap-icons-1.11.3/chevron-bar-left.svg b/app/static/css/bootstrap-icons-1.11.3/chevron-bar-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chevron-bar-left.svg rename to app/static/css/bootstrap-icons-1.11.3/chevron-bar-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/chevron-bar-right.svg b/app/static/css/bootstrap-icons-1.11.3/chevron-bar-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chevron-bar-right.svg rename to app/static/css/bootstrap-icons-1.11.3/chevron-bar-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/chevron-bar-up.svg b/app/static/css/bootstrap-icons-1.11.3/chevron-bar-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chevron-bar-up.svg rename to app/static/css/bootstrap-icons-1.11.3/chevron-bar-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/chevron-compact-down.svg b/app/static/css/bootstrap-icons-1.11.3/chevron-compact-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chevron-compact-down.svg rename to app/static/css/bootstrap-icons-1.11.3/chevron-compact-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/chevron-compact-left.svg b/app/static/css/bootstrap-icons-1.11.3/chevron-compact-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chevron-compact-left.svg rename to app/static/css/bootstrap-icons-1.11.3/chevron-compact-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/chevron-compact-right.svg b/app/static/css/bootstrap-icons-1.11.3/chevron-compact-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chevron-compact-right.svg rename to app/static/css/bootstrap-icons-1.11.3/chevron-compact-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/chevron-compact-up.svg b/app/static/css/bootstrap-icons-1.11.3/chevron-compact-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chevron-compact-up.svg rename to app/static/css/bootstrap-icons-1.11.3/chevron-compact-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/chevron-contract.svg b/app/static/css/bootstrap-icons-1.11.3/chevron-contract.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chevron-contract.svg rename to app/static/css/bootstrap-icons-1.11.3/chevron-contract.svg diff --git a/static/css/bootstrap-icons-1.11.3/chevron-double-down.svg b/app/static/css/bootstrap-icons-1.11.3/chevron-double-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chevron-double-down.svg rename to app/static/css/bootstrap-icons-1.11.3/chevron-double-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/chevron-double-left.svg b/app/static/css/bootstrap-icons-1.11.3/chevron-double-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chevron-double-left.svg rename to app/static/css/bootstrap-icons-1.11.3/chevron-double-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/chevron-double-right.svg b/app/static/css/bootstrap-icons-1.11.3/chevron-double-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chevron-double-right.svg rename to app/static/css/bootstrap-icons-1.11.3/chevron-double-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/chevron-double-up.svg b/app/static/css/bootstrap-icons-1.11.3/chevron-double-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chevron-double-up.svg rename to app/static/css/bootstrap-icons-1.11.3/chevron-double-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/chevron-down.svg b/app/static/css/bootstrap-icons-1.11.3/chevron-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chevron-down.svg rename to app/static/css/bootstrap-icons-1.11.3/chevron-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/chevron-expand.svg b/app/static/css/bootstrap-icons-1.11.3/chevron-expand.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chevron-expand.svg rename to app/static/css/bootstrap-icons-1.11.3/chevron-expand.svg diff --git a/static/css/bootstrap-icons-1.11.3/chevron-left.svg b/app/static/css/bootstrap-icons-1.11.3/chevron-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chevron-left.svg rename to app/static/css/bootstrap-icons-1.11.3/chevron-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/chevron-right.svg b/app/static/css/bootstrap-icons-1.11.3/chevron-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chevron-right.svg rename to app/static/css/bootstrap-icons-1.11.3/chevron-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/chevron-up.svg b/app/static/css/bootstrap-icons-1.11.3/chevron-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/chevron-up.svg rename to app/static/css/bootstrap-icons-1.11.3/chevron-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/circle-half.svg b/app/static/css/bootstrap-icons-1.11.3/circle-half.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/circle-half.svg rename to app/static/css/bootstrap-icons-1.11.3/circle-half.svg diff --git a/static/css/bootstrap-icons-1.11.3/circle-square.svg b/app/static/css/bootstrap-icons-1.11.3/circle-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/circle-square.svg rename to app/static/css/bootstrap-icons-1.11.3/circle-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/circle.svg b/app/static/css/bootstrap-icons-1.11.3/circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/circle.svg rename to app/static/css/bootstrap-icons-1.11.3/circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard-check-fill.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard-check-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard-check-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard-check-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard-check.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard-check.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard-data-fill.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard-data-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard-data-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard-data-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard-data.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard-data.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard-data.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard-data.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard-fill.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard-heart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard-heart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard-heart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard-heart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard-heart.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard-heart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard-heart.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard-heart.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard-minus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard-minus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard-minus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard-minus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard-minus.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard-minus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard-minus.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard-minus.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard-plus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard-plus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard-plus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard-plus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard-plus.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard-plus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard-plus.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard-plus.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard-pulse.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard-pulse.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard-pulse.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard-pulse.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard-x-fill.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard-x-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard-x-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard-x-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard-x.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard-x.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard2-check-fill.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard2-check-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard2-check-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard2-check-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard2-check.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard2-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard2-check.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard2-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard2-data-fill.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard2-data-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard2-data-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard2-data-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard2-data.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard2-data.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard2-data.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard2-data.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard2-fill.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard2-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard2-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard2-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard2-heart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard2-heart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard2-heart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard2-heart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard2-heart.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard2-heart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard2-heart.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard2-heart.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard2-minus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard2-minus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard2-minus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard2-minus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard2-minus.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard2-minus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard2-minus.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard2-minus.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard2-plus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard2-plus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard2-plus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard2-plus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard2-plus.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard2-plus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard2-plus.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard2-plus.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard2-pulse-fill.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard2-pulse-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard2-pulse-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard2-pulse-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard2-pulse.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard2-pulse.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard2-pulse.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard2-pulse.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard2-x-fill.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard2-x-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard2-x-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard2-x-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard2-x.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard2-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard2-x.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard2-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/clipboard2.svg b/app/static/css/bootstrap-icons-1.11.3/clipboard2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clipboard2.svg rename to app/static/css/bootstrap-icons-1.11.3/clipboard2.svg diff --git a/static/css/bootstrap-icons-1.11.3/clock-fill.svg b/app/static/css/bootstrap-icons-1.11.3/clock-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clock-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/clock-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/clock-history.svg b/app/static/css/bootstrap-icons-1.11.3/clock-history.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clock-history.svg rename to app/static/css/bootstrap-icons-1.11.3/clock-history.svg diff --git a/static/css/bootstrap-icons-1.11.3/clock.svg b/app/static/css/bootstrap-icons-1.11.3/clock.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clock.svg rename to app/static/css/bootstrap-icons-1.11.3/clock.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-arrow-down-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-arrow-down-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-arrow-down-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-arrow-down-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-arrow-down.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-arrow-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-arrow-down.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-arrow-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-arrow-up-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-arrow-up-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-arrow-up-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-arrow-up-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-arrow-up.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-arrow-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-arrow-up.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-arrow-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-check-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-check-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-check-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-check-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-check.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-check.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-download-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-download-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-download-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-download-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-download.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-download.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-download.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-download.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-drizzle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-drizzle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-drizzle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-drizzle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-drizzle.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-drizzle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-drizzle.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-drizzle.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-fog-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-fog-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-fog-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-fog-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-fog.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-fog.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-fog.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-fog.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-fog2-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-fog2-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-fog2-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-fog2-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-fog2.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-fog2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-fog2.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-fog2.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-hail-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-hail-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-hail-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-hail-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-hail.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-hail.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-hail.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-hail.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-haze-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-haze-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-haze-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-haze-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-haze.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-haze.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-haze.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-haze.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-haze2-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-haze2-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-haze2-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-haze2-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-haze2.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-haze2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-haze2.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-haze2.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-lightning-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-lightning-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-lightning-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-lightning-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-lightning-rain-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-lightning-rain-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-lightning-rain-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-lightning-rain-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-lightning-rain.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-lightning-rain.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-lightning-rain.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-lightning-rain.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-lightning.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-lightning.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-lightning.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-lightning.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-minus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-minus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-minus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-minus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-minus.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-minus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-minus.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-minus.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-moon-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-moon-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-moon-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-moon-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-moon.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-moon.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-moon.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-moon.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-plus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-plus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-plus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-plus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-plus.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-plus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-plus.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-plus.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-rain-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-rain-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-rain-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-rain-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-rain-heavy-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-rain-heavy-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-rain-heavy-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-rain-heavy-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-rain-heavy.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-rain-heavy.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-rain-heavy.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-rain-heavy.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-rain.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-rain.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-rain.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-rain.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-slash-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-slash-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-slash-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-slash-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-slash.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-slash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-slash.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-slash.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-sleet-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-sleet-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-sleet-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-sleet-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-sleet.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-sleet.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-sleet.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-sleet.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-snow-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-snow-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-snow-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-snow-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-snow.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-snow.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-snow.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-snow.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-sun-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-sun-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-sun-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-sun-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-sun.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-sun.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-sun.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-sun.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-upload-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-upload-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-upload-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-upload-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud-upload.svg b/app/static/css/bootstrap-icons-1.11.3/cloud-upload.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud-upload.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud-upload.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloud.svg b/app/static/css/bootstrap-icons-1.11.3/cloud.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloud.svg rename to app/static/css/bootstrap-icons-1.11.3/cloud.svg diff --git a/static/css/bootstrap-icons-1.11.3/clouds-fill.svg b/app/static/css/bootstrap-icons-1.11.3/clouds-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clouds-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/clouds-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/clouds.svg b/app/static/css/bootstrap-icons-1.11.3/clouds.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/clouds.svg rename to app/static/css/bootstrap-icons-1.11.3/clouds.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloudy-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cloudy-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloudy-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cloudy-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cloudy.svg b/app/static/css/bootstrap-icons-1.11.3/cloudy.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cloudy.svg rename to app/static/css/bootstrap-icons-1.11.3/cloudy.svg diff --git a/static/css/bootstrap-icons-1.11.3/code-slash.svg b/app/static/css/bootstrap-icons-1.11.3/code-slash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/code-slash.svg rename to app/static/css/bootstrap-icons-1.11.3/code-slash.svg diff --git a/static/css/bootstrap-icons-1.11.3/code-square.svg b/app/static/css/bootstrap-icons-1.11.3/code-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/code-square.svg rename to app/static/css/bootstrap-icons-1.11.3/code-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/code.svg b/app/static/css/bootstrap-icons-1.11.3/code.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/code.svg rename to app/static/css/bootstrap-icons-1.11.3/code.svg diff --git a/static/css/bootstrap-icons-1.11.3/coin.svg b/app/static/css/bootstrap-icons-1.11.3/coin.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/coin.svg rename to app/static/css/bootstrap-icons-1.11.3/coin.svg diff --git a/static/css/bootstrap-icons-1.11.3/collection-fill.svg b/app/static/css/bootstrap-icons-1.11.3/collection-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/collection-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/collection-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/collection-play-fill.svg b/app/static/css/bootstrap-icons-1.11.3/collection-play-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/collection-play-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/collection-play-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/collection-play.svg b/app/static/css/bootstrap-icons-1.11.3/collection-play.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/collection-play.svg rename to app/static/css/bootstrap-icons-1.11.3/collection-play.svg diff --git a/static/css/bootstrap-icons-1.11.3/collection.svg b/app/static/css/bootstrap-icons-1.11.3/collection.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/collection.svg rename to app/static/css/bootstrap-icons-1.11.3/collection.svg diff --git a/static/css/bootstrap-icons-1.11.3/columns-gap.svg b/app/static/css/bootstrap-icons-1.11.3/columns-gap.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/columns-gap.svg rename to app/static/css/bootstrap-icons-1.11.3/columns-gap.svg diff --git a/static/css/bootstrap-icons-1.11.3/columns.svg b/app/static/css/bootstrap-icons-1.11.3/columns.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/columns.svg rename to app/static/css/bootstrap-icons-1.11.3/columns.svg diff --git a/static/css/bootstrap-icons-1.11.3/command.svg b/app/static/css/bootstrap-icons-1.11.3/command.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/command.svg rename to app/static/css/bootstrap-icons-1.11.3/command.svg diff --git a/static/css/bootstrap-icons-1.11.3/compass-fill.svg b/app/static/css/bootstrap-icons-1.11.3/compass-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/compass-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/compass-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/compass.svg b/app/static/css/bootstrap-icons-1.11.3/compass.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/compass.svg rename to app/static/css/bootstrap-icons-1.11.3/compass.svg diff --git a/static/css/bootstrap-icons-1.11.3/cone-striped.svg b/app/static/css/bootstrap-icons-1.11.3/cone-striped.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cone-striped.svg rename to app/static/css/bootstrap-icons-1.11.3/cone-striped.svg diff --git a/static/css/bootstrap-icons-1.11.3/cone.svg b/app/static/css/bootstrap-icons-1.11.3/cone.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cone.svg rename to app/static/css/bootstrap-icons-1.11.3/cone.svg diff --git a/static/css/bootstrap-icons-1.11.3/controller.svg b/app/static/css/bootstrap-icons-1.11.3/controller.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/controller.svg rename to app/static/css/bootstrap-icons-1.11.3/controller.svg diff --git a/static/css/bootstrap-icons-1.11.3/cookie.svg b/app/static/css/bootstrap-icons-1.11.3/cookie.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cookie.svg rename to app/static/css/bootstrap-icons-1.11.3/cookie.svg diff --git a/static/css/bootstrap-icons-1.11.3/copy.svg b/app/static/css/bootstrap-icons-1.11.3/copy.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/copy.svg rename to app/static/css/bootstrap-icons-1.11.3/copy.svg diff --git a/static/css/bootstrap-icons-1.11.3/cpu-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cpu-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cpu-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cpu-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cpu.svg b/app/static/css/bootstrap-icons-1.11.3/cpu.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cpu.svg rename to app/static/css/bootstrap-icons-1.11.3/cpu.svg diff --git a/static/css/bootstrap-icons-1.11.3/credit-card-2-back-fill.svg b/app/static/css/bootstrap-icons-1.11.3/credit-card-2-back-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/credit-card-2-back-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/credit-card-2-back-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/credit-card-2-back.svg b/app/static/css/bootstrap-icons-1.11.3/credit-card-2-back.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/credit-card-2-back.svg rename to app/static/css/bootstrap-icons-1.11.3/credit-card-2-back.svg diff --git a/static/css/bootstrap-icons-1.11.3/credit-card-2-front-fill.svg b/app/static/css/bootstrap-icons-1.11.3/credit-card-2-front-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/credit-card-2-front-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/credit-card-2-front-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/credit-card-2-front.svg b/app/static/css/bootstrap-icons-1.11.3/credit-card-2-front.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/credit-card-2-front.svg rename to app/static/css/bootstrap-icons-1.11.3/credit-card-2-front.svg diff --git a/static/css/bootstrap-icons-1.11.3/credit-card-fill.svg b/app/static/css/bootstrap-icons-1.11.3/credit-card-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/credit-card-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/credit-card-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/credit-card.svg b/app/static/css/bootstrap-icons-1.11.3/credit-card.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/credit-card.svg rename to app/static/css/bootstrap-icons-1.11.3/credit-card.svg diff --git a/static/css/bootstrap-icons-1.11.3/crop.svg b/app/static/css/bootstrap-icons-1.11.3/crop.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/crop.svg rename to app/static/css/bootstrap-icons-1.11.3/crop.svg diff --git a/static/css/bootstrap-icons-1.11.3/crosshair.svg b/app/static/css/bootstrap-icons-1.11.3/crosshair.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/crosshair.svg rename to app/static/css/bootstrap-icons-1.11.3/crosshair.svg diff --git a/static/css/bootstrap-icons-1.11.3/crosshair2.svg b/app/static/css/bootstrap-icons-1.11.3/crosshair2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/crosshair2.svg rename to app/static/css/bootstrap-icons-1.11.3/crosshair2.svg diff --git a/static/css/bootstrap-icons-1.11.3/cup-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cup-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cup-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cup-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cup-hot-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cup-hot-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cup-hot-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cup-hot-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cup-hot.svg b/app/static/css/bootstrap-icons-1.11.3/cup-hot.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cup-hot.svg rename to app/static/css/bootstrap-icons-1.11.3/cup-hot.svg diff --git a/static/css/bootstrap-icons-1.11.3/cup-straw.svg b/app/static/css/bootstrap-icons-1.11.3/cup-straw.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cup-straw.svg rename to app/static/css/bootstrap-icons-1.11.3/cup-straw.svg diff --git a/static/css/bootstrap-icons-1.11.3/cup.svg b/app/static/css/bootstrap-icons-1.11.3/cup.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cup.svg rename to app/static/css/bootstrap-icons-1.11.3/cup.svg diff --git a/static/css/bootstrap-icons-1.11.3/currency-bitcoin.svg b/app/static/css/bootstrap-icons-1.11.3/currency-bitcoin.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/currency-bitcoin.svg rename to app/static/css/bootstrap-icons-1.11.3/currency-bitcoin.svg diff --git a/static/css/bootstrap-icons-1.11.3/currency-dollar.svg b/app/static/css/bootstrap-icons-1.11.3/currency-dollar.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/currency-dollar.svg rename to app/static/css/bootstrap-icons-1.11.3/currency-dollar.svg diff --git a/static/css/bootstrap-icons-1.11.3/currency-euro.svg b/app/static/css/bootstrap-icons-1.11.3/currency-euro.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/currency-euro.svg rename to app/static/css/bootstrap-icons-1.11.3/currency-euro.svg diff --git a/static/css/bootstrap-icons-1.11.3/currency-exchange.svg b/app/static/css/bootstrap-icons-1.11.3/currency-exchange.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/currency-exchange.svg rename to app/static/css/bootstrap-icons-1.11.3/currency-exchange.svg diff --git a/static/css/bootstrap-icons-1.11.3/currency-pound.svg b/app/static/css/bootstrap-icons-1.11.3/currency-pound.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/currency-pound.svg rename to app/static/css/bootstrap-icons-1.11.3/currency-pound.svg diff --git a/static/css/bootstrap-icons-1.11.3/currency-rupee.svg b/app/static/css/bootstrap-icons-1.11.3/currency-rupee.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/currency-rupee.svg rename to app/static/css/bootstrap-icons-1.11.3/currency-rupee.svg diff --git a/static/css/bootstrap-icons-1.11.3/currency-yen.svg b/app/static/css/bootstrap-icons-1.11.3/currency-yen.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/currency-yen.svg rename to app/static/css/bootstrap-icons-1.11.3/currency-yen.svg diff --git a/static/css/bootstrap-icons-1.11.3/cursor-fill.svg b/app/static/css/bootstrap-icons-1.11.3/cursor-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cursor-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/cursor-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/cursor-text.svg b/app/static/css/bootstrap-icons-1.11.3/cursor-text.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cursor-text.svg rename to app/static/css/bootstrap-icons-1.11.3/cursor-text.svg diff --git a/static/css/bootstrap-icons-1.11.3/cursor.svg b/app/static/css/bootstrap-icons-1.11.3/cursor.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/cursor.svg rename to app/static/css/bootstrap-icons-1.11.3/cursor.svg diff --git a/static/css/bootstrap-icons-1.11.3/dash-circle-dotted.svg b/app/static/css/bootstrap-icons-1.11.3/dash-circle-dotted.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dash-circle-dotted.svg rename to app/static/css/bootstrap-icons-1.11.3/dash-circle-dotted.svg diff --git a/static/css/bootstrap-icons-1.11.3/dash-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/dash-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dash-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/dash-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/dash-circle.svg b/app/static/css/bootstrap-icons-1.11.3/dash-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dash-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/dash-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/dash-lg.svg b/app/static/css/bootstrap-icons-1.11.3/dash-lg.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dash-lg.svg rename to app/static/css/bootstrap-icons-1.11.3/dash-lg.svg diff --git a/static/css/bootstrap-icons-1.11.3/dash-square-dotted.svg b/app/static/css/bootstrap-icons-1.11.3/dash-square-dotted.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dash-square-dotted.svg rename to app/static/css/bootstrap-icons-1.11.3/dash-square-dotted.svg diff --git a/static/css/bootstrap-icons-1.11.3/dash-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/dash-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dash-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/dash-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/dash-square.svg b/app/static/css/bootstrap-icons-1.11.3/dash-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dash-square.svg rename to app/static/css/bootstrap-icons-1.11.3/dash-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/dash.svg b/app/static/css/bootstrap-icons-1.11.3/dash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dash.svg rename to app/static/css/bootstrap-icons-1.11.3/dash.svg diff --git a/static/css/bootstrap-icons-1.11.3/database-add.svg b/app/static/css/bootstrap-icons-1.11.3/database-add.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/database-add.svg rename to app/static/css/bootstrap-icons-1.11.3/database-add.svg diff --git a/static/css/bootstrap-icons-1.11.3/database-check.svg b/app/static/css/bootstrap-icons-1.11.3/database-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/database-check.svg rename to app/static/css/bootstrap-icons-1.11.3/database-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/database-dash.svg b/app/static/css/bootstrap-icons-1.11.3/database-dash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/database-dash.svg rename to app/static/css/bootstrap-icons-1.11.3/database-dash.svg diff --git a/static/css/bootstrap-icons-1.11.3/database-down.svg b/app/static/css/bootstrap-icons-1.11.3/database-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/database-down.svg rename to app/static/css/bootstrap-icons-1.11.3/database-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/database-exclamation.svg b/app/static/css/bootstrap-icons-1.11.3/database-exclamation.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/database-exclamation.svg rename to app/static/css/bootstrap-icons-1.11.3/database-exclamation.svg diff --git a/static/css/bootstrap-icons-1.11.3/database-fill-add.svg b/app/static/css/bootstrap-icons-1.11.3/database-fill-add.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/database-fill-add.svg rename to app/static/css/bootstrap-icons-1.11.3/database-fill-add.svg diff --git a/static/css/bootstrap-icons-1.11.3/database-fill-check.svg b/app/static/css/bootstrap-icons-1.11.3/database-fill-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/database-fill-check.svg rename to app/static/css/bootstrap-icons-1.11.3/database-fill-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/database-fill-dash.svg b/app/static/css/bootstrap-icons-1.11.3/database-fill-dash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/database-fill-dash.svg rename to app/static/css/bootstrap-icons-1.11.3/database-fill-dash.svg diff --git a/static/css/bootstrap-icons-1.11.3/database-fill-down.svg b/app/static/css/bootstrap-icons-1.11.3/database-fill-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/database-fill-down.svg rename to app/static/css/bootstrap-icons-1.11.3/database-fill-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/database-fill-exclamation.svg b/app/static/css/bootstrap-icons-1.11.3/database-fill-exclamation.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/database-fill-exclamation.svg rename to app/static/css/bootstrap-icons-1.11.3/database-fill-exclamation.svg diff --git a/static/css/bootstrap-icons-1.11.3/database-fill-gear.svg b/app/static/css/bootstrap-icons-1.11.3/database-fill-gear.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/database-fill-gear.svg rename to app/static/css/bootstrap-icons-1.11.3/database-fill-gear.svg diff --git a/static/css/bootstrap-icons-1.11.3/database-fill-lock.svg b/app/static/css/bootstrap-icons-1.11.3/database-fill-lock.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/database-fill-lock.svg rename to app/static/css/bootstrap-icons-1.11.3/database-fill-lock.svg diff --git a/static/css/bootstrap-icons-1.11.3/database-fill-slash.svg b/app/static/css/bootstrap-icons-1.11.3/database-fill-slash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/database-fill-slash.svg rename to app/static/css/bootstrap-icons-1.11.3/database-fill-slash.svg diff --git a/static/css/bootstrap-icons-1.11.3/database-fill-up.svg b/app/static/css/bootstrap-icons-1.11.3/database-fill-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/database-fill-up.svg rename to app/static/css/bootstrap-icons-1.11.3/database-fill-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/database-fill-x.svg b/app/static/css/bootstrap-icons-1.11.3/database-fill-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/database-fill-x.svg rename to app/static/css/bootstrap-icons-1.11.3/database-fill-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/database-fill.svg b/app/static/css/bootstrap-icons-1.11.3/database-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/database-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/database-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/database-gear.svg b/app/static/css/bootstrap-icons-1.11.3/database-gear.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/database-gear.svg rename to app/static/css/bootstrap-icons-1.11.3/database-gear.svg diff --git a/static/css/bootstrap-icons-1.11.3/database-lock.svg b/app/static/css/bootstrap-icons-1.11.3/database-lock.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/database-lock.svg rename to app/static/css/bootstrap-icons-1.11.3/database-lock.svg diff --git a/static/css/bootstrap-icons-1.11.3/database-slash.svg b/app/static/css/bootstrap-icons-1.11.3/database-slash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/database-slash.svg rename to app/static/css/bootstrap-icons-1.11.3/database-slash.svg diff --git a/static/css/bootstrap-icons-1.11.3/database-up.svg b/app/static/css/bootstrap-icons-1.11.3/database-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/database-up.svg rename to app/static/css/bootstrap-icons-1.11.3/database-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/database-x.svg b/app/static/css/bootstrap-icons-1.11.3/database-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/database-x.svg rename to app/static/css/bootstrap-icons-1.11.3/database-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/database.svg b/app/static/css/bootstrap-icons-1.11.3/database.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/database.svg rename to app/static/css/bootstrap-icons-1.11.3/database.svg diff --git a/static/css/bootstrap-icons-1.11.3/device-hdd-fill.svg b/app/static/css/bootstrap-icons-1.11.3/device-hdd-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/device-hdd-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/device-hdd-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/device-hdd.svg b/app/static/css/bootstrap-icons-1.11.3/device-hdd.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/device-hdd.svg rename to app/static/css/bootstrap-icons-1.11.3/device-hdd.svg diff --git a/static/css/bootstrap-icons-1.11.3/device-ssd-fill.svg b/app/static/css/bootstrap-icons-1.11.3/device-ssd-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/device-ssd-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/device-ssd-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/device-ssd.svg b/app/static/css/bootstrap-icons-1.11.3/device-ssd.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/device-ssd.svg rename to app/static/css/bootstrap-icons-1.11.3/device-ssd.svg diff --git a/static/css/bootstrap-icons-1.11.3/diagram-2-fill.svg b/app/static/css/bootstrap-icons-1.11.3/diagram-2-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/diagram-2-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/diagram-2-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/diagram-2.svg b/app/static/css/bootstrap-icons-1.11.3/diagram-2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/diagram-2.svg rename to app/static/css/bootstrap-icons-1.11.3/diagram-2.svg diff --git a/static/css/bootstrap-icons-1.11.3/diagram-3-fill.svg b/app/static/css/bootstrap-icons-1.11.3/diagram-3-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/diagram-3-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/diagram-3-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/diagram-3.svg b/app/static/css/bootstrap-icons-1.11.3/diagram-3.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/diagram-3.svg rename to app/static/css/bootstrap-icons-1.11.3/diagram-3.svg diff --git a/static/css/bootstrap-icons-1.11.3/diamond-fill.svg b/app/static/css/bootstrap-icons-1.11.3/diamond-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/diamond-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/diamond-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/diamond-half.svg b/app/static/css/bootstrap-icons-1.11.3/diamond-half.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/diamond-half.svg rename to app/static/css/bootstrap-icons-1.11.3/diamond-half.svg diff --git a/static/css/bootstrap-icons-1.11.3/diamond.svg b/app/static/css/bootstrap-icons-1.11.3/diamond.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/diamond.svg rename to app/static/css/bootstrap-icons-1.11.3/diamond.svg diff --git a/static/css/bootstrap-icons-1.11.3/dice-1-fill.svg b/app/static/css/bootstrap-icons-1.11.3/dice-1-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dice-1-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/dice-1-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/dice-1.svg b/app/static/css/bootstrap-icons-1.11.3/dice-1.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dice-1.svg rename to app/static/css/bootstrap-icons-1.11.3/dice-1.svg diff --git a/static/css/bootstrap-icons-1.11.3/dice-2-fill.svg b/app/static/css/bootstrap-icons-1.11.3/dice-2-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dice-2-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/dice-2-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/dice-2.svg b/app/static/css/bootstrap-icons-1.11.3/dice-2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dice-2.svg rename to app/static/css/bootstrap-icons-1.11.3/dice-2.svg diff --git a/static/css/bootstrap-icons-1.11.3/dice-3-fill.svg b/app/static/css/bootstrap-icons-1.11.3/dice-3-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dice-3-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/dice-3-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/dice-3.svg b/app/static/css/bootstrap-icons-1.11.3/dice-3.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dice-3.svg rename to app/static/css/bootstrap-icons-1.11.3/dice-3.svg diff --git a/static/css/bootstrap-icons-1.11.3/dice-4-fill.svg b/app/static/css/bootstrap-icons-1.11.3/dice-4-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dice-4-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/dice-4-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/dice-4.svg b/app/static/css/bootstrap-icons-1.11.3/dice-4.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dice-4.svg rename to app/static/css/bootstrap-icons-1.11.3/dice-4.svg diff --git a/static/css/bootstrap-icons-1.11.3/dice-5-fill.svg b/app/static/css/bootstrap-icons-1.11.3/dice-5-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dice-5-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/dice-5-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/dice-5.svg b/app/static/css/bootstrap-icons-1.11.3/dice-5.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dice-5.svg rename to app/static/css/bootstrap-icons-1.11.3/dice-5.svg diff --git a/static/css/bootstrap-icons-1.11.3/dice-6-fill.svg b/app/static/css/bootstrap-icons-1.11.3/dice-6-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dice-6-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/dice-6-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/dice-6.svg b/app/static/css/bootstrap-icons-1.11.3/dice-6.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dice-6.svg rename to app/static/css/bootstrap-icons-1.11.3/dice-6.svg diff --git a/static/css/bootstrap-icons-1.11.3/disc-fill.svg b/app/static/css/bootstrap-icons-1.11.3/disc-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/disc-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/disc-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/disc.svg b/app/static/css/bootstrap-icons-1.11.3/disc.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/disc.svg rename to app/static/css/bootstrap-icons-1.11.3/disc.svg diff --git a/static/css/bootstrap-icons-1.11.3/discord.svg b/app/static/css/bootstrap-icons-1.11.3/discord.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/discord.svg rename to app/static/css/bootstrap-icons-1.11.3/discord.svg diff --git a/static/css/bootstrap-icons-1.11.3/display-fill.svg b/app/static/css/bootstrap-icons-1.11.3/display-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/display-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/display-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/display.svg b/app/static/css/bootstrap-icons-1.11.3/display.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/display.svg rename to app/static/css/bootstrap-icons-1.11.3/display.svg diff --git a/static/css/bootstrap-icons-1.11.3/displayport-fill.svg b/app/static/css/bootstrap-icons-1.11.3/displayport-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/displayport-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/displayport-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/displayport.svg b/app/static/css/bootstrap-icons-1.11.3/displayport.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/displayport.svg rename to app/static/css/bootstrap-icons-1.11.3/displayport.svg diff --git a/static/css/bootstrap-icons-1.11.3/distribute-horizontal.svg b/app/static/css/bootstrap-icons-1.11.3/distribute-horizontal.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/distribute-horizontal.svg rename to app/static/css/bootstrap-icons-1.11.3/distribute-horizontal.svg diff --git a/static/css/bootstrap-icons-1.11.3/distribute-vertical.svg b/app/static/css/bootstrap-icons-1.11.3/distribute-vertical.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/distribute-vertical.svg rename to app/static/css/bootstrap-icons-1.11.3/distribute-vertical.svg diff --git a/static/css/bootstrap-icons-1.11.3/door-closed-fill.svg b/app/static/css/bootstrap-icons-1.11.3/door-closed-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/door-closed-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/door-closed-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/door-closed.svg b/app/static/css/bootstrap-icons-1.11.3/door-closed.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/door-closed.svg rename to app/static/css/bootstrap-icons-1.11.3/door-closed.svg diff --git a/static/css/bootstrap-icons-1.11.3/door-open-fill.svg b/app/static/css/bootstrap-icons-1.11.3/door-open-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/door-open-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/door-open-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/door-open.svg b/app/static/css/bootstrap-icons-1.11.3/door-open.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/door-open.svg rename to app/static/css/bootstrap-icons-1.11.3/door-open.svg diff --git a/static/css/bootstrap-icons-1.11.3/dot.svg b/app/static/css/bootstrap-icons-1.11.3/dot.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dot.svg rename to app/static/css/bootstrap-icons-1.11.3/dot.svg diff --git a/static/css/bootstrap-icons-1.11.3/download.svg b/app/static/css/bootstrap-icons-1.11.3/download.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/download.svg rename to app/static/css/bootstrap-icons-1.11.3/download.svg diff --git a/static/css/bootstrap-icons-1.11.3/dpad-fill.svg b/app/static/css/bootstrap-icons-1.11.3/dpad-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dpad-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/dpad-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/dpad.svg b/app/static/css/bootstrap-icons-1.11.3/dpad.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dpad.svg rename to app/static/css/bootstrap-icons-1.11.3/dpad.svg diff --git a/static/css/bootstrap-icons-1.11.3/dribbble.svg b/app/static/css/bootstrap-icons-1.11.3/dribbble.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dribbble.svg rename to app/static/css/bootstrap-icons-1.11.3/dribbble.svg diff --git a/static/css/bootstrap-icons-1.11.3/dropbox.svg b/app/static/css/bootstrap-icons-1.11.3/dropbox.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/dropbox.svg rename to app/static/css/bootstrap-icons-1.11.3/dropbox.svg diff --git a/static/css/bootstrap-icons-1.11.3/droplet-fill.svg b/app/static/css/bootstrap-icons-1.11.3/droplet-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/droplet-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/droplet-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/droplet-half.svg b/app/static/css/bootstrap-icons-1.11.3/droplet-half.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/droplet-half.svg rename to app/static/css/bootstrap-icons-1.11.3/droplet-half.svg diff --git a/static/css/bootstrap-icons-1.11.3/droplet.svg b/app/static/css/bootstrap-icons-1.11.3/droplet.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/droplet.svg rename to app/static/css/bootstrap-icons-1.11.3/droplet.svg diff --git a/static/css/bootstrap-icons-1.11.3/duffle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/duffle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/duffle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/duffle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/duffle.svg b/app/static/css/bootstrap-icons-1.11.3/duffle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/duffle.svg rename to app/static/css/bootstrap-icons-1.11.3/duffle.svg diff --git a/static/css/bootstrap-icons-1.11.3/ear-fill.svg b/app/static/css/bootstrap-icons-1.11.3/ear-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/ear-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/ear-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/ear.svg b/app/static/css/bootstrap-icons-1.11.3/ear.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/ear.svg rename to app/static/css/bootstrap-icons-1.11.3/ear.svg diff --git a/static/css/bootstrap-icons-1.11.3/earbuds.svg b/app/static/css/bootstrap-icons-1.11.3/earbuds.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/earbuds.svg rename to app/static/css/bootstrap-icons-1.11.3/earbuds.svg diff --git a/static/css/bootstrap-icons-1.11.3/easel-fill.svg b/app/static/css/bootstrap-icons-1.11.3/easel-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/easel-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/easel-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/easel.svg b/app/static/css/bootstrap-icons-1.11.3/easel.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/easel.svg rename to app/static/css/bootstrap-icons-1.11.3/easel.svg diff --git a/static/css/bootstrap-icons-1.11.3/easel2-fill.svg b/app/static/css/bootstrap-icons-1.11.3/easel2-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/easel2-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/easel2-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/easel2.svg b/app/static/css/bootstrap-icons-1.11.3/easel2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/easel2.svg rename to app/static/css/bootstrap-icons-1.11.3/easel2.svg diff --git a/static/css/bootstrap-icons-1.11.3/easel3-fill.svg b/app/static/css/bootstrap-icons-1.11.3/easel3-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/easel3-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/easel3-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/easel3.svg b/app/static/css/bootstrap-icons-1.11.3/easel3.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/easel3.svg rename to app/static/css/bootstrap-icons-1.11.3/easel3.svg diff --git a/static/css/bootstrap-icons-1.11.3/egg-fill.svg b/app/static/css/bootstrap-icons-1.11.3/egg-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/egg-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/egg-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/egg-fried.svg b/app/static/css/bootstrap-icons-1.11.3/egg-fried.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/egg-fried.svg rename to app/static/css/bootstrap-icons-1.11.3/egg-fried.svg diff --git a/static/css/bootstrap-icons-1.11.3/egg.svg b/app/static/css/bootstrap-icons-1.11.3/egg.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/egg.svg rename to app/static/css/bootstrap-icons-1.11.3/egg.svg diff --git a/static/css/bootstrap-icons-1.11.3/eject-fill.svg b/app/static/css/bootstrap-icons-1.11.3/eject-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/eject-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/eject-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/eject.svg b/app/static/css/bootstrap-icons-1.11.3/eject.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/eject.svg rename to app/static/css/bootstrap-icons-1.11.3/eject.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-angry-fill.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-angry-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-angry-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-angry-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-angry.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-angry.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-angry.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-angry.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-astonished-fill.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-astonished-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-astonished-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-astonished-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-astonished.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-astonished.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-astonished.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-astonished.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-dizzy-fill.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-dizzy-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-dizzy-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-dizzy-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-dizzy.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-dizzy.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-dizzy.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-dizzy.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-expressionless-fill.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-expressionless-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-expressionless-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-expressionless-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-expressionless.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-expressionless.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-expressionless.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-expressionless.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-frown-fill.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-frown-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-frown-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-frown-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-frown.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-frown.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-frown.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-frown.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-grimace-fill.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-grimace-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-grimace-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-grimace-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-grimace.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-grimace.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-grimace.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-grimace.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-grin-fill.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-grin-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-grin-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-grin-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-grin.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-grin.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-grin.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-grin.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-heart-eyes-fill.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-heart-eyes-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-heart-eyes-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-heart-eyes-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-heart-eyes.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-heart-eyes.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-heart-eyes.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-heart-eyes.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-kiss-fill.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-kiss-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-kiss-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-kiss-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-kiss.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-kiss.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-kiss.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-kiss.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-laughing-fill.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-laughing-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-laughing-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-laughing-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-laughing.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-laughing.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-laughing.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-laughing.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-neutral-fill.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-neutral-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-neutral-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-neutral-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-neutral.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-neutral.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-neutral.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-neutral.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-smile-fill.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-smile-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-smile-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-smile-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-smile-upside-down-fill.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-smile-upside-down-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-smile-upside-down-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-smile-upside-down-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-smile-upside-down.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-smile-upside-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-smile-upside-down.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-smile-upside-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-smile.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-smile.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-smile.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-smile.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-sunglasses-fill.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-sunglasses-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-sunglasses-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-sunglasses-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-sunglasses.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-sunglasses.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-sunglasses.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-sunglasses.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-surprise-fill.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-surprise-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-surprise-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-surprise-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-surprise.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-surprise.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-surprise.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-surprise.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-tear-fill.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-tear-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-tear-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-tear-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-tear.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-tear.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-tear.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-tear.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-wink-fill.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-wink-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-wink-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-wink-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/emoji-wink.svg b/app/static/css/bootstrap-icons-1.11.3/emoji-wink.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/emoji-wink.svg rename to app/static/css/bootstrap-icons-1.11.3/emoji-wink.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-arrow-down-fill.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-arrow-down-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-arrow-down-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-arrow-down-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-arrow-down.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-arrow-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-arrow-down.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-arrow-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-arrow-up-fill.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-arrow-up-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-arrow-up-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-arrow-up-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-arrow-up.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-arrow-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-arrow-up.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-arrow-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-at-fill.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-at-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-at-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-at-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-at.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-at.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-at.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-at.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-check-fill.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-check-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-check-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-check-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-check.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-check.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-dash-fill.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-dash-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-dash-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-dash-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-dash.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-dash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-dash.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-dash.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-exclamation-fill.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-exclamation-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-exclamation-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-exclamation-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-exclamation.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-exclamation.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-exclamation.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-exclamation.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-fill.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-heart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-heart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-heart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-heart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-heart.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-heart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-heart.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-heart.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-open-fill.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-open-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-open-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-open-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-open-heart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-open-heart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-open-heart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-open-heart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-open-heart.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-open-heart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-open-heart.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-open-heart.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-open.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-open.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-open.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-open.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-paper-fill.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-paper-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-paper-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-paper-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-paper-heart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-paper-heart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-paper-heart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-paper-heart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-paper-heart.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-paper-heart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-paper-heart.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-paper-heart.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-paper.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-paper.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-paper.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-paper.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-plus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-plus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-plus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-plus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-plus.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-plus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-plus.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-plus.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-slash-fill.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-slash-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-slash-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-slash-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-slash.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-slash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-slash.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-slash.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-x-fill.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-x-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-x-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-x-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope-x.svg b/app/static/css/bootstrap-icons-1.11.3/envelope-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope-x.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/envelope.svg b/app/static/css/bootstrap-icons-1.11.3/envelope.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/envelope.svg rename to app/static/css/bootstrap-icons-1.11.3/envelope.svg diff --git a/static/css/bootstrap-icons-1.11.3/eraser-fill.svg b/app/static/css/bootstrap-icons-1.11.3/eraser-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/eraser-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/eraser-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/eraser.svg b/app/static/css/bootstrap-icons-1.11.3/eraser.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/eraser.svg rename to app/static/css/bootstrap-icons-1.11.3/eraser.svg diff --git a/static/css/bootstrap-icons-1.11.3/escape.svg b/app/static/css/bootstrap-icons-1.11.3/escape.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/escape.svg rename to app/static/css/bootstrap-icons-1.11.3/escape.svg diff --git a/static/css/bootstrap-icons-1.11.3/ethernet.svg b/app/static/css/bootstrap-icons-1.11.3/ethernet.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/ethernet.svg rename to app/static/css/bootstrap-icons-1.11.3/ethernet.svg diff --git a/static/css/bootstrap-icons-1.11.3/ev-front-fill.svg b/app/static/css/bootstrap-icons-1.11.3/ev-front-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/ev-front-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/ev-front-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/ev-front.svg b/app/static/css/bootstrap-icons-1.11.3/ev-front.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/ev-front.svg rename to app/static/css/bootstrap-icons-1.11.3/ev-front.svg diff --git a/static/css/bootstrap-icons-1.11.3/ev-station-fill.svg b/app/static/css/bootstrap-icons-1.11.3/ev-station-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/ev-station-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/ev-station-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/ev-station.svg b/app/static/css/bootstrap-icons-1.11.3/ev-station.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/ev-station.svg rename to app/static/css/bootstrap-icons-1.11.3/ev-station.svg diff --git a/static/css/bootstrap-icons-1.11.3/exclamation-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/exclamation-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/exclamation-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/exclamation-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/exclamation-circle.svg b/app/static/css/bootstrap-icons-1.11.3/exclamation-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/exclamation-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/exclamation-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/exclamation-diamond-fill.svg b/app/static/css/bootstrap-icons-1.11.3/exclamation-diamond-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/exclamation-diamond-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/exclamation-diamond-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/exclamation-diamond.svg b/app/static/css/bootstrap-icons-1.11.3/exclamation-diamond.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/exclamation-diamond.svg rename to app/static/css/bootstrap-icons-1.11.3/exclamation-diamond.svg diff --git a/static/css/bootstrap-icons-1.11.3/exclamation-lg.svg b/app/static/css/bootstrap-icons-1.11.3/exclamation-lg.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/exclamation-lg.svg rename to app/static/css/bootstrap-icons-1.11.3/exclamation-lg.svg diff --git a/static/css/bootstrap-icons-1.11.3/exclamation-octagon-fill.svg b/app/static/css/bootstrap-icons-1.11.3/exclamation-octagon-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/exclamation-octagon-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/exclamation-octagon-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/exclamation-octagon.svg b/app/static/css/bootstrap-icons-1.11.3/exclamation-octagon.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/exclamation-octagon.svg rename to app/static/css/bootstrap-icons-1.11.3/exclamation-octagon.svg diff --git a/static/css/bootstrap-icons-1.11.3/exclamation-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/exclamation-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/exclamation-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/exclamation-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/exclamation-square.svg b/app/static/css/bootstrap-icons-1.11.3/exclamation-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/exclamation-square.svg rename to app/static/css/bootstrap-icons-1.11.3/exclamation-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/exclamation-triangle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/exclamation-triangle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/exclamation-triangle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/exclamation-triangle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/exclamation-triangle.svg b/app/static/css/bootstrap-icons-1.11.3/exclamation-triangle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/exclamation-triangle.svg rename to app/static/css/bootstrap-icons-1.11.3/exclamation-triangle.svg diff --git a/static/css/bootstrap-icons-1.11.3/exclamation.svg b/app/static/css/bootstrap-icons-1.11.3/exclamation.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/exclamation.svg rename to app/static/css/bootstrap-icons-1.11.3/exclamation.svg diff --git a/static/css/bootstrap-icons-1.11.3/exclude.svg b/app/static/css/bootstrap-icons-1.11.3/exclude.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/exclude.svg rename to app/static/css/bootstrap-icons-1.11.3/exclude.svg diff --git a/static/css/bootstrap-icons-1.11.3/explicit-fill.svg b/app/static/css/bootstrap-icons-1.11.3/explicit-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/explicit-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/explicit-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/explicit.svg b/app/static/css/bootstrap-icons-1.11.3/explicit.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/explicit.svg rename to app/static/css/bootstrap-icons-1.11.3/explicit.svg diff --git a/static/css/bootstrap-icons-1.11.3/exposure.svg b/app/static/css/bootstrap-icons-1.11.3/exposure.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/exposure.svg rename to app/static/css/bootstrap-icons-1.11.3/exposure.svg diff --git a/static/css/bootstrap-icons-1.11.3/eye-fill.svg b/app/static/css/bootstrap-icons-1.11.3/eye-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/eye-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/eye-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/eye-slash-fill.svg b/app/static/css/bootstrap-icons-1.11.3/eye-slash-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/eye-slash-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/eye-slash-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/eye-slash.svg b/app/static/css/bootstrap-icons-1.11.3/eye-slash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/eye-slash.svg rename to app/static/css/bootstrap-icons-1.11.3/eye-slash.svg diff --git a/static/css/bootstrap-icons-1.11.3/eye.svg b/app/static/css/bootstrap-icons-1.11.3/eye.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/eye.svg rename to app/static/css/bootstrap-icons-1.11.3/eye.svg diff --git a/static/css/bootstrap-icons-1.11.3/eyedropper.svg b/app/static/css/bootstrap-icons-1.11.3/eyedropper.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/eyedropper.svg rename to app/static/css/bootstrap-icons-1.11.3/eyedropper.svg diff --git a/static/css/bootstrap-icons-1.11.3/eyeglasses.svg b/app/static/css/bootstrap-icons-1.11.3/eyeglasses.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/eyeglasses.svg rename to app/static/css/bootstrap-icons-1.11.3/eyeglasses.svg diff --git a/static/css/bootstrap-icons-1.11.3/facebook.svg b/app/static/css/bootstrap-icons-1.11.3/facebook.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/facebook.svg rename to app/static/css/bootstrap-icons-1.11.3/facebook.svg diff --git a/static/css/bootstrap-icons-1.11.3/fan.svg b/app/static/css/bootstrap-icons-1.11.3/fan.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/fan.svg rename to app/static/css/bootstrap-icons-1.11.3/fan.svg diff --git a/static/css/bootstrap-icons-1.11.3/fast-forward-btn-fill.svg b/app/static/css/bootstrap-icons-1.11.3/fast-forward-btn-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/fast-forward-btn-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/fast-forward-btn-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/fast-forward-btn.svg b/app/static/css/bootstrap-icons-1.11.3/fast-forward-btn.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/fast-forward-btn.svg rename to app/static/css/bootstrap-icons-1.11.3/fast-forward-btn.svg diff --git a/static/css/bootstrap-icons-1.11.3/fast-forward-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/fast-forward-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/fast-forward-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/fast-forward-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/fast-forward-circle.svg b/app/static/css/bootstrap-icons-1.11.3/fast-forward-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/fast-forward-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/fast-forward-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/fast-forward-fill.svg b/app/static/css/bootstrap-icons-1.11.3/fast-forward-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/fast-forward-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/fast-forward-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/fast-forward.svg b/app/static/css/bootstrap-icons-1.11.3/fast-forward.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/fast-forward.svg rename to app/static/css/bootstrap-icons-1.11.3/fast-forward.svg diff --git a/static/css/bootstrap-icons-1.11.3/feather.svg b/app/static/css/bootstrap-icons-1.11.3/feather.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/feather.svg rename to app/static/css/bootstrap-icons-1.11.3/feather.svg diff --git a/static/css/bootstrap-icons-1.11.3/feather2.svg b/app/static/css/bootstrap-icons-1.11.3/feather2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/feather2.svg rename to app/static/css/bootstrap-icons-1.11.3/feather2.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-arrow-down-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-arrow-down-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-arrow-down-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-arrow-down-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-arrow-down.svg b/app/static/css/bootstrap-icons-1.11.3/file-arrow-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-arrow-down.svg rename to app/static/css/bootstrap-icons-1.11.3/file-arrow-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-arrow-up-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-arrow-up-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-arrow-up-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-arrow-up-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-arrow-up.svg b/app/static/css/bootstrap-icons-1.11.3/file-arrow-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-arrow-up.svg rename to app/static/css/bootstrap-icons-1.11.3/file-arrow-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-bar-graph-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-bar-graph-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-bar-graph-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-bar-graph-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-bar-graph.svg b/app/static/css/bootstrap-icons-1.11.3/file-bar-graph.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-bar-graph.svg rename to app/static/css/bootstrap-icons-1.11.3/file-bar-graph.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-binary-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-binary-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-binary-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-binary-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-binary.svg b/app/static/css/bootstrap-icons-1.11.3/file-binary.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-binary.svg rename to app/static/css/bootstrap-icons-1.11.3/file-binary.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-break-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-break-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-break-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-break-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-break.svg b/app/static/css/bootstrap-icons-1.11.3/file-break.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-break.svg rename to app/static/css/bootstrap-icons-1.11.3/file-break.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-check-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-check-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-check-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-check-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-check.svg b/app/static/css/bootstrap-icons-1.11.3/file-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-check.svg rename to app/static/css/bootstrap-icons-1.11.3/file-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-code-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-code-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-code-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-code-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-code.svg b/app/static/css/bootstrap-icons-1.11.3/file-code.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-code.svg rename to app/static/css/bootstrap-icons-1.11.3/file-code.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-diff-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-diff-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-diff-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-diff-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-diff.svg b/app/static/css/bootstrap-icons-1.11.3/file-diff.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-diff.svg rename to app/static/css/bootstrap-icons-1.11.3/file-diff.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-arrow-down-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-arrow-down-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-arrow-down-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-arrow-down-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-arrow-down.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-arrow-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-arrow-down.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-arrow-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-arrow-up-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-arrow-up-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-arrow-up-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-arrow-up-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-arrow-up.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-arrow-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-arrow-up.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-arrow-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-bar-graph-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-bar-graph-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-bar-graph-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-bar-graph-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-bar-graph.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-bar-graph.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-bar-graph.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-bar-graph.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-binary-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-binary-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-binary-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-binary-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-binary.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-binary.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-binary.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-binary.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-break-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-break-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-break-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-break-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-break.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-break.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-break.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-break.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-check-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-check-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-check-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-check-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-check.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-check.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-code-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-code-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-code-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-code-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-code.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-code.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-code.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-code.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-diff-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-diff-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-diff-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-diff-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-diff.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-diff.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-diff.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-diff.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-easel-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-easel-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-easel-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-easel-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-easel.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-easel.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-easel.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-easel.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-excel-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-excel-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-excel-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-excel-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-excel.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-excel.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-excel.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-excel.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-font-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-font-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-font-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-font-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-font.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-font.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-font.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-font.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-image-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-image-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-image-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-image-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-image.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-image.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-image.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-image.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-lock-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-lock-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-lock-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-lock-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-lock.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-lock.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-lock.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-lock.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-lock2-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-lock2-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-lock2-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-lock2-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-lock2.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-lock2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-lock2.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-lock2.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-medical-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-medical-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-medical-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-medical-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-medical.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-medical.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-medical.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-medical.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-minus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-minus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-minus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-minus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-minus.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-minus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-minus.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-minus.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-music-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-music-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-music-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-music-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-music.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-music.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-music.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-music.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-pdf-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-pdf-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-pdf-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-pdf-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-pdf.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-pdf.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-pdf.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-pdf.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-person-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-person-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-person-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-person-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-person.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-person.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-person.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-person.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-play-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-play-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-play-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-play-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-play.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-play.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-play.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-play.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-plus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-plus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-plus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-plus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-plus.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-plus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-plus.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-plus.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-post-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-post-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-post-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-post-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-post.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-post.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-post.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-post.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-ppt-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-ppt-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-ppt-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-ppt-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-ppt.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-ppt.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-ppt.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-ppt.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-richtext-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-richtext-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-richtext-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-richtext-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-richtext.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-richtext.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-richtext.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-richtext.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-ruled-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-ruled-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-ruled-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-ruled-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-ruled.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-ruled.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-ruled.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-ruled.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-slides-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-slides-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-slides-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-slides-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-slides.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-slides.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-slides.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-slides.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-spreadsheet-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-spreadsheet-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-spreadsheet-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-spreadsheet-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-spreadsheet.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-spreadsheet.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-spreadsheet.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-spreadsheet.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-text-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-text-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-text-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-text-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-text.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-text.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-text.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-text.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-word-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-word-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-word-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-word-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-word.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-word.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-word.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-word.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-x-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-x-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-x-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-x-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-x.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-x.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-zip-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-zip-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-zip-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-zip-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark-zip.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark-zip.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark-zip.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark-zip.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-earmark.svg b/app/static/css/bootstrap-icons-1.11.3/file-earmark.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-earmark.svg rename to app/static/css/bootstrap-icons-1.11.3/file-earmark.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-easel-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-easel-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-easel-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-easel-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-easel.svg b/app/static/css/bootstrap-icons-1.11.3/file-easel.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-easel.svg rename to app/static/css/bootstrap-icons-1.11.3/file-easel.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-excel-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-excel-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-excel-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-excel-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-excel.svg b/app/static/css/bootstrap-icons-1.11.3/file-excel.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-excel.svg rename to app/static/css/bootstrap-icons-1.11.3/file-excel.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-font-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-font-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-font-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-font-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-font.svg b/app/static/css/bootstrap-icons-1.11.3/file-font.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-font.svg rename to app/static/css/bootstrap-icons-1.11.3/file-font.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-image-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-image-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-image-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-image-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-image.svg b/app/static/css/bootstrap-icons-1.11.3/file-image.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-image.svg rename to app/static/css/bootstrap-icons-1.11.3/file-image.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-lock-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-lock-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-lock-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-lock-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-lock.svg b/app/static/css/bootstrap-icons-1.11.3/file-lock.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-lock.svg rename to app/static/css/bootstrap-icons-1.11.3/file-lock.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-lock2-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-lock2-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-lock2-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-lock2-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-lock2.svg b/app/static/css/bootstrap-icons-1.11.3/file-lock2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-lock2.svg rename to app/static/css/bootstrap-icons-1.11.3/file-lock2.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-medical-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-medical-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-medical-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-medical-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-medical.svg b/app/static/css/bootstrap-icons-1.11.3/file-medical.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-medical.svg rename to app/static/css/bootstrap-icons-1.11.3/file-medical.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-minus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-minus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-minus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-minus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-minus.svg b/app/static/css/bootstrap-icons-1.11.3/file-minus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-minus.svg rename to app/static/css/bootstrap-icons-1.11.3/file-minus.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-music-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-music-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-music-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-music-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-music.svg b/app/static/css/bootstrap-icons-1.11.3/file-music.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-music.svg rename to app/static/css/bootstrap-icons-1.11.3/file-music.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-pdf-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-pdf-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-pdf-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-pdf-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-pdf.svg b/app/static/css/bootstrap-icons-1.11.3/file-pdf.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-pdf.svg rename to app/static/css/bootstrap-icons-1.11.3/file-pdf.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-person-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-person-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-person-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-person-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-person.svg b/app/static/css/bootstrap-icons-1.11.3/file-person.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-person.svg rename to app/static/css/bootstrap-icons-1.11.3/file-person.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-play-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-play-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-play-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-play-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-play.svg b/app/static/css/bootstrap-icons-1.11.3/file-play.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-play.svg rename to app/static/css/bootstrap-icons-1.11.3/file-play.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-plus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-plus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-plus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-plus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-plus.svg b/app/static/css/bootstrap-icons-1.11.3/file-plus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-plus.svg rename to app/static/css/bootstrap-icons-1.11.3/file-plus.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-post-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-post-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-post-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-post-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-post.svg b/app/static/css/bootstrap-icons-1.11.3/file-post.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-post.svg rename to app/static/css/bootstrap-icons-1.11.3/file-post.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-ppt-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-ppt-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-ppt-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-ppt-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-ppt.svg b/app/static/css/bootstrap-icons-1.11.3/file-ppt.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-ppt.svg rename to app/static/css/bootstrap-icons-1.11.3/file-ppt.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-richtext-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-richtext-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-richtext-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-richtext-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-richtext.svg b/app/static/css/bootstrap-icons-1.11.3/file-richtext.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-richtext.svg rename to app/static/css/bootstrap-icons-1.11.3/file-richtext.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-ruled-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-ruled-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-ruled-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-ruled-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-ruled.svg b/app/static/css/bootstrap-icons-1.11.3/file-ruled.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-ruled.svg rename to app/static/css/bootstrap-icons-1.11.3/file-ruled.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-slides-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-slides-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-slides-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-slides-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-slides.svg b/app/static/css/bootstrap-icons-1.11.3/file-slides.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-slides.svg rename to app/static/css/bootstrap-icons-1.11.3/file-slides.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-spreadsheet-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-spreadsheet-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-spreadsheet-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-spreadsheet-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-spreadsheet.svg b/app/static/css/bootstrap-icons-1.11.3/file-spreadsheet.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-spreadsheet.svg rename to app/static/css/bootstrap-icons-1.11.3/file-spreadsheet.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-text-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-text-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-text-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-text-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-text.svg b/app/static/css/bootstrap-icons-1.11.3/file-text.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-text.svg rename to app/static/css/bootstrap-icons-1.11.3/file-text.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-word-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-word-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-word-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-word-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-word.svg b/app/static/css/bootstrap-icons-1.11.3/file-word.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-word.svg rename to app/static/css/bootstrap-icons-1.11.3/file-word.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-x-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-x-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-x-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-x-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-x.svg b/app/static/css/bootstrap-icons-1.11.3/file-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-x.svg rename to app/static/css/bootstrap-icons-1.11.3/file-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-zip-fill.svg b/app/static/css/bootstrap-icons-1.11.3/file-zip-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-zip-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/file-zip-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/file-zip.svg b/app/static/css/bootstrap-icons-1.11.3/file-zip.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file-zip.svg rename to app/static/css/bootstrap-icons-1.11.3/file-zip.svg diff --git a/static/css/bootstrap-icons-1.11.3/file.svg b/app/static/css/bootstrap-icons-1.11.3/file.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/file.svg rename to app/static/css/bootstrap-icons-1.11.3/file.svg diff --git a/static/css/bootstrap-icons-1.11.3/files-alt.svg b/app/static/css/bootstrap-icons-1.11.3/files-alt.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/files-alt.svg rename to app/static/css/bootstrap-icons-1.11.3/files-alt.svg diff --git a/static/css/bootstrap-icons-1.11.3/files.svg b/app/static/css/bootstrap-icons-1.11.3/files.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/files.svg rename to app/static/css/bootstrap-icons-1.11.3/files.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-aac.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-aac.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-aac.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-aac.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-ai.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-ai.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-ai.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-ai.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-bmp.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-bmp.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-bmp.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-bmp.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-cs.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-cs.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-cs.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-cs.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-css.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-css.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-css.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-css.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-csv.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-csv.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-csv.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-csv.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-doc.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-doc.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-doc.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-doc.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-docx.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-docx.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-docx.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-docx.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-exe.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-exe.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-exe.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-exe.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-gif.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-gif.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-gif.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-gif.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-heic.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-heic.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-heic.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-heic.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-html.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-html.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-html.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-html.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-java.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-java.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-java.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-java.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-jpg.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-jpg.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-jpg.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-jpg.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-js.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-js.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-js.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-js.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-json.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-json.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-json.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-json.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-jsx.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-jsx.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-jsx.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-jsx.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-key.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-key.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-key.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-key.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-m4p.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-m4p.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-m4p.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-m4p.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-md.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-md.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-md.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-md.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-mdx.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-mdx.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-mdx.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-mdx.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-mov.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-mov.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-mov.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-mov.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-mp3.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-mp3.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-mp3.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-mp3.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-mp4.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-mp4.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-mp4.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-mp4.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-otf.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-otf.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-otf.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-otf.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-pdf.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-pdf.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-pdf.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-pdf.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-php.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-php.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-php.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-php.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-png.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-png.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-png.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-png.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-ppt.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-ppt.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-ppt.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-ppt.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-pptx.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-pptx.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-pptx.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-pptx.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-psd.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-psd.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-psd.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-psd.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-py.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-py.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-py.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-py.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-raw.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-raw.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-raw.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-raw.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-rb.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-rb.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-rb.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-rb.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-sass.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-sass.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-sass.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-sass.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-scss.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-scss.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-scss.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-scss.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-sh.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-sh.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-sh.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-sh.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-sql.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-sql.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-sql.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-sql.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-svg.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-svg.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-svg.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-svg.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-tiff.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-tiff.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-tiff.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-tiff.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-tsx.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-tsx.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-tsx.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-tsx.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-ttf.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-ttf.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-ttf.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-ttf.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-txt.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-txt.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-txt.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-txt.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-wav.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-wav.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-wav.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-wav.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-woff.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-woff.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-woff.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-woff.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-xls.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-xls.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-xls.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-xls.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-xlsx.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-xlsx.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-xlsx.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-xlsx.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-xml.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-xml.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-xml.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-xml.svg diff --git a/static/css/bootstrap-icons-1.11.3/filetype-yml.svg b/app/static/css/bootstrap-icons-1.11.3/filetype-yml.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filetype-yml.svg rename to app/static/css/bootstrap-icons-1.11.3/filetype-yml.svg diff --git a/static/css/bootstrap-icons-1.11.3/film.svg b/app/static/css/bootstrap-icons-1.11.3/film.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/film.svg rename to app/static/css/bootstrap-icons-1.11.3/film.svg diff --git a/static/css/bootstrap-icons-1.11.3/filter-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/filter-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filter-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/filter-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/filter-circle.svg b/app/static/css/bootstrap-icons-1.11.3/filter-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filter-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/filter-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/filter-left.svg b/app/static/css/bootstrap-icons-1.11.3/filter-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filter-left.svg rename to app/static/css/bootstrap-icons-1.11.3/filter-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/filter-right.svg b/app/static/css/bootstrap-icons-1.11.3/filter-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filter-right.svg rename to app/static/css/bootstrap-icons-1.11.3/filter-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/filter-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/filter-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filter-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/filter-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/filter-square.svg b/app/static/css/bootstrap-icons-1.11.3/filter-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filter-square.svg rename to app/static/css/bootstrap-icons-1.11.3/filter-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/filter.svg b/app/static/css/bootstrap-icons-1.11.3/filter.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/filter.svg rename to app/static/css/bootstrap-icons-1.11.3/filter.svg diff --git a/static/css/bootstrap-icons-1.11.3/fingerprint.svg b/app/static/css/bootstrap-icons-1.11.3/fingerprint.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/fingerprint.svg rename to app/static/css/bootstrap-icons-1.11.3/fingerprint.svg diff --git a/static/css/bootstrap-icons-1.11.3/fire.svg b/app/static/css/bootstrap-icons-1.11.3/fire.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/fire.svg rename to app/static/css/bootstrap-icons-1.11.3/fire.svg diff --git a/static/css/bootstrap-icons-1.11.3/flag-fill.svg b/app/static/css/bootstrap-icons-1.11.3/flag-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/flag-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/flag-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/flag.svg b/app/static/css/bootstrap-icons-1.11.3/flag.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/flag.svg rename to app/static/css/bootstrap-icons-1.11.3/flag.svg diff --git a/static/css/bootstrap-icons-1.11.3/floppy-fill.svg b/app/static/css/bootstrap-icons-1.11.3/floppy-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/floppy-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/floppy-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/floppy.svg b/app/static/css/bootstrap-icons-1.11.3/floppy.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/floppy.svg rename to app/static/css/bootstrap-icons-1.11.3/floppy.svg diff --git a/static/css/bootstrap-icons-1.11.3/floppy2-fill.svg b/app/static/css/bootstrap-icons-1.11.3/floppy2-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/floppy2-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/floppy2-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/floppy2.svg b/app/static/css/bootstrap-icons-1.11.3/floppy2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/floppy2.svg rename to app/static/css/bootstrap-icons-1.11.3/floppy2.svg diff --git a/static/css/bootstrap-icons-1.11.3/flower1.svg b/app/static/css/bootstrap-icons-1.11.3/flower1.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/flower1.svg rename to app/static/css/bootstrap-icons-1.11.3/flower1.svg diff --git a/static/css/bootstrap-icons-1.11.3/flower2.svg b/app/static/css/bootstrap-icons-1.11.3/flower2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/flower2.svg rename to app/static/css/bootstrap-icons-1.11.3/flower2.svg diff --git a/static/css/bootstrap-icons-1.11.3/flower3.svg b/app/static/css/bootstrap-icons-1.11.3/flower3.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/flower3.svg rename to app/static/css/bootstrap-icons-1.11.3/flower3.svg diff --git a/static/css/bootstrap-icons-1.11.3/folder-check.svg b/app/static/css/bootstrap-icons-1.11.3/folder-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/folder-check.svg rename to app/static/css/bootstrap-icons-1.11.3/folder-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/folder-fill.svg b/app/static/css/bootstrap-icons-1.11.3/folder-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/folder-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/folder-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/folder-minus.svg b/app/static/css/bootstrap-icons-1.11.3/folder-minus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/folder-minus.svg rename to app/static/css/bootstrap-icons-1.11.3/folder-minus.svg diff --git a/static/css/bootstrap-icons-1.11.3/folder-plus.svg b/app/static/css/bootstrap-icons-1.11.3/folder-plus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/folder-plus.svg rename to app/static/css/bootstrap-icons-1.11.3/folder-plus.svg diff --git a/static/css/bootstrap-icons-1.11.3/folder-symlink-fill.svg b/app/static/css/bootstrap-icons-1.11.3/folder-symlink-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/folder-symlink-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/folder-symlink-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/folder-symlink.svg b/app/static/css/bootstrap-icons-1.11.3/folder-symlink.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/folder-symlink.svg rename to app/static/css/bootstrap-icons-1.11.3/folder-symlink.svg diff --git a/static/css/bootstrap-icons-1.11.3/folder-x.svg b/app/static/css/bootstrap-icons-1.11.3/folder-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/folder-x.svg rename to app/static/css/bootstrap-icons-1.11.3/folder-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/folder.svg b/app/static/css/bootstrap-icons-1.11.3/folder.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/folder.svg rename to app/static/css/bootstrap-icons-1.11.3/folder.svg diff --git a/static/css/bootstrap-icons-1.11.3/folder2-open.svg b/app/static/css/bootstrap-icons-1.11.3/folder2-open.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/folder2-open.svg rename to app/static/css/bootstrap-icons-1.11.3/folder2-open.svg diff --git a/static/css/bootstrap-icons-1.11.3/folder2.svg b/app/static/css/bootstrap-icons-1.11.3/folder2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/folder2.svg rename to app/static/css/bootstrap-icons-1.11.3/folder2.svg diff --git a/static/css/bootstrap-icons-1.11.3/font/bootstrap-icons.css b/app/static/css/bootstrap-icons-1.11.3/font/bootstrap-icons.css similarity index 99% rename from static/css/bootstrap-icons-1.11.3/font/bootstrap-icons.css rename to app/static/css/bootstrap-icons-1.11.3/font/bootstrap-icons.css index bc84a5f..1f440c9 100644 --- a/static/css/bootstrap-icons-1.11.3/font/bootstrap-icons.css +++ b/app/static/css/bootstrap-icons-1.11.3/font/bootstrap-icons.css @@ -7,8 +7,8 @@ @font-face { font-display: block; font-family: "bootstrap-icons"; - src: url("./fonts/bootstrap-icons.woff2?dd67030699838ea613ee6dbda90effa6") format("woff2"), -url("./fonts/bootstrap-icons.woff?dd67030699838ea613ee6dbda90effa6") format("woff"); + src: url("fonts/bootstrap-icons.woff2?dd67030699838ea613ee6dbda90effa6") format("woff2"), +url("fonts/bootstrap-icons.woff?dd67030699838ea613ee6dbda90effa6") format("woff"); } .bi::before, diff --git a/static/css/bootstrap-icons-1.11.3/font/bootstrap-icons.json b/app/static/css/bootstrap-icons-1.11.3/font/bootstrap-icons.json similarity index 100% rename from static/css/bootstrap-icons-1.11.3/font/bootstrap-icons.json rename to app/static/css/bootstrap-icons-1.11.3/font/bootstrap-icons.json diff --git a/app/static/css/bootstrap-icons-1.11.3/font/bootstrap-icons.min.css b/app/static/css/bootstrap-icons-1.11.3/font/bootstrap-icons.min.css new file mode 100644 index 0000000..ba0f07f --- /dev/null +++ b/app/static/css/bootstrap-icons-1.11.3/font/bootstrap-icons.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap Icons v1.11.3 (https://icons.getbootstrap.com/) + * Copyright 2019-2024 The Bootstrap Authors + * Licensed under MIT (https://github.com/twbs/icons/blob/main/LICENSE) + */@font-face{font-display:block;font-family:bootstrap-icons;src:url("fonts/bootstrap-icons.woff2?dd67030699838ea613ee6dbda90effa6") format("woff2"),url("fonts/bootstrap-icons.woff?dd67030699838ea613ee6dbda90effa6") format("woff")}.bi::before,[class*=" bi-"]::before,[class^=bi-]::before{display:inline-block;font-family:bootstrap-icons!important;font-style:normal;font-weight:400!important;font-variant:normal;text-transform:none;line-height:1;vertical-align:-.125em;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale} .bi-123::before{content:"\f67f"} .bi-alarm-fill::before{content:"\f101"} .bi-alarm::before{content:"\f102"} .bi-align-bottom::before{content:"\f103"} .bi-align-center::before{content:"\f104"} .bi-align-end::before{content:"\f105"} .bi-align-middle::before{content:"\f106"} .bi-align-start::before{content:"\f107"} .bi-align-top::before{content:"\f108"} .bi-alt::before{content:"\f109"} .bi-app-indicator::before{content:"\f10a"} .bi-app::before{content:"\f10b"} .bi-archive-fill::before{content:"\f10c"} .bi-archive::before{content:"\f10d"} .bi-arrow-90deg-down::before{content:"\f10e"} .bi-arrow-90deg-left::before{content:"\f10f"} .bi-arrow-90deg-right::before{content:"\f110"} .bi-arrow-90deg-up::before{content:"\f111"} .bi-arrow-bar-down::before{content:"\f112"} .bi-arrow-bar-left::before{content:"\f113"} .bi-arrow-bar-right::before{content:"\f114"} .bi-arrow-bar-up::before{content:"\f115"} .bi-arrow-clockwise::before{content:"\f116"} .bi-arrow-counterclockwise::before{content:"\f117"} .bi-arrow-down-circle-fill::before{content:"\f118"} .bi-arrow-down-circle::before{content:"\f119"} .bi-arrow-down-left-circle-fill::before{content:"\f11a"} .bi-arrow-down-left-circle::before{content:"\f11b"} .bi-arrow-down-left-square-fill::before{content:"\f11c"} .bi-arrow-down-left-square::before{content:"\f11d"} .bi-arrow-down-left::before{content:"\f11e"} .bi-arrow-down-right-circle-fill::before{content:"\f11f"} .bi-arrow-down-right-circle::before{content:"\f120"} .bi-arrow-down-right-square-fill::before{content:"\f121"} .bi-arrow-down-right-square::before{content:"\f122"} .bi-arrow-down-right::before{content:"\f123"} .bi-arrow-down-short::before{content:"\f124"} .bi-arrow-down-square-fill::before{content:"\f125"} .bi-arrow-down-square::before{content:"\f126"} .bi-arrow-down-up::before{content:"\f127"} .bi-arrow-down::before{content:"\f128"} .bi-arrow-left-circle-fill::before{content:"\f129"} .bi-arrow-left-circle::before{content:"\f12a"} .bi-arrow-left-right::before{content:"\f12b"} .bi-arrow-left-short::before{content:"\f12c"} .bi-arrow-left-square-fill::before{content:"\f12d"} .bi-arrow-left-square::before{content:"\f12e"} .bi-arrow-left::before{content:"\f12f"} .bi-arrow-repeat::before{content:"\f130"} .bi-arrow-return-left::before{content:"\f131"} .bi-arrow-return-right::before{content:"\f132"} .bi-arrow-right-circle-fill::before{content:"\f133"} .bi-arrow-right-circle::before{content:"\f134"} .bi-arrow-right-short::before{content:"\f135"} .bi-arrow-right-square-fill::before{content:"\f136"} .bi-arrow-right-square::before{content:"\f137"} .bi-arrow-right::before{content:"\f138"} .bi-arrow-up-circle-fill::before{content:"\f139"} .bi-arrow-up-circle::before{content:"\f13a"} .bi-arrow-up-left-circle-fill::before{content:"\f13b"} .bi-arrow-up-left-circle::before{content:"\f13c"} .bi-arrow-up-left-square-fill::before{content:"\f13d"} .bi-arrow-up-left-square::before{content:"\f13e"} .bi-arrow-up-left::before{content:"\f13f"} .bi-arrow-up-right-circle-fill::before{content:"\f140"} .bi-arrow-up-right-circle::before{content:"\f141"} .bi-arrow-up-right-square-fill::before{content:"\f142"} .bi-arrow-up-right-square::before{content:"\f143"} .bi-arrow-up-right::before{content:"\f144"} .bi-arrow-up-short::before{content:"\f145"} .bi-arrow-up-square-fill::before{content:"\f146"} .bi-arrow-up-square::before{content:"\f147"} .bi-arrow-up::before{content:"\f148"} .bi-arrows-angle-contract::before{content:"\f149"} .bi-arrows-angle-expand::before{content:"\f14a"} .bi-arrows-collapse::before{content:"\f14b"} .bi-arrows-expand::before{content:"\f14c"} .bi-arrows-fullscreen::before{content:"\f14d"} .bi-arrows-move::before{content:"\f14e"} .bi-aspect-ratio-fill::before{content:"\f14f"} .bi-aspect-ratio::before{content:"\f150"} .bi-asterisk::before{content:"\f151"} .bi-at::before{content:"\f152"} .bi-award-fill::before{content:"\f153"} .bi-award::before{content:"\f154"} .bi-back::before{content:"\f155"} .bi-backspace-fill::before{content:"\f156"} .bi-backspace-reverse-fill::before{content:"\f157"} .bi-backspace-reverse::before{content:"\f158"} .bi-backspace::before{content:"\f159"} .bi-badge-3d-fill::before{content:"\f15a"} .bi-badge-3d::before{content:"\f15b"} .bi-badge-4k-fill::before{content:"\f15c"} .bi-badge-4k::before{content:"\f15d"} .bi-badge-8k-fill::before{content:"\f15e"} .bi-badge-8k::before{content:"\f15f"} .bi-badge-ad-fill::before{content:"\f160"} .bi-badge-ad::before{content:"\f161"} .bi-badge-ar-fill::before{content:"\f162"} .bi-badge-ar::before{content:"\f163"} .bi-badge-cc-fill::before{content:"\f164"} .bi-badge-cc::before{content:"\f165"} .bi-badge-hd-fill::before{content:"\f166"} .bi-badge-hd::before{content:"\f167"} .bi-badge-tm-fill::before{content:"\f168"} .bi-badge-tm::before{content:"\f169"} .bi-badge-vo-fill::before{content:"\f16a"} .bi-badge-vo::before{content:"\f16b"} .bi-badge-vr-fill::before{content:"\f16c"} .bi-badge-vr::before{content:"\f16d"} .bi-badge-wc-fill::before{content:"\f16e"} .bi-badge-wc::before{content:"\f16f"} .bi-bag-check-fill::before{content:"\f170"} .bi-bag-check::before{content:"\f171"} .bi-bag-dash-fill::before{content:"\f172"} .bi-bag-dash::before{content:"\f173"} .bi-bag-fill::before{content:"\f174"} .bi-bag-plus-fill::before{content:"\f175"} .bi-bag-plus::before{content:"\f176"} .bi-bag-x-fill::before{content:"\f177"} .bi-bag-x::before{content:"\f178"} .bi-bag::before{content:"\f179"} .bi-bar-chart-fill::before{content:"\f17a"} .bi-bar-chart-line-fill::before{content:"\f17b"} .bi-bar-chart-line::before{content:"\f17c"} .bi-bar-chart-steps::before{content:"\f17d"} .bi-bar-chart::before{content:"\f17e"} .bi-basket-fill::before{content:"\f17f"} .bi-basket::before{content:"\f180"} .bi-basket2-fill::before{content:"\f181"} .bi-basket2::before{content:"\f182"} .bi-basket3-fill::before{content:"\f183"} .bi-basket3::before{content:"\f184"} .bi-battery-charging::before{content:"\f185"} .bi-battery-full::before{content:"\f186"} .bi-battery-half::before{content:"\f187"} .bi-battery::before{content:"\f188"} .bi-bell-fill::before{content:"\f189"} .bi-bell::before{content:"\f18a"} .bi-bezier::before{content:"\f18b"} .bi-bezier2::before{content:"\f18c"} .bi-bicycle::before{content:"\f18d"} .bi-binoculars-fill::before{content:"\f18e"} .bi-binoculars::before{content:"\f18f"} .bi-blockquote-left::before{content:"\f190"} .bi-blockquote-right::before{content:"\f191"} .bi-book-fill::before{content:"\f192"} .bi-book-half::before{content:"\f193"} .bi-book::before{content:"\f194"} .bi-bookmark-check-fill::before{content:"\f195"} .bi-bookmark-check::before{content:"\f196"} .bi-bookmark-dash-fill::before{content:"\f197"} .bi-bookmark-dash::before{content:"\f198"} .bi-bookmark-fill::before{content:"\f199"} .bi-bookmark-heart-fill::before{content:"\f19a"} .bi-bookmark-heart::before{content:"\f19b"} .bi-bookmark-plus-fill::before{content:"\f19c"} .bi-bookmark-plus::before{content:"\f19d"} .bi-bookmark-star-fill::before{content:"\f19e"} .bi-bookmark-star::before{content:"\f19f"} .bi-bookmark-x-fill::before{content:"\f1a0"} .bi-bookmark-x::before{content:"\f1a1"} .bi-bookmark::before{content:"\f1a2"} .bi-bookmarks-fill::before{content:"\f1a3"} .bi-bookmarks::before{content:"\f1a4"} .bi-bookshelf::before{content:"\f1a5"} .bi-bootstrap-fill::before{content:"\f1a6"} .bi-bootstrap-reboot::before{content:"\f1a7"} .bi-bootstrap::before{content:"\f1a8"} .bi-border-all::before{content:"\f1a9"} .bi-border-bottom::before{content:"\f1aa"} .bi-border-center::before{content:"\f1ab"} .bi-border-inner::before{content:"\f1ac"} .bi-border-left::before{content:"\f1ad"} .bi-border-middle::before{content:"\f1ae"} .bi-border-outer::before{content:"\f1af"} .bi-border-right::before{content:"\f1b0"} .bi-border-style::before{content:"\f1b1"} .bi-border-top::before{content:"\f1b2"} .bi-border-width::before{content:"\f1b3"} .bi-border::before{content:"\f1b4"} .bi-bounding-box-circles::before{content:"\f1b5"} .bi-bounding-box::before{content:"\f1b6"} .bi-box-arrow-down-left::before{content:"\f1b7"} .bi-box-arrow-down-right::before{content:"\f1b8"} .bi-box-arrow-down::before{content:"\f1b9"} .bi-box-arrow-in-down-left::before{content:"\f1ba"} .bi-box-arrow-in-down-right::before{content:"\f1bb"} .bi-box-arrow-in-down::before{content:"\f1bc"} .bi-box-arrow-in-left::before{content:"\f1bd"} .bi-box-arrow-in-right::before{content:"\f1be"} .bi-box-arrow-in-up-left::before{content:"\f1bf"} .bi-box-arrow-in-up-right::before{content:"\f1c0"} .bi-box-arrow-in-up::before{content:"\f1c1"} .bi-box-arrow-left::before{content:"\f1c2"} .bi-box-arrow-right::before{content:"\f1c3"} .bi-box-arrow-up-left::before{content:"\f1c4"} .bi-box-arrow-up-right::before{content:"\f1c5"} .bi-box-arrow-up::before{content:"\f1c6"} .bi-box-seam::before{content:"\f1c7"} .bi-box::before{content:"\f1c8"} .bi-braces::before{content:"\f1c9"} .bi-bricks::before{content:"\f1ca"} .bi-briefcase-fill::before{content:"\f1cb"} .bi-briefcase::before{content:"\f1cc"} .bi-brightness-alt-high-fill::before{content:"\f1cd"} .bi-brightness-alt-high::before{content:"\f1ce"} .bi-brightness-alt-low-fill::before{content:"\f1cf"} .bi-brightness-alt-low::before{content:"\f1d0"} .bi-brightness-high-fill::before{content:"\f1d1"} .bi-brightness-high::before{content:"\f1d2"} .bi-brightness-low-fill::before{content:"\f1d3"} .bi-brightness-low::before{content:"\f1d4"} .bi-broadcast-pin::before{content:"\f1d5"} .bi-broadcast::before{content:"\f1d6"} .bi-brush-fill::before{content:"\f1d7"} .bi-brush::before{content:"\f1d8"} .bi-bucket-fill::before{content:"\f1d9"} .bi-bucket::before{content:"\f1da"} .bi-bug-fill::before{content:"\f1db"} .bi-bug::before{content:"\f1dc"} .bi-building::before{content:"\f1dd"} .bi-bullseye::before{content:"\f1de"} .bi-calculator-fill::before{content:"\f1df"} .bi-calculator::before{content:"\f1e0"} .bi-calendar-check-fill::before{content:"\f1e1"} .bi-calendar-check::before{content:"\f1e2"} .bi-calendar-date-fill::before{content:"\f1e3"} .bi-calendar-date::before{content:"\f1e4"} .bi-calendar-day-fill::before{content:"\f1e5"} .bi-calendar-day::before{content:"\f1e6"} .bi-calendar-event-fill::before{content:"\f1e7"} .bi-calendar-event::before{content:"\f1e8"} .bi-calendar-fill::before{content:"\f1e9"} .bi-calendar-minus-fill::before{content:"\f1ea"} .bi-calendar-minus::before{content:"\f1eb"} .bi-calendar-month-fill::before{content:"\f1ec"} .bi-calendar-month::before{content:"\f1ed"} .bi-calendar-plus-fill::before{content:"\f1ee"} .bi-calendar-plus::before{content:"\f1ef"} .bi-calendar-range-fill::before{content:"\f1f0"} .bi-calendar-range::before{content:"\f1f1"} .bi-calendar-week-fill::before{content:"\f1f2"} .bi-calendar-week::before{content:"\f1f3"} .bi-calendar-x-fill::before{content:"\f1f4"} .bi-calendar-x::before{content:"\f1f5"} .bi-calendar::before{content:"\f1f6"} .bi-calendar2-check-fill::before{content:"\f1f7"} .bi-calendar2-check::before{content:"\f1f8"} .bi-calendar2-date-fill::before{content:"\f1f9"} .bi-calendar2-date::before{content:"\f1fa"} .bi-calendar2-day-fill::before{content:"\f1fb"} .bi-calendar2-day::before{content:"\f1fc"} .bi-calendar2-event-fill::before{content:"\f1fd"} .bi-calendar2-event::before{content:"\f1fe"} .bi-calendar2-fill::before{content:"\f1ff"} .bi-calendar2-minus-fill::before{content:"\f200"} .bi-calendar2-minus::before{content:"\f201"} .bi-calendar2-month-fill::before{content:"\f202"} .bi-calendar2-month::before{content:"\f203"} .bi-calendar2-plus-fill::before{content:"\f204"} .bi-calendar2-plus::before{content:"\f205"} .bi-calendar2-range-fill::before{content:"\f206"} .bi-calendar2-range::before{content:"\f207"} .bi-calendar2-week-fill::before{content:"\f208"} .bi-calendar2-week::before{content:"\f209"} .bi-calendar2-x-fill::before{content:"\f20a"} .bi-calendar2-x::before{content:"\f20b"} .bi-calendar2::before{content:"\f20c"} .bi-calendar3-event-fill::before{content:"\f20d"} .bi-calendar3-event::before{content:"\f20e"} .bi-calendar3-fill::before{content:"\f20f"} .bi-calendar3-range-fill::before{content:"\f210"} .bi-calendar3-range::before{content:"\f211"} .bi-calendar3-week-fill::before{content:"\f212"} .bi-calendar3-week::before{content:"\f213"} .bi-calendar3::before{content:"\f214"} .bi-calendar4-event::before{content:"\f215"} .bi-calendar4-range::before{content:"\f216"} .bi-calendar4-week::before{content:"\f217"} .bi-calendar4::before{content:"\f218"} .bi-camera-fill::before{content:"\f219"} .bi-camera-reels-fill::before{content:"\f21a"} .bi-camera-reels::before{content:"\f21b"} .bi-camera-video-fill::before{content:"\f21c"} .bi-camera-video-off-fill::before{content:"\f21d"} .bi-camera-video-off::before{content:"\f21e"} .bi-camera-video::before{content:"\f21f"} .bi-camera::before{content:"\f220"} .bi-camera2::before{content:"\f221"} .bi-capslock-fill::before{content:"\f222"} .bi-capslock::before{content:"\f223"} .bi-card-checklist::before{content:"\f224"} .bi-card-heading::before{content:"\f225"} .bi-card-image::before{content:"\f226"} .bi-card-list::before{content:"\f227"} .bi-card-text::before{content:"\f228"} .bi-caret-down-fill::before{content:"\f229"} .bi-caret-down-square-fill::before{content:"\f22a"} .bi-caret-down-square::before{content:"\f22b"} .bi-caret-down::before{content:"\f22c"} .bi-caret-left-fill::before{content:"\f22d"} .bi-caret-left-square-fill::before{content:"\f22e"} .bi-caret-left-square::before{content:"\f22f"} .bi-caret-left::before{content:"\f230"} .bi-caret-right-fill::before{content:"\f231"} .bi-caret-right-square-fill::before{content:"\f232"} .bi-caret-right-square::before{content:"\f233"} .bi-caret-right::before{content:"\f234"} .bi-caret-up-fill::before{content:"\f235"} .bi-caret-up-square-fill::before{content:"\f236"} .bi-caret-up-square::before{content:"\f237"} .bi-caret-up::before{content:"\f238"} .bi-cart-check-fill::before{content:"\f239"} .bi-cart-check::before{content:"\f23a"} .bi-cart-dash-fill::before{content:"\f23b"} .bi-cart-dash::before{content:"\f23c"} .bi-cart-fill::before{content:"\f23d"} .bi-cart-plus-fill::before{content:"\f23e"} .bi-cart-plus::before{content:"\f23f"} .bi-cart-x-fill::before{content:"\f240"} .bi-cart-x::before{content:"\f241"} .bi-cart::before{content:"\f242"} .bi-cart2::before{content:"\f243"} .bi-cart3::before{content:"\f244"} .bi-cart4::before{content:"\f245"} .bi-cash-stack::before{content:"\f246"} .bi-cash::before{content:"\f247"} .bi-cast::before{content:"\f248"} .bi-chat-dots-fill::before{content:"\f249"} .bi-chat-dots::before{content:"\f24a"} .bi-chat-fill::before{content:"\f24b"} .bi-chat-left-dots-fill::before{content:"\f24c"} .bi-chat-left-dots::before{content:"\f24d"} .bi-chat-left-fill::before{content:"\f24e"} .bi-chat-left-quote-fill::before{content:"\f24f"} .bi-chat-left-quote::before{content:"\f250"} .bi-chat-left-text-fill::before{content:"\f251"} .bi-chat-left-text::before{content:"\f252"} .bi-chat-left::before{content:"\f253"} .bi-chat-quote-fill::before{content:"\f254"} .bi-chat-quote::before{content:"\f255"} .bi-chat-right-dots-fill::before{content:"\f256"} .bi-chat-right-dots::before{content:"\f257"} .bi-chat-right-fill::before{content:"\f258"} .bi-chat-right-quote-fill::before{content:"\f259"} .bi-chat-right-quote::before{content:"\f25a"} .bi-chat-right-text-fill::before{content:"\f25b"} .bi-chat-right-text::before{content:"\f25c"} .bi-chat-right::before{content:"\f25d"} .bi-chat-square-dots-fill::before{content:"\f25e"} .bi-chat-square-dots::before{content:"\f25f"} .bi-chat-square-fill::before{content:"\f260"} .bi-chat-square-quote-fill::before{content:"\f261"} .bi-chat-square-quote::before{content:"\f262"} .bi-chat-square-text-fill::before{content:"\f263"} .bi-chat-square-text::before{content:"\f264"} .bi-chat-square::before{content:"\f265"} .bi-chat-text-fill::before{content:"\f266"} .bi-chat-text::before{content:"\f267"} .bi-chat::before{content:"\f268"} .bi-check-all::before{content:"\f269"} .bi-check-circle-fill::before{content:"\f26a"} .bi-check-circle::before{content:"\f26b"} .bi-check-square-fill::before{content:"\f26c"} .bi-check-square::before{content:"\f26d"} .bi-check::before{content:"\f26e"} .bi-check2-all::before{content:"\f26f"} .bi-check2-circle::before{content:"\f270"} .bi-check2-square::before{content:"\f271"} .bi-check2::before{content:"\f272"} .bi-chevron-bar-contract::before{content:"\f273"} .bi-chevron-bar-down::before{content:"\f274"} .bi-chevron-bar-expand::before{content:"\f275"} .bi-chevron-bar-left::before{content:"\f276"} .bi-chevron-bar-right::before{content:"\f277"} .bi-chevron-bar-up::before{content:"\f278"} .bi-chevron-compact-down::before{content:"\f279"} .bi-chevron-compact-left::before{content:"\f27a"} .bi-chevron-compact-right::before{content:"\f27b"} .bi-chevron-compact-up::before{content:"\f27c"} .bi-chevron-contract::before{content:"\f27d"} .bi-chevron-double-down::before{content:"\f27e"} .bi-chevron-double-left::before{content:"\f27f"} .bi-chevron-double-right::before{content:"\f280"} .bi-chevron-double-up::before{content:"\f281"} .bi-chevron-down::before{content:"\f282"} .bi-chevron-expand::before{content:"\f283"} .bi-chevron-left::before{content:"\f284"} .bi-chevron-right::before{content:"\f285"} .bi-chevron-up::before{content:"\f286"} .bi-circle-fill::before{content:"\f287"} .bi-circle-half::before{content:"\f288"} .bi-circle-square::before{content:"\f289"} .bi-circle::before{content:"\f28a"} .bi-clipboard-check::before{content:"\f28b"} .bi-clipboard-data::before{content:"\f28c"} .bi-clipboard-minus::before{content:"\f28d"} .bi-clipboard-plus::before{content:"\f28e"} .bi-clipboard-x::before{content:"\f28f"} .bi-clipboard::before{content:"\f290"} .bi-clock-fill::before{content:"\f291"} .bi-clock-history::before{content:"\f292"} .bi-clock::before{content:"\f293"} .bi-cloud-arrow-down-fill::before{content:"\f294"} .bi-cloud-arrow-down::before{content:"\f295"} .bi-cloud-arrow-up-fill::before{content:"\f296"} .bi-cloud-arrow-up::before{content:"\f297"} .bi-cloud-check-fill::before{content:"\f298"} .bi-cloud-check::before{content:"\f299"} .bi-cloud-download-fill::before{content:"\f29a"} .bi-cloud-download::before{content:"\f29b"} .bi-cloud-drizzle-fill::before{content:"\f29c"} .bi-cloud-drizzle::before{content:"\f29d"} .bi-cloud-fill::before{content:"\f29e"} .bi-cloud-fog-fill::before{content:"\f29f"} .bi-cloud-fog::before{content:"\f2a0"} .bi-cloud-fog2-fill::before{content:"\f2a1"} .bi-cloud-fog2::before{content:"\f2a2"} .bi-cloud-hail-fill::before{content:"\f2a3"} .bi-cloud-hail::before{content:"\f2a4"} .bi-cloud-haze-fill::before{content:"\f2a6"} .bi-cloud-haze::before{content:"\f2a7"} .bi-cloud-haze2-fill::before{content:"\f2a8"} .bi-cloud-lightning-fill::before{content:"\f2a9"} .bi-cloud-lightning-rain-fill::before{content:"\f2aa"} .bi-cloud-lightning-rain::before{content:"\f2ab"} .bi-cloud-lightning::before{content:"\f2ac"} .bi-cloud-minus-fill::before{content:"\f2ad"} .bi-cloud-minus::before{content:"\f2ae"} .bi-cloud-moon-fill::before{content:"\f2af"} .bi-cloud-moon::before{content:"\f2b0"} .bi-cloud-plus-fill::before{content:"\f2b1"} .bi-cloud-plus::before{content:"\f2b2"} .bi-cloud-rain-fill::before{content:"\f2b3"} .bi-cloud-rain-heavy-fill::before{content:"\f2b4"} .bi-cloud-rain-heavy::before{content:"\f2b5"} .bi-cloud-rain::before{content:"\f2b6"} .bi-cloud-slash-fill::before{content:"\f2b7"} .bi-cloud-slash::before{content:"\f2b8"} .bi-cloud-sleet-fill::before{content:"\f2b9"} .bi-cloud-sleet::before{content:"\f2ba"} .bi-cloud-snow-fill::before{content:"\f2bb"} .bi-cloud-snow::before{content:"\f2bc"} .bi-cloud-sun-fill::before{content:"\f2bd"} .bi-cloud-sun::before{content:"\f2be"} .bi-cloud-upload-fill::before{content:"\f2bf"} .bi-cloud-upload::before{content:"\f2c0"} .bi-cloud::before{content:"\f2c1"} .bi-clouds-fill::before{content:"\f2c2"} .bi-clouds::before{content:"\f2c3"} .bi-cloudy-fill::before{content:"\f2c4"} .bi-cloudy::before{content:"\f2c5"} .bi-code-slash::before{content:"\f2c6"} .bi-code-square::before{content:"\f2c7"} .bi-code::before{content:"\f2c8"} .bi-collection-fill::before{content:"\f2c9"} .bi-collection-play-fill::before{content:"\f2ca"} .bi-collection-play::before{content:"\f2cb"} .bi-collection::before{content:"\f2cc"} .bi-columns-gap::before{content:"\f2cd"} .bi-columns::before{content:"\f2ce"} .bi-command::before{content:"\f2cf"} .bi-compass-fill::before{content:"\f2d0"} .bi-compass::before{content:"\f2d1"} .bi-cone-striped::before{content:"\f2d2"} .bi-cone::before{content:"\f2d3"} .bi-controller::before{content:"\f2d4"} .bi-cpu-fill::before{content:"\f2d5"} .bi-cpu::before{content:"\f2d6"} .bi-credit-card-2-back-fill::before{content:"\f2d7"} .bi-credit-card-2-back::before{content:"\f2d8"} .bi-credit-card-2-front-fill::before{content:"\f2d9"} .bi-credit-card-2-front::before{content:"\f2da"} .bi-credit-card-fill::before{content:"\f2db"} .bi-credit-card::before{content:"\f2dc"} .bi-crop::before{content:"\f2dd"} .bi-cup-fill::before{content:"\f2de"} .bi-cup-straw::before{content:"\f2df"} .bi-cup::before{content:"\f2e0"} .bi-cursor-fill::before{content:"\f2e1"} .bi-cursor-text::before{content:"\f2e2"} .bi-cursor::before{content:"\f2e3"} .bi-dash-circle-dotted::before{content:"\f2e4"} .bi-dash-circle-fill::before{content:"\f2e5"} .bi-dash-circle::before{content:"\f2e6"} .bi-dash-square-dotted::before{content:"\f2e7"} .bi-dash-square-fill::before{content:"\f2e8"} .bi-dash-square::before{content:"\f2e9"} .bi-dash::before{content:"\f2ea"} .bi-diagram-2-fill::before{content:"\f2eb"} .bi-diagram-2::before{content:"\f2ec"} .bi-diagram-3-fill::before{content:"\f2ed"} .bi-diagram-3::before{content:"\f2ee"} .bi-diamond-fill::before{content:"\f2ef"} .bi-diamond-half::before{content:"\f2f0"} .bi-diamond::before{content:"\f2f1"} .bi-dice-1-fill::before{content:"\f2f2"} .bi-dice-1::before{content:"\f2f3"} .bi-dice-2-fill::before{content:"\f2f4"} .bi-dice-2::before{content:"\f2f5"} .bi-dice-3-fill::before{content:"\f2f6"} .bi-dice-3::before{content:"\f2f7"} .bi-dice-4-fill::before{content:"\f2f8"} .bi-dice-4::before{content:"\f2f9"} .bi-dice-5-fill::before{content:"\f2fa"} .bi-dice-5::before{content:"\f2fb"} .bi-dice-6-fill::before{content:"\f2fc"} .bi-dice-6::before{content:"\f2fd"} .bi-disc-fill::before{content:"\f2fe"} .bi-disc::before{content:"\f2ff"} .bi-discord::before{content:"\f300"} .bi-display-fill::before{content:"\f301"} .bi-display::before{content:"\f302"} .bi-distribute-horizontal::before{content:"\f303"} .bi-distribute-vertical::before{content:"\f304"} .bi-door-closed-fill::before{content:"\f305"} .bi-door-closed::before{content:"\f306"} .bi-door-open-fill::before{content:"\f307"} .bi-door-open::before{content:"\f308"} .bi-dot::before{content:"\f309"} .bi-download::before{content:"\f30a"} .bi-droplet-fill::before{content:"\f30b"} .bi-droplet-half::before{content:"\f30c"} .bi-droplet::before{content:"\f30d"} .bi-earbuds::before{content:"\f30e"} .bi-easel-fill::before{content:"\f30f"} .bi-easel::before{content:"\f310"} .bi-egg-fill::before{content:"\f311"} .bi-egg-fried::before{content:"\f312"} .bi-egg::before{content:"\f313"} .bi-eject-fill::before{content:"\f314"} .bi-eject::before{content:"\f315"} .bi-emoji-angry-fill::before{content:"\f316"} .bi-emoji-angry::before{content:"\f317"} .bi-emoji-dizzy-fill::before{content:"\f318"} .bi-emoji-dizzy::before{content:"\f319"} .bi-emoji-expressionless-fill::before{content:"\f31a"} .bi-emoji-expressionless::before{content:"\f31b"} .bi-emoji-frown-fill::before{content:"\f31c"} .bi-emoji-frown::before{content:"\f31d"} .bi-emoji-heart-eyes-fill::before{content:"\f31e"} .bi-emoji-heart-eyes::before{content:"\f31f"} .bi-emoji-laughing-fill::before{content:"\f320"} .bi-emoji-laughing::before{content:"\f321"} .bi-emoji-neutral-fill::before{content:"\f322"} .bi-emoji-neutral::before{content:"\f323"} .bi-emoji-smile-fill::before{content:"\f324"} .bi-emoji-smile-upside-down-fill::before{content:"\f325"} .bi-emoji-smile-upside-down::before{content:"\f326"} .bi-emoji-smile::before{content:"\f327"} .bi-emoji-sunglasses-fill::before{content:"\f328"} .bi-emoji-sunglasses::before{content:"\f329"} .bi-emoji-wink-fill::before{content:"\f32a"} .bi-emoji-wink::before{content:"\f32b"} .bi-envelope-fill::before{content:"\f32c"} .bi-envelope-open-fill::before{content:"\f32d"} .bi-envelope-open::before{content:"\f32e"} .bi-envelope::before{content:"\f32f"} .bi-eraser-fill::before{content:"\f330"} .bi-eraser::before{content:"\f331"} .bi-exclamation-circle-fill::before{content:"\f332"} .bi-exclamation-circle::before{content:"\f333"} .bi-exclamation-diamond-fill::before{content:"\f334"} .bi-exclamation-diamond::before{content:"\f335"} .bi-exclamation-octagon-fill::before{content:"\f336"} .bi-exclamation-octagon::before{content:"\f337"} .bi-exclamation-square-fill::before{content:"\f338"} .bi-exclamation-square::before{content:"\f339"} .bi-exclamation-triangle-fill::before{content:"\f33a"} .bi-exclamation-triangle::before{content:"\f33b"} .bi-exclamation::before{content:"\f33c"} .bi-exclude::before{content:"\f33d"} .bi-eye-fill::before{content:"\f33e"} .bi-eye-slash-fill::before{content:"\f33f"} .bi-eye-slash::before{content:"\f340"} .bi-eye::before{content:"\f341"} .bi-eyedropper::before{content:"\f342"} .bi-eyeglasses::before{content:"\f343"} .bi-facebook::before{content:"\f344"} .bi-file-arrow-down-fill::before{content:"\f345"} .bi-file-arrow-down::before{content:"\f346"} .bi-file-arrow-up-fill::before{content:"\f347"} .bi-file-arrow-up::before{content:"\f348"} .bi-file-bar-graph-fill::before{content:"\f349"} .bi-file-bar-graph::before{content:"\f34a"} .bi-file-binary-fill::before{content:"\f34b"} .bi-file-binary::before{content:"\f34c"} .bi-file-break-fill::before{content:"\f34d"} .bi-file-break::before{content:"\f34e"} .bi-file-check-fill::before{content:"\f34f"} .bi-file-check::before{content:"\f350"} .bi-file-code-fill::before{content:"\f351"} .bi-file-code::before{content:"\f352"} .bi-file-diff-fill::before{content:"\f353"} .bi-file-diff::before{content:"\f354"} .bi-file-earmark-arrow-down-fill::before{content:"\f355"} .bi-file-earmark-arrow-down::before{content:"\f356"} .bi-file-earmark-arrow-up-fill::before{content:"\f357"} .bi-file-earmark-arrow-up::before{content:"\f358"} .bi-file-earmark-bar-graph-fill::before{content:"\f359"} .bi-file-earmark-bar-graph::before{content:"\f35a"} .bi-file-earmark-binary-fill::before{content:"\f35b"} .bi-file-earmark-binary::before{content:"\f35c"} .bi-file-earmark-break-fill::before{content:"\f35d"} .bi-file-earmark-break::before{content:"\f35e"} .bi-file-earmark-check-fill::before{content:"\f35f"} .bi-file-earmark-check::before{content:"\f360"} .bi-file-earmark-code-fill::before{content:"\f361"} .bi-file-earmark-code::before{content:"\f362"} .bi-file-earmark-diff-fill::before{content:"\f363"} .bi-file-earmark-diff::before{content:"\f364"} .bi-file-earmark-easel-fill::before{content:"\f365"} .bi-file-earmark-easel::before{content:"\f366"} .bi-file-earmark-excel-fill::before{content:"\f367"} .bi-file-earmark-excel::before{content:"\f368"} .bi-file-earmark-fill::before{content:"\f369"} .bi-file-earmark-font-fill::before{content:"\f36a"} .bi-file-earmark-font::before{content:"\f36b"} .bi-file-earmark-image-fill::before{content:"\f36c"} .bi-file-earmark-image::before{content:"\f36d"} .bi-file-earmark-lock-fill::before{content:"\f36e"} .bi-file-earmark-lock::before{content:"\f36f"} .bi-file-earmark-lock2-fill::before{content:"\f370"} .bi-file-earmark-lock2::before{content:"\f371"} .bi-file-earmark-medical-fill::before{content:"\f372"} .bi-file-earmark-medical::before{content:"\f373"} .bi-file-earmark-minus-fill::before{content:"\f374"} .bi-file-earmark-minus::before{content:"\f375"} .bi-file-earmark-music-fill::before{content:"\f376"} .bi-file-earmark-music::before{content:"\f377"} .bi-file-earmark-person-fill::before{content:"\f378"} .bi-file-earmark-person::before{content:"\f379"} .bi-file-earmark-play-fill::before{content:"\f37a"} .bi-file-earmark-play::before{content:"\f37b"} .bi-file-earmark-plus-fill::before{content:"\f37c"} .bi-file-earmark-plus::before{content:"\f37d"} .bi-file-earmark-post-fill::before{content:"\f37e"} .bi-file-earmark-post::before{content:"\f37f"} .bi-file-earmark-ppt-fill::before{content:"\f380"} .bi-file-earmark-ppt::before{content:"\f381"} .bi-file-earmark-richtext-fill::before{content:"\f382"} .bi-file-earmark-richtext::before{content:"\f383"} .bi-file-earmark-ruled-fill::before{content:"\f384"} .bi-file-earmark-ruled::before{content:"\f385"} .bi-file-earmark-slides-fill::before{content:"\f386"} .bi-file-earmark-slides::before{content:"\f387"} .bi-file-earmark-spreadsheet-fill::before{content:"\f388"} .bi-file-earmark-spreadsheet::before{content:"\f389"} .bi-file-earmark-text-fill::before{content:"\f38a"} .bi-file-earmark-text::before{content:"\f38b"} .bi-file-earmark-word-fill::before{content:"\f38c"} .bi-file-earmark-word::before{content:"\f38d"} .bi-file-earmark-x-fill::before{content:"\f38e"} .bi-file-earmark-x::before{content:"\f38f"} .bi-file-earmark-zip-fill::before{content:"\f390"} .bi-file-earmark-zip::before{content:"\f391"} .bi-file-earmark::before{content:"\f392"} .bi-file-easel-fill::before{content:"\f393"} .bi-file-easel::before{content:"\f394"} .bi-file-excel-fill::before{content:"\f395"} .bi-file-excel::before{content:"\f396"} .bi-file-fill::before{content:"\f397"} .bi-file-font-fill::before{content:"\f398"} .bi-file-font::before{content:"\f399"} .bi-file-image-fill::before{content:"\f39a"} .bi-file-image::before{content:"\f39b"} .bi-file-lock-fill::before{content:"\f39c"} .bi-file-lock::before{content:"\f39d"} .bi-file-lock2-fill::before{content:"\f39e"} .bi-file-lock2::before{content:"\f39f"} .bi-file-medical-fill::before{content:"\f3a0"} .bi-file-medical::before{content:"\f3a1"} .bi-file-minus-fill::before{content:"\f3a2"} .bi-file-minus::before{content:"\f3a3"} .bi-file-music-fill::before{content:"\f3a4"} .bi-file-music::before{content:"\f3a5"} .bi-file-person-fill::before{content:"\f3a6"} .bi-file-person::before{content:"\f3a7"} .bi-file-play-fill::before{content:"\f3a8"} .bi-file-play::before{content:"\f3a9"} .bi-file-plus-fill::before{content:"\f3aa"} .bi-file-plus::before{content:"\f3ab"} .bi-file-post-fill::before{content:"\f3ac"} .bi-file-post::before{content:"\f3ad"} .bi-file-ppt-fill::before{content:"\f3ae"} .bi-file-ppt::before{content:"\f3af"} .bi-file-richtext-fill::before{content:"\f3b0"} .bi-file-richtext::before{content:"\f3b1"} .bi-file-ruled-fill::before{content:"\f3b2"} .bi-file-ruled::before{content:"\f3b3"} .bi-file-slides-fill::before{content:"\f3b4"} .bi-file-slides::before{content:"\f3b5"} .bi-file-spreadsheet-fill::before{content:"\f3b6"} .bi-file-spreadsheet::before{content:"\f3b7"} .bi-file-text-fill::before{content:"\f3b8"} .bi-file-text::before{content:"\f3b9"} .bi-file-word-fill::before{content:"\f3ba"} .bi-file-word::before{content:"\f3bb"} .bi-file-x-fill::before{content:"\f3bc"} .bi-file-x::before{content:"\f3bd"} .bi-file-zip-fill::before{content:"\f3be"} .bi-file-zip::before{content:"\f3bf"} .bi-file::before{content:"\f3c0"} .bi-files-alt::before{content:"\f3c1"} .bi-files::before{content:"\f3c2"} .bi-film::before{content:"\f3c3"} .bi-filter-circle-fill::before{content:"\f3c4"} .bi-filter-circle::before{content:"\f3c5"} .bi-filter-left::before{content:"\f3c6"} .bi-filter-right::before{content:"\f3c7"} .bi-filter-square-fill::before{content:"\f3c8"} .bi-filter-square::before{content:"\f3c9"} .bi-filter::before{content:"\f3ca"} .bi-flag-fill::before{content:"\f3cb"} .bi-flag::before{content:"\f3cc"} .bi-flower1::before{content:"\f3cd"} .bi-flower2::before{content:"\f3ce"} .bi-flower3::before{content:"\f3cf"} .bi-folder-check::before{content:"\f3d0"} .bi-folder-fill::before{content:"\f3d1"} .bi-folder-minus::before{content:"\f3d2"} .bi-folder-plus::before{content:"\f3d3"} .bi-folder-symlink-fill::before{content:"\f3d4"} .bi-folder-symlink::before{content:"\f3d5"} .bi-folder-x::before{content:"\f3d6"} .bi-folder::before{content:"\f3d7"} .bi-folder2-open::before{content:"\f3d8"} .bi-folder2::before{content:"\f3d9"} .bi-fonts::before{content:"\f3da"} .bi-forward-fill::before{content:"\f3db"} .bi-forward::before{content:"\f3dc"} .bi-front::before{content:"\f3dd"} .bi-fullscreen-exit::before{content:"\f3de"} .bi-fullscreen::before{content:"\f3df"} .bi-funnel-fill::before{content:"\f3e0"} .bi-funnel::before{content:"\f3e1"} .bi-gear-fill::before{content:"\f3e2"} .bi-gear-wide-connected::before{content:"\f3e3"} .bi-gear-wide::before{content:"\f3e4"} .bi-gear::before{content:"\f3e5"} .bi-gem::before{content:"\f3e6"} .bi-geo-alt-fill::before{content:"\f3e7"} .bi-geo-alt::before{content:"\f3e8"} .bi-geo-fill::before{content:"\f3e9"} .bi-geo::before{content:"\f3ea"} .bi-gift-fill::before{content:"\f3eb"} .bi-gift::before{content:"\f3ec"} .bi-github::before{content:"\f3ed"} .bi-globe::before{content:"\f3ee"} .bi-globe2::before{content:"\f3ef"} .bi-google::before{content:"\f3f0"} .bi-graph-down::before{content:"\f3f1"} .bi-graph-up::before{content:"\f3f2"} .bi-grid-1x2-fill::before{content:"\f3f3"} .bi-grid-1x2::before{content:"\f3f4"} .bi-grid-3x2-gap-fill::before{content:"\f3f5"} .bi-grid-3x2-gap::before{content:"\f3f6"} .bi-grid-3x2::before{content:"\f3f7"} .bi-grid-3x3-gap-fill::before{content:"\f3f8"} .bi-grid-3x3-gap::before{content:"\f3f9"} .bi-grid-3x3::before{content:"\f3fa"} .bi-grid-fill::before{content:"\f3fb"} .bi-grid::before{content:"\f3fc"} .bi-grip-horizontal::before{content:"\f3fd"} .bi-grip-vertical::before{content:"\f3fe"} .bi-hammer::before{content:"\f3ff"} .bi-hand-index-fill::before{content:"\f400"} .bi-hand-index-thumb-fill::before{content:"\f401"} .bi-hand-index-thumb::before{content:"\f402"} .bi-hand-index::before{content:"\f403"} .bi-hand-thumbs-down-fill::before{content:"\f404"} .bi-hand-thumbs-down::before{content:"\f405"} .bi-hand-thumbs-up-fill::before{content:"\f406"} .bi-hand-thumbs-up::before{content:"\f407"} .bi-handbag-fill::before{content:"\f408"} .bi-handbag::before{content:"\f409"} .bi-hash::before{content:"\f40a"} .bi-hdd-fill::before{content:"\f40b"} .bi-hdd-network-fill::before{content:"\f40c"} .bi-hdd-network::before{content:"\f40d"} .bi-hdd-rack-fill::before{content:"\f40e"} .bi-hdd-rack::before{content:"\f40f"} .bi-hdd-stack-fill::before{content:"\f410"} .bi-hdd-stack::before{content:"\f411"} .bi-hdd::before{content:"\f412"} .bi-headphones::before{content:"\f413"} .bi-headset::before{content:"\f414"} .bi-heart-fill::before{content:"\f415"} .bi-heart-half::before{content:"\f416"} .bi-heart::before{content:"\f417"} .bi-heptagon-fill::before{content:"\f418"} .bi-heptagon-half::before{content:"\f419"} .bi-heptagon::before{content:"\f41a"} .bi-hexagon-fill::before{content:"\f41b"} .bi-hexagon-half::before{content:"\f41c"} .bi-hexagon::before{content:"\f41d"} .bi-hourglass-bottom::before{content:"\f41e"} .bi-hourglass-split::before{content:"\f41f"} .bi-hourglass-top::before{content:"\f420"} .bi-hourglass::before{content:"\f421"} .bi-house-door-fill::before{content:"\f422"} .bi-house-door::before{content:"\f423"} .bi-house-fill::before{content:"\f424"} .bi-house::before{content:"\f425"} .bi-hr::before{content:"\f426"} .bi-hurricane::before{content:"\f427"} .bi-image-alt::before{content:"\f428"} .bi-image-fill::before{content:"\f429"} .bi-image::before{content:"\f42a"} .bi-images::before{content:"\f42b"} .bi-inbox-fill::before{content:"\f42c"} .bi-inbox::before{content:"\f42d"} .bi-inboxes-fill::before{content:"\f42e"} .bi-inboxes::before{content:"\f42f"} .bi-info-circle-fill::before{content:"\f430"} .bi-info-circle::before{content:"\f431"} .bi-info-square-fill::before{content:"\f432"} .bi-info-square::before{content:"\f433"} .bi-info::before{content:"\f434"} .bi-input-cursor-text::before{content:"\f435"} .bi-input-cursor::before{content:"\f436"} .bi-instagram::before{content:"\f437"} .bi-intersect::before{content:"\f438"} .bi-journal-album::before{content:"\f439"} .bi-journal-arrow-down::before{content:"\f43a"} .bi-journal-arrow-up::before{content:"\f43b"} .bi-journal-bookmark-fill::before{content:"\f43c"} .bi-journal-bookmark::before{content:"\f43d"} .bi-journal-check::before{content:"\f43e"} .bi-journal-code::before{content:"\f43f"} .bi-journal-medical::before{content:"\f440"} .bi-journal-minus::before{content:"\f441"} .bi-journal-plus::before{content:"\f442"} .bi-journal-richtext::before{content:"\f443"} .bi-journal-text::before{content:"\f444"} .bi-journal-x::before{content:"\f445"} .bi-journal::before{content:"\f446"} .bi-journals::before{content:"\f447"} .bi-joystick::before{content:"\f448"} .bi-justify-left::before{content:"\f449"} .bi-justify-right::before{content:"\f44a"} .bi-justify::before{content:"\f44b"} .bi-kanban-fill::before{content:"\f44c"} .bi-kanban::before{content:"\f44d"} .bi-key-fill::before{content:"\f44e"} .bi-key::before{content:"\f44f"} .bi-keyboard-fill::before{content:"\f450"} .bi-keyboard::before{content:"\f451"} .bi-ladder::before{content:"\f452"} .bi-lamp-fill::before{content:"\f453"} .bi-lamp::before{content:"\f454"} .bi-laptop-fill::before{content:"\f455"} .bi-laptop::before{content:"\f456"} .bi-layer-backward::before{content:"\f457"} .bi-layer-forward::before{content:"\f458"} .bi-layers-fill::before{content:"\f459"} .bi-layers-half::before{content:"\f45a"} .bi-layers::before{content:"\f45b"} .bi-layout-sidebar-inset-reverse::before{content:"\f45c"} .bi-layout-sidebar-inset::before{content:"\f45d"} .bi-layout-sidebar-reverse::before{content:"\f45e"} .bi-layout-sidebar::before{content:"\f45f"} .bi-layout-split::before{content:"\f460"} .bi-layout-text-sidebar-reverse::before{content:"\f461"} .bi-layout-text-sidebar::before{content:"\f462"} .bi-layout-text-window-reverse::before{content:"\f463"} .bi-layout-text-window::before{content:"\f464"} .bi-layout-three-columns::before{content:"\f465"} .bi-layout-wtf::before{content:"\f466"} .bi-life-preserver::before{content:"\f467"} .bi-lightbulb-fill::before{content:"\f468"} .bi-lightbulb-off-fill::before{content:"\f469"} .bi-lightbulb-off::before{content:"\f46a"} .bi-lightbulb::before{content:"\f46b"} .bi-lightning-charge-fill::before{content:"\f46c"} .bi-lightning-charge::before{content:"\f46d"} .bi-lightning-fill::before{content:"\f46e"} .bi-lightning::before{content:"\f46f"} .bi-link-45deg::before{content:"\f470"} .bi-link::before{content:"\f471"} .bi-linkedin::before{content:"\f472"} .bi-list-check::before{content:"\f473"} .bi-list-nested::before{content:"\f474"} .bi-list-ol::before{content:"\f475"} .bi-list-stars::before{content:"\f476"} .bi-list-task::before{content:"\f477"} .bi-list-ul::before{content:"\f478"} .bi-list::before{content:"\f479"} .bi-lock-fill::before{content:"\f47a"} .bi-lock::before{content:"\f47b"} .bi-mailbox::before{content:"\f47c"} .bi-mailbox2::before{content:"\f47d"} .bi-map-fill::before{content:"\f47e"} .bi-map::before{content:"\f47f"} .bi-markdown-fill::before{content:"\f480"} .bi-markdown::before{content:"\f481"} .bi-mask::before{content:"\f482"} .bi-megaphone-fill::before{content:"\f483"} .bi-megaphone::before{content:"\f484"} .bi-menu-app-fill::before{content:"\f485"} .bi-menu-app::before{content:"\f486"} .bi-menu-button-fill::before{content:"\f487"} .bi-menu-button-wide-fill::before{content:"\f488"} .bi-menu-button-wide::before{content:"\f489"} .bi-menu-button::before{content:"\f48a"} .bi-menu-down::before{content:"\f48b"} .bi-menu-up::before{content:"\f48c"} .bi-mic-fill::before{content:"\f48d"} .bi-mic-mute-fill::before{content:"\f48e"} .bi-mic-mute::before{content:"\f48f"} .bi-mic::before{content:"\f490"} .bi-minecart-loaded::before{content:"\f491"} .bi-minecart::before{content:"\f492"} .bi-moisture::before{content:"\f493"} .bi-moon-fill::before{content:"\f494"} .bi-moon-stars-fill::before{content:"\f495"} .bi-moon-stars::before{content:"\f496"} .bi-moon::before{content:"\f497"} .bi-mouse-fill::before{content:"\f498"} .bi-mouse::before{content:"\f499"} .bi-mouse2-fill::before{content:"\f49a"} .bi-mouse2::before{content:"\f49b"} .bi-mouse3-fill::before{content:"\f49c"} .bi-mouse3::before{content:"\f49d"} .bi-music-note-beamed::before{content:"\f49e"} .bi-music-note-list::before{content:"\f49f"} .bi-music-note::before{content:"\f4a0"} .bi-music-player-fill::before{content:"\f4a1"} .bi-music-player::before{content:"\f4a2"} .bi-newspaper::before{content:"\f4a3"} .bi-node-minus-fill::before{content:"\f4a4"} .bi-node-minus::before{content:"\f4a5"} .bi-node-plus-fill::before{content:"\f4a6"} .bi-node-plus::before{content:"\f4a7"} .bi-nut-fill::before{content:"\f4a8"} .bi-nut::before{content:"\f4a9"} .bi-octagon-fill::before{content:"\f4aa"} .bi-octagon-half::before{content:"\f4ab"} .bi-octagon::before{content:"\f4ac"} .bi-option::before{content:"\f4ad"} .bi-outlet::before{content:"\f4ae"} .bi-paint-bucket::before{content:"\f4af"} .bi-palette-fill::before{content:"\f4b0"} .bi-palette::before{content:"\f4b1"} .bi-palette2::before{content:"\f4b2"} .bi-paperclip::before{content:"\f4b3"} .bi-paragraph::before{content:"\f4b4"} .bi-patch-check-fill::before{content:"\f4b5"} .bi-patch-check::before{content:"\f4b6"} .bi-patch-exclamation-fill::before{content:"\f4b7"} .bi-patch-exclamation::before{content:"\f4b8"} .bi-patch-minus-fill::before{content:"\f4b9"} .bi-patch-minus::before{content:"\f4ba"} .bi-patch-plus-fill::before{content:"\f4bb"} .bi-patch-plus::before{content:"\f4bc"} .bi-patch-question-fill::before{content:"\f4bd"} .bi-patch-question::before{content:"\f4be"} .bi-pause-btn-fill::before{content:"\f4bf"} .bi-pause-btn::before{content:"\f4c0"} .bi-pause-circle-fill::before{content:"\f4c1"} .bi-pause-circle::before{content:"\f4c2"} .bi-pause-fill::before{content:"\f4c3"} .bi-pause::before{content:"\f4c4"} .bi-peace-fill::before{content:"\f4c5"} .bi-peace::before{content:"\f4c6"} .bi-pen-fill::before{content:"\f4c7"} .bi-pen::before{content:"\f4c8"} .bi-pencil-fill::before{content:"\f4c9"} .bi-pencil-square::before{content:"\f4ca"} .bi-pencil::before{content:"\f4cb"} .bi-pentagon-fill::before{content:"\f4cc"} .bi-pentagon-half::before{content:"\f4cd"} .bi-pentagon::before{content:"\f4ce"} .bi-people-fill::before{content:"\f4cf"} .bi-people::before{content:"\f4d0"} .bi-percent::before{content:"\f4d1"} .bi-person-badge-fill::before{content:"\f4d2"} .bi-person-badge::before{content:"\f4d3"} .bi-person-bounding-box::before{content:"\f4d4"} .bi-person-check-fill::before{content:"\f4d5"} .bi-person-check::before{content:"\f4d6"} .bi-person-circle::before{content:"\f4d7"} .bi-person-dash-fill::before{content:"\f4d8"} .bi-person-dash::before{content:"\f4d9"} .bi-person-fill::before{content:"\f4da"} .bi-person-lines-fill::before{content:"\f4db"} .bi-person-plus-fill::before{content:"\f4dc"} .bi-person-plus::before{content:"\f4dd"} .bi-person-square::before{content:"\f4de"} .bi-person-x-fill::before{content:"\f4df"} .bi-person-x::before{content:"\f4e0"} .bi-person::before{content:"\f4e1"} .bi-phone-fill::before{content:"\f4e2"} .bi-phone-landscape-fill::before{content:"\f4e3"} .bi-phone-landscape::before{content:"\f4e4"} .bi-phone-vibrate-fill::before{content:"\f4e5"} .bi-phone-vibrate::before{content:"\f4e6"} .bi-phone::before{content:"\f4e7"} .bi-pie-chart-fill::before{content:"\f4e8"} .bi-pie-chart::before{content:"\f4e9"} .bi-pin-angle-fill::before{content:"\f4ea"} .bi-pin-angle::before{content:"\f4eb"} .bi-pin-fill::before{content:"\f4ec"} .bi-pin::before{content:"\f4ed"} .bi-pip-fill::before{content:"\f4ee"} .bi-pip::before{content:"\f4ef"} .bi-play-btn-fill::before{content:"\f4f0"} .bi-play-btn::before{content:"\f4f1"} .bi-play-circle-fill::before{content:"\f4f2"} .bi-play-circle::before{content:"\f4f3"} .bi-play-fill::before{content:"\f4f4"} .bi-play::before{content:"\f4f5"} .bi-plug-fill::before{content:"\f4f6"} .bi-plug::before{content:"\f4f7"} .bi-plus-circle-dotted::before{content:"\f4f8"} .bi-plus-circle-fill::before{content:"\f4f9"} .bi-plus-circle::before{content:"\f4fa"} .bi-plus-square-dotted::before{content:"\f4fb"} .bi-plus-square-fill::before{content:"\f4fc"} .bi-plus-square::before{content:"\f4fd"} .bi-plus::before{content:"\f4fe"} .bi-power::before{content:"\f4ff"} .bi-printer-fill::before{content:"\f500"} .bi-printer::before{content:"\f501"} .bi-puzzle-fill::before{content:"\f502"} .bi-puzzle::before{content:"\f503"} .bi-question-circle-fill::before{content:"\f504"} .bi-question-circle::before{content:"\f505"} .bi-question-diamond-fill::before{content:"\f506"} .bi-question-diamond::before{content:"\f507"} .bi-question-octagon-fill::before{content:"\f508"} .bi-question-octagon::before{content:"\f509"} .bi-question-square-fill::before{content:"\f50a"} .bi-question-square::before{content:"\f50b"} .bi-question::before{content:"\f50c"} .bi-rainbow::before{content:"\f50d"} .bi-receipt-cutoff::before{content:"\f50e"} .bi-receipt::before{content:"\f50f"} .bi-reception-0::before{content:"\f510"} .bi-reception-1::before{content:"\f511"} .bi-reception-2::before{content:"\f512"} .bi-reception-3::before{content:"\f513"} .bi-reception-4::before{content:"\f514"} .bi-record-btn-fill::before{content:"\f515"} .bi-record-btn::before{content:"\f516"} .bi-record-circle-fill::before{content:"\f517"} .bi-record-circle::before{content:"\f518"} .bi-record-fill::before{content:"\f519"} .bi-record::before{content:"\f51a"} .bi-record2-fill::before{content:"\f51b"} .bi-record2::before{content:"\f51c"} .bi-reply-all-fill::before{content:"\f51d"} .bi-reply-all::before{content:"\f51e"} .bi-reply-fill::before{content:"\f51f"} .bi-reply::before{content:"\f520"} .bi-rss-fill::before{content:"\f521"} .bi-rss::before{content:"\f522"} .bi-rulers::before{content:"\f523"} .bi-save-fill::before{content:"\f524"} .bi-save::before{content:"\f525"} .bi-save2-fill::before{content:"\f526"} .bi-save2::before{content:"\f527"} .bi-scissors::before{content:"\f528"} .bi-screwdriver::before{content:"\f529"} .bi-search::before{content:"\f52a"} .bi-segmented-nav::before{content:"\f52b"} .bi-server::before{content:"\f52c"} .bi-share-fill::before{content:"\f52d"} .bi-share::before{content:"\f52e"} .bi-shield-check::before{content:"\f52f"} .bi-shield-exclamation::before{content:"\f530"} .bi-shield-fill-check::before{content:"\f531"} .bi-shield-fill-exclamation::before{content:"\f532"} .bi-shield-fill-minus::before{content:"\f533"} .bi-shield-fill-plus::before{content:"\f534"} .bi-shield-fill-x::before{content:"\f535"} .bi-shield-fill::before{content:"\f536"} .bi-shield-lock-fill::before{content:"\f537"} .bi-shield-lock::before{content:"\f538"} .bi-shield-minus::before{content:"\f539"} .bi-shield-plus::before{content:"\f53a"} .bi-shield-shaded::before{content:"\f53b"} .bi-shield-slash-fill::before{content:"\f53c"} .bi-shield-slash::before{content:"\f53d"} .bi-shield-x::before{content:"\f53e"} .bi-shield::before{content:"\f53f"} .bi-shift-fill::before{content:"\f540"} .bi-shift::before{content:"\f541"} .bi-shop-window::before{content:"\f542"} .bi-shop::before{content:"\f543"} .bi-shuffle::before{content:"\f544"} .bi-signpost-2-fill::before{content:"\f545"} .bi-signpost-2::before{content:"\f546"} .bi-signpost-fill::before{content:"\f547"} .bi-signpost-split-fill::before{content:"\f548"} .bi-signpost-split::before{content:"\f549"} .bi-signpost::before{content:"\f54a"} .bi-sim-fill::before{content:"\f54b"} .bi-sim::before{content:"\f54c"} .bi-skip-backward-btn-fill::before{content:"\f54d"} .bi-skip-backward-btn::before{content:"\f54e"} .bi-skip-backward-circle-fill::before{content:"\f54f"} .bi-skip-backward-circle::before{content:"\f550"} .bi-skip-backward-fill::before{content:"\f551"} .bi-skip-backward::before{content:"\f552"} .bi-skip-end-btn-fill::before{content:"\f553"} .bi-skip-end-btn::before{content:"\f554"} .bi-skip-end-circle-fill::before{content:"\f555"} .bi-skip-end-circle::before{content:"\f556"} .bi-skip-end-fill::before{content:"\f557"} .bi-skip-end::before{content:"\f558"} .bi-skip-forward-btn-fill::before{content:"\f559"} .bi-skip-forward-btn::before{content:"\f55a"} .bi-skip-forward-circle-fill::before{content:"\f55b"} .bi-skip-forward-circle::before{content:"\f55c"} .bi-skip-forward-fill::before{content:"\f55d"} .bi-skip-forward::before{content:"\f55e"} .bi-skip-start-btn-fill::before{content:"\f55f"} .bi-skip-start-btn::before{content:"\f560"} .bi-skip-start-circle-fill::before{content:"\f561"} .bi-skip-start-circle::before{content:"\f562"} .bi-skip-start-fill::before{content:"\f563"} .bi-skip-start::before{content:"\f564"} .bi-slack::before{content:"\f565"} .bi-slash-circle-fill::before{content:"\f566"} .bi-slash-circle::before{content:"\f567"} .bi-slash-square-fill::before{content:"\f568"} .bi-slash-square::before{content:"\f569"} .bi-slash::before{content:"\f56a"} .bi-sliders::before{content:"\f56b"} .bi-smartwatch::before{content:"\f56c"} .bi-snow::before{content:"\f56d"} .bi-snow2::before{content:"\f56e"} .bi-snow3::before{content:"\f56f"} .bi-sort-alpha-down-alt::before{content:"\f570"} .bi-sort-alpha-down::before{content:"\f571"} .bi-sort-alpha-up-alt::before{content:"\f572"} .bi-sort-alpha-up::before{content:"\f573"} .bi-sort-down-alt::before{content:"\f574"} .bi-sort-down::before{content:"\f575"} .bi-sort-numeric-down-alt::before{content:"\f576"} .bi-sort-numeric-down::before{content:"\f577"} .bi-sort-numeric-up-alt::before{content:"\f578"} .bi-sort-numeric-up::before{content:"\f579"} .bi-sort-up-alt::before{content:"\f57a"} .bi-sort-up::before{content:"\f57b"} .bi-soundwave::before{content:"\f57c"} .bi-speaker-fill::before{content:"\f57d"} .bi-speaker::before{content:"\f57e"} .bi-speedometer::before{content:"\f57f"} .bi-speedometer2::before{content:"\f580"} .bi-spellcheck::before{content:"\f581"} .bi-square-fill::before{content:"\f582"} .bi-square-half::before{content:"\f583"} .bi-square::before{content:"\f584"} .bi-stack::before{content:"\f585"} .bi-star-fill::before{content:"\f586"} .bi-star-half::before{content:"\f587"} .bi-star::before{content:"\f588"} .bi-stars::before{content:"\f589"} .bi-stickies-fill::before{content:"\f58a"} .bi-stickies::before{content:"\f58b"} .bi-sticky-fill::before{content:"\f58c"} .bi-sticky::before{content:"\f58d"} .bi-stop-btn-fill::before{content:"\f58e"} .bi-stop-btn::before{content:"\f58f"} .bi-stop-circle-fill::before{content:"\f590"} .bi-stop-circle::before{content:"\f591"} .bi-stop-fill::before{content:"\f592"} .bi-stop::before{content:"\f593"} .bi-stoplights-fill::before{content:"\f594"} .bi-stoplights::before{content:"\f595"} .bi-stopwatch-fill::before{content:"\f596"} .bi-stopwatch::before{content:"\f597"} .bi-subtract::before{content:"\f598"} .bi-suit-club-fill::before{content:"\f599"} .bi-suit-club::before{content:"\f59a"} .bi-suit-diamond-fill::before{content:"\f59b"} .bi-suit-diamond::before{content:"\f59c"} .bi-suit-heart-fill::before{content:"\f59d"} .bi-suit-heart::before{content:"\f59e"} .bi-suit-spade-fill::before{content:"\f59f"} .bi-suit-spade::before{content:"\f5a0"} .bi-sun-fill::before{content:"\f5a1"} .bi-sun::before{content:"\f5a2"} .bi-sunglasses::before{content:"\f5a3"} .bi-sunrise-fill::before{content:"\f5a4"} .bi-sunrise::before{content:"\f5a5"} .bi-sunset-fill::before{content:"\f5a6"} .bi-sunset::before{content:"\f5a7"} .bi-symmetry-horizontal::before{content:"\f5a8"} .bi-symmetry-vertical::before{content:"\f5a9"} .bi-table::before{content:"\f5aa"} .bi-tablet-fill::before{content:"\f5ab"} .bi-tablet-landscape-fill::before{content:"\f5ac"} .bi-tablet-landscape::before{content:"\f5ad"} .bi-tablet::before{content:"\f5ae"} .bi-tag-fill::before{content:"\f5af"} .bi-tag::before{content:"\f5b0"} .bi-tags-fill::before{content:"\f5b1"} .bi-tags::before{content:"\f5b2"} .bi-telegram::before{content:"\f5b3"} .bi-telephone-fill::before{content:"\f5b4"} .bi-telephone-forward-fill::before{content:"\f5b5"} .bi-telephone-forward::before{content:"\f5b6"} .bi-telephone-inbound-fill::before{content:"\f5b7"} .bi-telephone-inbound::before{content:"\f5b8"} .bi-telephone-minus-fill::before{content:"\f5b9"} .bi-telephone-minus::before{content:"\f5ba"} .bi-telephone-outbound-fill::before{content:"\f5bb"} .bi-telephone-outbound::before{content:"\f5bc"} .bi-telephone-plus-fill::before{content:"\f5bd"} .bi-telephone-plus::before{content:"\f5be"} .bi-telephone-x-fill::before{content:"\f5bf"} .bi-telephone-x::before{content:"\f5c0"} .bi-telephone::before{content:"\f5c1"} .bi-terminal-fill::before{content:"\f5c2"} .bi-terminal::before{content:"\f5c3"} .bi-text-center::before{content:"\f5c4"} .bi-text-indent-left::before{content:"\f5c5"} .bi-text-indent-right::before{content:"\f5c6"} .bi-text-left::before{content:"\f5c7"} .bi-text-paragraph::before{content:"\f5c8"} .bi-text-right::before{content:"\f5c9"} .bi-textarea-resize::before{content:"\f5ca"} .bi-textarea-t::before{content:"\f5cb"} .bi-textarea::before{content:"\f5cc"} .bi-thermometer-half::before{content:"\f5cd"} .bi-thermometer-high::before{content:"\f5ce"} .bi-thermometer-low::before{content:"\f5cf"} .bi-thermometer-snow::before{content:"\f5d0"} .bi-thermometer-sun::before{content:"\f5d1"} .bi-thermometer::before{content:"\f5d2"} .bi-three-dots-vertical::before{content:"\f5d3"} .bi-three-dots::before{content:"\f5d4"} .bi-toggle-off::before{content:"\f5d5"} .bi-toggle-on::before{content:"\f5d6"} .bi-toggle2-off::before{content:"\f5d7"} .bi-toggle2-on::before{content:"\f5d8"} .bi-toggles::before{content:"\f5d9"} .bi-toggles2::before{content:"\f5da"} .bi-tools::before{content:"\f5db"} .bi-tornado::before{content:"\f5dc"} .bi-trash-fill::before{content:"\f5dd"} .bi-trash::before{content:"\f5de"} .bi-trash2-fill::before{content:"\f5df"} .bi-trash2::before{content:"\f5e0"} .bi-tree-fill::before{content:"\f5e1"} .bi-tree::before{content:"\f5e2"} .bi-triangle-fill::before{content:"\f5e3"} .bi-triangle-half::before{content:"\f5e4"} .bi-triangle::before{content:"\f5e5"} .bi-trophy-fill::before{content:"\f5e6"} .bi-trophy::before{content:"\f5e7"} .bi-tropical-storm::before{content:"\f5e8"} .bi-truck-flatbed::before{content:"\f5e9"} .bi-truck::before{content:"\f5ea"} .bi-tsunami::before{content:"\f5eb"} .bi-tv-fill::before{content:"\f5ec"} .bi-tv::before{content:"\f5ed"} .bi-twitch::before{content:"\f5ee"} .bi-twitter::before{content:"\f5ef"} .bi-type-bold::before{content:"\f5f0"} .bi-type-h1::before{content:"\f5f1"} .bi-type-h2::before{content:"\f5f2"} .bi-type-h3::before{content:"\f5f3"} .bi-type-italic::before{content:"\f5f4"} .bi-type-strikethrough::before{content:"\f5f5"} .bi-type-underline::before{content:"\f5f6"} .bi-type::before{content:"\f5f7"} .bi-ui-checks-grid::before{content:"\f5f8"} .bi-ui-checks::before{content:"\f5f9"} .bi-ui-radios-grid::before{content:"\f5fa"} .bi-ui-radios::before{content:"\f5fb"} .bi-umbrella-fill::before{content:"\f5fc"} .bi-umbrella::before{content:"\f5fd"} .bi-union::before{content:"\f5fe"} .bi-unlock-fill::before{content:"\f5ff"} .bi-unlock::before{content:"\f600"} .bi-upc-scan::before{content:"\f601"} .bi-upc::before{content:"\f602"} .bi-upload::before{content:"\f603"} .bi-vector-pen::before{content:"\f604"} .bi-view-list::before{content:"\f605"} .bi-view-stacked::before{content:"\f606"} .bi-vinyl-fill::before{content:"\f607"} .bi-vinyl::before{content:"\f608"} .bi-voicemail::before{content:"\f609"} .bi-volume-down-fill::before{content:"\f60a"} .bi-volume-down::before{content:"\f60b"} .bi-volume-mute-fill::before{content:"\f60c"} .bi-volume-mute::before{content:"\f60d"} .bi-volume-off-fill::before{content:"\f60e"} .bi-volume-off::before{content:"\f60f"} .bi-volume-up-fill::before{content:"\f610"} .bi-volume-up::before{content:"\f611"} .bi-vr::before{content:"\f612"} .bi-wallet-fill::before{content:"\f613"} .bi-wallet::before{content:"\f614"} .bi-wallet2::before{content:"\f615"} .bi-watch::before{content:"\f616"} .bi-water::before{content:"\f617"} .bi-whatsapp::before{content:"\f618"} .bi-wifi-1::before{content:"\f619"} .bi-wifi-2::before{content:"\f61a"} .bi-wifi-off::before{content:"\f61b"} .bi-wifi::before{content:"\f61c"} .bi-wind::before{content:"\f61d"} .bi-window-dock::before{content:"\f61e"} .bi-window-sidebar::before{content:"\f61f"} .bi-window::before{content:"\f620"} .bi-wrench::before{content:"\f621"} .bi-x-circle-fill::before{content:"\f622"} .bi-x-circle::before{content:"\f623"} .bi-x-diamond-fill::before{content:"\f624"} .bi-x-diamond::before{content:"\f625"} .bi-x-octagon-fill::before{content:"\f626"} .bi-x-octagon::before{content:"\f627"} .bi-x-square-fill::before{content:"\f628"} .bi-x-square::before{content:"\f629"} .bi-x::before{content:"\f62a"} .bi-youtube::before{content:"\f62b"} .bi-zoom-in::before{content:"\f62c"} .bi-zoom-out::before{content:"\f62d"} .bi-bank::before{content:"\f62e"} .bi-bank2::before{content:"\f62f"} .bi-bell-slash-fill::before{content:"\f630"} .bi-bell-slash::before{content:"\f631"} .bi-cash-coin::before{content:"\f632"} .bi-check-lg::before{content:"\f633"} .bi-coin::before{content:"\f634"} .bi-currency-bitcoin::before{content:"\f635"} .bi-currency-dollar::before{content:"\f636"} .bi-currency-euro::before{content:"\f637"} .bi-currency-exchange::before{content:"\f638"} .bi-currency-pound::before{content:"\f639"} .bi-currency-yen::before{content:"\f63a"} .bi-dash-lg::before{content:"\f63b"} .bi-exclamation-lg::before{content:"\f63c"} .bi-file-earmark-pdf-fill::before{content:"\f63d"} .bi-file-earmark-pdf::before{content:"\f63e"} .bi-file-pdf-fill::before{content:"\f63f"} .bi-file-pdf::before{content:"\f640"} .bi-gender-ambiguous::before{content:"\f641"} .bi-gender-female::before{content:"\f642"} .bi-gender-male::before{content:"\f643"} .bi-gender-trans::before{content:"\f644"} .bi-headset-vr::before{content:"\f645"} .bi-info-lg::before{content:"\f646"} .bi-mastodon::before{content:"\f647"} .bi-messenger::before{content:"\f648"} .bi-piggy-bank-fill::before{content:"\f649"} .bi-piggy-bank::before{content:"\f64a"} .bi-pin-map-fill::before{content:"\f64b"} .bi-pin-map::before{content:"\f64c"} .bi-plus-lg::before{content:"\f64d"} .bi-question-lg::before{content:"\f64e"} .bi-recycle::before{content:"\f64f"} .bi-reddit::before{content:"\f650"} .bi-safe-fill::before{content:"\f651"} .bi-safe2-fill::before{content:"\f652"} .bi-safe2::before{content:"\f653"} .bi-sd-card-fill::before{content:"\f654"} .bi-sd-card::before{content:"\f655"} .bi-skype::before{content:"\f656"} .bi-slash-lg::before{content:"\f657"} .bi-translate::before{content:"\f658"} .bi-x-lg::before{content:"\f659"} .bi-safe::before{content:"\f65a"} .bi-apple::before{content:"\f65b"} .bi-microsoft::before{content:"\f65d"} .bi-windows::before{content:"\f65e"} .bi-behance::before{content:"\f65c"} .bi-dribbble::before{content:"\f65f"} .bi-line::before{content:"\f660"} .bi-medium::before{content:"\f661"} .bi-paypal::before{content:"\f662"} .bi-pinterest::before{content:"\f663"} .bi-signal::before{content:"\f664"} .bi-snapchat::before{content:"\f665"} .bi-spotify::before{content:"\f666"} .bi-stack-overflow::before{content:"\f667"} .bi-strava::before{content:"\f668"} .bi-wordpress::before{content:"\f669"} .bi-vimeo::before{content:"\f66a"} .bi-activity::before{content:"\f66b"} .bi-easel2-fill::before{content:"\f66c"} .bi-easel2::before{content:"\f66d"} .bi-easel3-fill::before{content:"\f66e"} .bi-easel3::before{content:"\f66f"} .bi-fan::before{content:"\f670"} .bi-fingerprint::before{content:"\f671"} .bi-graph-down-arrow::before{content:"\f672"} .bi-graph-up-arrow::before{content:"\f673"} .bi-hypnotize::before{content:"\f674"} .bi-magic::before{content:"\f675"} .bi-person-rolodex::before{content:"\f676"} .bi-person-video::before{content:"\f677"} .bi-person-video2::before{content:"\f678"} .bi-person-video3::before{content:"\f679"} .bi-person-workspace::before{content:"\f67a"} .bi-radioactive::before{content:"\f67b"} .bi-webcam-fill::before{content:"\f67c"} .bi-webcam::before{content:"\f67d"} .bi-yin-yang::before{content:"\f67e"} .bi-bandaid-fill::before{content:"\f680"} .bi-bandaid::before{content:"\f681"} .bi-bluetooth::before{content:"\f682"} .bi-body-text::before{content:"\f683"} .bi-boombox::before{content:"\f684"} .bi-boxes::before{content:"\f685"} .bi-dpad-fill::before{content:"\f686"} .bi-dpad::before{content:"\f687"} .bi-ear-fill::before{content:"\f688"} .bi-ear::before{content:"\f689"} .bi-envelope-check-fill::before{content:"\f68b"} .bi-envelope-check::before{content:"\f68c"} .bi-envelope-dash-fill::before{content:"\f68e"} .bi-envelope-dash::before{content:"\f68f"} .bi-envelope-exclamation-fill::before{content:"\f691"} .bi-envelope-exclamation::before{content:"\f692"} .bi-envelope-plus-fill::before{content:"\f693"} .bi-envelope-plus::before{content:"\f694"} .bi-envelope-slash-fill::before{content:"\f696"} .bi-envelope-slash::before{content:"\f697"} .bi-envelope-x-fill::before{content:"\f699"} .bi-envelope-x::before{content:"\f69a"} .bi-explicit-fill::before{content:"\f69b"} .bi-explicit::before{content:"\f69c"} .bi-git::before{content:"\f69d"} .bi-infinity::before{content:"\f69e"} .bi-list-columns-reverse::before{content:"\f69f"} .bi-list-columns::before{content:"\f6a0"} .bi-meta::before{content:"\f6a1"} .bi-nintendo-switch::before{content:"\f6a4"} .bi-pc-display-horizontal::before{content:"\f6a5"} .bi-pc-display::before{content:"\f6a6"} .bi-pc-horizontal::before{content:"\f6a7"} .bi-pc::before{content:"\f6a8"} .bi-playstation::before{content:"\f6a9"} .bi-plus-slash-minus::before{content:"\f6aa"} .bi-projector-fill::before{content:"\f6ab"} .bi-projector::before{content:"\f6ac"} .bi-qr-code-scan::before{content:"\f6ad"} .bi-qr-code::before{content:"\f6ae"} .bi-quora::before{content:"\f6af"} .bi-quote::before{content:"\f6b0"} .bi-robot::before{content:"\f6b1"} .bi-send-check-fill::before{content:"\f6b2"} .bi-send-check::before{content:"\f6b3"} .bi-send-dash-fill::before{content:"\f6b4"} .bi-send-dash::before{content:"\f6b5"} .bi-send-exclamation-fill::before{content:"\f6b7"} .bi-send-exclamation::before{content:"\f6b8"} .bi-send-fill::before{content:"\f6b9"} .bi-send-plus-fill::before{content:"\f6ba"} .bi-send-plus::before{content:"\f6bb"} .bi-send-slash-fill::before{content:"\f6bc"} .bi-send-slash::before{content:"\f6bd"} .bi-send-x-fill::before{content:"\f6be"} .bi-send-x::before{content:"\f6bf"} .bi-send::before{content:"\f6c0"} .bi-steam::before{content:"\f6c1"} .bi-terminal-dash::before{content:"\f6c3"} .bi-terminal-plus::before{content:"\f6c4"} .bi-terminal-split::before{content:"\f6c5"} .bi-ticket-detailed-fill::before{content:"\f6c6"} .bi-ticket-detailed::before{content:"\f6c7"} .bi-ticket-fill::before{content:"\f6c8"} .bi-ticket-perforated-fill::before{content:"\f6c9"} .bi-ticket-perforated::before{content:"\f6ca"} .bi-ticket::before{content:"\f6cb"} .bi-tiktok::before{content:"\f6cc"} .bi-window-dash::before{content:"\f6cd"} .bi-window-desktop::before{content:"\f6ce"} .bi-window-fullscreen::before{content:"\f6cf"} .bi-window-plus::before{content:"\f6d0"} .bi-window-split::before{content:"\f6d1"} .bi-window-stack::before{content:"\f6d2"} .bi-window-x::before{content:"\f6d3"} .bi-xbox::before{content:"\f6d4"} .bi-ethernet::before{content:"\f6d5"} .bi-hdmi-fill::before{content:"\f6d6"} .bi-hdmi::before{content:"\f6d7"} .bi-usb-c-fill::before{content:"\f6d8"} .bi-usb-c::before{content:"\f6d9"} .bi-usb-fill::before{content:"\f6da"} .bi-usb-plug-fill::before{content:"\f6db"} .bi-usb-plug::before{content:"\f6dc"} .bi-usb-symbol::before{content:"\f6dd"} .bi-usb::before{content:"\f6de"} .bi-boombox-fill::before{content:"\f6df"} .bi-displayport::before{content:"\f6e1"} .bi-gpu-card::before{content:"\f6e2"} .bi-memory::before{content:"\f6e3"} .bi-modem-fill::before{content:"\f6e4"} .bi-modem::before{content:"\f6e5"} .bi-motherboard-fill::before{content:"\f6e6"} .bi-motherboard::before{content:"\f6e7"} .bi-optical-audio-fill::before{content:"\f6e8"} .bi-optical-audio::before{content:"\f6e9"} .bi-pci-card::before{content:"\f6ea"} .bi-router-fill::before{content:"\f6eb"} .bi-router::before{content:"\f6ec"} .bi-thunderbolt-fill::before{content:"\f6ef"} .bi-thunderbolt::before{content:"\f6f0"} .bi-usb-drive-fill::before{content:"\f6f1"} .bi-usb-drive::before{content:"\f6f2"} .bi-usb-micro-fill::before{content:"\f6f3"} .bi-usb-micro::before{content:"\f6f4"} .bi-usb-mini-fill::before{content:"\f6f5"} .bi-usb-mini::before{content:"\f6f6"} .bi-cloud-haze2::before{content:"\f6f7"} .bi-device-hdd-fill::before{content:"\f6f8"} .bi-device-hdd::before{content:"\f6f9"} .bi-device-ssd-fill::before{content:"\f6fa"} .bi-device-ssd::before{content:"\f6fb"} .bi-displayport-fill::before{content:"\f6fc"} .bi-mortarboard-fill::before{content:"\f6fd"} .bi-mortarboard::before{content:"\f6fe"} .bi-terminal-x::before{content:"\f6ff"} .bi-arrow-through-heart-fill::before{content:"\f700"} .bi-arrow-through-heart::before{content:"\f701"} .bi-badge-sd-fill::before{content:"\f702"} .bi-badge-sd::before{content:"\f703"} .bi-bag-heart-fill::before{content:"\f704"} .bi-bag-heart::before{content:"\f705"} .bi-balloon-fill::before{content:"\f706"} .bi-balloon-heart-fill::before{content:"\f707"} .bi-balloon-heart::before{content:"\f708"} .bi-balloon::before{content:"\f709"} .bi-box2-fill::before{content:"\f70a"} .bi-box2-heart-fill::before{content:"\f70b"} .bi-box2-heart::before{content:"\f70c"} .bi-box2::before{content:"\f70d"} .bi-braces-asterisk::before{content:"\f70e"} .bi-calendar-heart-fill::before{content:"\f70f"} .bi-calendar-heart::before{content:"\f710"} .bi-calendar2-heart-fill::before{content:"\f711"} .bi-calendar2-heart::before{content:"\f712"} .bi-chat-heart-fill::before{content:"\f713"} .bi-chat-heart::before{content:"\f714"} .bi-chat-left-heart-fill::before{content:"\f715"} .bi-chat-left-heart::before{content:"\f716"} .bi-chat-right-heart-fill::before{content:"\f717"} .bi-chat-right-heart::before{content:"\f718"} .bi-chat-square-heart-fill::before{content:"\f719"} .bi-chat-square-heart::before{content:"\f71a"} .bi-clipboard-check-fill::before{content:"\f71b"} .bi-clipboard-data-fill::before{content:"\f71c"} .bi-clipboard-fill::before{content:"\f71d"} .bi-clipboard-heart-fill::before{content:"\f71e"} .bi-clipboard-heart::before{content:"\f71f"} .bi-clipboard-minus-fill::before{content:"\f720"} .bi-clipboard-plus-fill::before{content:"\f721"} .bi-clipboard-pulse::before{content:"\f722"} .bi-clipboard-x-fill::before{content:"\f723"} .bi-clipboard2-check-fill::before{content:"\f724"} .bi-clipboard2-check::before{content:"\f725"} .bi-clipboard2-data-fill::before{content:"\f726"} .bi-clipboard2-data::before{content:"\f727"} .bi-clipboard2-fill::before{content:"\f728"} .bi-clipboard2-heart-fill::before{content:"\f729"} .bi-clipboard2-heart::before{content:"\f72a"} .bi-clipboard2-minus-fill::before{content:"\f72b"} .bi-clipboard2-minus::before{content:"\f72c"} .bi-clipboard2-plus-fill::before{content:"\f72d"} .bi-clipboard2-plus::before{content:"\f72e"} .bi-clipboard2-pulse-fill::before{content:"\f72f"} .bi-clipboard2-pulse::before{content:"\f730"} .bi-clipboard2-x-fill::before{content:"\f731"} .bi-clipboard2-x::before{content:"\f732"} .bi-clipboard2::before{content:"\f733"} .bi-emoji-kiss-fill::before{content:"\f734"} .bi-emoji-kiss::before{content:"\f735"} .bi-envelope-heart-fill::before{content:"\f736"} .bi-envelope-heart::before{content:"\f737"} .bi-envelope-open-heart-fill::before{content:"\f738"} .bi-envelope-open-heart::before{content:"\f739"} .bi-envelope-paper-fill::before{content:"\f73a"} .bi-envelope-paper-heart-fill::before{content:"\f73b"} .bi-envelope-paper-heart::before{content:"\f73c"} .bi-envelope-paper::before{content:"\f73d"} .bi-filetype-aac::before{content:"\f73e"} .bi-filetype-ai::before{content:"\f73f"} .bi-filetype-bmp::before{content:"\f740"} .bi-filetype-cs::before{content:"\f741"} .bi-filetype-css::before{content:"\f742"} .bi-filetype-csv::before{content:"\f743"} .bi-filetype-doc::before{content:"\f744"} .bi-filetype-docx::before{content:"\f745"} .bi-filetype-exe::before{content:"\f746"} .bi-filetype-gif::before{content:"\f747"} .bi-filetype-heic::before{content:"\f748"} .bi-filetype-html::before{content:"\f749"} .bi-filetype-java::before{content:"\f74a"} .bi-filetype-jpg::before{content:"\f74b"} .bi-filetype-js::before{content:"\f74c"} .bi-filetype-jsx::before{content:"\f74d"} .bi-filetype-key::before{content:"\f74e"} .bi-filetype-m4p::before{content:"\f74f"} .bi-filetype-md::before{content:"\f750"} .bi-filetype-mdx::before{content:"\f751"} .bi-filetype-mov::before{content:"\f752"} .bi-filetype-mp3::before{content:"\f753"} .bi-filetype-mp4::before{content:"\f754"} .bi-filetype-otf::before{content:"\f755"} .bi-filetype-pdf::before{content:"\f756"} .bi-filetype-php::before{content:"\f757"} .bi-filetype-png::before{content:"\f758"} .bi-filetype-ppt::before{content:"\f75a"} .bi-filetype-psd::before{content:"\f75b"} .bi-filetype-py::before{content:"\f75c"} .bi-filetype-raw::before{content:"\f75d"} .bi-filetype-rb::before{content:"\f75e"} .bi-filetype-sass::before{content:"\f75f"} .bi-filetype-scss::before{content:"\f760"} .bi-filetype-sh::before{content:"\f761"} .bi-filetype-svg::before{content:"\f762"} .bi-filetype-tiff::before{content:"\f763"} .bi-filetype-tsx::before{content:"\f764"} .bi-filetype-ttf::before{content:"\f765"} .bi-filetype-txt::before{content:"\f766"} .bi-filetype-wav::before{content:"\f767"} .bi-filetype-woff::before{content:"\f768"} .bi-filetype-xls::before{content:"\f76a"} .bi-filetype-xml::before{content:"\f76b"} .bi-filetype-yml::before{content:"\f76c"} .bi-heart-arrow::before{content:"\f76d"} .bi-heart-pulse-fill::before{content:"\f76e"} .bi-heart-pulse::before{content:"\f76f"} .bi-heartbreak-fill::before{content:"\f770"} .bi-heartbreak::before{content:"\f771"} .bi-hearts::before{content:"\f772"} .bi-hospital-fill::before{content:"\f773"} .bi-hospital::before{content:"\f774"} .bi-house-heart-fill::before{content:"\f775"} .bi-house-heart::before{content:"\f776"} .bi-incognito::before{content:"\f777"} .bi-magnet-fill::before{content:"\f778"} .bi-magnet::before{content:"\f779"} .bi-person-heart::before{content:"\f77a"} .bi-person-hearts::before{content:"\f77b"} .bi-phone-flip::before{content:"\f77c"} .bi-plugin::before{content:"\f77d"} .bi-postage-fill::before{content:"\f77e"} .bi-postage-heart-fill::before{content:"\f77f"} .bi-postage-heart::before{content:"\f780"} .bi-postage::before{content:"\f781"} .bi-postcard-fill::before{content:"\f782"} .bi-postcard-heart-fill::before{content:"\f783"} .bi-postcard-heart::before{content:"\f784"} .bi-postcard::before{content:"\f785"} .bi-search-heart-fill::before{content:"\f786"} .bi-search-heart::before{content:"\f787"} .bi-sliders2-vertical::before{content:"\f788"} .bi-sliders2::before{content:"\f789"} .bi-trash3-fill::before{content:"\f78a"} .bi-trash3::before{content:"\f78b"} .bi-valentine::before{content:"\f78c"} .bi-valentine2::before{content:"\f78d"} .bi-wrench-adjustable-circle-fill::before{content:"\f78e"} .bi-wrench-adjustable-circle::before{content:"\f78f"} .bi-wrench-adjustable::before{content:"\f790"} .bi-filetype-json::before{content:"\f791"} .bi-filetype-pptx::before{content:"\f792"} .bi-filetype-xlsx::before{content:"\f793"} .bi-1-circle-fill::before{content:"\f796"} .bi-1-circle::before{content:"\f797"} .bi-1-square-fill::before{content:"\f798"} .bi-1-square::before{content:"\f799"} .bi-2-circle-fill::before{content:"\f79c"} .bi-2-circle::before{content:"\f79d"} .bi-2-square-fill::before{content:"\f79e"} .bi-2-square::before{content:"\f79f"} .bi-3-circle-fill::before{content:"\f7a2"} .bi-3-circle::before{content:"\f7a3"} .bi-3-square-fill::before{content:"\f7a4"} .bi-3-square::before{content:"\f7a5"} .bi-4-circle-fill::before{content:"\f7a8"} .bi-4-circle::before{content:"\f7a9"} .bi-4-square-fill::before{content:"\f7aa"} .bi-4-square::before{content:"\f7ab"} .bi-5-circle-fill::before{content:"\f7ae"} .bi-5-circle::before{content:"\f7af"} .bi-5-square-fill::before{content:"\f7b0"} .bi-5-square::before{content:"\f7b1"} .bi-6-circle-fill::before{content:"\f7b4"} .bi-6-circle::before{content:"\f7b5"} .bi-6-square-fill::before{content:"\f7b6"} .bi-6-square::before{content:"\f7b7"} .bi-7-circle-fill::before{content:"\f7ba"} .bi-7-circle::before{content:"\f7bb"} .bi-7-square-fill::before{content:"\f7bc"} .bi-7-square::before{content:"\f7bd"} .bi-8-circle-fill::before{content:"\f7c0"} .bi-8-circle::before{content:"\f7c1"} .bi-8-square-fill::before{content:"\f7c2"} .bi-8-square::before{content:"\f7c3"} .bi-9-circle-fill::before{content:"\f7c6"} .bi-9-circle::before{content:"\f7c7"} .bi-9-square-fill::before{content:"\f7c8"} .bi-9-square::before{content:"\f7c9"} .bi-airplane-engines-fill::before{content:"\f7ca"} .bi-airplane-engines::before{content:"\f7cb"} .bi-airplane-fill::before{content:"\f7cc"} .bi-airplane::before{content:"\f7cd"} .bi-alexa::before{content:"\f7ce"} .bi-alipay::before{content:"\f7cf"} .bi-android::before{content:"\f7d0"} .bi-android2::before{content:"\f7d1"} .bi-box-fill::before{content:"\f7d2"} .bi-box-seam-fill::before{content:"\f7d3"} .bi-browser-chrome::before{content:"\f7d4"} .bi-browser-edge::before{content:"\f7d5"} .bi-browser-firefox::before{content:"\f7d6"} .bi-browser-safari::before{content:"\f7d7"} .bi-c-circle-fill::before{content:"\f7da"} .bi-c-circle::before{content:"\f7db"} .bi-c-square-fill::before{content:"\f7dc"} .bi-c-square::before{content:"\f7dd"} .bi-capsule-pill::before{content:"\f7de"} .bi-capsule::before{content:"\f7df"} .bi-car-front-fill::before{content:"\f7e0"} .bi-car-front::before{content:"\f7e1"} .bi-cassette-fill::before{content:"\f7e2"} .bi-cassette::before{content:"\f7e3"} .bi-cc-circle-fill::before{content:"\f7e6"} .bi-cc-circle::before{content:"\f7e7"} .bi-cc-square-fill::before{content:"\f7e8"} .bi-cc-square::before{content:"\f7e9"} .bi-cup-hot-fill::before{content:"\f7ea"} .bi-cup-hot::before{content:"\f7eb"} .bi-currency-rupee::before{content:"\f7ec"} .bi-dropbox::before{content:"\f7ed"} .bi-escape::before{content:"\f7ee"} .bi-fast-forward-btn-fill::before{content:"\f7ef"} .bi-fast-forward-btn::before{content:"\f7f0"} .bi-fast-forward-circle-fill::before{content:"\f7f1"} .bi-fast-forward-circle::before{content:"\f7f2"} .bi-fast-forward-fill::before{content:"\f7f3"} .bi-fast-forward::before{content:"\f7f4"} .bi-filetype-sql::before{content:"\f7f5"} .bi-fire::before{content:"\f7f6"} .bi-google-play::before{content:"\f7f7"} .bi-h-circle-fill::before{content:"\f7fa"} .bi-h-circle::before{content:"\f7fb"} .bi-h-square-fill::before{content:"\f7fc"} .bi-h-square::before{content:"\f7fd"} .bi-indent::before{content:"\f7fe"} .bi-lungs-fill::before{content:"\f7ff"} .bi-lungs::before{content:"\f800"} .bi-microsoft-teams::before{content:"\f801"} .bi-p-circle-fill::before{content:"\f804"} .bi-p-circle::before{content:"\f805"} .bi-p-square-fill::before{content:"\f806"} .bi-p-square::before{content:"\f807"} .bi-pass-fill::before{content:"\f808"} .bi-pass::before{content:"\f809"} .bi-prescription::before{content:"\f80a"} .bi-prescription2::before{content:"\f80b"} .bi-r-circle-fill::before{content:"\f80e"} .bi-r-circle::before{content:"\f80f"} .bi-r-square-fill::before{content:"\f810"} .bi-r-square::before{content:"\f811"} .bi-repeat-1::before{content:"\f812"} .bi-repeat::before{content:"\f813"} .bi-rewind-btn-fill::before{content:"\f814"} .bi-rewind-btn::before{content:"\f815"} .bi-rewind-circle-fill::before{content:"\f816"} .bi-rewind-circle::before{content:"\f817"} .bi-rewind-fill::before{content:"\f818"} .bi-rewind::before{content:"\f819"} .bi-train-freight-front-fill::before{content:"\f81a"} .bi-train-freight-front::before{content:"\f81b"} .bi-train-front-fill::before{content:"\f81c"} .bi-train-front::before{content:"\f81d"} .bi-train-lightrail-front-fill::before{content:"\f81e"} .bi-train-lightrail-front::before{content:"\f81f"} .bi-truck-front-fill::before{content:"\f820"} .bi-truck-front::before{content:"\f821"} .bi-ubuntu::before{content:"\f822"} .bi-unindent::before{content:"\f823"} .bi-unity::before{content:"\f824"} .bi-universal-access-circle::before{content:"\f825"} .bi-universal-access::before{content:"\f826"} .bi-virus::before{content:"\f827"} .bi-virus2::before{content:"\f828"} .bi-wechat::before{content:"\f829"} .bi-yelp::before{content:"\f82a"} .bi-sign-stop-fill::before{content:"\f82b"} .bi-sign-stop-lights-fill::before{content:"\f82c"} .bi-sign-stop-lights::before{content:"\f82d"} .bi-sign-stop::before{content:"\f82e"} .bi-sign-turn-left-fill::before{content:"\f82f"} .bi-sign-turn-left::before{content:"\f830"} .bi-sign-turn-right-fill::before{content:"\f831"} .bi-sign-turn-right::before{content:"\f832"} .bi-sign-turn-slight-left-fill::before{content:"\f833"} .bi-sign-turn-slight-left::before{content:"\f834"} .bi-sign-turn-slight-right-fill::before{content:"\f835"} .bi-sign-turn-slight-right::before{content:"\f836"} .bi-sign-yield-fill::before{content:"\f837"} .bi-sign-yield::before{content:"\f838"} .bi-ev-station-fill::before{content:"\f839"} .bi-ev-station::before{content:"\f83a"} .bi-fuel-pump-diesel-fill::before{content:"\f83b"} .bi-fuel-pump-diesel::before{content:"\f83c"} .bi-fuel-pump-fill::before{content:"\f83d"} .bi-fuel-pump::before{content:"\f83e"} .bi-0-circle-fill::before{content:"\f83f"} .bi-0-circle::before{content:"\f840"} .bi-0-square-fill::before{content:"\f841"} .bi-0-square::before{content:"\f842"} .bi-rocket-fill::before{content:"\f843"} .bi-rocket-takeoff-fill::before{content:"\f844"} .bi-rocket-takeoff::before{content:"\f845"} .bi-rocket::before{content:"\f846"} .bi-stripe::before{content:"\f847"} .bi-subscript::before{content:"\f848"} .bi-superscript::before{content:"\f849"} .bi-trello::before{content:"\f84a"} .bi-envelope-at-fill::before{content:"\f84b"} .bi-envelope-at::before{content:"\f84c"} .bi-regex::before{content:"\f84d"} .bi-text-wrap::before{content:"\f84e"} .bi-sign-dead-end-fill::before{content:"\f84f"} .bi-sign-dead-end::before{content:"\f850"} .bi-sign-do-not-enter-fill::before{content:"\f851"} .bi-sign-do-not-enter::before{content:"\f852"} .bi-sign-intersection-fill::before{content:"\f853"} .bi-sign-intersection-side-fill::before{content:"\f854"} .bi-sign-intersection-side::before{content:"\f855"} .bi-sign-intersection-t-fill::before{content:"\f856"} .bi-sign-intersection-t::before{content:"\f857"} .bi-sign-intersection-y-fill::before{content:"\f858"} .bi-sign-intersection-y::before{content:"\f859"} .bi-sign-intersection::before{content:"\f85a"} .bi-sign-merge-left-fill::before{content:"\f85b"} .bi-sign-merge-left::before{content:"\f85c"} .bi-sign-merge-right-fill::before{content:"\f85d"} .bi-sign-merge-right::before{content:"\f85e"} .bi-sign-no-left-turn-fill::before{content:"\f85f"} .bi-sign-no-left-turn::before{content:"\f860"} .bi-sign-no-parking-fill::before{content:"\f861"} .bi-sign-no-parking::before{content:"\f862"} .bi-sign-no-right-turn-fill::before{content:"\f863"} .bi-sign-no-right-turn::before{content:"\f864"} .bi-sign-railroad-fill::before{content:"\f865"} .bi-sign-railroad::before{content:"\f866"} .bi-building-add::before{content:"\f867"} .bi-building-check::before{content:"\f868"} .bi-building-dash::before{content:"\f869"} .bi-building-down::before{content:"\f86a"} .bi-building-exclamation::before{content:"\f86b"} .bi-building-fill-add::before{content:"\f86c"} .bi-building-fill-check::before{content:"\f86d"} .bi-building-fill-dash::before{content:"\f86e"} .bi-building-fill-down::before{content:"\f86f"} .bi-building-fill-exclamation::before{content:"\f870"} .bi-building-fill-gear::before{content:"\f871"} .bi-building-fill-lock::before{content:"\f872"} .bi-building-fill-slash::before{content:"\f873"} .bi-building-fill-up::before{content:"\f874"} .bi-building-fill-x::before{content:"\f875"} .bi-building-fill::before{content:"\f876"} .bi-building-gear::before{content:"\f877"} .bi-building-lock::before{content:"\f878"} .bi-building-slash::before{content:"\f879"} .bi-building-up::before{content:"\f87a"} .bi-building-x::before{content:"\f87b"} .bi-buildings-fill::before{content:"\f87c"} .bi-buildings::before{content:"\f87d"} .bi-bus-front-fill::before{content:"\f87e"} .bi-bus-front::before{content:"\f87f"} .bi-ev-front-fill::before{content:"\f880"} .bi-ev-front::before{content:"\f881"} .bi-globe-americas::before{content:"\f882"} .bi-globe-asia-australia::before{content:"\f883"} .bi-globe-central-south-asia::before{content:"\f884"} .bi-globe-europe-africa::before{content:"\f885"} .bi-house-add-fill::before{content:"\f886"} .bi-house-add::before{content:"\f887"} .bi-house-check-fill::before{content:"\f888"} .bi-house-check::before{content:"\f889"} .bi-house-dash-fill::before{content:"\f88a"} .bi-house-dash::before{content:"\f88b"} .bi-house-down-fill::before{content:"\f88c"} .bi-house-down::before{content:"\f88d"} .bi-house-exclamation-fill::before{content:"\f88e"} .bi-house-exclamation::before{content:"\f88f"} .bi-house-gear-fill::before{content:"\f890"} .bi-house-gear::before{content:"\f891"} .bi-house-lock-fill::before{content:"\f892"} .bi-house-lock::before{content:"\f893"} .bi-house-slash-fill::before{content:"\f894"} .bi-house-slash::before{content:"\f895"} .bi-house-up-fill::before{content:"\f896"} .bi-house-up::before{content:"\f897"} .bi-house-x-fill::before{content:"\f898"} .bi-house-x::before{content:"\f899"} .bi-person-add::before{content:"\f89a"} .bi-person-down::before{content:"\f89b"} .bi-person-exclamation::before{content:"\f89c"} .bi-person-fill-add::before{content:"\f89d"} .bi-person-fill-check::before{content:"\f89e"} .bi-person-fill-dash::before{content:"\f89f"} .bi-person-fill-down::before{content:"\f8a0"} .bi-person-fill-exclamation::before{content:"\f8a1"} .bi-person-fill-gear::before{content:"\f8a2"} .bi-person-fill-lock::before{content:"\f8a3"} .bi-person-fill-slash::before{content:"\f8a4"} .bi-person-fill-up::before{content:"\f8a5"} .bi-person-fill-x::before{content:"\f8a6"} .bi-person-gear::before{content:"\f8a7"} .bi-person-lock::before{content:"\f8a8"} .bi-person-slash::before{content:"\f8a9"} .bi-person-up::before{content:"\f8aa"} .bi-scooter::before{content:"\f8ab"} .bi-taxi-front-fill::before{content:"\f8ac"} .bi-taxi-front::before{content:"\f8ad"} .bi-amd::before{content:"\f8ae"} .bi-database-add::before{content:"\f8af"} .bi-database-check::before{content:"\f8b0"} .bi-database-dash::before{content:"\f8b1"} .bi-database-down::before{content:"\f8b2"} .bi-database-exclamation::before{content:"\f8b3"} .bi-database-fill-add::before{content:"\f8b4"} .bi-database-fill-check::before{content:"\f8b5"} .bi-database-fill-dash::before{content:"\f8b6"} .bi-database-fill-down::before{content:"\f8b7"} .bi-database-fill-exclamation::before{content:"\f8b8"} .bi-database-fill-gear::before{content:"\f8b9"} .bi-database-fill-lock::before{content:"\f8ba"} .bi-database-fill-slash::before{content:"\f8bb"} .bi-database-fill-up::before{content:"\f8bc"} .bi-database-fill-x::before{content:"\f8bd"} .bi-database-fill::before{content:"\f8be"} .bi-database-gear::before{content:"\f8bf"} .bi-database-lock::before{content:"\f8c0"} .bi-database-slash::before{content:"\f8c1"} .bi-database-up::before{content:"\f8c2"} .bi-database-x::before{content:"\f8c3"} .bi-database::before{content:"\f8c4"} .bi-houses-fill::before{content:"\f8c5"} .bi-houses::before{content:"\f8c6"} .bi-nvidia::before{content:"\f8c7"} .bi-person-vcard-fill::before{content:"\f8c8"} .bi-person-vcard::before{content:"\f8c9"} .bi-sina-weibo::before{content:"\f8ca"} .bi-tencent-qq::before{content:"\f8cb"} .bi-wikipedia::before{content:"\f8cc"} .bi-alphabet-uppercase::before{content:"\f2a5"} .bi-alphabet::before{content:"\f68a"} .bi-amazon::before{content:"\f68d"} .bi-arrows-collapse-vertical::before{content:"\f690"} .bi-arrows-expand-vertical::before{content:"\f695"} .bi-arrows-vertical::before{content:"\f698"} .bi-arrows::before{content:"\f6a2"} .bi-ban-fill::before{content:"\f6a3"} .bi-ban::before{content:"\f6b6"} .bi-bing::before{content:"\f6c2"} .bi-cake::before{content:"\f6e0"} .bi-cake2::before{content:"\f6ed"} .bi-cookie::before{content:"\f6ee"} .bi-copy::before{content:"\f759"} .bi-crosshair::before{content:"\f769"} .bi-crosshair2::before{content:"\f794"} .bi-emoji-astonished-fill::before{content:"\f795"} .bi-emoji-astonished::before{content:"\f79a"} .bi-emoji-grimace-fill::before{content:"\f79b"} .bi-emoji-grimace::before{content:"\f7a0"} .bi-emoji-grin-fill::before{content:"\f7a1"} .bi-emoji-grin::before{content:"\f7a6"} .bi-emoji-surprise-fill::before{content:"\f7a7"} .bi-emoji-surprise::before{content:"\f7ac"} .bi-emoji-tear-fill::before{content:"\f7ad"} .bi-emoji-tear::before{content:"\f7b2"} .bi-envelope-arrow-down-fill::before{content:"\f7b3"} .bi-envelope-arrow-down::before{content:"\f7b8"} .bi-envelope-arrow-up-fill::before{content:"\f7b9"} .bi-envelope-arrow-up::before{content:"\f7be"} .bi-feather::before{content:"\f7bf"} .bi-feather2::before{content:"\f7c4"} .bi-floppy-fill::before{content:"\f7c5"} .bi-floppy::before{content:"\f7d8"} .bi-floppy2-fill::before{content:"\f7d9"} .bi-floppy2::before{content:"\f7e4"} .bi-gitlab::before{content:"\f7e5"} .bi-highlighter::before{content:"\f7f8"} .bi-marker-tip::before{content:"\f802"} .bi-nvme-fill::before{content:"\f803"} .bi-nvme::before{content:"\f80c"} .bi-opencollective::before{content:"\f80d"} .bi-pci-card-network::before{content:"\f8cd"} .bi-pci-card-sound::before{content:"\f8ce"} .bi-radar::before{content:"\f8cf"} .bi-send-arrow-down-fill::before{content:"\f8d0"} .bi-send-arrow-down::before{content:"\f8d1"} .bi-send-arrow-up-fill::before{content:"\f8d2"} .bi-send-arrow-up::before{content:"\f8d3"} .bi-sim-slash-fill::before{content:"\f8d4"} .bi-sim-slash::before{content:"\f8d5"} .bi-sourceforge::before{content:"\f8d6"} .bi-substack::before{content:"\f8d7"} .bi-threads-fill::before{content:"\f8d8"} .bi-threads::before{content:"\f8d9"} .bi-transparency::before{content:"\f8da"} .bi-twitter-x::before{content:"\f8db"} .bi-type-h4::before{content:"\f8dc"} .bi-type-h5::before{content:"\f8dd"} .bi-type-h6::before{content:"\f8de"} .bi-backpack-fill::before{content:"\f8df"} .bi-backpack::before{content:"\f8e0"} .bi-backpack2-fill::before{content:"\f8e1"} .bi-backpack2::before{content:"\f8e2"} .bi-backpack3-fill::before{content:"\f8e3"} .bi-backpack3::before{content:"\f8e4"} .bi-backpack4-fill::before{content:"\f8e5"} .bi-backpack4::before{content:"\f8e6"} .bi-brilliance::before{content:"\f8e7"} .bi-cake-fill::before{content:"\f8e8"} .bi-cake2-fill::before{content:"\f8e9"} .bi-duffle-fill::before{content:"\f8ea"} .bi-duffle::before{content:"\f8eb"} .bi-exposure::before{content:"\f8ec"} .bi-gender-neuter::before{content:"\f8ed"} .bi-highlights::before{content:"\f8ee"} .bi-luggage-fill::before{content:"\f8ef"} .bi-luggage::before{content:"\f8f0"} .bi-mailbox-flag::before{content:"\f8f1"} .bi-mailbox2-flag::before{content:"\f8f2"} .bi-noise-reduction::before{content:"\f8f3"} .bi-passport-fill::before{content:"\f8f4"} .bi-passport::before{content:"\f8f5"} .bi-person-arms-up::before{content:"\f8f6"} .bi-person-raised-hand::before{content:"\f8f7"} .bi-person-standing-dress::before{content:"\f8f8"} .bi-person-standing::before{content:"\f8f9"} .bi-person-walking::before{content:"\f8fa"} .bi-person-wheelchair::before{content:"\f8fb"} .bi-shadows::before{content:"\f8fc"} .bi-suitcase-fill::before{content:"\f8fd"} .bi-suitcase-lg-fill::before{content:"\f8fe"} .bi-suitcase-lg::before{content:"\f8ff"} .bi-suitcase::before{content:"\f900"} .bi-suitcase2-fill::before{content:"\f901"} .bi-suitcase2::before{content:"\f902"} .bi-vignette::before{content:"\f903"} \ No newline at end of file diff --git a/static/css/bootstrap-icons-1.11.3/font/bootstrap-icons.scss b/app/static/css/bootstrap-icons-1.11.3/font/bootstrap-icons.scss similarity index 100% rename from static/css/bootstrap-icons-1.11.3/font/bootstrap-icons.scss rename to app/static/css/bootstrap-icons-1.11.3/font/bootstrap-icons.scss diff --git a/static/css/bootstrap-icons-1.11.3/font/fonts/bootstrap-icons.woff b/app/static/css/bootstrap-icons-1.11.3/font/fonts/bootstrap-icons.woff similarity index 100% rename from static/css/bootstrap-icons-1.11.3/font/fonts/bootstrap-icons.woff rename to app/static/css/bootstrap-icons-1.11.3/font/fonts/bootstrap-icons.woff diff --git a/static/css/bootstrap-icons-1.11.3/font/fonts/bootstrap-icons.woff2 b/app/static/css/bootstrap-icons-1.11.3/font/fonts/bootstrap-icons.woff2 similarity index 100% rename from static/css/bootstrap-icons-1.11.3/font/fonts/bootstrap-icons.woff2 rename to app/static/css/bootstrap-icons-1.11.3/font/fonts/bootstrap-icons.woff2 diff --git a/static/css/bootstrap-icons-1.11.3/fonts.svg b/app/static/css/bootstrap-icons-1.11.3/fonts.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/fonts.svg rename to app/static/css/bootstrap-icons-1.11.3/fonts.svg diff --git a/static/css/bootstrap-icons-1.11.3/forward-fill.svg b/app/static/css/bootstrap-icons-1.11.3/forward-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/forward-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/forward-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/forward.svg b/app/static/css/bootstrap-icons-1.11.3/forward.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/forward.svg rename to app/static/css/bootstrap-icons-1.11.3/forward.svg diff --git a/static/css/bootstrap-icons-1.11.3/front.svg b/app/static/css/bootstrap-icons-1.11.3/front.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/front.svg rename to app/static/css/bootstrap-icons-1.11.3/front.svg diff --git a/static/css/bootstrap-icons-1.11.3/fuel-pump-diesel-fill.svg b/app/static/css/bootstrap-icons-1.11.3/fuel-pump-diesel-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/fuel-pump-diesel-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/fuel-pump-diesel-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/fuel-pump-diesel.svg b/app/static/css/bootstrap-icons-1.11.3/fuel-pump-diesel.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/fuel-pump-diesel.svg rename to app/static/css/bootstrap-icons-1.11.3/fuel-pump-diesel.svg diff --git a/static/css/bootstrap-icons-1.11.3/fuel-pump-fill.svg b/app/static/css/bootstrap-icons-1.11.3/fuel-pump-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/fuel-pump-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/fuel-pump-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/fuel-pump.svg b/app/static/css/bootstrap-icons-1.11.3/fuel-pump.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/fuel-pump.svg rename to app/static/css/bootstrap-icons-1.11.3/fuel-pump.svg diff --git a/static/css/bootstrap-icons-1.11.3/fullscreen-exit.svg b/app/static/css/bootstrap-icons-1.11.3/fullscreen-exit.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/fullscreen-exit.svg rename to app/static/css/bootstrap-icons-1.11.3/fullscreen-exit.svg diff --git a/static/css/bootstrap-icons-1.11.3/fullscreen.svg b/app/static/css/bootstrap-icons-1.11.3/fullscreen.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/fullscreen.svg rename to app/static/css/bootstrap-icons-1.11.3/fullscreen.svg diff --git a/static/css/bootstrap-icons-1.11.3/funnel-fill.svg b/app/static/css/bootstrap-icons-1.11.3/funnel-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/funnel-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/funnel-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/funnel.svg b/app/static/css/bootstrap-icons-1.11.3/funnel.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/funnel.svg rename to app/static/css/bootstrap-icons-1.11.3/funnel.svg diff --git a/static/css/bootstrap-icons-1.11.3/gear-fill.svg b/app/static/css/bootstrap-icons-1.11.3/gear-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/gear-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/gear-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/gear-wide-connected.svg b/app/static/css/bootstrap-icons-1.11.3/gear-wide-connected.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/gear-wide-connected.svg rename to app/static/css/bootstrap-icons-1.11.3/gear-wide-connected.svg diff --git a/static/css/bootstrap-icons-1.11.3/gear-wide.svg b/app/static/css/bootstrap-icons-1.11.3/gear-wide.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/gear-wide.svg rename to app/static/css/bootstrap-icons-1.11.3/gear-wide.svg diff --git a/static/css/bootstrap-icons-1.11.3/gear.svg b/app/static/css/bootstrap-icons-1.11.3/gear.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/gear.svg rename to app/static/css/bootstrap-icons-1.11.3/gear.svg diff --git a/static/css/bootstrap-icons-1.11.3/gem.svg b/app/static/css/bootstrap-icons-1.11.3/gem.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/gem.svg rename to app/static/css/bootstrap-icons-1.11.3/gem.svg diff --git a/static/css/bootstrap-icons-1.11.3/gender-ambiguous.svg b/app/static/css/bootstrap-icons-1.11.3/gender-ambiguous.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/gender-ambiguous.svg rename to app/static/css/bootstrap-icons-1.11.3/gender-ambiguous.svg diff --git a/static/css/bootstrap-icons-1.11.3/gender-female.svg b/app/static/css/bootstrap-icons-1.11.3/gender-female.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/gender-female.svg rename to app/static/css/bootstrap-icons-1.11.3/gender-female.svg diff --git a/static/css/bootstrap-icons-1.11.3/gender-male.svg b/app/static/css/bootstrap-icons-1.11.3/gender-male.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/gender-male.svg rename to app/static/css/bootstrap-icons-1.11.3/gender-male.svg diff --git a/static/css/bootstrap-icons-1.11.3/gender-neuter.svg b/app/static/css/bootstrap-icons-1.11.3/gender-neuter.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/gender-neuter.svg rename to app/static/css/bootstrap-icons-1.11.3/gender-neuter.svg diff --git a/static/css/bootstrap-icons-1.11.3/gender-trans.svg b/app/static/css/bootstrap-icons-1.11.3/gender-trans.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/gender-trans.svg rename to app/static/css/bootstrap-icons-1.11.3/gender-trans.svg diff --git a/static/css/bootstrap-icons-1.11.3/geo-alt-fill.svg b/app/static/css/bootstrap-icons-1.11.3/geo-alt-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/geo-alt-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/geo-alt-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/geo-alt.svg b/app/static/css/bootstrap-icons-1.11.3/geo-alt.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/geo-alt.svg rename to app/static/css/bootstrap-icons-1.11.3/geo-alt.svg diff --git a/static/css/bootstrap-icons-1.11.3/geo-fill.svg b/app/static/css/bootstrap-icons-1.11.3/geo-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/geo-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/geo-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/geo.svg b/app/static/css/bootstrap-icons-1.11.3/geo.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/geo.svg rename to app/static/css/bootstrap-icons-1.11.3/geo.svg diff --git a/static/css/bootstrap-icons-1.11.3/gift-fill.svg b/app/static/css/bootstrap-icons-1.11.3/gift-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/gift-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/gift-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/gift.svg b/app/static/css/bootstrap-icons-1.11.3/gift.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/gift.svg rename to app/static/css/bootstrap-icons-1.11.3/gift.svg diff --git a/static/css/bootstrap-icons-1.11.3/git.svg b/app/static/css/bootstrap-icons-1.11.3/git.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/git.svg rename to app/static/css/bootstrap-icons-1.11.3/git.svg diff --git a/static/css/bootstrap-icons-1.11.3/github.svg b/app/static/css/bootstrap-icons-1.11.3/github.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/github.svg rename to app/static/css/bootstrap-icons-1.11.3/github.svg diff --git a/static/css/bootstrap-icons-1.11.3/gitlab.svg b/app/static/css/bootstrap-icons-1.11.3/gitlab.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/gitlab.svg rename to app/static/css/bootstrap-icons-1.11.3/gitlab.svg diff --git a/static/css/bootstrap-icons-1.11.3/globe-americas.svg b/app/static/css/bootstrap-icons-1.11.3/globe-americas.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/globe-americas.svg rename to app/static/css/bootstrap-icons-1.11.3/globe-americas.svg diff --git a/static/css/bootstrap-icons-1.11.3/globe-asia-australia.svg b/app/static/css/bootstrap-icons-1.11.3/globe-asia-australia.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/globe-asia-australia.svg rename to app/static/css/bootstrap-icons-1.11.3/globe-asia-australia.svg diff --git a/static/css/bootstrap-icons-1.11.3/globe-central-south-asia.svg b/app/static/css/bootstrap-icons-1.11.3/globe-central-south-asia.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/globe-central-south-asia.svg rename to app/static/css/bootstrap-icons-1.11.3/globe-central-south-asia.svg diff --git a/static/css/bootstrap-icons-1.11.3/globe-europe-africa.svg b/app/static/css/bootstrap-icons-1.11.3/globe-europe-africa.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/globe-europe-africa.svg rename to app/static/css/bootstrap-icons-1.11.3/globe-europe-africa.svg diff --git a/static/css/bootstrap-icons-1.11.3/globe.svg b/app/static/css/bootstrap-icons-1.11.3/globe.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/globe.svg rename to app/static/css/bootstrap-icons-1.11.3/globe.svg diff --git a/static/css/bootstrap-icons-1.11.3/globe2.svg b/app/static/css/bootstrap-icons-1.11.3/globe2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/globe2.svg rename to app/static/css/bootstrap-icons-1.11.3/globe2.svg diff --git a/static/css/bootstrap-icons-1.11.3/google-play.svg b/app/static/css/bootstrap-icons-1.11.3/google-play.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/google-play.svg rename to app/static/css/bootstrap-icons-1.11.3/google-play.svg diff --git a/static/css/bootstrap-icons-1.11.3/google.svg b/app/static/css/bootstrap-icons-1.11.3/google.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/google.svg rename to app/static/css/bootstrap-icons-1.11.3/google.svg diff --git a/static/css/bootstrap-icons-1.11.3/gpu-card.svg b/app/static/css/bootstrap-icons-1.11.3/gpu-card.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/gpu-card.svg rename to app/static/css/bootstrap-icons-1.11.3/gpu-card.svg diff --git a/static/css/bootstrap-icons-1.11.3/graph-down-arrow.svg b/app/static/css/bootstrap-icons-1.11.3/graph-down-arrow.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/graph-down-arrow.svg rename to app/static/css/bootstrap-icons-1.11.3/graph-down-arrow.svg diff --git a/static/css/bootstrap-icons-1.11.3/graph-down.svg b/app/static/css/bootstrap-icons-1.11.3/graph-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/graph-down.svg rename to app/static/css/bootstrap-icons-1.11.3/graph-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/graph-up-arrow.svg b/app/static/css/bootstrap-icons-1.11.3/graph-up-arrow.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/graph-up-arrow.svg rename to app/static/css/bootstrap-icons-1.11.3/graph-up-arrow.svg diff --git a/static/css/bootstrap-icons-1.11.3/graph-up.svg b/app/static/css/bootstrap-icons-1.11.3/graph-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/graph-up.svg rename to app/static/css/bootstrap-icons-1.11.3/graph-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/grid-1x2-fill.svg b/app/static/css/bootstrap-icons-1.11.3/grid-1x2-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/grid-1x2-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/grid-1x2-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/grid-1x2.svg b/app/static/css/bootstrap-icons-1.11.3/grid-1x2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/grid-1x2.svg rename to app/static/css/bootstrap-icons-1.11.3/grid-1x2.svg diff --git a/static/css/bootstrap-icons-1.11.3/grid-3x2-gap-fill.svg b/app/static/css/bootstrap-icons-1.11.3/grid-3x2-gap-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/grid-3x2-gap-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/grid-3x2-gap-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/grid-3x2-gap.svg b/app/static/css/bootstrap-icons-1.11.3/grid-3x2-gap.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/grid-3x2-gap.svg rename to app/static/css/bootstrap-icons-1.11.3/grid-3x2-gap.svg diff --git a/static/css/bootstrap-icons-1.11.3/grid-3x2.svg b/app/static/css/bootstrap-icons-1.11.3/grid-3x2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/grid-3x2.svg rename to app/static/css/bootstrap-icons-1.11.3/grid-3x2.svg diff --git a/static/css/bootstrap-icons-1.11.3/grid-3x3-gap-fill.svg b/app/static/css/bootstrap-icons-1.11.3/grid-3x3-gap-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/grid-3x3-gap-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/grid-3x3-gap-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/grid-3x3-gap.svg b/app/static/css/bootstrap-icons-1.11.3/grid-3x3-gap.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/grid-3x3-gap.svg rename to app/static/css/bootstrap-icons-1.11.3/grid-3x3-gap.svg diff --git a/static/css/bootstrap-icons-1.11.3/grid-3x3.svg b/app/static/css/bootstrap-icons-1.11.3/grid-3x3.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/grid-3x3.svg rename to app/static/css/bootstrap-icons-1.11.3/grid-3x3.svg diff --git a/static/css/bootstrap-icons-1.11.3/grid-fill.svg b/app/static/css/bootstrap-icons-1.11.3/grid-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/grid-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/grid-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/grid.svg b/app/static/css/bootstrap-icons-1.11.3/grid.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/grid.svg rename to app/static/css/bootstrap-icons-1.11.3/grid.svg diff --git a/static/css/bootstrap-icons-1.11.3/grip-horizontal.svg b/app/static/css/bootstrap-icons-1.11.3/grip-horizontal.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/grip-horizontal.svg rename to app/static/css/bootstrap-icons-1.11.3/grip-horizontal.svg diff --git a/static/css/bootstrap-icons-1.11.3/grip-vertical.svg b/app/static/css/bootstrap-icons-1.11.3/grip-vertical.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/grip-vertical.svg rename to app/static/css/bootstrap-icons-1.11.3/grip-vertical.svg diff --git a/static/css/bootstrap-icons-1.11.3/h-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/h-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/h-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/h-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/h-circle.svg b/app/static/css/bootstrap-icons-1.11.3/h-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/h-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/h-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/h-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/h-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/h-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/h-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/h-square.svg b/app/static/css/bootstrap-icons-1.11.3/h-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/h-square.svg rename to app/static/css/bootstrap-icons-1.11.3/h-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/hammer.svg b/app/static/css/bootstrap-icons-1.11.3/hammer.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hammer.svg rename to app/static/css/bootstrap-icons-1.11.3/hammer.svg diff --git a/static/css/bootstrap-icons-1.11.3/hand-index-fill.svg b/app/static/css/bootstrap-icons-1.11.3/hand-index-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hand-index-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/hand-index-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/hand-index-thumb-fill.svg b/app/static/css/bootstrap-icons-1.11.3/hand-index-thumb-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hand-index-thumb-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/hand-index-thumb-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/hand-index-thumb.svg b/app/static/css/bootstrap-icons-1.11.3/hand-index-thumb.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hand-index-thumb.svg rename to app/static/css/bootstrap-icons-1.11.3/hand-index-thumb.svg diff --git a/static/css/bootstrap-icons-1.11.3/hand-index.svg b/app/static/css/bootstrap-icons-1.11.3/hand-index.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hand-index.svg rename to app/static/css/bootstrap-icons-1.11.3/hand-index.svg diff --git a/static/css/bootstrap-icons-1.11.3/hand-thumbs-down-fill.svg b/app/static/css/bootstrap-icons-1.11.3/hand-thumbs-down-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hand-thumbs-down-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/hand-thumbs-down-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/hand-thumbs-down.svg b/app/static/css/bootstrap-icons-1.11.3/hand-thumbs-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hand-thumbs-down.svg rename to app/static/css/bootstrap-icons-1.11.3/hand-thumbs-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/hand-thumbs-up-fill.svg b/app/static/css/bootstrap-icons-1.11.3/hand-thumbs-up-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hand-thumbs-up-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/hand-thumbs-up-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/hand-thumbs-up.svg b/app/static/css/bootstrap-icons-1.11.3/hand-thumbs-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hand-thumbs-up.svg rename to app/static/css/bootstrap-icons-1.11.3/hand-thumbs-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/handbag-fill.svg b/app/static/css/bootstrap-icons-1.11.3/handbag-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/handbag-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/handbag-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/handbag.svg b/app/static/css/bootstrap-icons-1.11.3/handbag.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/handbag.svg rename to app/static/css/bootstrap-icons-1.11.3/handbag.svg diff --git a/static/css/bootstrap-icons-1.11.3/hash.svg b/app/static/css/bootstrap-icons-1.11.3/hash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hash.svg rename to app/static/css/bootstrap-icons-1.11.3/hash.svg diff --git a/static/css/bootstrap-icons-1.11.3/hdd-fill.svg b/app/static/css/bootstrap-icons-1.11.3/hdd-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hdd-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/hdd-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/hdd-network-fill.svg b/app/static/css/bootstrap-icons-1.11.3/hdd-network-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hdd-network-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/hdd-network-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/hdd-network.svg b/app/static/css/bootstrap-icons-1.11.3/hdd-network.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hdd-network.svg rename to app/static/css/bootstrap-icons-1.11.3/hdd-network.svg diff --git a/static/css/bootstrap-icons-1.11.3/hdd-rack-fill.svg b/app/static/css/bootstrap-icons-1.11.3/hdd-rack-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hdd-rack-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/hdd-rack-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/hdd-rack.svg b/app/static/css/bootstrap-icons-1.11.3/hdd-rack.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hdd-rack.svg rename to app/static/css/bootstrap-icons-1.11.3/hdd-rack.svg diff --git a/static/css/bootstrap-icons-1.11.3/hdd-stack-fill.svg b/app/static/css/bootstrap-icons-1.11.3/hdd-stack-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hdd-stack-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/hdd-stack-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/hdd-stack.svg b/app/static/css/bootstrap-icons-1.11.3/hdd-stack.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hdd-stack.svg rename to app/static/css/bootstrap-icons-1.11.3/hdd-stack.svg diff --git a/static/css/bootstrap-icons-1.11.3/hdd.svg b/app/static/css/bootstrap-icons-1.11.3/hdd.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hdd.svg rename to app/static/css/bootstrap-icons-1.11.3/hdd.svg diff --git a/static/css/bootstrap-icons-1.11.3/hdmi-fill.svg b/app/static/css/bootstrap-icons-1.11.3/hdmi-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hdmi-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/hdmi-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/hdmi.svg b/app/static/css/bootstrap-icons-1.11.3/hdmi.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hdmi.svg rename to app/static/css/bootstrap-icons-1.11.3/hdmi.svg diff --git a/static/css/bootstrap-icons-1.11.3/headphones.svg b/app/static/css/bootstrap-icons-1.11.3/headphones.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/headphones.svg rename to app/static/css/bootstrap-icons-1.11.3/headphones.svg diff --git a/static/css/bootstrap-icons-1.11.3/headset-vr.svg b/app/static/css/bootstrap-icons-1.11.3/headset-vr.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/headset-vr.svg rename to app/static/css/bootstrap-icons-1.11.3/headset-vr.svg diff --git a/static/css/bootstrap-icons-1.11.3/headset.svg b/app/static/css/bootstrap-icons-1.11.3/headset.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/headset.svg rename to app/static/css/bootstrap-icons-1.11.3/headset.svg diff --git a/static/css/bootstrap-icons-1.11.3/heart-arrow.svg b/app/static/css/bootstrap-icons-1.11.3/heart-arrow.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/heart-arrow.svg rename to app/static/css/bootstrap-icons-1.11.3/heart-arrow.svg diff --git a/static/css/bootstrap-icons-1.11.3/heart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/heart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/heart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/heart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/heart-half.svg b/app/static/css/bootstrap-icons-1.11.3/heart-half.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/heart-half.svg rename to app/static/css/bootstrap-icons-1.11.3/heart-half.svg diff --git a/static/css/bootstrap-icons-1.11.3/heart-pulse-fill.svg b/app/static/css/bootstrap-icons-1.11.3/heart-pulse-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/heart-pulse-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/heart-pulse-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/heart-pulse.svg b/app/static/css/bootstrap-icons-1.11.3/heart-pulse.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/heart-pulse.svg rename to app/static/css/bootstrap-icons-1.11.3/heart-pulse.svg diff --git a/static/css/bootstrap-icons-1.11.3/heart.svg b/app/static/css/bootstrap-icons-1.11.3/heart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/heart.svg rename to app/static/css/bootstrap-icons-1.11.3/heart.svg diff --git a/static/css/bootstrap-icons-1.11.3/heartbreak-fill.svg b/app/static/css/bootstrap-icons-1.11.3/heartbreak-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/heartbreak-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/heartbreak-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/heartbreak.svg b/app/static/css/bootstrap-icons-1.11.3/heartbreak.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/heartbreak.svg rename to app/static/css/bootstrap-icons-1.11.3/heartbreak.svg diff --git a/static/css/bootstrap-icons-1.11.3/hearts.svg b/app/static/css/bootstrap-icons-1.11.3/hearts.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hearts.svg rename to app/static/css/bootstrap-icons-1.11.3/hearts.svg diff --git a/static/css/bootstrap-icons-1.11.3/heptagon-fill.svg b/app/static/css/bootstrap-icons-1.11.3/heptagon-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/heptagon-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/heptagon-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/heptagon-half.svg b/app/static/css/bootstrap-icons-1.11.3/heptagon-half.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/heptagon-half.svg rename to app/static/css/bootstrap-icons-1.11.3/heptagon-half.svg diff --git a/static/css/bootstrap-icons-1.11.3/heptagon.svg b/app/static/css/bootstrap-icons-1.11.3/heptagon.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/heptagon.svg rename to app/static/css/bootstrap-icons-1.11.3/heptagon.svg diff --git a/static/css/bootstrap-icons-1.11.3/hexagon-fill.svg b/app/static/css/bootstrap-icons-1.11.3/hexagon-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hexagon-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/hexagon-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/hexagon-half.svg b/app/static/css/bootstrap-icons-1.11.3/hexagon-half.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hexagon-half.svg rename to app/static/css/bootstrap-icons-1.11.3/hexagon-half.svg diff --git a/static/css/bootstrap-icons-1.11.3/hexagon.svg b/app/static/css/bootstrap-icons-1.11.3/hexagon.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hexagon.svg rename to app/static/css/bootstrap-icons-1.11.3/hexagon.svg diff --git a/static/css/bootstrap-icons-1.11.3/highlighter.svg b/app/static/css/bootstrap-icons-1.11.3/highlighter.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/highlighter.svg rename to app/static/css/bootstrap-icons-1.11.3/highlighter.svg diff --git a/static/css/bootstrap-icons-1.11.3/highlights.svg b/app/static/css/bootstrap-icons-1.11.3/highlights.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/highlights.svg rename to app/static/css/bootstrap-icons-1.11.3/highlights.svg diff --git a/static/css/bootstrap-icons-1.11.3/hospital-fill.svg b/app/static/css/bootstrap-icons-1.11.3/hospital-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hospital-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/hospital-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/hospital.svg b/app/static/css/bootstrap-icons-1.11.3/hospital.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hospital.svg rename to app/static/css/bootstrap-icons-1.11.3/hospital.svg diff --git a/static/css/bootstrap-icons-1.11.3/hourglass-bottom.svg b/app/static/css/bootstrap-icons-1.11.3/hourglass-bottom.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hourglass-bottom.svg rename to app/static/css/bootstrap-icons-1.11.3/hourglass-bottom.svg diff --git a/static/css/bootstrap-icons-1.11.3/hourglass-split.svg b/app/static/css/bootstrap-icons-1.11.3/hourglass-split.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hourglass-split.svg rename to app/static/css/bootstrap-icons-1.11.3/hourglass-split.svg diff --git a/static/css/bootstrap-icons-1.11.3/hourglass-top.svg b/app/static/css/bootstrap-icons-1.11.3/hourglass-top.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hourglass-top.svg rename to app/static/css/bootstrap-icons-1.11.3/hourglass-top.svg diff --git a/static/css/bootstrap-icons-1.11.3/hourglass.svg b/app/static/css/bootstrap-icons-1.11.3/hourglass.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hourglass.svg rename to app/static/css/bootstrap-icons-1.11.3/hourglass.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-add-fill.svg b/app/static/css/bootstrap-icons-1.11.3/house-add-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-add-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/house-add-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-add.svg b/app/static/css/bootstrap-icons-1.11.3/house-add.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-add.svg rename to app/static/css/bootstrap-icons-1.11.3/house-add.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-check-fill.svg b/app/static/css/bootstrap-icons-1.11.3/house-check-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-check-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/house-check-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-check.svg b/app/static/css/bootstrap-icons-1.11.3/house-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-check.svg rename to app/static/css/bootstrap-icons-1.11.3/house-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-dash-fill.svg b/app/static/css/bootstrap-icons-1.11.3/house-dash-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-dash-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/house-dash-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-dash.svg b/app/static/css/bootstrap-icons-1.11.3/house-dash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-dash.svg rename to app/static/css/bootstrap-icons-1.11.3/house-dash.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-door-fill.svg b/app/static/css/bootstrap-icons-1.11.3/house-door-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-door-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/house-door-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-door.svg b/app/static/css/bootstrap-icons-1.11.3/house-door.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-door.svg rename to app/static/css/bootstrap-icons-1.11.3/house-door.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-down-fill.svg b/app/static/css/bootstrap-icons-1.11.3/house-down-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-down-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/house-down-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-down.svg b/app/static/css/bootstrap-icons-1.11.3/house-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-down.svg rename to app/static/css/bootstrap-icons-1.11.3/house-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-exclamation-fill.svg b/app/static/css/bootstrap-icons-1.11.3/house-exclamation-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-exclamation-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/house-exclamation-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-exclamation.svg b/app/static/css/bootstrap-icons-1.11.3/house-exclamation.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-exclamation.svg rename to app/static/css/bootstrap-icons-1.11.3/house-exclamation.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-fill.svg b/app/static/css/bootstrap-icons-1.11.3/house-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/house-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-gear-fill.svg b/app/static/css/bootstrap-icons-1.11.3/house-gear-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-gear-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/house-gear-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-gear.svg b/app/static/css/bootstrap-icons-1.11.3/house-gear.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-gear.svg rename to app/static/css/bootstrap-icons-1.11.3/house-gear.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-heart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/house-heart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-heart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/house-heart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-heart.svg b/app/static/css/bootstrap-icons-1.11.3/house-heart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-heart.svg rename to app/static/css/bootstrap-icons-1.11.3/house-heart.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-lock-fill.svg b/app/static/css/bootstrap-icons-1.11.3/house-lock-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-lock-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/house-lock-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-lock.svg b/app/static/css/bootstrap-icons-1.11.3/house-lock.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-lock.svg rename to app/static/css/bootstrap-icons-1.11.3/house-lock.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-slash-fill.svg b/app/static/css/bootstrap-icons-1.11.3/house-slash-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-slash-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/house-slash-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-slash.svg b/app/static/css/bootstrap-icons-1.11.3/house-slash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-slash.svg rename to app/static/css/bootstrap-icons-1.11.3/house-slash.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-up-fill.svg b/app/static/css/bootstrap-icons-1.11.3/house-up-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-up-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/house-up-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-up.svg b/app/static/css/bootstrap-icons-1.11.3/house-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-up.svg rename to app/static/css/bootstrap-icons-1.11.3/house-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-x-fill.svg b/app/static/css/bootstrap-icons-1.11.3/house-x-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-x-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/house-x-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/house-x.svg b/app/static/css/bootstrap-icons-1.11.3/house-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house-x.svg rename to app/static/css/bootstrap-icons-1.11.3/house-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/house.svg b/app/static/css/bootstrap-icons-1.11.3/house.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/house.svg rename to app/static/css/bootstrap-icons-1.11.3/house.svg diff --git a/static/css/bootstrap-icons-1.11.3/houses-fill.svg b/app/static/css/bootstrap-icons-1.11.3/houses-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/houses-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/houses-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/houses.svg b/app/static/css/bootstrap-icons-1.11.3/houses.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/houses.svg rename to app/static/css/bootstrap-icons-1.11.3/houses.svg diff --git a/static/css/bootstrap-icons-1.11.3/hr.svg b/app/static/css/bootstrap-icons-1.11.3/hr.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hr.svg rename to app/static/css/bootstrap-icons-1.11.3/hr.svg diff --git a/static/css/bootstrap-icons-1.11.3/hurricane.svg b/app/static/css/bootstrap-icons-1.11.3/hurricane.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hurricane.svg rename to app/static/css/bootstrap-icons-1.11.3/hurricane.svg diff --git a/static/css/bootstrap-icons-1.11.3/hypnotize.svg b/app/static/css/bootstrap-icons-1.11.3/hypnotize.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/hypnotize.svg rename to app/static/css/bootstrap-icons-1.11.3/hypnotize.svg diff --git a/static/css/bootstrap-icons-1.11.3/image-alt.svg b/app/static/css/bootstrap-icons-1.11.3/image-alt.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/image-alt.svg rename to app/static/css/bootstrap-icons-1.11.3/image-alt.svg diff --git a/static/css/bootstrap-icons-1.11.3/image-fill.svg b/app/static/css/bootstrap-icons-1.11.3/image-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/image-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/image-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/image.svg b/app/static/css/bootstrap-icons-1.11.3/image.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/image.svg rename to app/static/css/bootstrap-icons-1.11.3/image.svg diff --git a/static/css/bootstrap-icons-1.11.3/images.svg b/app/static/css/bootstrap-icons-1.11.3/images.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/images.svg rename to app/static/css/bootstrap-icons-1.11.3/images.svg diff --git a/static/css/bootstrap-icons-1.11.3/inbox-fill.svg b/app/static/css/bootstrap-icons-1.11.3/inbox-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/inbox-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/inbox-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/inbox.svg b/app/static/css/bootstrap-icons-1.11.3/inbox.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/inbox.svg rename to app/static/css/bootstrap-icons-1.11.3/inbox.svg diff --git a/static/css/bootstrap-icons-1.11.3/inboxes-fill.svg b/app/static/css/bootstrap-icons-1.11.3/inboxes-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/inboxes-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/inboxes-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/inboxes.svg b/app/static/css/bootstrap-icons-1.11.3/inboxes.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/inboxes.svg rename to app/static/css/bootstrap-icons-1.11.3/inboxes.svg diff --git a/static/css/bootstrap-icons-1.11.3/incognito.svg b/app/static/css/bootstrap-icons-1.11.3/incognito.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/incognito.svg rename to app/static/css/bootstrap-icons-1.11.3/incognito.svg diff --git a/static/css/bootstrap-icons-1.11.3/indent.svg b/app/static/css/bootstrap-icons-1.11.3/indent.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/indent.svg rename to app/static/css/bootstrap-icons-1.11.3/indent.svg diff --git a/static/css/bootstrap-icons-1.11.3/infinity.svg b/app/static/css/bootstrap-icons-1.11.3/infinity.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/infinity.svg rename to app/static/css/bootstrap-icons-1.11.3/infinity.svg diff --git a/static/css/bootstrap-icons-1.11.3/info-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/info-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/info-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/info-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/info-circle.svg b/app/static/css/bootstrap-icons-1.11.3/info-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/info-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/info-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/info-lg.svg b/app/static/css/bootstrap-icons-1.11.3/info-lg.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/info-lg.svg rename to app/static/css/bootstrap-icons-1.11.3/info-lg.svg diff --git a/static/css/bootstrap-icons-1.11.3/info-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/info-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/info-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/info-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/info-square.svg b/app/static/css/bootstrap-icons-1.11.3/info-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/info-square.svg rename to app/static/css/bootstrap-icons-1.11.3/info-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/info.svg b/app/static/css/bootstrap-icons-1.11.3/info.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/info.svg rename to app/static/css/bootstrap-icons-1.11.3/info.svg diff --git a/static/css/bootstrap-icons-1.11.3/input-cursor-text.svg b/app/static/css/bootstrap-icons-1.11.3/input-cursor-text.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/input-cursor-text.svg rename to app/static/css/bootstrap-icons-1.11.3/input-cursor-text.svg diff --git a/static/css/bootstrap-icons-1.11.3/input-cursor.svg b/app/static/css/bootstrap-icons-1.11.3/input-cursor.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/input-cursor.svg rename to app/static/css/bootstrap-icons-1.11.3/input-cursor.svg diff --git a/static/css/bootstrap-icons-1.11.3/instagram.svg b/app/static/css/bootstrap-icons-1.11.3/instagram.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/instagram.svg rename to app/static/css/bootstrap-icons-1.11.3/instagram.svg diff --git a/static/css/bootstrap-icons-1.11.3/intersect.svg b/app/static/css/bootstrap-icons-1.11.3/intersect.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/intersect.svg rename to app/static/css/bootstrap-icons-1.11.3/intersect.svg diff --git a/static/css/bootstrap-icons-1.11.3/journal-album.svg b/app/static/css/bootstrap-icons-1.11.3/journal-album.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/journal-album.svg rename to app/static/css/bootstrap-icons-1.11.3/journal-album.svg diff --git a/static/css/bootstrap-icons-1.11.3/journal-arrow-down.svg b/app/static/css/bootstrap-icons-1.11.3/journal-arrow-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/journal-arrow-down.svg rename to app/static/css/bootstrap-icons-1.11.3/journal-arrow-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/journal-arrow-up.svg b/app/static/css/bootstrap-icons-1.11.3/journal-arrow-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/journal-arrow-up.svg rename to app/static/css/bootstrap-icons-1.11.3/journal-arrow-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/journal-bookmark-fill.svg b/app/static/css/bootstrap-icons-1.11.3/journal-bookmark-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/journal-bookmark-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/journal-bookmark-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/journal-bookmark.svg b/app/static/css/bootstrap-icons-1.11.3/journal-bookmark.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/journal-bookmark.svg rename to app/static/css/bootstrap-icons-1.11.3/journal-bookmark.svg diff --git a/static/css/bootstrap-icons-1.11.3/journal-check.svg b/app/static/css/bootstrap-icons-1.11.3/journal-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/journal-check.svg rename to app/static/css/bootstrap-icons-1.11.3/journal-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/journal-code.svg b/app/static/css/bootstrap-icons-1.11.3/journal-code.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/journal-code.svg rename to app/static/css/bootstrap-icons-1.11.3/journal-code.svg diff --git a/static/css/bootstrap-icons-1.11.3/journal-medical.svg b/app/static/css/bootstrap-icons-1.11.3/journal-medical.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/journal-medical.svg rename to app/static/css/bootstrap-icons-1.11.3/journal-medical.svg diff --git a/static/css/bootstrap-icons-1.11.3/journal-minus.svg b/app/static/css/bootstrap-icons-1.11.3/journal-minus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/journal-minus.svg rename to app/static/css/bootstrap-icons-1.11.3/journal-minus.svg diff --git a/static/css/bootstrap-icons-1.11.3/journal-plus.svg b/app/static/css/bootstrap-icons-1.11.3/journal-plus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/journal-plus.svg rename to app/static/css/bootstrap-icons-1.11.3/journal-plus.svg diff --git a/static/css/bootstrap-icons-1.11.3/journal-richtext.svg b/app/static/css/bootstrap-icons-1.11.3/journal-richtext.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/journal-richtext.svg rename to app/static/css/bootstrap-icons-1.11.3/journal-richtext.svg diff --git a/static/css/bootstrap-icons-1.11.3/journal-text.svg b/app/static/css/bootstrap-icons-1.11.3/journal-text.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/journal-text.svg rename to app/static/css/bootstrap-icons-1.11.3/journal-text.svg diff --git a/static/css/bootstrap-icons-1.11.3/journal-x.svg b/app/static/css/bootstrap-icons-1.11.3/journal-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/journal-x.svg rename to app/static/css/bootstrap-icons-1.11.3/journal-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/journal.svg b/app/static/css/bootstrap-icons-1.11.3/journal.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/journal.svg rename to app/static/css/bootstrap-icons-1.11.3/journal.svg diff --git a/static/css/bootstrap-icons-1.11.3/journals.svg b/app/static/css/bootstrap-icons-1.11.3/journals.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/journals.svg rename to app/static/css/bootstrap-icons-1.11.3/journals.svg diff --git a/static/css/bootstrap-icons-1.11.3/joystick.svg b/app/static/css/bootstrap-icons-1.11.3/joystick.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/joystick.svg rename to app/static/css/bootstrap-icons-1.11.3/joystick.svg diff --git a/static/css/bootstrap-icons-1.11.3/justify-left.svg b/app/static/css/bootstrap-icons-1.11.3/justify-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/justify-left.svg rename to app/static/css/bootstrap-icons-1.11.3/justify-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/justify-right.svg b/app/static/css/bootstrap-icons-1.11.3/justify-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/justify-right.svg rename to app/static/css/bootstrap-icons-1.11.3/justify-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/justify.svg b/app/static/css/bootstrap-icons-1.11.3/justify.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/justify.svg rename to app/static/css/bootstrap-icons-1.11.3/justify.svg diff --git a/static/css/bootstrap-icons-1.11.3/kanban-fill.svg b/app/static/css/bootstrap-icons-1.11.3/kanban-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/kanban-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/kanban-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/kanban.svg b/app/static/css/bootstrap-icons-1.11.3/kanban.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/kanban.svg rename to app/static/css/bootstrap-icons-1.11.3/kanban.svg diff --git a/static/css/bootstrap-icons-1.11.3/key-fill.svg b/app/static/css/bootstrap-icons-1.11.3/key-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/key-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/key-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/key.svg b/app/static/css/bootstrap-icons-1.11.3/key.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/key.svg rename to app/static/css/bootstrap-icons-1.11.3/key.svg diff --git a/static/css/bootstrap-icons-1.11.3/keyboard-fill.svg b/app/static/css/bootstrap-icons-1.11.3/keyboard-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/keyboard-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/keyboard-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/keyboard.svg b/app/static/css/bootstrap-icons-1.11.3/keyboard.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/keyboard.svg rename to app/static/css/bootstrap-icons-1.11.3/keyboard.svg diff --git a/static/css/bootstrap-icons-1.11.3/ladder.svg b/app/static/css/bootstrap-icons-1.11.3/ladder.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/ladder.svg rename to app/static/css/bootstrap-icons-1.11.3/ladder.svg diff --git a/static/css/bootstrap-icons-1.11.3/lamp-fill.svg b/app/static/css/bootstrap-icons-1.11.3/lamp-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/lamp-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/lamp-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/lamp.svg b/app/static/css/bootstrap-icons-1.11.3/lamp.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/lamp.svg rename to app/static/css/bootstrap-icons-1.11.3/lamp.svg diff --git a/static/css/bootstrap-icons-1.11.3/laptop-fill.svg b/app/static/css/bootstrap-icons-1.11.3/laptop-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/laptop-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/laptop-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/laptop.svg b/app/static/css/bootstrap-icons-1.11.3/laptop.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/laptop.svg rename to app/static/css/bootstrap-icons-1.11.3/laptop.svg diff --git a/static/css/bootstrap-icons-1.11.3/layer-backward.svg b/app/static/css/bootstrap-icons-1.11.3/layer-backward.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/layer-backward.svg rename to app/static/css/bootstrap-icons-1.11.3/layer-backward.svg diff --git a/static/css/bootstrap-icons-1.11.3/layer-forward.svg b/app/static/css/bootstrap-icons-1.11.3/layer-forward.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/layer-forward.svg rename to app/static/css/bootstrap-icons-1.11.3/layer-forward.svg diff --git a/static/css/bootstrap-icons-1.11.3/layers-fill.svg b/app/static/css/bootstrap-icons-1.11.3/layers-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/layers-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/layers-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/layers-half.svg b/app/static/css/bootstrap-icons-1.11.3/layers-half.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/layers-half.svg rename to app/static/css/bootstrap-icons-1.11.3/layers-half.svg diff --git a/static/css/bootstrap-icons-1.11.3/layers.svg b/app/static/css/bootstrap-icons-1.11.3/layers.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/layers.svg rename to app/static/css/bootstrap-icons-1.11.3/layers.svg diff --git a/static/css/bootstrap-icons-1.11.3/layout-sidebar-inset-reverse.svg b/app/static/css/bootstrap-icons-1.11.3/layout-sidebar-inset-reverse.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/layout-sidebar-inset-reverse.svg rename to app/static/css/bootstrap-icons-1.11.3/layout-sidebar-inset-reverse.svg diff --git a/static/css/bootstrap-icons-1.11.3/layout-sidebar-inset.svg b/app/static/css/bootstrap-icons-1.11.3/layout-sidebar-inset.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/layout-sidebar-inset.svg rename to app/static/css/bootstrap-icons-1.11.3/layout-sidebar-inset.svg diff --git a/static/css/bootstrap-icons-1.11.3/layout-sidebar-reverse.svg b/app/static/css/bootstrap-icons-1.11.3/layout-sidebar-reverse.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/layout-sidebar-reverse.svg rename to app/static/css/bootstrap-icons-1.11.3/layout-sidebar-reverse.svg diff --git a/static/css/bootstrap-icons-1.11.3/layout-sidebar.svg b/app/static/css/bootstrap-icons-1.11.3/layout-sidebar.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/layout-sidebar.svg rename to app/static/css/bootstrap-icons-1.11.3/layout-sidebar.svg diff --git a/static/css/bootstrap-icons-1.11.3/layout-split.svg b/app/static/css/bootstrap-icons-1.11.3/layout-split.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/layout-split.svg rename to app/static/css/bootstrap-icons-1.11.3/layout-split.svg diff --git a/static/css/bootstrap-icons-1.11.3/layout-text-sidebar-reverse.svg b/app/static/css/bootstrap-icons-1.11.3/layout-text-sidebar-reverse.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/layout-text-sidebar-reverse.svg rename to app/static/css/bootstrap-icons-1.11.3/layout-text-sidebar-reverse.svg diff --git a/static/css/bootstrap-icons-1.11.3/layout-text-sidebar.svg b/app/static/css/bootstrap-icons-1.11.3/layout-text-sidebar.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/layout-text-sidebar.svg rename to app/static/css/bootstrap-icons-1.11.3/layout-text-sidebar.svg diff --git a/static/css/bootstrap-icons-1.11.3/layout-text-window-reverse.svg b/app/static/css/bootstrap-icons-1.11.3/layout-text-window-reverse.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/layout-text-window-reverse.svg rename to app/static/css/bootstrap-icons-1.11.3/layout-text-window-reverse.svg diff --git a/static/css/bootstrap-icons-1.11.3/layout-text-window.svg b/app/static/css/bootstrap-icons-1.11.3/layout-text-window.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/layout-text-window.svg rename to app/static/css/bootstrap-icons-1.11.3/layout-text-window.svg diff --git a/static/css/bootstrap-icons-1.11.3/layout-three-columns.svg b/app/static/css/bootstrap-icons-1.11.3/layout-three-columns.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/layout-three-columns.svg rename to app/static/css/bootstrap-icons-1.11.3/layout-three-columns.svg diff --git a/static/css/bootstrap-icons-1.11.3/layout-wtf.svg b/app/static/css/bootstrap-icons-1.11.3/layout-wtf.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/layout-wtf.svg rename to app/static/css/bootstrap-icons-1.11.3/layout-wtf.svg diff --git a/static/css/bootstrap-icons-1.11.3/life-preserver.svg b/app/static/css/bootstrap-icons-1.11.3/life-preserver.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/life-preserver.svg rename to app/static/css/bootstrap-icons-1.11.3/life-preserver.svg diff --git a/static/css/bootstrap-icons-1.11.3/lightbulb-fill.svg b/app/static/css/bootstrap-icons-1.11.3/lightbulb-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/lightbulb-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/lightbulb-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/lightbulb-off-fill.svg b/app/static/css/bootstrap-icons-1.11.3/lightbulb-off-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/lightbulb-off-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/lightbulb-off-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/lightbulb-off.svg b/app/static/css/bootstrap-icons-1.11.3/lightbulb-off.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/lightbulb-off.svg rename to app/static/css/bootstrap-icons-1.11.3/lightbulb-off.svg diff --git a/static/css/bootstrap-icons-1.11.3/lightbulb.svg b/app/static/css/bootstrap-icons-1.11.3/lightbulb.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/lightbulb.svg rename to app/static/css/bootstrap-icons-1.11.3/lightbulb.svg diff --git a/static/css/bootstrap-icons-1.11.3/lightning-charge-fill.svg b/app/static/css/bootstrap-icons-1.11.3/lightning-charge-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/lightning-charge-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/lightning-charge-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/lightning-charge.svg b/app/static/css/bootstrap-icons-1.11.3/lightning-charge.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/lightning-charge.svg rename to app/static/css/bootstrap-icons-1.11.3/lightning-charge.svg diff --git a/static/css/bootstrap-icons-1.11.3/lightning-fill.svg b/app/static/css/bootstrap-icons-1.11.3/lightning-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/lightning-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/lightning-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/lightning.svg b/app/static/css/bootstrap-icons-1.11.3/lightning.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/lightning.svg rename to app/static/css/bootstrap-icons-1.11.3/lightning.svg diff --git a/static/css/bootstrap-icons-1.11.3/line.svg b/app/static/css/bootstrap-icons-1.11.3/line.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/line.svg rename to app/static/css/bootstrap-icons-1.11.3/line.svg diff --git a/static/css/bootstrap-icons-1.11.3/link-45deg.svg b/app/static/css/bootstrap-icons-1.11.3/link-45deg.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/link-45deg.svg rename to app/static/css/bootstrap-icons-1.11.3/link-45deg.svg diff --git a/static/css/bootstrap-icons-1.11.3/link.svg b/app/static/css/bootstrap-icons-1.11.3/link.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/link.svg rename to app/static/css/bootstrap-icons-1.11.3/link.svg diff --git a/static/css/bootstrap-icons-1.11.3/linkedin.svg b/app/static/css/bootstrap-icons-1.11.3/linkedin.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/linkedin.svg rename to app/static/css/bootstrap-icons-1.11.3/linkedin.svg diff --git a/static/css/bootstrap-icons-1.11.3/list-check.svg b/app/static/css/bootstrap-icons-1.11.3/list-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/list-check.svg rename to app/static/css/bootstrap-icons-1.11.3/list-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/list-columns-reverse.svg b/app/static/css/bootstrap-icons-1.11.3/list-columns-reverse.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/list-columns-reverse.svg rename to app/static/css/bootstrap-icons-1.11.3/list-columns-reverse.svg diff --git a/static/css/bootstrap-icons-1.11.3/list-columns.svg b/app/static/css/bootstrap-icons-1.11.3/list-columns.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/list-columns.svg rename to app/static/css/bootstrap-icons-1.11.3/list-columns.svg diff --git a/static/css/bootstrap-icons-1.11.3/list-nested.svg b/app/static/css/bootstrap-icons-1.11.3/list-nested.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/list-nested.svg rename to app/static/css/bootstrap-icons-1.11.3/list-nested.svg diff --git a/static/css/bootstrap-icons-1.11.3/list-ol.svg b/app/static/css/bootstrap-icons-1.11.3/list-ol.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/list-ol.svg rename to app/static/css/bootstrap-icons-1.11.3/list-ol.svg diff --git a/static/css/bootstrap-icons-1.11.3/list-stars.svg b/app/static/css/bootstrap-icons-1.11.3/list-stars.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/list-stars.svg rename to app/static/css/bootstrap-icons-1.11.3/list-stars.svg diff --git a/static/css/bootstrap-icons-1.11.3/list-task.svg b/app/static/css/bootstrap-icons-1.11.3/list-task.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/list-task.svg rename to app/static/css/bootstrap-icons-1.11.3/list-task.svg diff --git a/static/css/bootstrap-icons-1.11.3/list-ul.svg b/app/static/css/bootstrap-icons-1.11.3/list-ul.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/list-ul.svg rename to app/static/css/bootstrap-icons-1.11.3/list-ul.svg diff --git a/static/css/bootstrap-icons-1.11.3/list.svg b/app/static/css/bootstrap-icons-1.11.3/list.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/list.svg rename to app/static/css/bootstrap-icons-1.11.3/list.svg diff --git a/static/css/bootstrap-icons-1.11.3/lock-fill.svg b/app/static/css/bootstrap-icons-1.11.3/lock-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/lock-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/lock-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/lock.svg b/app/static/css/bootstrap-icons-1.11.3/lock.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/lock.svg rename to app/static/css/bootstrap-icons-1.11.3/lock.svg diff --git a/static/css/bootstrap-icons-1.11.3/luggage-fill.svg b/app/static/css/bootstrap-icons-1.11.3/luggage-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/luggage-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/luggage-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/luggage.svg b/app/static/css/bootstrap-icons-1.11.3/luggage.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/luggage.svg rename to app/static/css/bootstrap-icons-1.11.3/luggage.svg diff --git a/static/css/bootstrap-icons-1.11.3/lungs-fill.svg b/app/static/css/bootstrap-icons-1.11.3/lungs-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/lungs-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/lungs-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/lungs.svg b/app/static/css/bootstrap-icons-1.11.3/lungs.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/lungs.svg rename to app/static/css/bootstrap-icons-1.11.3/lungs.svg diff --git a/static/css/bootstrap-icons-1.11.3/magic.svg b/app/static/css/bootstrap-icons-1.11.3/magic.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/magic.svg rename to app/static/css/bootstrap-icons-1.11.3/magic.svg diff --git a/static/css/bootstrap-icons-1.11.3/magnet-fill.svg b/app/static/css/bootstrap-icons-1.11.3/magnet-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/magnet-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/magnet-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/magnet.svg b/app/static/css/bootstrap-icons-1.11.3/magnet.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/magnet.svg rename to app/static/css/bootstrap-icons-1.11.3/magnet.svg diff --git a/static/css/bootstrap-icons-1.11.3/mailbox-flag.svg b/app/static/css/bootstrap-icons-1.11.3/mailbox-flag.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/mailbox-flag.svg rename to app/static/css/bootstrap-icons-1.11.3/mailbox-flag.svg diff --git a/static/css/bootstrap-icons-1.11.3/mailbox.svg b/app/static/css/bootstrap-icons-1.11.3/mailbox.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/mailbox.svg rename to app/static/css/bootstrap-icons-1.11.3/mailbox.svg diff --git a/static/css/bootstrap-icons-1.11.3/mailbox2-flag.svg b/app/static/css/bootstrap-icons-1.11.3/mailbox2-flag.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/mailbox2-flag.svg rename to app/static/css/bootstrap-icons-1.11.3/mailbox2-flag.svg diff --git a/static/css/bootstrap-icons-1.11.3/mailbox2.svg b/app/static/css/bootstrap-icons-1.11.3/mailbox2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/mailbox2.svg rename to app/static/css/bootstrap-icons-1.11.3/mailbox2.svg diff --git a/static/css/bootstrap-icons-1.11.3/map-fill.svg b/app/static/css/bootstrap-icons-1.11.3/map-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/map-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/map-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/map.svg b/app/static/css/bootstrap-icons-1.11.3/map.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/map.svg rename to app/static/css/bootstrap-icons-1.11.3/map.svg diff --git a/static/css/bootstrap-icons-1.11.3/markdown-fill.svg b/app/static/css/bootstrap-icons-1.11.3/markdown-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/markdown-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/markdown-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/markdown.svg b/app/static/css/bootstrap-icons-1.11.3/markdown.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/markdown.svg rename to app/static/css/bootstrap-icons-1.11.3/markdown.svg diff --git a/static/css/bootstrap-icons-1.11.3/marker-tip.svg b/app/static/css/bootstrap-icons-1.11.3/marker-tip.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/marker-tip.svg rename to app/static/css/bootstrap-icons-1.11.3/marker-tip.svg diff --git a/static/css/bootstrap-icons-1.11.3/mask.svg b/app/static/css/bootstrap-icons-1.11.3/mask.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/mask.svg rename to app/static/css/bootstrap-icons-1.11.3/mask.svg diff --git a/static/css/bootstrap-icons-1.11.3/mastodon.svg b/app/static/css/bootstrap-icons-1.11.3/mastodon.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/mastodon.svg rename to app/static/css/bootstrap-icons-1.11.3/mastodon.svg diff --git a/static/css/bootstrap-icons-1.11.3/medium.svg b/app/static/css/bootstrap-icons-1.11.3/medium.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/medium.svg rename to app/static/css/bootstrap-icons-1.11.3/medium.svg diff --git a/static/css/bootstrap-icons-1.11.3/megaphone-fill.svg b/app/static/css/bootstrap-icons-1.11.3/megaphone-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/megaphone-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/megaphone-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/megaphone.svg b/app/static/css/bootstrap-icons-1.11.3/megaphone.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/megaphone.svg rename to app/static/css/bootstrap-icons-1.11.3/megaphone.svg diff --git a/static/css/bootstrap-icons-1.11.3/memory.svg b/app/static/css/bootstrap-icons-1.11.3/memory.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/memory.svg rename to app/static/css/bootstrap-icons-1.11.3/memory.svg diff --git a/static/css/bootstrap-icons-1.11.3/menu-app-fill.svg b/app/static/css/bootstrap-icons-1.11.3/menu-app-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/menu-app-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/menu-app-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/menu-app.svg b/app/static/css/bootstrap-icons-1.11.3/menu-app.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/menu-app.svg rename to app/static/css/bootstrap-icons-1.11.3/menu-app.svg diff --git a/static/css/bootstrap-icons-1.11.3/menu-button-fill.svg b/app/static/css/bootstrap-icons-1.11.3/menu-button-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/menu-button-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/menu-button-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/menu-button-wide-fill.svg b/app/static/css/bootstrap-icons-1.11.3/menu-button-wide-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/menu-button-wide-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/menu-button-wide-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/menu-button-wide.svg b/app/static/css/bootstrap-icons-1.11.3/menu-button-wide.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/menu-button-wide.svg rename to app/static/css/bootstrap-icons-1.11.3/menu-button-wide.svg diff --git a/static/css/bootstrap-icons-1.11.3/menu-button.svg b/app/static/css/bootstrap-icons-1.11.3/menu-button.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/menu-button.svg rename to app/static/css/bootstrap-icons-1.11.3/menu-button.svg diff --git a/static/css/bootstrap-icons-1.11.3/menu-down.svg b/app/static/css/bootstrap-icons-1.11.3/menu-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/menu-down.svg rename to app/static/css/bootstrap-icons-1.11.3/menu-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/menu-up.svg b/app/static/css/bootstrap-icons-1.11.3/menu-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/menu-up.svg rename to app/static/css/bootstrap-icons-1.11.3/menu-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/messenger.svg b/app/static/css/bootstrap-icons-1.11.3/messenger.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/messenger.svg rename to app/static/css/bootstrap-icons-1.11.3/messenger.svg diff --git a/static/css/bootstrap-icons-1.11.3/meta.svg b/app/static/css/bootstrap-icons-1.11.3/meta.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/meta.svg rename to app/static/css/bootstrap-icons-1.11.3/meta.svg diff --git a/static/css/bootstrap-icons-1.11.3/mic-fill.svg b/app/static/css/bootstrap-icons-1.11.3/mic-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/mic-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/mic-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/mic-mute-fill.svg b/app/static/css/bootstrap-icons-1.11.3/mic-mute-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/mic-mute-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/mic-mute-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/mic-mute.svg b/app/static/css/bootstrap-icons-1.11.3/mic-mute.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/mic-mute.svg rename to app/static/css/bootstrap-icons-1.11.3/mic-mute.svg diff --git a/static/css/bootstrap-icons-1.11.3/mic.svg b/app/static/css/bootstrap-icons-1.11.3/mic.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/mic.svg rename to app/static/css/bootstrap-icons-1.11.3/mic.svg diff --git a/static/css/bootstrap-icons-1.11.3/microsoft-teams.svg b/app/static/css/bootstrap-icons-1.11.3/microsoft-teams.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/microsoft-teams.svg rename to app/static/css/bootstrap-icons-1.11.3/microsoft-teams.svg diff --git a/static/css/bootstrap-icons-1.11.3/microsoft.svg b/app/static/css/bootstrap-icons-1.11.3/microsoft.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/microsoft.svg rename to app/static/css/bootstrap-icons-1.11.3/microsoft.svg diff --git a/static/css/bootstrap-icons-1.11.3/minecart-loaded.svg b/app/static/css/bootstrap-icons-1.11.3/minecart-loaded.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/minecart-loaded.svg rename to app/static/css/bootstrap-icons-1.11.3/minecart-loaded.svg diff --git a/static/css/bootstrap-icons-1.11.3/minecart.svg b/app/static/css/bootstrap-icons-1.11.3/minecart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/minecart.svg rename to app/static/css/bootstrap-icons-1.11.3/minecart.svg diff --git a/static/css/bootstrap-icons-1.11.3/modem-fill.svg b/app/static/css/bootstrap-icons-1.11.3/modem-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/modem-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/modem-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/modem.svg b/app/static/css/bootstrap-icons-1.11.3/modem.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/modem.svg rename to app/static/css/bootstrap-icons-1.11.3/modem.svg diff --git a/static/css/bootstrap-icons-1.11.3/moisture.svg b/app/static/css/bootstrap-icons-1.11.3/moisture.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/moisture.svg rename to app/static/css/bootstrap-icons-1.11.3/moisture.svg diff --git a/static/css/bootstrap-icons-1.11.3/moon-fill.svg b/app/static/css/bootstrap-icons-1.11.3/moon-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/moon-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/moon-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/moon-stars-fill.svg b/app/static/css/bootstrap-icons-1.11.3/moon-stars-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/moon-stars-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/moon-stars-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/moon-stars.svg b/app/static/css/bootstrap-icons-1.11.3/moon-stars.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/moon-stars.svg rename to app/static/css/bootstrap-icons-1.11.3/moon-stars.svg diff --git a/static/css/bootstrap-icons-1.11.3/moon.svg b/app/static/css/bootstrap-icons-1.11.3/moon.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/moon.svg rename to app/static/css/bootstrap-icons-1.11.3/moon.svg diff --git a/static/css/bootstrap-icons-1.11.3/mortarboard-fill.svg b/app/static/css/bootstrap-icons-1.11.3/mortarboard-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/mortarboard-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/mortarboard-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/mortarboard.svg b/app/static/css/bootstrap-icons-1.11.3/mortarboard.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/mortarboard.svg rename to app/static/css/bootstrap-icons-1.11.3/mortarboard.svg diff --git a/static/css/bootstrap-icons-1.11.3/motherboard-fill.svg b/app/static/css/bootstrap-icons-1.11.3/motherboard-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/motherboard-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/motherboard-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/motherboard.svg b/app/static/css/bootstrap-icons-1.11.3/motherboard.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/motherboard.svg rename to app/static/css/bootstrap-icons-1.11.3/motherboard.svg diff --git a/static/css/bootstrap-icons-1.11.3/mouse-fill.svg b/app/static/css/bootstrap-icons-1.11.3/mouse-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/mouse-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/mouse-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/mouse.svg b/app/static/css/bootstrap-icons-1.11.3/mouse.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/mouse.svg rename to app/static/css/bootstrap-icons-1.11.3/mouse.svg diff --git a/static/css/bootstrap-icons-1.11.3/mouse2-fill.svg b/app/static/css/bootstrap-icons-1.11.3/mouse2-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/mouse2-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/mouse2-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/mouse2.svg b/app/static/css/bootstrap-icons-1.11.3/mouse2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/mouse2.svg rename to app/static/css/bootstrap-icons-1.11.3/mouse2.svg diff --git a/static/css/bootstrap-icons-1.11.3/mouse3-fill.svg b/app/static/css/bootstrap-icons-1.11.3/mouse3-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/mouse3-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/mouse3-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/mouse3.svg b/app/static/css/bootstrap-icons-1.11.3/mouse3.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/mouse3.svg rename to app/static/css/bootstrap-icons-1.11.3/mouse3.svg diff --git a/static/css/bootstrap-icons-1.11.3/music-note-beamed.svg b/app/static/css/bootstrap-icons-1.11.3/music-note-beamed.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/music-note-beamed.svg rename to app/static/css/bootstrap-icons-1.11.3/music-note-beamed.svg diff --git a/static/css/bootstrap-icons-1.11.3/music-note-list.svg b/app/static/css/bootstrap-icons-1.11.3/music-note-list.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/music-note-list.svg rename to app/static/css/bootstrap-icons-1.11.3/music-note-list.svg diff --git a/static/css/bootstrap-icons-1.11.3/music-note.svg b/app/static/css/bootstrap-icons-1.11.3/music-note.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/music-note.svg rename to app/static/css/bootstrap-icons-1.11.3/music-note.svg diff --git a/static/css/bootstrap-icons-1.11.3/music-player-fill.svg b/app/static/css/bootstrap-icons-1.11.3/music-player-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/music-player-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/music-player-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/music-player.svg b/app/static/css/bootstrap-icons-1.11.3/music-player.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/music-player.svg rename to app/static/css/bootstrap-icons-1.11.3/music-player.svg diff --git a/static/css/bootstrap-icons-1.11.3/newspaper.svg b/app/static/css/bootstrap-icons-1.11.3/newspaper.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/newspaper.svg rename to app/static/css/bootstrap-icons-1.11.3/newspaper.svg diff --git a/static/css/bootstrap-icons-1.11.3/nintendo-switch.svg b/app/static/css/bootstrap-icons-1.11.3/nintendo-switch.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/nintendo-switch.svg rename to app/static/css/bootstrap-icons-1.11.3/nintendo-switch.svg diff --git a/static/css/bootstrap-icons-1.11.3/node-minus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/node-minus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/node-minus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/node-minus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/node-minus.svg b/app/static/css/bootstrap-icons-1.11.3/node-minus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/node-minus.svg rename to app/static/css/bootstrap-icons-1.11.3/node-minus.svg diff --git a/static/css/bootstrap-icons-1.11.3/node-plus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/node-plus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/node-plus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/node-plus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/node-plus.svg b/app/static/css/bootstrap-icons-1.11.3/node-plus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/node-plus.svg rename to app/static/css/bootstrap-icons-1.11.3/node-plus.svg diff --git a/static/css/bootstrap-icons-1.11.3/noise-reduction.svg b/app/static/css/bootstrap-icons-1.11.3/noise-reduction.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/noise-reduction.svg rename to app/static/css/bootstrap-icons-1.11.3/noise-reduction.svg diff --git a/static/css/bootstrap-icons-1.11.3/nut-fill.svg b/app/static/css/bootstrap-icons-1.11.3/nut-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/nut-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/nut-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/nut.svg b/app/static/css/bootstrap-icons-1.11.3/nut.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/nut.svg rename to app/static/css/bootstrap-icons-1.11.3/nut.svg diff --git a/static/css/bootstrap-icons-1.11.3/nvidia.svg b/app/static/css/bootstrap-icons-1.11.3/nvidia.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/nvidia.svg rename to app/static/css/bootstrap-icons-1.11.3/nvidia.svg diff --git a/static/css/bootstrap-icons-1.11.3/nvme-fill.svg b/app/static/css/bootstrap-icons-1.11.3/nvme-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/nvme-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/nvme-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/nvme.svg b/app/static/css/bootstrap-icons-1.11.3/nvme.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/nvme.svg rename to app/static/css/bootstrap-icons-1.11.3/nvme.svg diff --git a/static/css/bootstrap-icons-1.11.3/octagon-fill.svg b/app/static/css/bootstrap-icons-1.11.3/octagon-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/octagon-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/octagon-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/octagon-half.svg b/app/static/css/bootstrap-icons-1.11.3/octagon-half.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/octagon-half.svg rename to app/static/css/bootstrap-icons-1.11.3/octagon-half.svg diff --git a/static/css/bootstrap-icons-1.11.3/octagon.svg b/app/static/css/bootstrap-icons-1.11.3/octagon.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/octagon.svg rename to app/static/css/bootstrap-icons-1.11.3/octagon.svg diff --git a/static/css/bootstrap-icons-1.11.3/opencollective.svg b/app/static/css/bootstrap-icons-1.11.3/opencollective.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/opencollective.svg rename to app/static/css/bootstrap-icons-1.11.3/opencollective.svg diff --git a/static/css/bootstrap-icons-1.11.3/optical-audio-fill.svg b/app/static/css/bootstrap-icons-1.11.3/optical-audio-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/optical-audio-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/optical-audio-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/optical-audio.svg b/app/static/css/bootstrap-icons-1.11.3/optical-audio.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/optical-audio.svg rename to app/static/css/bootstrap-icons-1.11.3/optical-audio.svg diff --git a/static/css/bootstrap-icons-1.11.3/option.svg b/app/static/css/bootstrap-icons-1.11.3/option.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/option.svg rename to app/static/css/bootstrap-icons-1.11.3/option.svg diff --git a/static/css/bootstrap-icons-1.11.3/outlet.svg b/app/static/css/bootstrap-icons-1.11.3/outlet.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/outlet.svg rename to app/static/css/bootstrap-icons-1.11.3/outlet.svg diff --git a/static/css/bootstrap-icons-1.11.3/p-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/p-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/p-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/p-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/p-circle.svg b/app/static/css/bootstrap-icons-1.11.3/p-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/p-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/p-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/p-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/p-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/p-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/p-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/p-square.svg b/app/static/css/bootstrap-icons-1.11.3/p-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/p-square.svg rename to app/static/css/bootstrap-icons-1.11.3/p-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/paint-bucket.svg b/app/static/css/bootstrap-icons-1.11.3/paint-bucket.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/paint-bucket.svg rename to app/static/css/bootstrap-icons-1.11.3/paint-bucket.svg diff --git a/static/css/bootstrap-icons-1.11.3/palette-fill.svg b/app/static/css/bootstrap-icons-1.11.3/palette-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/palette-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/palette-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/palette.svg b/app/static/css/bootstrap-icons-1.11.3/palette.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/palette.svg rename to app/static/css/bootstrap-icons-1.11.3/palette.svg diff --git a/static/css/bootstrap-icons-1.11.3/palette2.svg b/app/static/css/bootstrap-icons-1.11.3/palette2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/palette2.svg rename to app/static/css/bootstrap-icons-1.11.3/palette2.svg diff --git a/static/css/bootstrap-icons-1.11.3/paperclip.svg b/app/static/css/bootstrap-icons-1.11.3/paperclip.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/paperclip.svg rename to app/static/css/bootstrap-icons-1.11.3/paperclip.svg diff --git a/static/css/bootstrap-icons-1.11.3/paragraph.svg b/app/static/css/bootstrap-icons-1.11.3/paragraph.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/paragraph.svg rename to app/static/css/bootstrap-icons-1.11.3/paragraph.svg diff --git a/static/css/bootstrap-icons-1.11.3/pass-fill.svg b/app/static/css/bootstrap-icons-1.11.3/pass-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pass-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/pass-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/pass.svg b/app/static/css/bootstrap-icons-1.11.3/pass.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pass.svg rename to app/static/css/bootstrap-icons-1.11.3/pass.svg diff --git a/static/css/bootstrap-icons-1.11.3/passport-fill.svg b/app/static/css/bootstrap-icons-1.11.3/passport-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/passport-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/passport-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/passport.svg b/app/static/css/bootstrap-icons-1.11.3/passport.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/passport.svg rename to app/static/css/bootstrap-icons-1.11.3/passport.svg diff --git a/static/css/bootstrap-icons-1.11.3/patch-check-fill.svg b/app/static/css/bootstrap-icons-1.11.3/patch-check-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/patch-check-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/patch-check-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/patch-check.svg b/app/static/css/bootstrap-icons-1.11.3/patch-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/patch-check.svg rename to app/static/css/bootstrap-icons-1.11.3/patch-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/patch-exclamation-fill.svg b/app/static/css/bootstrap-icons-1.11.3/patch-exclamation-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/patch-exclamation-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/patch-exclamation-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/patch-exclamation.svg b/app/static/css/bootstrap-icons-1.11.3/patch-exclamation.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/patch-exclamation.svg rename to app/static/css/bootstrap-icons-1.11.3/patch-exclamation.svg diff --git a/static/css/bootstrap-icons-1.11.3/patch-minus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/patch-minus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/patch-minus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/patch-minus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/patch-minus.svg b/app/static/css/bootstrap-icons-1.11.3/patch-minus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/patch-minus.svg rename to app/static/css/bootstrap-icons-1.11.3/patch-minus.svg diff --git a/static/css/bootstrap-icons-1.11.3/patch-plus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/patch-plus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/patch-plus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/patch-plus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/patch-plus.svg b/app/static/css/bootstrap-icons-1.11.3/patch-plus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/patch-plus.svg rename to app/static/css/bootstrap-icons-1.11.3/patch-plus.svg diff --git a/static/css/bootstrap-icons-1.11.3/patch-question-fill.svg b/app/static/css/bootstrap-icons-1.11.3/patch-question-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/patch-question-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/patch-question-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/patch-question.svg b/app/static/css/bootstrap-icons-1.11.3/patch-question.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/patch-question.svg rename to app/static/css/bootstrap-icons-1.11.3/patch-question.svg diff --git a/static/css/bootstrap-icons-1.11.3/pause-btn-fill.svg b/app/static/css/bootstrap-icons-1.11.3/pause-btn-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pause-btn-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/pause-btn-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/pause-btn.svg b/app/static/css/bootstrap-icons-1.11.3/pause-btn.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pause-btn.svg rename to app/static/css/bootstrap-icons-1.11.3/pause-btn.svg diff --git a/static/css/bootstrap-icons-1.11.3/pause-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/pause-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pause-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/pause-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/pause-circle.svg b/app/static/css/bootstrap-icons-1.11.3/pause-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pause-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/pause-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/pause-fill.svg b/app/static/css/bootstrap-icons-1.11.3/pause-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pause-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/pause-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/pause.svg b/app/static/css/bootstrap-icons-1.11.3/pause.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pause.svg rename to app/static/css/bootstrap-icons-1.11.3/pause.svg diff --git a/static/css/bootstrap-icons-1.11.3/paypal.svg b/app/static/css/bootstrap-icons-1.11.3/paypal.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/paypal.svg rename to app/static/css/bootstrap-icons-1.11.3/paypal.svg diff --git a/static/css/bootstrap-icons-1.11.3/pc-display-horizontal.svg b/app/static/css/bootstrap-icons-1.11.3/pc-display-horizontal.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pc-display-horizontal.svg rename to app/static/css/bootstrap-icons-1.11.3/pc-display-horizontal.svg diff --git a/static/css/bootstrap-icons-1.11.3/pc-display.svg b/app/static/css/bootstrap-icons-1.11.3/pc-display.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pc-display.svg rename to app/static/css/bootstrap-icons-1.11.3/pc-display.svg diff --git a/static/css/bootstrap-icons-1.11.3/pc-horizontal.svg b/app/static/css/bootstrap-icons-1.11.3/pc-horizontal.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pc-horizontal.svg rename to app/static/css/bootstrap-icons-1.11.3/pc-horizontal.svg diff --git a/static/css/bootstrap-icons-1.11.3/pc.svg b/app/static/css/bootstrap-icons-1.11.3/pc.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pc.svg rename to app/static/css/bootstrap-icons-1.11.3/pc.svg diff --git a/static/css/bootstrap-icons-1.11.3/pci-card-network.svg b/app/static/css/bootstrap-icons-1.11.3/pci-card-network.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pci-card-network.svg rename to app/static/css/bootstrap-icons-1.11.3/pci-card-network.svg diff --git a/static/css/bootstrap-icons-1.11.3/pci-card-sound.svg b/app/static/css/bootstrap-icons-1.11.3/pci-card-sound.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pci-card-sound.svg rename to app/static/css/bootstrap-icons-1.11.3/pci-card-sound.svg diff --git a/static/css/bootstrap-icons-1.11.3/pci-card.svg b/app/static/css/bootstrap-icons-1.11.3/pci-card.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pci-card.svg rename to app/static/css/bootstrap-icons-1.11.3/pci-card.svg diff --git a/static/css/bootstrap-icons-1.11.3/peace-fill.svg b/app/static/css/bootstrap-icons-1.11.3/peace-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/peace-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/peace-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/peace.svg b/app/static/css/bootstrap-icons-1.11.3/peace.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/peace.svg rename to app/static/css/bootstrap-icons-1.11.3/peace.svg diff --git a/static/css/bootstrap-icons-1.11.3/pen-fill.svg b/app/static/css/bootstrap-icons-1.11.3/pen-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pen-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/pen-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/pen.svg b/app/static/css/bootstrap-icons-1.11.3/pen.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pen.svg rename to app/static/css/bootstrap-icons-1.11.3/pen.svg diff --git a/static/css/bootstrap-icons-1.11.3/pencil-fill.svg b/app/static/css/bootstrap-icons-1.11.3/pencil-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pencil-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/pencil-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/pencil-square.svg b/app/static/css/bootstrap-icons-1.11.3/pencil-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pencil-square.svg rename to app/static/css/bootstrap-icons-1.11.3/pencil-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/pencil.svg b/app/static/css/bootstrap-icons-1.11.3/pencil.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pencil.svg rename to app/static/css/bootstrap-icons-1.11.3/pencil.svg diff --git a/static/css/bootstrap-icons-1.11.3/pentagon-fill.svg b/app/static/css/bootstrap-icons-1.11.3/pentagon-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pentagon-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/pentagon-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/pentagon-half.svg b/app/static/css/bootstrap-icons-1.11.3/pentagon-half.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pentagon-half.svg rename to app/static/css/bootstrap-icons-1.11.3/pentagon-half.svg diff --git a/static/css/bootstrap-icons-1.11.3/pentagon.svg b/app/static/css/bootstrap-icons-1.11.3/pentagon.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pentagon.svg rename to app/static/css/bootstrap-icons-1.11.3/pentagon.svg diff --git a/static/css/bootstrap-icons-1.11.3/people-fill.svg b/app/static/css/bootstrap-icons-1.11.3/people-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/people-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/people-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/people.svg b/app/static/css/bootstrap-icons-1.11.3/people.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/people.svg rename to app/static/css/bootstrap-icons-1.11.3/people.svg diff --git a/static/css/bootstrap-icons-1.11.3/percent.svg b/app/static/css/bootstrap-icons-1.11.3/percent.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/percent.svg rename to app/static/css/bootstrap-icons-1.11.3/percent.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-add.svg b/app/static/css/bootstrap-icons-1.11.3/person-add.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-add.svg rename to app/static/css/bootstrap-icons-1.11.3/person-add.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-arms-up.svg b/app/static/css/bootstrap-icons-1.11.3/person-arms-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-arms-up.svg rename to app/static/css/bootstrap-icons-1.11.3/person-arms-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-badge-fill.svg b/app/static/css/bootstrap-icons-1.11.3/person-badge-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-badge-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/person-badge-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-badge.svg b/app/static/css/bootstrap-icons-1.11.3/person-badge.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-badge.svg rename to app/static/css/bootstrap-icons-1.11.3/person-badge.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-bounding-box.svg b/app/static/css/bootstrap-icons-1.11.3/person-bounding-box.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-bounding-box.svg rename to app/static/css/bootstrap-icons-1.11.3/person-bounding-box.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-check-fill.svg b/app/static/css/bootstrap-icons-1.11.3/person-check-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-check-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/person-check-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-check.svg b/app/static/css/bootstrap-icons-1.11.3/person-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-check.svg rename to app/static/css/bootstrap-icons-1.11.3/person-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-circle.svg b/app/static/css/bootstrap-icons-1.11.3/person-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/person-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-dash-fill.svg b/app/static/css/bootstrap-icons-1.11.3/person-dash-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-dash-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/person-dash-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-dash.svg b/app/static/css/bootstrap-icons-1.11.3/person-dash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-dash.svg rename to app/static/css/bootstrap-icons-1.11.3/person-dash.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-down.svg b/app/static/css/bootstrap-icons-1.11.3/person-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-down.svg rename to app/static/css/bootstrap-icons-1.11.3/person-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-exclamation.svg b/app/static/css/bootstrap-icons-1.11.3/person-exclamation.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-exclamation.svg rename to app/static/css/bootstrap-icons-1.11.3/person-exclamation.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-fill-add.svg b/app/static/css/bootstrap-icons-1.11.3/person-fill-add.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-fill-add.svg rename to app/static/css/bootstrap-icons-1.11.3/person-fill-add.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-fill-check.svg b/app/static/css/bootstrap-icons-1.11.3/person-fill-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-fill-check.svg rename to app/static/css/bootstrap-icons-1.11.3/person-fill-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-fill-dash.svg b/app/static/css/bootstrap-icons-1.11.3/person-fill-dash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-fill-dash.svg rename to app/static/css/bootstrap-icons-1.11.3/person-fill-dash.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-fill-down.svg b/app/static/css/bootstrap-icons-1.11.3/person-fill-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-fill-down.svg rename to app/static/css/bootstrap-icons-1.11.3/person-fill-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-fill-exclamation.svg b/app/static/css/bootstrap-icons-1.11.3/person-fill-exclamation.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-fill-exclamation.svg rename to app/static/css/bootstrap-icons-1.11.3/person-fill-exclamation.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-fill-gear.svg b/app/static/css/bootstrap-icons-1.11.3/person-fill-gear.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-fill-gear.svg rename to app/static/css/bootstrap-icons-1.11.3/person-fill-gear.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-fill-lock.svg b/app/static/css/bootstrap-icons-1.11.3/person-fill-lock.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-fill-lock.svg rename to app/static/css/bootstrap-icons-1.11.3/person-fill-lock.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-fill-slash.svg b/app/static/css/bootstrap-icons-1.11.3/person-fill-slash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-fill-slash.svg rename to app/static/css/bootstrap-icons-1.11.3/person-fill-slash.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-fill-up.svg b/app/static/css/bootstrap-icons-1.11.3/person-fill-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-fill-up.svg rename to app/static/css/bootstrap-icons-1.11.3/person-fill-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-fill-x.svg b/app/static/css/bootstrap-icons-1.11.3/person-fill-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-fill-x.svg rename to app/static/css/bootstrap-icons-1.11.3/person-fill-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-fill.svg b/app/static/css/bootstrap-icons-1.11.3/person-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/person-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-gear.svg b/app/static/css/bootstrap-icons-1.11.3/person-gear.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-gear.svg rename to app/static/css/bootstrap-icons-1.11.3/person-gear.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-heart.svg b/app/static/css/bootstrap-icons-1.11.3/person-heart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-heart.svg rename to app/static/css/bootstrap-icons-1.11.3/person-heart.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-hearts.svg b/app/static/css/bootstrap-icons-1.11.3/person-hearts.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-hearts.svg rename to app/static/css/bootstrap-icons-1.11.3/person-hearts.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-lines-fill.svg b/app/static/css/bootstrap-icons-1.11.3/person-lines-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-lines-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/person-lines-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-lock.svg b/app/static/css/bootstrap-icons-1.11.3/person-lock.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-lock.svg rename to app/static/css/bootstrap-icons-1.11.3/person-lock.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-plus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/person-plus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-plus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/person-plus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-plus.svg b/app/static/css/bootstrap-icons-1.11.3/person-plus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-plus.svg rename to app/static/css/bootstrap-icons-1.11.3/person-plus.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-raised-hand.svg b/app/static/css/bootstrap-icons-1.11.3/person-raised-hand.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-raised-hand.svg rename to app/static/css/bootstrap-icons-1.11.3/person-raised-hand.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-rolodex.svg b/app/static/css/bootstrap-icons-1.11.3/person-rolodex.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-rolodex.svg rename to app/static/css/bootstrap-icons-1.11.3/person-rolodex.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-slash.svg b/app/static/css/bootstrap-icons-1.11.3/person-slash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-slash.svg rename to app/static/css/bootstrap-icons-1.11.3/person-slash.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-square.svg b/app/static/css/bootstrap-icons-1.11.3/person-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-square.svg rename to app/static/css/bootstrap-icons-1.11.3/person-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-standing-dress.svg b/app/static/css/bootstrap-icons-1.11.3/person-standing-dress.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-standing-dress.svg rename to app/static/css/bootstrap-icons-1.11.3/person-standing-dress.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-standing.svg b/app/static/css/bootstrap-icons-1.11.3/person-standing.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-standing.svg rename to app/static/css/bootstrap-icons-1.11.3/person-standing.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-up.svg b/app/static/css/bootstrap-icons-1.11.3/person-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-up.svg rename to app/static/css/bootstrap-icons-1.11.3/person-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-vcard-fill.svg b/app/static/css/bootstrap-icons-1.11.3/person-vcard-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-vcard-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/person-vcard-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-vcard.svg b/app/static/css/bootstrap-icons-1.11.3/person-vcard.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-vcard.svg rename to app/static/css/bootstrap-icons-1.11.3/person-vcard.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-video.svg b/app/static/css/bootstrap-icons-1.11.3/person-video.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-video.svg rename to app/static/css/bootstrap-icons-1.11.3/person-video.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-video2.svg b/app/static/css/bootstrap-icons-1.11.3/person-video2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-video2.svg rename to app/static/css/bootstrap-icons-1.11.3/person-video2.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-video3.svg b/app/static/css/bootstrap-icons-1.11.3/person-video3.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-video3.svg rename to app/static/css/bootstrap-icons-1.11.3/person-video3.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-walking.svg b/app/static/css/bootstrap-icons-1.11.3/person-walking.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-walking.svg rename to app/static/css/bootstrap-icons-1.11.3/person-walking.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-wheelchair.svg b/app/static/css/bootstrap-icons-1.11.3/person-wheelchair.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-wheelchair.svg rename to app/static/css/bootstrap-icons-1.11.3/person-wheelchair.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-workspace.svg b/app/static/css/bootstrap-icons-1.11.3/person-workspace.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-workspace.svg rename to app/static/css/bootstrap-icons-1.11.3/person-workspace.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-x-fill.svg b/app/static/css/bootstrap-icons-1.11.3/person-x-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-x-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/person-x-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/person-x.svg b/app/static/css/bootstrap-icons-1.11.3/person-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person-x.svg rename to app/static/css/bootstrap-icons-1.11.3/person-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/person.svg b/app/static/css/bootstrap-icons-1.11.3/person.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/person.svg rename to app/static/css/bootstrap-icons-1.11.3/person.svg diff --git a/static/css/bootstrap-icons-1.11.3/phone-fill.svg b/app/static/css/bootstrap-icons-1.11.3/phone-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/phone-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/phone-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/phone-flip.svg b/app/static/css/bootstrap-icons-1.11.3/phone-flip.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/phone-flip.svg rename to app/static/css/bootstrap-icons-1.11.3/phone-flip.svg diff --git a/static/css/bootstrap-icons-1.11.3/phone-landscape-fill.svg b/app/static/css/bootstrap-icons-1.11.3/phone-landscape-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/phone-landscape-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/phone-landscape-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/phone-landscape.svg b/app/static/css/bootstrap-icons-1.11.3/phone-landscape.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/phone-landscape.svg rename to app/static/css/bootstrap-icons-1.11.3/phone-landscape.svg diff --git a/static/css/bootstrap-icons-1.11.3/phone-vibrate-fill.svg b/app/static/css/bootstrap-icons-1.11.3/phone-vibrate-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/phone-vibrate-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/phone-vibrate-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/phone-vibrate.svg b/app/static/css/bootstrap-icons-1.11.3/phone-vibrate.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/phone-vibrate.svg rename to app/static/css/bootstrap-icons-1.11.3/phone-vibrate.svg diff --git a/static/css/bootstrap-icons-1.11.3/phone.svg b/app/static/css/bootstrap-icons-1.11.3/phone.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/phone.svg rename to app/static/css/bootstrap-icons-1.11.3/phone.svg diff --git a/static/css/bootstrap-icons-1.11.3/pie-chart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/pie-chart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pie-chart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/pie-chart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/pie-chart.svg b/app/static/css/bootstrap-icons-1.11.3/pie-chart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pie-chart.svg rename to app/static/css/bootstrap-icons-1.11.3/pie-chart.svg diff --git a/static/css/bootstrap-icons-1.11.3/piggy-bank-fill.svg b/app/static/css/bootstrap-icons-1.11.3/piggy-bank-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/piggy-bank-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/piggy-bank-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/piggy-bank.svg b/app/static/css/bootstrap-icons-1.11.3/piggy-bank.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/piggy-bank.svg rename to app/static/css/bootstrap-icons-1.11.3/piggy-bank.svg diff --git a/static/css/bootstrap-icons-1.11.3/pin-angle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/pin-angle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pin-angle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/pin-angle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/pin-angle.svg b/app/static/css/bootstrap-icons-1.11.3/pin-angle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pin-angle.svg rename to app/static/css/bootstrap-icons-1.11.3/pin-angle.svg diff --git a/static/css/bootstrap-icons-1.11.3/pin-fill.svg b/app/static/css/bootstrap-icons-1.11.3/pin-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pin-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/pin-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/pin-map-fill.svg b/app/static/css/bootstrap-icons-1.11.3/pin-map-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pin-map-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/pin-map-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/pin-map.svg b/app/static/css/bootstrap-icons-1.11.3/pin-map.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pin-map.svg rename to app/static/css/bootstrap-icons-1.11.3/pin-map.svg diff --git a/static/css/bootstrap-icons-1.11.3/pin.svg b/app/static/css/bootstrap-icons-1.11.3/pin.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pin.svg rename to app/static/css/bootstrap-icons-1.11.3/pin.svg diff --git a/static/css/bootstrap-icons-1.11.3/pinterest.svg b/app/static/css/bootstrap-icons-1.11.3/pinterest.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pinterest.svg rename to app/static/css/bootstrap-icons-1.11.3/pinterest.svg diff --git a/static/css/bootstrap-icons-1.11.3/pip-fill.svg b/app/static/css/bootstrap-icons-1.11.3/pip-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pip-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/pip-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/pip.svg b/app/static/css/bootstrap-icons-1.11.3/pip.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/pip.svg rename to app/static/css/bootstrap-icons-1.11.3/pip.svg diff --git a/static/css/bootstrap-icons-1.11.3/play-btn-fill.svg b/app/static/css/bootstrap-icons-1.11.3/play-btn-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/play-btn-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/play-btn-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/play-btn.svg b/app/static/css/bootstrap-icons-1.11.3/play-btn.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/play-btn.svg rename to app/static/css/bootstrap-icons-1.11.3/play-btn.svg diff --git a/static/css/bootstrap-icons-1.11.3/play-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/play-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/play-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/play-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/play-circle.svg b/app/static/css/bootstrap-icons-1.11.3/play-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/play-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/play-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/play-fill.svg b/app/static/css/bootstrap-icons-1.11.3/play-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/play-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/play-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/play.svg b/app/static/css/bootstrap-icons-1.11.3/play.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/play.svg rename to app/static/css/bootstrap-icons-1.11.3/play.svg diff --git a/static/css/bootstrap-icons-1.11.3/playstation.svg b/app/static/css/bootstrap-icons-1.11.3/playstation.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/playstation.svg rename to app/static/css/bootstrap-icons-1.11.3/playstation.svg diff --git a/static/css/bootstrap-icons-1.11.3/plug-fill.svg b/app/static/css/bootstrap-icons-1.11.3/plug-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/plug-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/plug-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/plug.svg b/app/static/css/bootstrap-icons-1.11.3/plug.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/plug.svg rename to app/static/css/bootstrap-icons-1.11.3/plug.svg diff --git a/static/css/bootstrap-icons-1.11.3/plugin.svg b/app/static/css/bootstrap-icons-1.11.3/plugin.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/plugin.svg rename to app/static/css/bootstrap-icons-1.11.3/plugin.svg diff --git a/static/css/bootstrap-icons-1.11.3/plus-circle-dotted.svg b/app/static/css/bootstrap-icons-1.11.3/plus-circle-dotted.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/plus-circle-dotted.svg rename to app/static/css/bootstrap-icons-1.11.3/plus-circle-dotted.svg diff --git a/static/css/bootstrap-icons-1.11.3/plus-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/plus-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/plus-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/plus-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/plus-circle.svg b/app/static/css/bootstrap-icons-1.11.3/plus-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/plus-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/plus-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/plus-lg.svg b/app/static/css/bootstrap-icons-1.11.3/plus-lg.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/plus-lg.svg rename to app/static/css/bootstrap-icons-1.11.3/plus-lg.svg diff --git a/static/css/bootstrap-icons-1.11.3/plus-slash-minus.svg b/app/static/css/bootstrap-icons-1.11.3/plus-slash-minus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/plus-slash-minus.svg rename to app/static/css/bootstrap-icons-1.11.3/plus-slash-minus.svg diff --git a/static/css/bootstrap-icons-1.11.3/plus-square-dotted.svg b/app/static/css/bootstrap-icons-1.11.3/plus-square-dotted.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/plus-square-dotted.svg rename to app/static/css/bootstrap-icons-1.11.3/plus-square-dotted.svg diff --git a/static/css/bootstrap-icons-1.11.3/plus-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/plus-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/plus-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/plus-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/plus-square.svg b/app/static/css/bootstrap-icons-1.11.3/plus-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/plus-square.svg rename to app/static/css/bootstrap-icons-1.11.3/plus-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/plus.svg b/app/static/css/bootstrap-icons-1.11.3/plus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/plus.svg rename to app/static/css/bootstrap-icons-1.11.3/plus.svg diff --git a/static/css/bootstrap-icons-1.11.3/postage-fill.svg b/app/static/css/bootstrap-icons-1.11.3/postage-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/postage-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/postage-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/postage-heart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/postage-heart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/postage-heart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/postage-heart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/postage-heart.svg b/app/static/css/bootstrap-icons-1.11.3/postage-heart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/postage-heart.svg rename to app/static/css/bootstrap-icons-1.11.3/postage-heart.svg diff --git a/static/css/bootstrap-icons-1.11.3/postage.svg b/app/static/css/bootstrap-icons-1.11.3/postage.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/postage.svg rename to app/static/css/bootstrap-icons-1.11.3/postage.svg diff --git a/static/css/bootstrap-icons-1.11.3/postcard-fill.svg b/app/static/css/bootstrap-icons-1.11.3/postcard-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/postcard-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/postcard-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/postcard-heart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/postcard-heart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/postcard-heart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/postcard-heart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/postcard-heart.svg b/app/static/css/bootstrap-icons-1.11.3/postcard-heart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/postcard-heart.svg rename to app/static/css/bootstrap-icons-1.11.3/postcard-heart.svg diff --git a/static/css/bootstrap-icons-1.11.3/postcard.svg b/app/static/css/bootstrap-icons-1.11.3/postcard.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/postcard.svg rename to app/static/css/bootstrap-icons-1.11.3/postcard.svg diff --git a/static/css/bootstrap-icons-1.11.3/power.svg b/app/static/css/bootstrap-icons-1.11.3/power.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/power.svg rename to app/static/css/bootstrap-icons-1.11.3/power.svg diff --git a/static/css/bootstrap-icons-1.11.3/prescription.svg b/app/static/css/bootstrap-icons-1.11.3/prescription.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/prescription.svg rename to app/static/css/bootstrap-icons-1.11.3/prescription.svg diff --git a/static/css/bootstrap-icons-1.11.3/prescription2.svg b/app/static/css/bootstrap-icons-1.11.3/prescription2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/prescription2.svg rename to app/static/css/bootstrap-icons-1.11.3/prescription2.svg diff --git a/static/css/bootstrap-icons-1.11.3/printer-fill.svg b/app/static/css/bootstrap-icons-1.11.3/printer-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/printer-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/printer-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/printer.svg b/app/static/css/bootstrap-icons-1.11.3/printer.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/printer.svg rename to app/static/css/bootstrap-icons-1.11.3/printer.svg diff --git a/static/css/bootstrap-icons-1.11.3/projector-fill.svg b/app/static/css/bootstrap-icons-1.11.3/projector-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/projector-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/projector-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/projector.svg b/app/static/css/bootstrap-icons-1.11.3/projector.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/projector.svg rename to app/static/css/bootstrap-icons-1.11.3/projector.svg diff --git a/static/css/bootstrap-icons-1.11.3/puzzle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/puzzle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/puzzle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/puzzle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/puzzle.svg b/app/static/css/bootstrap-icons-1.11.3/puzzle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/puzzle.svg rename to app/static/css/bootstrap-icons-1.11.3/puzzle.svg diff --git a/static/css/bootstrap-icons-1.11.3/qr-code-scan.svg b/app/static/css/bootstrap-icons-1.11.3/qr-code-scan.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/qr-code-scan.svg rename to app/static/css/bootstrap-icons-1.11.3/qr-code-scan.svg diff --git a/static/css/bootstrap-icons-1.11.3/qr-code.svg b/app/static/css/bootstrap-icons-1.11.3/qr-code.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/qr-code.svg rename to app/static/css/bootstrap-icons-1.11.3/qr-code.svg diff --git a/static/css/bootstrap-icons-1.11.3/question-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/question-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/question-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/question-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/question-circle.svg b/app/static/css/bootstrap-icons-1.11.3/question-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/question-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/question-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/question-diamond-fill.svg b/app/static/css/bootstrap-icons-1.11.3/question-diamond-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/question-diamond-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/question-diamond-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/question-diamond.svg b/app/static/css/bootstrap-icons-1.11.3/question-diamond.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/question-diamond.svg rename to app/static/css/bootstrap-icons-1.11.3/question-diamond.svg diff --git a/static/css/bootstrap-icons-1.11.3/question-lg.svg b/app/static/css/bootstrap-icons-1.11.3/question-lg.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/question-lg.svg rename to app/static/css/bootstrap-icons-1.11.3/question-lg.svg diff --git a/static/css/bootstrap-icons-1.11.3/question-octagon-fill.svg b/app/static/css/bootstrap-icons-1.11.3/question-octagon-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/question-octagon-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/question-octagon-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/question-octagon.svg b/app/static/css/bootstrap-icons-1.11.3/question-octagon.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/question-octagon.svg rename to app/static/css/bootstrap-icons-1.11.3/question-octagon.svg diff --git a/static/css/bootstrap-icons-1.11.3/question-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/question-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/question-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/question-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/question-square.svg b/app/static/css/bootstrap-icons-1.11.3/question-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/question-square.svg rename to app/static/css/bootstrap-icons-1.11.3/question-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/question.svg b/app/static/css/bootstrap-icons-1.11.3/question.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/question.svg rename to app/static/css/bootstrap-icons-1.11.3/question.svg diff --git a/static/css/bootstrap-icons-1.11.3/quora.svg b/app/static/css/bootstrap-icons-1.11.3/quora.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/quora.svg rename to app/static/css/bootstrap-icons-1.11.3/quora.svg diff --git a/static/css/bootstrap-icons-1.11.3/quote.svg b/app/static/css/bootstrap-icons-1.11.3/quote.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/quote.svg rename to app/static/css/bootstrap-icons-1.11.3/quote.svg diff --git a/static/css/bootstrap-icons-1.11.3/r-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/r-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/r-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/r-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/r-circle.svg b/app/static/css/bootstrap-icons-1.11.3/r-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/r-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/r-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/r-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/r-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/r-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/r-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/r-square.svg b/app/static/css/bootstrap-icons-1.11.3/r-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/r-square.svg rename to app/static/css/bootstrap-icons-1.11.3/r-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/radar.svg b/app/static/css/bootstrap-icons-1.11.3/radar.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/radar.svg rename to app/static/css/bootstrap-icons-1.11.3/radar.svg diff --git a/static/css/bootstrap-icons-1.11.3/radioactive.svg b/app/static/css/bootstrap-icons-1.11.3/radioactive.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/radioactive.svg rename to app/static/css/bootstrap-icons-1.11.3/radioactive.svg diff --git a/static/css/bootstrap-icons-1.11.3/rainbow.svg b/app/static/css/bootstrap-icons-1.11.3/rainbow.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/rainbow.svg rename to app/static/css/bootstrap-icons-1.11.3/rainbow.svg diff --git a/static/css/bootstrap-icons-1.11.3/receipt-cutoff.svg b/app/static/css/bootstrap-icons-1.11.3/receipt-cutoff.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/receipt-cutoff.svg rename to app/static/css/bootstrap-icons-1.11.3/receipt-cutoff.svg diff --git a/static/css/bootstrap-icons-1.11.3/receipt.svg b/app/static/css/bootstrap-icons-1.11.3/receipt.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/receipt.svg rename to app/static/css/bootstrap-icons-1.11.3/receipt.svg diff --git a/static/css/bootstrap-icons-1.11.3/reception-0.svg b/app/static/css/bootstrap-icons-1.11.3/reception-0.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/reception-0.svg rename to app/static/css/bootstrap-icons-1.11.3/reception-0.svg diff --git a/static/css/bootstrap-icons-1.11.3/reception-1.svg b/app/static/css/bootstrap-icons-1.11.3/reception-1.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/reception-1.svg rename to app/static/css/bootstrap-icons-1.11.3/reception-1.svg diff --git a/static/css/bootstrap-icons-1.11.3/reception-2.svg b/app/static/css/bootstrap-icons-1.11.3/reception-2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/reception-2.svg rename to app/static/css/bootstrap-icons-1.11.3/reception-2.svg diff --git a/static/css/bootstrap-icons-1.11.3/reception-3.svg b/app/static/css/bootstrap-icons-1.11.3/reception-3.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/reception-3.svg rename to app/static/css/bootstrap-icons-1.11.3/reception-3.svg diff --git a/static/css/bootstrap-icons-1.11.3/reception-4.svg b/app/static/css/bootstrap-icons-1.11.3/reception-4.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/reception-4.svg rename to app/static/css/bootstrap-icons-1.11.3/reception-4.svg diff --git a/static/css/bootstrap-icons-1.11.3/record-btn-fill.svg b/app/static/css/bootstrap-icons-1.11.3/record-btn-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/record-btn-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/record-btn-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/record-btn.svg b/app/static/css/bootstrap-icons-1.11.3/record-btn.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/record-btn.svg rename to app/static/css/bootstrap-icons-1.11.3/record-btn.svg diff --git a/static/css/bootstrap-icons-1.11.3/record-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/record-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/record-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/record-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/record-circle.svg b/app/static/css/bootstrap-icons-1.11.3/record-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/record-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/record-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/record-fill.svg b/app/static/css/bootstrap-icons-1.11.3/record-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/record-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/record-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/record.svg b/app/static/css/bootstrap-icons-1.11.3/record.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/record.svg rename to app/static/css/bootstrap-icons-1.11.3/record.svg diff --git a/static/css/bootstrap-icons-1.11.3/record2-fill.svg b/app/static/css/bootstrap-icons-1.11.3/record2-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/record2-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/record2-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/record2.svg b/app/static/css/bootstrap-icons-1.11.3/record2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/record2.svg rename to app/static/css/bootstrap-icons-1.11.3/record2.svg diff --git a/static/css/bootstrap-icons-1.11.3/recycle.svg b/app/static/css/bootstrap-icons-1.11.3/recycle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/recycle.svg rename to app/static/css/bootstrap-icons-1.11.3/recycle.svg diff --git a/static/css/bootstrap-icons-1.11.3/reddit.svg b/app/static/css/bootstrap-icons-1.11.3/reddit.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/reddit.svg rename to app/static/css/bootstrap-icons-1.11.3/reddit.svg diff --git a/static/css/bootstrap-icons-1.11.3/regex.svg b/app/static/css/bootstrap-icons-1.11.3/regex.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/regex.svg rename to app/static/css/bootstrap-icons-1.11.3/regex.svg diff --git a/static/css/bootstrap-icons-1.11.3/repeat-1.svg b/app/static/css/bootstrap-icons-1.11.3/repeat-1.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/repeat-1.svg rename to app/static/css/bootstrap-icons-1.11.3/repeat-1.svg diff --git a/static/css/bootstrap-icons-1.11.3/repeat.svg b/app/static/css/bootstrap-icons-1.11.3/repeat.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/repeat.svg rename to app/static/css/bootstrap-icons-1.11.3/repeat.svg diff --git a/static/css/bootstrap-icons-1.11.3/reply-all-fill.svg b/app/static/css/bootstrap-icons-1.11.3/reply-all-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/reply-all-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/reply-all-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/reply-all.svg b/app/static/css/bootstrap-icons-1.11.3/reply-all.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/reply-all.svg rename to app/static/css/bootstrap-icons-1.11.3/reply-all.svg diff --git a/static/css/bootstrap-icons-1.11.3/reply-fill.svg b/app/static/css/bootstrap-icons-1.11.3/reply-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/reply-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/reply-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/reply.svg b/app/static/css/bootstrap-icons-1.11.3/reply.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/reply.svg rename to app/static/css/bootstrap-icons-1.11.3/reply.svg diff --git a/static/css/bootstrap-icons-1.11.3/rewind-btn-fill.svg b/app/static/css/bootstrap-icons-1.11.3/rewind-btn-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/rewind-btn-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/rewind-btn-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/rewind-btn.svg b/app/static/css/bootstrap-icons-1.11.3/rewind-btn.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/rewind-btn.svg rename to app/static/css/bootstrap-icons-1.11.3/rewind-btn.svg diff --git a/static/css/bootstrap-icons-1.11.3/rewind-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/rewind-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/rewind-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/rewind-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/rewind-circle.svg b/app/static/css/bootstrap-icons-1.11.3/rewind-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/rewind-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/rewind-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/rewind-fill.svg b/app/static/css/bootstrap-icons-1.11.3/rewind-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/rewind-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/rewind-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/rewind.svg b/app/static/css/bootstrap-icons-1.11.3/rewind.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/rewind.svg rename to app/static/css/bootstrap-icons-1.11.3/rewind.svg diff --git a/static/css/bootstrap-icons-1.11.3/robot.svg b/app/static/css/bootstrap-icons-1.11.3/robot.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/robot.svg rename to app/static/css/bootstrap-icons-1.11.3/robot.svg diff --git a/static/css/bootstrap-icons-1.11.3/rocket-fill.svg b/app/static/css/bootstrap-icons-1.11.3/rocket-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/rocket-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/rocket-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/rocket-takeoff-fill.svg b/app/static/css/bootstrap-icons-1.11.3/rocket-takeoff-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/rocket-takeoff-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/rocket-takeoff-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/rocket-takeoff.svg b/app/static/css/bootstrap-icons-1.11.3/rocket-takeoff.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/rocket-takeoff.svg rename to app/static/css/bootstrap-icons-1.11.3/rocket-takeoff.svg diff --git a/static/css/bootstrap-icons-1.11.3/rocket.svg b/app/static/css/bootstrap-icons-1.11.3/rocket.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/rocket.svg rename to app/static/css/bootstrap-icons-1.11.3/rocket.svg diff --git a/static/css/bootstrap-icons-1.11.3/router-fill.svg b/app/static/css/bootstrap-icons-1.11.3/router-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/router-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/router-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/router.svg b/app/static/css/bootstrap-icons-1.11.3/router.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/router.svg rename to app/static/css/bootstrap-icons-1.11.3/router.svg diff --git a/static/css/bootstrap-icons-1.11.3/rss-fill.svg b/app/static/css/bootstrap-icons-1.11.3/rss-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/rss-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/rss-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/rss.svg b/app/static/css/bootstrap-icons-1.11.3/rss.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/rss.svg rename to app/static/css/bootstrap-icons-1.11.3/rss.svg diff --git a/static/css/bootstrap-icons-1.11.3/rulers.svg b/app/static/css/bootstrap-icons-1.11.3/rulers.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/rulers.svg rename to app/static/css/bootstrap-icons-1.11.3/rulers.svg diff --git a/static/css/bootstrap-icons-1.11.3/safe-fill.svg b/app/static/css/bootstrap-icons-1.11.3/safe-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/safe-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/safe-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/safe.svg b/app/static/css/bootstrap-icons-1.11.3/safe.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/safe.svg rename to app/static/css/bootstrap-icons-1.11.3/safe.svg diff --git a/static/css/bootstrap-icons-1.11.3/safe2-fill.svg b/app/static/css/bootstrap-icons-1.11.3/safe2-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/safe2-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/safe2-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/safe2.svg b/app/static/css/bootstrap-icons-1.11.3/safe2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/safe2.svg rename to app/static/css/bootstrap-icons-1.11.3/safe2.svg diff --git a/static/css/bootstrap-icons-1.11.3/save-fill.svg b/app/static/css/bootstrap-icons-1.11.3/save-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/save-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/save-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/save.svg b/app/static/css/bootstrap-icons-1.11.3/save.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/save.svg rename to app/static/css/bootstrap-icons-1.11.3/save.svg diff --git a/static/css/bootstrap-icons-1.11.3/save2-fill.svg b/app/static/css/bootstrap-icons-1.11.3/save2-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/save2-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/save2-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/save2.svg b/app/static/css/bootstrap-icons-1.11.3/save2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/save2.svg rename to app/static/css/bootstrap-icons-1.11.3/save2.svg diff --git a/static/css/bootstrap-icons-1.11.3/scissors.svg b/app/static/css/bootstrap-icons-1.11.3/scissors.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/scissors.svg rename to app/static/css/bootstrap-icons-1.11.3/scissors.svg diff --git a/static/css/bootstrap-icons-1.11.3/scooter.svg b/app/static/css/bootstrap-icons-1.11.3/scooter.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/scooter.svg rename to app/static/css/bootstrap-icons-1.11.3/scooter.svg diff --git a/static/css/bootstrap-icons-1.11.3/screwdriver.svg b/app/static/css/bootstrap-icons-1.11.3/screwdriver.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/screwdriver.svg rename to app/static/css/bootstrap-icons-1.11.3/screwdriver.svg diff --git a/static/css/bootstrap-icons-1.11.3/sd-card-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sd-card-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sd-card-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sd-card-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sd-card.svg b/app/static/css/bootstrap-icons-1.11.3/sd-card.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sd-card.svg rename to app/static/css/bootstrap-icons-1.11.3/sd-card.svg diff --git a/static/css/bootstrap-icons-1.11.3/search-heart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/search-heart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/search-heart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/search-heart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/search-heart.svg b/app/static/css/bootstrap-icons-1.11.3/search-heart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/search-heart.svg rename to app/static/css/bootstrap-icons-1.11.3/search-heart.svg diff --git a/static/css/bootstrap-icons-1.11.3/search.svg b/app/static/css/bootstrap-icons-1.11.3/search.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/search.svg rename to app/static/css/bootstrap-icons-1.11.3/search.svg diff --git a/static/css/bootstrap-icons-1.11.3/segmented-nav.svg b/app/static/css/bootstrap-icons-1.11.3/segmented-nav.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/segmented-nav.svg rename to app/static/css/bootstrap-icons-1.11.3/segmented-nav.svg diff --git a/static/css/bootstrap-icons-1.11.3/send-arrow-down-fill.svg b/app/static/css/bootstrap-icons-1.11.3/send-arrow-down-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/send-arrow-down-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/send-arrow-down-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/send-arrow-down.svg b/app/static/css/bootstrap-icons-1.11.3/send-arrow-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/send-arrow-down.svg rename to app/static/css/bootstrap-icons-1.11.3/send-arrow-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/send-arrow-up-fill.svg b/app/static/css/bootstrap-icons-1.11.3/send-arrow-up-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/send-arrow-up-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/send-arrow-up-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/send-arrow-up.svg b/app/static/css/bootstrap-icons-1.11.3/send-arrow-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/send-arrow-up.svg rename to app/static/css/bootstrap-icons-1.11.3/send-arrow-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/send-check-fill.svg b/app/static/css/bootstrap-icons-1.11.3/send-check-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/send-check-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/send-check-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/send-check.svg b/app/static/css/bootstrap-icons-1.11.3/send-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/send-check.svg rename to app/static/css/bootstrap-icons-1.11.3/send-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/send-dash-fill.svg b/app/static/css/bootstrap-icons-1.11.3/send-dash-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/send-dash-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/send-dash-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/send-dash.svg b/app/static/css/bootstrap-icons-1.11.3/send-dash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/send-dash.svg rename to app/static/css/bootstrap-icons-1.11.3/send-dash.svg diff --git a/static/css/bootstrap-icons-1.11.3/send-exclamation-fill.svg b/app/static/css/bootstrap-icons-1.11.3/send-exclamation-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/send-exclamation-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/send-exclamation-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/send-exclamation.svg b/app/static/css/bootstrap-icons-1.11.3/send-exclamation.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/send-exclamation.svg rename to app/static/css/bootstrap-icons-1.11.3/send-exclamation.svg diff --git a/static/css/bootstrap-icons-1.11.3/send-fill.svg b/app/static/css/bootstrap-icons-1.11.3/send-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/send-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/send-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/send-plus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/send-plus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/send-plus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/send-plus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/send-plus.svg b/app/static/css/bootstrap-icons-1.11.3/send-plus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/send-plus.svg rename to app/static/css/bootstrap-icons-1.11.3/send-plus.svg diff --git a/static/css/bootstrap-icons-1.11.3/send-slash-fill.svg b/app/static/css/bootstrap-icons-1.11.3/send-slash-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/send-slash-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/send-slash-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/send-slash.svg b/app/static/css/bootstrap-icons-1.11.3/send-slash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/send-slash.svg rename to app/static/css/bootstrap-icons-1.11.3/send-slash.svg diff --git a/static/css/bootstrap-icons-1.11.3/send-x-fill.svg b/app/static/css/bootstrap-icons-1.11.3/send-x-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/send-x-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/send-x-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/send-x.svg b/app/static/css/bootstrap-icons-1.11.3/send-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/send-x.svg rename to app/static/css/bootstrap-icons-1.11.3/send-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/send.svg b/app/static/css/bootstrap-icons-1.11.3/send.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/send.svg rename to app/static/css/bootstrap-icons-1.11.3/send.svg diff --git a/static/css/bootstrap-icons-1.11.3/server.svg b/app/static/css/bootstrap-icons-1.11.3/server.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/server.svg rename to app/static/css/bootstrap-icons-1.11.3/server.svg diff --git a/static/css/bootstrap-icons-1.11.3/shadows.svg b/app/static/css/bootstrap-icons-1.11.3/shadows.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/shadows.svg rename to app/static/css/bootstrap-icons-1.11.3/shadows.svg diff --git a/static/css/bootstrap-icons-1.11.3/share-fill.svg b/app/static/css/bootstrap-icons-1.11.3/share-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/share-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/share-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/share.svg b/app/static/css/bootstrap-icons-1.11.3/share.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/share.svg rename to app/static/css/bootstrap-icons-1.11.3/share.svg diff --git a/static/css/bootstrap-icons-1.11.3/shield-check.svg b/app/static/css/bootstrap-icons-1.11.3/shield-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/shield-check.svg rename to app/static/css/bootstrap-icons-1.11.3/shield-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/shield-exclamation.svg b/app/static/css/bootstrap-icons-1.11.3/shield-exclamation.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/shield-exclamation.svg rename to app/static/css/bootstrap-icons-1.11.3/shield-exclamation.svg diff --git a/static/css/bootstrap-icons-1.11.3/shield-fill-check.svg b/app/static/css/bootstrap-icons-1.11.3/shield-fill-check.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/shield-fill-check.svg rename to app/static/css/bootstrap-icons-1.11.3/shield-fill-check.svg diff --git a/static/css/bootstrap-icons-1.11.3/shield-fill-exclamation.svg b/app/static/css/bootstrap-icons-1.11.3/shield-fill-exclamation.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/shield-fill-exclamation.svg rename to app/static/css/bootstrap-icons-1.11.3/shield-fill-exclamation.svg diff --git a/static/css/bootstrap-icons-1.11.3/shield-fill-minus.svg b/app/static/css/bootstrap-icons-1.11.3/shield-fill-minus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/shield-fill-minus.svg rename to app/static/css/bootstrap-icons-1.11.3/shield-fill-minus.svg diff --git a/static/css/bootstrap-icons-1.11.3/shield-fill-plus.svg b/app/static/css/bootstrap-icons-1.11.3/shield-fill-plus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/shield-fill-plus.svg rename to app/static/css/bootstrap-icons-1.11.3/shield-fill-plus.svg diff --git a/static/css/bootstrap-icons-1.11.3/shield-fill-x.svg b/app/static/css/bootstrap-icons-1.11.3/shield-fill-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/shield-fill-x.svg rename to app/static/css/bootstrap-icons-1.11.3/shield-fill-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/shield-fill.svg b/app/static/css/bootstrap-icons-1.11.3/shield-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/shield-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/shield-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/shield-lock-fill.svg b/app/static/css/bootstrap-icons-1.11.3/shield-lock-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/shield-lock-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/shield-lock-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/shield-lock.svg b/app/static/css/bootstrap-icons-1.11.3/shield-lock.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/shield-lock.svg rename to app/static/css/bootstrap-icons-1.11.3/shield-lock.svg diff --git a/static/css/bootstrap-icons-1.11.3/shield-minus.svg b/app/static/css/bootstrap-icons-1.11.3/shield-minus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/shield-minus.svg rename to app/static/css/bootstrap-icons-1.11.3/shield-minus.svg diff --git a/static/css/bootstrap-icons-1.11.3/shield-plus.svg b/app/static/css/bootstrap-icons-1.11.3/shield-plus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/shield-plus.svg rename to app/static/css/bootstrap-icons-1.11.3/shield-plus.svg diff --git a/static/css/bootstrap-icons-1.11.3/shield-shaded.svg b/app/static/css/bootstrap-icons-1.11.3/shield-shaded.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/shield-shaded.svg rename to app/static/css/bootstrap-icons-1.11.3/shield-shaded.svg diff --git a/static/css/bootstrap-icons-1.11.3/shield-slash-fill.svg b/app/static/css/bootstrap-icons-1.11.3/shield-slash-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/shield-slash-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/shield-slash-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/shield-slash.svg b/app/static/css/bootstrap-icons-1.11.3/shield-slash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/shield-slash.svg rename to app/static/css/bootstrap-icons-1.11.3/shield-slash.svg diff --git a/static/css/bootstrap-icons-1.11.3/shield-x.svg b/app/static/css/bootstrap-icons-1.11.3/shield-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/shield-x.svg rename to app/static/css/bootstrap-icons-1.11.3/shield-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/shield.svg b/app/static/css/bootstrap-icons-1.11.3/shield.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/shield.svg rename to app/static/css/bootstrap-icons-1.11.3/shield.svg diff --git a/static/css/bootstrap-icons-1.11.3/shift-fill.svg b/app/static/css/bootstrap-icons-1.11.3/shift-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/shift-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/shift-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/shift.svg b/app/static/css/bootstrap-icons-1.11.3/shift.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/shift.svg rename to app/static/css/bootstrap-icons-1.11.3/shift.svg diff --git a/static/css/bootstrap-icons-1.11.3/shop-window.svg b/app/static/css/bootstrap-icons-1.11.3/shop-window.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/shop-window.svg rename to app/static/css/bootstrap-icons-1.11.3/shop-window.svg diff --git a/static/css/bootstrap-icons-1.11.3/shop.svg b/app/static/css/bootstrap-icons-1.11.3/shop.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/shop.svg rename to app/static/css/bootstrap-icons-1.11.3/shop.svg diff --git a/static/css/bootstrap-icons-1.11.3/shuffle.svg b/app/static/css/bootstrap-icons-1.11.3/shuffle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/shuffle.svg rename to app/static/css/bootstrap-icons-1.11.3/shuffle.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-dead-end-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sign-dead-end-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-dead-end-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-dead-end-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-dead-end.svg b/app/static/css/bootstrap-icons-1.11.3/sign-dead-end.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-dead-end.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-dead-end.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-do-not-enter-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sign-do-not-enter-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-do-not-enter-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-do-not-enter-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-do-not-enter.svg b/app/static/css/bootstrap-icons-1.11.3/sign-do-not-enter.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-do-not-enter.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-do-not-enter.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-intersection-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sign-intersection-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-intersection-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-intersection-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-intersection-side-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sign-intersection-side-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-intersection-side-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-intersection-side-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-intersection-side.svg b/app/static/css/bootstrap-icons-1.11.3/sign-intersection-side.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-intersection-side.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-intersection-side.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-intersection-t-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sign-intersection-t-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-intersection-t-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-intersection-t-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-intersection-t.svg b/app/static/css/bootstrap-icons-1.11.3/sign-intersection-t.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-intersection-t.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-intersection-t.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-intersection-y-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sign-intersection-y-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-intersection-y-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-intersection-y-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-intersection-y.svg b/app/static/css/bootstrap-icons-1.11.3/sign-intersection-y.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-intersection-y.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-intersection-y.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-intersection.svg b/app/static/css/bootstrap-icons-1.11.3/sign-intersection.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-intersection.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-intersection.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-merge-left-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sign-merge-left-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-merge-left-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-merge-left-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-merge-left.svg b/app/static/css/bootstrap-icons-1.11.3/sign-merge-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-merge-left.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-merge-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-merge-right-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sign-merge-right-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-merge-right-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-merge-right-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-merge-right.svg b/app/static/css/bootstrap-icons-1.11.3/sign-merge-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-merge-right.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-merge-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-no-left-turn-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sign-no-left-turn-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-no-left-turn-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-no-left-turn-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-no-left-turn.svg b/app/static/css/bootstrap-icons-1.11.3/sign-no-left-turn.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-no-left-turn.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-no-left-turn.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-no-parking-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sign-no-parking-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-no-parking-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-no-parking-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-no-parking.svg b/app/static/css/bootstrap-icons-1.11.3/sign-no-parking.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-no-parking.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-no-parking.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-no-right-turn-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sign-no-right-turn-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-no-right-turn-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-no-right-turn-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-no-right-turn.svg b/app/static/css/bootstrap-icons-1.11.3/sign-no-right-turn.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-no-right-turn.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-no-right-turn.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-railroad-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sign-railroad-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-railroad-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-railroad-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-railroad.svg b/app/static/css/bootstrap-icons-1.11.3/sign-railroad.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-railroad.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-railroad.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-stop-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sign-stop-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-stop-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-stop-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-stop-lights-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sign-stop-lights-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-stop-lights-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-stop-lights-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-stop-lights.svg b/app/static/css/bootstrap-icons-1.11.3/sign-stop-lights.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-stop-lights.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-stop-lights.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-stop.svg b/app/static/css/bootstrap-icons-1.11.3/sign-stop.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-stop.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-stop.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-turn-left-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sign-turn-left-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-turn-left-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-turn-left-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-turn-left.svg b/app/static/css/bootstrap-icons-1.11.3/sign-turn-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-turn-left.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-turn-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-turn-right-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sign-turn-right-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-turn-right-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-turn-right-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-turn-right.svg b/app/static/css/bootstrap-icons-1.11.3/sign-turn-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-turn-right.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-turn-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-turn-slight-left-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sign-turn-slight-left-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-turn-slight-left-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-turn-slight-left-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-turn-slight-left.svg b/app/static/css/bootstrap-icons-1.11.3/sign-turn-slight-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-turn-slight-left.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-turn-slight-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-turn-slight-right-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sign-turn-slight-right-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-turn-slight-right-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-turn-slight-right-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-turn-slight-right.svg b/app/static/css/bootstrap-icons-1.11.3/sign-turn-slight-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-turn-slight-right.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-turn-slight-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-yield-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sign-yield-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-yield-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-yield-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sign-yield.svg b/app/static/css/bootstrap-icons-1.11.3/sign-yield.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sign-yield.svg rename to app/static/css/bootstrap-icons-1.11.3/sign-yield.svg diff --git a/static/css/bootstrap-icons-1.11.3/signal.svg b/app/static/css/bootstrap-icons-1.11.3/signal.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/signal.svg rename to app/static/css/bootstrap-icons-1.11.3/signal.svg diff --git a/static/css/bootstrap-icons-1.11.3/signpost-2-fill.svg b/app/static/css/bootstrap-icons-1.11.3/signpost-2-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/signpost-2-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/signpost-2-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/signpost-2.svg b/app/static/css/bootstrap-icons-1.11.3/signpost-2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/signpost-2.svg rename to app/static/css/bootstrap-icons-1.11.3/signpost-2.svg diff --git a/static/css/bootstrap-icons-1.11.3/signpost-fill.svg b/app/static/css/bootstrap-icons-1.11.3/signpost-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/signpost-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/signpost-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/signpost-split-fill.svg b/app/static/css/bootstrap-icons-1.11.3/signpost-split-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/signpost-split-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/signpost-split-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/signpost-split.svg b/app/static/css/bootstrap-icons-1.11.3/signpost-split.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/signpost-split.svg rename to app/static/css/bootstrap-icons-1.11.3/signpost-split.svg diff --git a/static/css/bootstrap-icons-1.11.3/signpost.svg b/app/static/css/bootstrap-icons-1.11.3/signpost.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/signpost.svg rename to app/static/css/bootstrap-icons-1.11.3/signpost.svg diff --git a/static/css/bootstrap-icons-1.11.3/sim-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sim-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sim-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sim-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sim-slash-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sim-slash-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sim-slash-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sim-slash-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sim-slash.svg b/app/static/css/bootstrap-icons-1.11.3/sim-slash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sim-slash.svg rename to app/static/css/bootstrap-icons-1.11.3/sim-slash.svg diff --git a/static/css/bootstrap-icons-1.11.3/sim.svg b/app/static/css/bootstrap-icons-1.11.3/sim.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sim.svg rename to app/static/css/bootstrap-icons-1.11.3/sim.svg diff --git a/static/css/bootstrap-icons-1.11.3/sina-weibo.svg b/app/static/css/bootstrap-icons-1.11.3/sina-weibo.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sina-weibo.svg rename to app/static/css/bootstrap-icons-1.11.3/sina-weibo.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-backward-btn-fill.svg b/app/static/css/bootstrap-icons-1.11.3/skip-backward-btn-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-backward-btn-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-backward-btn-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-backward-btn.svg b/app/static/css/bootstrap-icons-1.11.3/skip-backward-btn.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-backward-btn.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-backward-btn.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-backward-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/skip-backward-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-backward-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-backward-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-backward-circle.svg b/app/static/css/bootstrap-icons-1.11.3/skip-backward-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-backward-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-backward-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-backward-fill.svg b/app/static/css/bootstrap-icons-1.11.3/skip-backward-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-backward-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-backward-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-backward.svg b/app/static/css/bootstrap-icons-1.11.3/skip-backward.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-backward.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-backward.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-end-btn-fill.svg b/app/static/css/bootstrap-icons-1.11.3/skip-end-btn-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-end-btn-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-end-btn-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-end-btn.svg b/app/static/css/bootstrap-icons-1.11.3/skip-end-btn.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-end-btn.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-end-btn.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-end-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/skip-end-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-end-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-end-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-end-circle.svg b/app/static/css/bootstrap-icons-1.11.3/skip-end-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-end-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-end-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-end-fill.svg b/app/static/css/bootstrap-icons-1.11.3/skip-end-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-end-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-end-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-end.svg b/app/static/css/bootstrap-icons-1.11.3/skip-end.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-end.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-end.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-forward-btn-fill.svg b/app/static/css/bootstrap-icons-1.11.3/skip-forward-btn-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-forward-btn-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-forward-btn-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-forward-btn.svg b/app/static/css/bootstrap-icons-1.11.3/skip-forward-btn.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-forward-btn.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-forward-btn.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-forward-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/skip-forward-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-forward-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-forward-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-forward-circle.svg b/app/static/css/bootstrap-icons-1.11.3/skip-forward-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-forward-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-forward-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-forward-fill.svg b/app/static/css/bootstrap-icons-1.11.3/skip-forward-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-forward-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-forward-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-forward.svg b/app/static/css/bootstrap-icons-1.11.3/skip-forward.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-forward.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-forward.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-start-btn-fill.svg b/app/static/css/bootstrap-icons-1.11.3/skip-start-btn-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-start-btn-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-start-btn-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-start-btn.svg b/app/static/css/bootstrap-icons-1.11.3/skip-start-btn.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-start-btn.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-start-btn.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-start-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/skip-start-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-start-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-start-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-start-circle.svg b/app/static/css/bootstrap-icons-1.11.3/skip-start-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-start-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-start-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-start-fill.svg b/app/static/css/bootstrap-icons-1.11.3/skip-start-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-start-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-start-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/skip-start.svg b/app/static/css/bootstrap-icons-1.11.3/skip-start.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skip-start.svg rename to app/static/css/bootstrap-icons-1.11.3/skip-start.svg diff --git a/static/css/bootstrap-icons-1.11.3/skype.svg b/app/static/css/bootstrap-icons-1.11.3/skype.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/skype.svg rename to app/static/css/bootstrap-icons-1.11.3/skype.svg diff --git a/static/css/bootstrap-icons-1.11.3/slack.svg b/app/static/css/bootstrap-icons-1.11.3/slack.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/slack.svg rename to app/static/css/bootstrap-icons-1.11.3/slack.svg diff --git a/static/css/bootstrap-icons-1.11.3/slash-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/slash-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/slash-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/slash-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/slash-circle.svg b/app/static/css/bootstrap-icons-1.11.3/slash-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/slash-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/slash-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/slash-lg.svg b/app/static/css/bootstrap-icons-1.11.3/slash-lg.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/slash-lg.svg rename to app/static/css/bootstrap-icons-1.11.3/slash-lg.svg diff --git a/static/css/bootstrap-icons-1.11.3/slash-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/slash-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/slash-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/slash-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/slash-square.svg b/app/static/css/bootstrap-icons-1.11.3/slash-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/slash-square.svg rename to app/static/css/bootstrap-icons-1.11.3/slash-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/slash.svg b/app/static/css/bootstrap-icons-1.11.3/slash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/slash.svg rename to app/static/css/bootstrap-icons-1.11.3/slash.svg diff --git a/static/css/bootstrap-icons-1.11.3/sliders.svg b/app/static/css/bootstrap-icons-1.11.3/sliders.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sliders.svg rename to app/static/css/bootstrap-icons-1.11.3/sliders.svg diff --git a/static/css/bootstrap-icons-1.11.3/sliders2-vertical.svg b/app/static/css/bootstrap-icons-1.11.3/sliders2-vertical.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sliders2-vertical.svg rename to app/static/css/bootstrap-icons-1.11.3/sliders2-vertical.svg diff --git a/static/css/bootstrap-icons-1.11.3/sliders2.svg b/app/static/css/bootstrap-icons-1.11.3/sliders2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sliders2.svg rename to app/static/css/bootstrap-icons-1.11.3/sliders2.svg diff --git a/static/css/bootstrap-icons-1.11.3/smartwatch.svg b/app/static/css/bootstrap-icons-1.11.3/smartwatch.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/smartwatch.svg rename to app/static/css/bootstrap-icons-1.11.3/smartwatch.svg diff --git a/static/css/bootstrap-icons-1.11.3/snapchat.svg b/app/static/css/bootstrap-icons-1.11.3/snapchat.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/snapchat.svg rename to app/static/css/bootstrap-icons-1.11.3/snapchat.svg diff --git a/static/css/bootstrap-icons-1.11.3/snow.svg b/app/static/css/bootstrap-icons-1.11.3/snow.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/snow.svg rename to app/static/css/bootstrap-icons-1.11.3/snow.svg diff --git a/static/css/bootstrap-icons-1.11.3/snow2.svg b/app/static/css/bootstrap-icons-1.11.3/snow2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/snow2.svg rename to app/static/css/bootstrap-icons-1.11.3/snow2.svg diff --git a/static/css/bootstrap-icons-1.11.3/snow3.svg b/app/static/css/bootstrap-icons-1.11.3/snow3.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/snow3.svg rename to app/static/css/bootstrap-icons-1.11.3/snow3.svg diff --git a/static/css/bootstrap-icons-1.11.3/sort-alpha-down-alt.svg b/app/static/css/bootstrap-icons-1.11.3/sort-alpha-down-alt.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sort-alpha-down-alt.svg rename to app/static/css/bootstrap-icons-1.11.3/sort-alpha-down-alt.svg diff --git a/static/css/bootstrap-icons-1.11.3/sort-alpha-down.svg b/app/static/css/bootstrap-icons-1.11.3/sort-alpha-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sort-alpha-down.svg rename to app/static/css/bootstrap-icons-1.11.3/sort-alpha-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/sort-alpha-up-alt.svg b/app/static/css/bootstrap-icons-1.11.3/sort-alpha-up-alt.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sort-alpha-up-alt.svg rename to app/static/css/bootstrap-icons-1.11.3/sort-alpha-up-alt.svg diff --git a/static/css/bootstrap-icons-1.11.3/sort-alpha-up.svg b/app/static/css/bootstrap-icons-1.11.3/sort-alpha-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sort-alpha-up.svg rename to app/static/css/bootstrap-icons-1.11.3/sort-alpha-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/sort-down-alt.svg b/app/static/css/bootstrap-icons-1.11.3/sort-down-alt.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sort-down-alt.svg rename to app/static/css/bootstrap-icons-1.11.3/sort-down-alt.svg diff --git a/static/css/bootstrap-icons-1.11.3/sort-down.svg b/app/static/css/bootstrap-icons-1.11.3/sort-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sort-down.svg rename to app/static/css/bootstrap-icons-1.11.3/sort-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/sort-numeric-down-alt.svg b/app/static/css/bootstrap-icons-1.11.3/sort-numeric-down-alt.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sort-numeric-down-alt.svg rename to app/static/css/bootstrap-icons-1.11.3/sort-numeric-down-alt.svg diff --git a/static/css/bootstrap-icons-1.11.3/sort-numeric-down.svg b/app/static/css/bootstrap-icons-1.11.3/sort-numeric-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sort-numeric-down.svg rename to app/static/css/bootstrap-icons-1.11.3/sort-numeric-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/sort-numeric-up-alt.svg b/app/static/css/bootstrap-icons-1.11.3/sort-numeric-up-alt.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sort-numeric-up-alt.svg rename to app/static/css/bootstrap-icons-1.11.3/sort-numeric-up-alt.svg diff --git a/static/css/bootstrap-icons-1.11.3/sort-numeric-up.svg b/app/static/css/bootstrap-icons-1.11.3/sort-numeric-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sort-numeric-up.svg rename to app/static/css/bootstrap-icons-1.11.3/sort-numeric-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/sort-up-alt.svg b/app/static/css/bootstrap-icons-1.11.3/sort-up-alt.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sort-up-alt.svg rename to app/static/css/bootstrap-icons-1.11.3/sort-up-alt.svg diff --git a/static/css/bootstrap-icons-1.11.3/sort-up.svg b/app/static/css/bootstrap-icons-1.11.3/sort-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sort-up.svg rename to app/static/css/bootstrap-icons-1.11.3/sort-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/soundwave.svg b/app/static/css/bootstrap-icons-1.11.3/soundwave.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/soundwave.svg rename to app/static/css/bootstrap-icons-1.11.3/soundwave.svg diff --git a/static/css/bootstrap-icons-1.11.3/sourceforge.svg b/app/static/css/bootstrap-icons-1.11.3/sourceforge.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sourceforge.svg rename to app/static/css/bootstrap-icons-1.11.3/sourceforge.svg diff --git a/static/css/bootstrap-icons-1.11.3/speaker-fill.svg b/app/static/css/bootstrap-icons-1.11.3/speaker-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/speaker-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/speaker-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/speaker.svg b/app/static/css/bootstrap-icons-1.11.3/speaker.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/speaker.svg rename to app/static/css/bootstrap-icons-1.11.3/speaker.svg diff --git a/static/css/bootstrap-icons-1.11.3/speedometer.svg b/app/static/css/bootstrap-icons-1.11.3/speedometer.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/speedometer.svg rename to app/static/css/bootstrap-icons-1.11.3/speedometer.svg diff --git a/static/css/bootstrap-icons-1.11.3/speedometer2.svg b/app/static/css/bootstrap-icons-1.11.3/speedometer2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/speedometer2.svg rename to app/static/css/bootstrap-icons-1.11.3/speedometer2.svg diff --git a/static/css/bootstrap-icons-1.11.3/spellcheck.svg b/app/static/css/bootstrap-icons-1.11.3/spellcheck.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/spellcheck.svg rename to app/static/css/bootstrap-icons-1.11.3/spellcheck.svg diff --git a/static/css/bootstrap-icons-1.11.3/spotify.svg b/app/static/css/bootstrap-icons-1.11.3/spotify.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/spotify.svg rename to app/static/css/bootstrap-icons-1.11.3/spotify.svg diff --git a/static/css/bootstrap-icons-1.11.3/square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/square-half.svg b/app/static/css/bootstrap-icons-1.11.3/square-half.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/square-half.svg rename to app/static/css/bootstrap-icons-1.11.3/square-half.svg diff --git a/static/css/bootstrap-icons-1.11.3/square.svg b/app/static/css/bootstrap-icons-1.11.3/square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/square.svg rename to app/static/css/bootstrap-icons-1.11.3/square.svg diff --git a/static/css/bootstrap-icons-1.11.3/stack-overflow.svg b/app/static/css/bootstrap-icons-1.11.3/stack-overflow.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/stack-overflow.svg rename to app/static/css/bootstrap-icons-1.11.3/stack-overflow.svg diff --git a/static/css/bootstrap-icons-1.11.3/stack.svg b/app/static/css/bootstrap-icons-1.11.3/stack.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/stack.svg rename to app/static/css/bootstrap-icons-1.11.3/stack.svg diff --git a/static/css/bootstrap-icons-1.11.3/star-fill.svg b/app/static/css/bootstrap-icons-1.11.3/star-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/star-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/star-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/star-half.svg b/app/static/css/bootstrap-icons-1.11.3/star-half.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/star-half.svg rename to app/static/css/bootstrap-icons-1.11.3/star-half.svg diff --git a/static/css/bootstrap-icons-1.11.3/star.svg b/app/static/css/bootstrap-icons-1.11.3/star.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/star.svg rename to app/static/css/bootstrap-icons-1.11.3/star.svg diff --git a/static/css/bootstrap-icons-1.11.3/stars.svg b/app/static/css/bootstrap-icons-1.11.3/stars.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/stars.svg rename to app/static/css/bootstrap-icons-1.11.3/stars.svg diff --git a/static/css/bootstrap-icons-1.11.3/steam.svg b/app/static/css/bootstrap-icons-1.11.3/steam.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/steam.svg rename to app/static/css/bootstrap-icons-1.11.3/steam.svg diff --git a/static/css/bootstrap-icons-1.11.3/stickies-fill.svg b/app/static/css/bootstrap-icons-1.11.3/stickies-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/stickies-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/stickies-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/stickies.svg b/app/static/css/bootstrap-icons-1.11.3/stickies.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/stickies.svg rename to app/static/css/bootstrap-icons-1.11.3/stickies.svg diff --git a/static/css/bootstrap-icons-1.11.3/sticky-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sticky-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sticky-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sticky-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sticky.svg b/app/static/css/bootstrap-icons-1.11.3/sticky.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sticky.svg rename to app/static/css/bootstrap-icons-1.11.3/sticky.svg diff --git a/static/css/bootstrap-icons-1.11.3/stop-btn-fill.svg b/app/static/css/bootstrap-icons-1.11.3/stop-btn-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/stop-btn-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/stop-btn-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/stop-btn.svg b/app/static/css/bootstrap-icons-1.11.3/stop-btn.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/stop-btn.svg rename to app/static/css/bootstrap-icons-1.11.3/stop-btn.svg diff --git a/static/css/bootstrap-icons-1.11.3/stop-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/stop-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/stop-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/stop-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/stop-circle.svg b/app/static/css/bootstrap-icons-1.11.3/stop-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/stop-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/stop-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/stop-fill.svg b/app/static/css/bootstrap-icons-1.11.3/stop-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/stop-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/stop-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/stop.svg b/app/static/css/bootstrap-icons-1.11.3/stop.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/stop.svg rename to app/static/css/bootstrap-icons-1.11.3/stop.svg diff --git a/static/css/bootstrap-icons-1.11.3/stoplights-fill.svg b/app/static/css/bootstrap-icons-1.11.3/stoplights-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/stoplights-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/stoplights-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/stoplights.svg b/app/static/css/bootstrap-icons-1.11.3/stoplights.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/stoplights.svg rename to app/static/css/bootstrap-icons-1.11.3/stoplights.svg diff --git a/static/css/bootstrap-icons-1.11.3/stopwatch-fill.svg b/app/static/css/bootstrap-icons-1.11.3/stopwatch-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/stopwatch-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/stopwatch-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/stopwatch.svg b/app/static/css/bootstrap-icons-1.11.3/stopwatch.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/stopwatch.svg rename to app/static/css/bootstrap-icons-1.11.3/stopwatch.svg diff --git a/static/css/bootstrap-icons-1.11.3/strava.svg b/app/static/css/bootstrap-icons-1.11.3/strava.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/strava.svg rename to app/static/css/bootstrap-icons-1.11.3/strava.svg diff --git a/static/css/bootstrap-icons-1.11.3/stripe.svg b/app/static/css/bootstrap-icons-1.11.3/stripe.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/stripe.svg rename to app/static/css/bootstrap-icons-1.11.3/stripe.svg diff --git a/static/css/bootstrap-icons-1.11.3/subscript.svg b/app/static/css/bootstrap-icons-1.11.3/subscript.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/subscript.svg rename to app/static/css/bootstrap-icons-1.11.3/subscript.svg diff --git a/static/css/bootstrap-icons-1.11.3/substack.svg b/app/static/css/bootstrap-icons-1.11.3/substack.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/substack.svg rename to app/static/css/bootstrap-icons-1.11.3/substack.svg diff --git a/static/css/bootstrap-icons-1.11.3/subtract.svg b/app/static/css/bootstrap-icons-1.11.3/subtract.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/subtract.svg rename to app/static/css/bootstrap-icons-1.11.3/subtract.svg diff --git a/static/css/bootstrap-icons-1.11.3/suit-club-fill.svg b/app/static/css/bootstrap-icons-1.11.3/suit-club-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/suit-club-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/suit-club-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/suit-club.svg b/app/static/css/bootstrap-icons-1.11.3/suit-club.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/suit-club.svg rename to app/static/css/bootstrap-icons-1.11.3/suit-club.svg diff --git a/static/css/bootstrap-icons-1.11.3/suit-diamond-fill.svg b/app/static/css/bootstrap-icons-1.11.3/suit-diamond-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/suit-diamond-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/suit-diamond-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/suit-diamond.svg b/app/static/css/bootstrap-icons-1.11.3/suit-diamond.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/suit-diamond.svg rename to app/static/css/bootstrap-icons-1.11.3/suit-diamond.svg diff --git a/static/css/bootstrap-icons-1.11.3/suit-heart-fill.svg b/app/static/css/bootstrap-icons-1.11.3/suit-heart-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/suit-heart-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/suit-heart-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/suit-heart.svg b/app/static/css/bootstrap-icons-1.11.3/suit-heart.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/suit-heart.svg rename to app/static/css/bootstrap-icons-1.11.3/suit-heart.svg diff --git a/static/css/bootstrap-icons-1.11.3/suit-spade-fill.svg b/app/static/css/bootstrap-icons-1.11.3/suit-spade-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/suit-spade-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/suit-spade-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/suit-spade.svg b/app/static/css/bootstrap-icons-1.11.3/suit-spade.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/suit-spade.svg rename to app/static/css/bootstrap-icons-1.11.3/suit-spade.svg diff --git a/static/css/bootstrap-icons-1.11.3/suitcase-fill.svg b/app/static/css/bootstrap-icons-1.11.3/suitcase-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/suitcase-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/suitcase-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/suitcase-lg-fill.svg b/app/static/css/bootstrap-icons-1.11.3/suitcase-lg-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/suitcase-lg-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/suitcase-lg-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/suitcase-lg.svg b/app/static/css/bootstrap-icons-1.11.3/suitcase-lg.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/suitcase-lg.svg rename to app/static/css/bootstrap-icons-1.11.3/suitcase-lg.svg diff --git a/static/css/bootstrap-icons-1.11.3/suitcase.svg b/app/static/css/bootstrap-icons-1.11.3/suitcase.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/suitcase.svg rename to app/static/css/bootstrap-icons-1.11.3/suitcase.svg diff --git a/static/css/bootstrap-icons-1.11.3/suitcase2-fill.svg b/app/static/css/bootstrap-icons-1.11.3/suitcase2-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/suitcase2-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/suitcase2-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/suitcase2.svg b/app/static/css/bootstrap-icons-1.11.3/suitcase2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/suitcase2.svg rename to app/static/css/bootstrap-icons-1.11.3/suitcase2.svg diff --git a/static/css/bootstrap-icons-1.11.3/sun-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sun-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sun-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sun-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sun.svg b/app/static/css/bootstrap-icons-1.11.3/sun.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sun.svg rename to app/static/css/bootstrap-icons-1.11.3/sun.svg diff --git a/static/css/bootstrap-icons-1.11.3/sunglasses.svg b/app/static/css/bootstrap-icons-1.11.3/sunglasses.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sunglasses.svg rename to app/static/css/bootstrap-icons-1.11.3/sunglasses.svg diff --git a/static/css/bootstrap-icons-1.11.3/sunrise-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sunrise-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sunrise-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sunrise-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sunrise.svg b/app/static/css/bootstrap-icons-1.11.3/sunrise.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sunrise.svg rename to app/static/css/bootstrap-icons-1.11.3/sunrise.svg diff --git a/static/css/bootstrap-icons-1.11.3/sunset-fill.svg b/app/static/css/bootstrap-icons-1.11.3/sunset-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sunset-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/sunset-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/sunset.svg b/app/static/css/bootstrap-icons-1.11.3/sunset.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/sunset.svg rename to app/static/css/bootstrap-icons-1.11.3/sunset.svg diff --git a/static/css/bootstrap-icons-1.11.3/superscript.svg b/app/static/css/bootstrap-icons-1.11.3/superscript.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/superscript.svg rename to app/static/css/bootstrap-icons-1.11.3/superscript.svg diff --git a/static/css/bootstrap-icons-1.11.3/symmetry-horizontal.svg b/app/static/css/bootstrap-icons-1.11.3/symmetry-horizontal.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/symmetry-horizontal.svg rename to app/static/css/bootstrap-icons-1.11.3/symmetry-horizontal.svg diff --git a/static/css/bootstrap-icons-1.11.3/symmetry-vertical.svg b/app/static/css/bootstrap-icons-1.11.3/symmetry-vertical.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/symmetry-vertical.svg rename to app/static/css/bootstrap-icons-1.11.3/symmetry-vertical.svg diff --git a/static/css/bootstrap-icons-1.11.3/table.svg b/app/static/css/bootstrap-icons-1.11.3/table.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/table.svg rename to app/static/css/bootstrap-icons-1.11.3/table.svg diff --git a/static/css/bootstrap-icons-1.11.3/tablet-fill.svg b/app/static/css/bootstrap-icons-1.11.3/tablet-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/tablet-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/tablet-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/tablet-landscape-fill.svg b/app/static/css/bootstrap-icons-1.11.3/tablet-landscape-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/tablet-landscape-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/tablet-landscape-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/tablet-landscape.svg b/app/static/css/bootstrap-icons-1.11.3/tablet-landscape.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/tablet-landscape.svg rename to app/static/css/bootstrap-icons-1.11.3/tablet-landscape.svg diff --git a/static/css/bootstrap-icons-1.11.3/tablet.svg b/app/static/css/bootstrap-icons-1.11.3/tablet.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/tablet.svg rename to app/static/css/bootstrap-icons-1.11.3/tablet.svg diff --git a/static/css/bootstrap-icons-1.11.3/tag-fill.svg b/app/static/css/bootstrap-icons-1.11.3/tag-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/tag-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/tag-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/tag.svg b/app/static/css/bootstrap-icons-1.11.3/tag.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/tag.svg rename to app/static/css/bootstrap-icons-1.11.3/tag.svg diff --git a/static/css/bootstrap-icons-1.11.3/tags-fill.svg b/app/static/css/bootstrap-icons-1.11.3/tags-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/tags-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/tags-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/tags.svg b/app/static/css/bootstrap-icons-1.11.3/tags.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/tags.svg rename to app/static/css/bootstrap-icons-1.11.3/tags.svg diff --git a/static/css/bootstrap-icons-1.11.3/taxi-front-fill.svg b/app/static/css/bootstrap-icons-1.11.3/taxi-front-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/taxi-front-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/taxi-front-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/taxi-front.svg b/app/static/css/bootstrap-icons-1.11.3/taxi-front.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/taxi-front.svg rename to app/static/css/bootstrap-icons-1.11.3/taxi-front.svg diff --git a/static/css/bootstrap-icons-1.11.3/telegram.svg b/app/static/css/bootstrap-icons-1.11.3/telegram.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/telegram.svg rename to app/static/css/bootstrap-icons-1.11.3/telegram.svg diff --git a/static/css/bootstrap-icons-1.11.3/telephone-fill.svg b/app/static/css/bootstrap-icons-1.11.3/telephone-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/telephone-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/telephone-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/telephone-forward-fill.svg b/app/static/css/bootstrap-icons-1.11.3/telephone-forward-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/telephone-forward-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/telephone-forward-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/telephone-forward.svg b/app/static/css/bootstrap-icons-1.11.3/telephone-forward.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/telephone-forward.svg rename to app/static/css/bootstrap-icons-1.11.3/telephone-forward.svg diff --git a/static/css/bootstrap-icons-1.11.3/telephone-inbound-fill.svg b/app/static/css/bootstrap-icons-1.11.3/telephone-inbound-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/telephone-inbound-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/telephone-inbound-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/telephone-inbound.svg b/app/static/css/bootstrap-icons-1.11.3/telephone-inbound.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/telephone-inbound.svg rename to app/static/css/bootstrap-icons-1.11.3/telephone-inbound.svg diff --git a/static/css/bootstrap-icons-1.11.3/telephone-minus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/telephone-minus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/telephone-minus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/telephone-minus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/telephone-minus.svg b/app/static/css/bootstrap-icons-1.11.3/telephone-minus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/telephone-minus.svg rename to app/static/css/bootstrap-icons-1.11.3/telephone-minus.svg diff --git a/static/css/bootstrap-icons-1.11.3/telephone-outbound-fill.svg b/app/static/css/bootstrap-icons-1.11.3/telephone-outbound-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/telephone-outbound-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/telephone-outbound-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/telephone-outbound.svg b/app/static/css/bootstrap-icons-1.11.3/telephone-outbound.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/telephone-outbound.svg rename to app/static/css/bootstrap-icons-1.11.3/telephone-outbound.svg diff --git a/static/css/bootstrap-icons-1.11.3/telephone-plus-fill.svg b/app/static/css/bootstrap-icons-1.11.3/telephone-plus-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/telephone-plus-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/telephone-plus-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/telephone-plus.svg b/app/static/css/bootstrap-icons-1.11.3/telephone-plus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/telephone-plus.svg rename to app/static/css/bootstrap-icons-1.11.3/telephone-plus.svg diff --git a/static/css/bootstrap-icons-1.11.3/telephone-x-fill.svg b/app/static/css/bootstrap-icons-1.11.3/telephone-x-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/telephone-x-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/telephone-x-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/telephone-x.svg b/app/static/css/bootstrap-icons-1.11.3/telephone-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/telephone-x.svg rename to app/static/css/bootstrap-icons-1.11.3/telephone-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/telephone.svg b/app/static/css/bootstrap-icons-1.11.3/telephone.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/telephone.svg rename to app/static/css/bootstrap-icons-1.11.3/telephone.svg diff --git a/static/css/bootstrap-icons-1.11.3/tencent-qq.svg b/app/static/css/bootstrap-icons-1.11.3/tencent-qq.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/tencent-qq.svg rename to app/static/css/bootstrap-icons-1.11.3/tencent-qq.svg diff --git a/static/css/bootstrap-icons-1.11.3/terminal-dash.svg b/app/static/css/bootstrap-icons-1.11.3/terminal-dash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/terminal-dash.svg rename to app/static/css/bootstrap-icons-1.11.3/terminal-dash.svg diff --git a/static/css/bootstrap-icons-1.11.3/terminal-fill.svg b/app/static/css/bootstrap-icons-1.11.3/terminal-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/terminal-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/terminal-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/terminal-plus.svg b/app/static/css/bootstrap-icons-1.11.3/terminal-plus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/terminal-plus.svg rename to app/static/css/bootstrap-icons-1.11.3/terminal-plus.svg diff --git a/static/css/bootstrap-icons-1.11.3/terminal-split.svg b/app/static/css/bootstrap-icons-1.11.3/terminal-split.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/terminal-split.svg rename to app/static/css/bootstrap-icons-1.11.3/terminal-split.svg diff --git a/static/css/bootstrap-icons-1.11.3/terminal-x.svg b/app/static/css/bootstrap-icons-1.11.3/terminal-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/terminal-x.svg rename to app/static/css/bootstrap-icons-1.11.3/terminal-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/terminal.svg b/app/static/css/bootstrap-icons-1.11.3/terminal.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/terminal.svg rename to app/static/css/bootstrap-icons-1.11.3/terminal.svg diff --git a/static/css/bootstrap-icons-1.11.3/text-center.svg b/app/static/css/bootstrap-icons-1.11.3/text-center.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/text-center.svg rename to app/static/css/bootstrap-icons-1.11.3/text-center.svg diff --git a/static/css/bootstrap-icons-1.11.3/text-indent-left.svg b/app/static/css/bootstrap-icons-1.11.3/text-indent-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/text-indent-left.svg rename to app/static/css/bootstrap-icons-1.11.3/text-indent-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/text-indent-right.svg b/app/static/css/bootstrap-icons-1.11.3/text-indent-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/text-indent-right.svg rename to app/static/css/bootstrap-icons-1.11.3/text-indent-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/text-left.svg b/app/static/css/bootstrap-icons-1.11.3/text-left.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/text-left.svg rename to app/static/css/bootstrap-icons-1.11.3/text-left.svg diff --git a/static/css/bootstrap-icons-1.11.3/text-paragraph.svg b/app/static/css/bootstrap-icons-1.11.3/text-paragraph.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/text-paragraph.svg rename to app/static/css/bootstrap-icons-1.11.3/text-paragraph.svg diff --git a/static/css/bootstrap-icons-1.11.3/text-right.svg b/app/static/css/bootstrap-icons-1.11.3/text-right.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/text-right.svg rename to app/static/css/bootstrap-icons-1.11.3/text-right.svg diff --git a/static/css/bootstrap-icons-1.11.3/text-wrap.svg b/app/static/css/bootstrap-icons-1.11.3/text-wrap.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/text-wrap.svg rename to app/static/css/bootstrap-icons-1.11.3/text-wrap.svg diff --git a/static/css/bootstrap-icons-1.11.3/textarea-resize.svg b/app/static/css/bootstrap-icons-1.11.3/textarea-resize.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/textarea-resize.svg rename to app/static/css/bootstrap-icons-1.11.3/textarea-resize.svg diff --git a/static/css/bootstrap-icons-1.11.3/textarea-t.svg b/app/static/css/bootstrap-icons-1.11.3/textarea-t.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/textarea-t.svg rename to app/static/css/bootstrap-icons-1.11.3/textarea-t.svg diff --git a/static/css/bootstrap-icons-1.11.3/textarea.svg b/app/static/css/bootstrap-icons-1.11.3/textarea.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/textarea.svg rename to app/static/css/bootstrap-icons-1.11.3/textarea.svg diff --git a/static/css/bootstrap-icons-1.11.3/thermometer-half.svg b/app/static/css/bootstrap-icons-1.11.3/thermometer-half.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/thermometer-half.svg rename to app/static/css/bootstrap-icons-1.11.3/thermometer-half.svg diff --git a/static/css/bootstrap-icons-1.11.3/thermometer-high.svg b/app/static/css/bootstrap-icons-1.11.3/thermometer-high.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/thermometer-high.svg rename to app/static/css/bootstrap-icons-1.11.3/thermometer-high.svg diff --git a/static/css/bootstrap-icons-1.11.3/thermometer-low.svg b/app/static/css/bootstrap-icons-1.11.3/thermometer-low.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/thermometer-low.svg rename to app/static/css/bootstrap-icons-1.11.3/thermometer-low.svg diff --git a/static/css/bootstrap-icons-1.11.3/thermometer-snow.svg b/app/static/css/bootstrap-icons-1.11.3/thermometer-snow.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/thermometer-snow.svg rename to app/static/css/bootstrap-icons-1.11.3/thermometer-snow.svg diff --git a/static/css/bootstrap-icons-1.11.3/thermometer-sun.svg b/app/static/css/bootstrap-icons-1.11.3/thermometer-sun.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/thermometer-sun.svg rename to app/static/css/bootstrap-icons-1.11.3/thermometer-sun.svg diff --git a/static/css/bootstrap-icons-1.11.3/thermometer.svg b/app/static/css/bootstrap-icons-1.11.3/thermometer.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/thermometer.svg rename to app/static/css/bootstrap-icons-1.11.3/thermometer.svg diff --git a/static/css/bootstrap-icons-1.11.3/threads-fill.svg b/app/static/css/bootstrap-icons-1.11.3/threads-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/threads-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/threads-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/threads.svg b/app/static/css/bootstrap-icons-1.11.3/threads.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/threads.svg rename to app/static/css/bootstrap-icons-1.11.3/threads.svg diff --git a/static/css/bootstrap-icons-1.11.3/three-dots-vertical.svg b/app/static/css/bootstrap-icons-1.11.3/three-dots-vertical.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/three-dots-vertical.svg rename to app/static/css/bootstrap-icons-1.11.3/three-dots-vertical.svg diff --git a/static/css/bootstrap-icons-1.11.3/three-dots.svg b/app/static/css/bootstrap-icons-1.11.3/three-dots.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/three-dots.svg rename to app/static/css/bootstrap-icons-1.11.3/three-dots.svg diff --git a/static/css/bootstrap-icons-1.11.3/thunderbolt-fill.svg b/app/static/css/bootstrap-icons-1.11.3/thunderbolt-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/thunderbolt-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/thunderbolt-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/thunderbolt.svg b/app/static/css/bootstrap-icons-1.11.3/thunderbolt.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/thunderbolt.svg rename to app/static/css/bootstrap-icons-1.11.3/thunderbolt.svg diff --git a/static/css/bootstrap-icons-1.11.3/ticket-detailed-fill.svg b/app/static/css/bootstrap-icons-1.11.3/ticket-detailed-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/ticket-detailed-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/ticket-detailed-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/ticket-detailed.svg b/app/static/css/bootstrap-icons-1.11.3/ticket-detailed.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/ticket-detailed.svg rename to app/static/css/bootstrap-icons-1.11.3/ticket-detailed.svg diff --git a/static/css/bootstrap-icons-1.11.3/ticket-fill.svg b/app/static/css/bootstrap-icons-1.11.3/ticket-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/ticket-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/ticket-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/ticket-perforated-fill.svg b/app/static/css/bootstrap-icons-1.11.3/ticket-perforated-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/ticket-perforated-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/ticket-perforated-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/ticket-perforated.svg b/app/static/css/bootstrap-icons-1.11.3/ticket-perforated.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/ticket-perforated.svg rename to app/static/css/bootstrap-icons-1.11.3/ticket-perforated.svg diff --git a/static/css/bootstrap-icons-1.11.3/ticket.svg b/app/static/css/bootstrap-icons-1.11.3/ticket.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/ticket.svg rename to app/static/css/bootstrap-icons-1.11.3/ticket.svg diff --git a/static/css/bootstrap-icons-1.11.3/tiktok.svg b/app/static/css/bootstrap-icons-1.11.3/tiktok.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/tiktok.svg rename to app/static/css/bootstrap-icons-1.11.3/tiktok.svg diff --git a/static/css/bootstrap-icons-1.11.3/toggle-off.svg b/app/static/css/bootstrap-icons-1.11.3/toggle-off.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/toggle-off.svg rename to app/static/css/bootstrap-icons-1.11.3/toggle-off.svg diff --git a/static/css/bootstrap-icons-1.11.3/toggle-on.svg b/app/static/css/bootstrap-icons-1.11.3/toggle-on.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/toggle-on.svg rename to app/static/css/bootstrap-icons-1.11.3/toggle-on.svg diff --git a/static/css/bootstrap-icons-1.11.3/toggle2-off.svg b/app/static/css/bootstrap-icons-1.11.3/toggle2-off.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/toggle2-off.svg rename to app/static/css/bootstrap-icons-1.11.3/toggle2-off.svg diff --git a/static/css/bootstrap-icons-1.11.3/toggle2-on.svg b/app/static/css/bootstrap-icons-1.11.3/toggle2-on.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/toggle2-on.svg rename to app/static/css/bootstrap-icons-1.11.3/toggle2-on.svg diff --git a/static/css/bootstrap-icons-1.11.3/toggles.svg b/app/static/css/bootstrap-icons-1.11.3/toggles.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/toggles.svg rename to app/static/css/bootstrap-icons-1.11.3/toggles.svg diff --git a/static/css/bootstrap-icons-1.11.3/toggles2.svg b/app/static/css/bootstrap-icons-1.11.3/toggles2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/toggles2.svg rename to app/static/css/bootstrap-icons-1.11.3/toggles2.svg diff --git a/static/css/bootstrap-icons-1.11.3/tools.svg b/app/static/css/bootstrap-icons-1.11.3/tools.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/tools.svg rename to app/static/css/bootstrap-icons-1.11.3/tools.svg diff --git a/static/css/bootstrap-icons-1.11.3/tornado.svg b/app/static/css/bootstrap-icons-1.11.3/tornado.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/tornado.svg rename to app/static/css/bootstrap-icons-1.11.3/tornado.svg diff --git a/static/css/bootstrap-icons-1.11.3/train-freight-front-fill.svg b/app/static/css/bootstrap-icons-1.11.3/train-freight-front-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/train-freight-front-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/train-freight-front-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/train-freight-front.svg b/app/static/css/bootstrap-icons-1.11.3/train-freight-front.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/train-freight-front.svg rename to app/static/css/bootstrap-icons-1.11.3/train-freight-front.svg diff --git a/static/css/bootstrap-icons-1.11.3/train-front-fill.svg b/app/static/css/bootstrap-icons-1.11.3/train-front-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/train-front-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/train-front-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/train-front.svg b/app/static/css/bootstrap-icons-1.11.3/train-front.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/train-front.svg rename to app/static/css/bootstrap-icons-1.11.3/train-front.svg diff --git a/static/css/bootstrap-icons-1.11.3/train-lightrail-front-fill.svg b/app/static/css/bootstrap-icons-1.11.3/train-lightrail-front-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/train-lightrail-front-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/train-lightrail-front-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/train-lightrail-front.svg b/app/static/css/bootstrap-icons-1.11.3/train-lightrail-front.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/train-lightrail-front.svg rename to app/static/css/bootstrap-icons-1.11.3/train-lightrail-front.svg diff --git a/static/css/bootstrap-icons-1.11.3/translate.svg b/app/static/css/bootstrap-icons-1.11.3/translate.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/translate.svg rename to app/static/css/bootstrap-icons-1.11.3/translate.svg diff --git a/static/css/bootstrap-icons-1.11.3/transparency.svg b/app/static/css/bootstrap-icons-1.11.3/transparency.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/transparency.svg rename to app/static/css/bootstrap-icons-1.11.3/transparency.svg diff --git a/static/css/bootstrap-icons-1.11.3/trash-fill.svg b/app/static/css/bootstrap-icons-1.11.3/trash-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/trash-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/trash-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/trash.svg b/app/static/css/bootstrap-icons-1.11.3/trash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/trash.svg rename to app/static/css/bootstrap-icons-1.11.3/trash.svg diff --git a/static/css/bootstrap-icons-1.11.3/trash2-fill.svg b/app/static/css/bootstrap-icons-1.11.3/trash2-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/trash2-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/trash2-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/trash2.svg b/app/static/css/bootstrap-icons-1.11.3/trash2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/trash2.svg rename to app/static/css/bootstrap-icons-1.11.3/trash2.svg diff --git a/static/css/bootstrap-icons-1.11.3/trash3-fill.svg b/app/static/css/bootstrap-icons-1.11.3/trash3-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/trash3-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/trash3-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/trash3.svg b/app/static/css/bootstrap-icons-1.11.3/trash3.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/trash3.svg rename to app/static/css/bootstrap-icons-1.11.3/trash3.svg diff --git a/static/css/bootstrap-icons-1.11.3/tree-fill.svg b/app/static/css/bootstrap-icons-1.11.3/tree-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/tree-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/tree-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/tree.svg b/app/static/css/bootstrap-icons-1.11.3/tree.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/tree.svg rename to app/static/css/bootstrap-icons-1.11.3/tree.svg diff --git a/static/css/bootstrap-icons-1.11.3/trello.svg b/app/static/css/bootstrap-icons-1.11.3/trello.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/trello.svg rename to app/static/css/bootstrap-icons-1.11.3/trello.svg diff --git a/static/css/bootstrap-icons-1.11.3/triangle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/triangle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/triangle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/triangle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/triangle-half.svg b/app/static/css/bootstrap-icons-1.11.3/triangle-half.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/triangle-half.svg rename to app/static/css/bootstrap-icons-1.11.3/triangle-half.svg diff --git a/static/css/bootstrap-icons-1.11.3/triangle.svg b/app/static/css/bootstrap-icons-1.11.3/triangle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/triangle.svg rename to app/static/css/bootstrap-icons-1.11.3/triangle.svg diff --git a/static/css/bootstrap-icons-1.11.3/trophy-fill.svg b/app/static/css/bootstrap-icons-1.11.3/trophy-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/trophy-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/trophy-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/trophy.svg b/app/static/css/bootstrap-icons-1.11.3/trophy.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/trophy.svg rename to app/static/css/bootstrap-icons-1.11.3/trophy.svg diff --git a/static/css/bootstrap-icons-1.11.3/tropical-storm.svg b/app/static/css/bootstrap-icons-1.11.3/tropical-storm.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/tropical-storm.svg rename to app/static/css/bootstrap-icons-1.11.3/tropical-storm.svg diff --git a/static/css/bootstrap-icons-1.11.3/truck-flatbed.svg b/app/static/css/bootstrap-icons-1.11.3/truck-flatbed.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/truck-flatbed.svg rename to app/static/css/bootstrap-icons-1.11.3/truck-flatbed.svg diff --git a/static/css/bootstrap-icons-1.11.3/truck-front-fill.svg b/app/static/css/bootstrap-icons-1.11.3/truck-front-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/truck-front-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/truck-front-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/truck-front.svg b/app/static/css/bootstrap-icons-1.11.3/truck-front.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/truck-front.svg rename to app/static/css/bootstrap-icons-1.11.3/truck-front.svg diff --git a/static/css/bootstrap-icons-1.11.3/truck.svg b/app/static/css/bootstrap-icons-1.11.3/truck.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/truck.svg rename to app/static/css/bootstrap-icons-1.11.3/truck.svg diff --git a/static/css/bootstrap-icons-1.11.3/tsunami.svg b/app/static/css/bootstrap-icons-1.11.3/tsunami.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/tsunami.svg rename to app/static/css/bootstrap-icons-1.11.3/tsunami.svg diff --git a/static/css/bootstrap-icons-1.11.3/tv-fill.svg b/app/static/css/bootstrap-icons-1.11.3/tv-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/tv-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/tv-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/tv.svg b/app/static/css/bootstrap-icons-1.11.3/tv.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/tv.svg rename to app/static/css/bootstrap-icons-1.11.3/tv.svg diff --git a/static/css/bootstrap-icons-1.11.3/twitch.svg b/app/static/css/bootstrap-icons-1.11.3/twitch.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/twitch.svg rename to app/static/css/bootstrap-icons-1.11.3/twitch.svg diff --git a/static/css/bootstrap-icons-1.11.3/twitter-x.svg b/app/static/css/bootstrap-icons-1.11.3/twitter-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/twitter-x.svg rename to app/static/css/bootstrap-icons-1.11.3/twitter-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/twitter.svg b/app/static/css/bootstrap-icons-1.11.3/twitter.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/twitter.svg rename to app/static/css/bootstrap-icons-1.11.3/twitter.svg diff --git a/static/css/bootstrap-icons-1.11.3/type-bold.svg b/app/static/css/bootstrap-icons-1.11.3/type-bold.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/type-bold.svg rename to app/static/css/bootstrap-icons-1.11.3/type-bold.svg diff --git a/static/css/bootstrap-icons-1.11.3/type-h1.svg b/app/static/css/bootstrap-icons-1.11.3/type-h1.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/type-h1.svg rename to app/static/css/bootstrap-icons-1.11.3/type-h1.svg diff --git a/static/css/bootstrap-icons-1.11.3/type-h2.svg b/app/static/css/bootstrap-icons-1.11.3/type-h2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/type-h2.svg rename to app/static/css/bootstrap-icons-1.11.3/type-h2.svg diff --git a/static/css/bootstrap-icons-1.11.3/type-h3.svg b/app/static/css/bootstrap-icons-1.11.3/type-h3.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/type-h3.svg rename to app/static/css/bootstrap-icons-1.11.3/type-h3.svg diff --git a/static/css/bootstrap-icons-1.11.3/type-h4.svg b/app/static/css/bootstrap-icons-1.11.3/type-h4.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/type-h4.svg rename to app/static/css/bootstrap-icons-1.11.3/type-h4.svg diff --git a/static/css/bootstrap-icons-1.11.3/type-h5.svg b/app/static/css/bootstrap-icons-1.11.3/type-h5.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/type-h5.svg rename to app/static/css/bootstrap-icons-1.11.3/type-h5.svg diff --git a/static/css/bootstrap-icons-1.11.3/type-h6.svg b/app/static/css/bootstrap-icons-1.11.3/type-h6.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/type-h6.svg rename to app/static/css/bootstrap-icons-1.11.3/type-h6.svg diff --git a/static/css/bootstrap-icons-1.11.3/type-italic.svg b/app/static/css/bootstrap-icons-1.11.3/type-italic.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/type-italic.svg rename to app/static/css/bootstrap-icons-1.11.3/type-italic.svg diff --git a/static/css/bootstrap-icons-1.11.3/type-strikethrough.svg b/app/static/css/bootstrap-icons-1.11.3/type-strikethrough.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/type-strikethrough.svg rename to app/static/css/bootstrap-icons-1.11.3/type-strikethrough.svg diff --git a/static/css/bootstrap-icons-1.11.3/type-underline.svg b/app/static/css/bootstrap-icons-1.11.3/type-underline.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/type-underline.svg rename to app/static/css/bootstrap-icons-1.11.3/type-underline.svg diff --git a/static/css/bootstrap-icons-1.11.3/type.svg b/app/static/css/bootstrap-icons-1.11.3/type.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/type.svg rename to app/static/css/bootstrap-icons-1.11.3/type.svg diff --git a/static/css/bootstrap-icons-1.11.3/ubuntu.svg b/app/static/css/bootstrap-icons-1.11.3/ubuntu.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/ubuntu.svg rename to app/static/css/bootstrap-icons-1.11.3/ubuntu.svg diff --git a/static/css/bootstrap-icons-1.11.3/ui-checks-grid.svg b/app/static/css/bootstrap-icons-1.11.3/ui-checks-grid.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/ui-checks-grid.svg rename to app/static/css/bootstrap-icons-1.11.3/ui-checks-grid.svg diff --git a/static/css/bootstrap-icons-1.11.3/ui-checks.svg b/app/static/css/bootstrap-icons-1.11.3/ui-checks.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/ui-checks.svg rename to app/static/css/bootstrap-icons-1.11.3/ui-checks.svg diff --git a/static/css/bootstrap-icons-1.11.3/ui-radios-grid.svg b/app/static/css/bootstrap-icons-1.11.3/ui-radios-grid.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/ui-radios-grid.svg rename to app/static/css/bootstrap-icons-1.11.3/ui-radios-grid.svg diff --git a/static/css/bootstrap-icons-1.11.3/ui-radios.svg b/app/static/css/bootstrap-icons-1.11.3/ui-radios.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/ui-radios.svg rename to app/static/css/bootstrap-icons-1.11.3/ui-radios.svg diff --git a/static/css/bootstrap-icons-1.11.3/umbrella-fill.svg b/app/static/css/bootstrap-icons-1.11.3/umbrella-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/umbrella-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/umbrella-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/umbrella.svg b/app/static/css/bootstrap-icons-1.11.3/umbrella.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/umbrella.svg rename to app/static/css/bootstrap-icons-1.11.3/umbrella.svg diff --git a/static/css/bootstrap-icons-1.11.3/unindent.svg b/app/static/css/bootstrap-icons-1.11.3/unindent.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/unindent.svg rename to app/static/css/bootstrap-icons-1.11.3/unindent.svg diff --git a/static/css/bootstrap-icons-1.11.3/union.svg b/app/static/css/bootstrap-icons-1.11.3/union.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/union.svg rename to app/static/css/bootstrap-icons-1.11.3/union.svg diff --git a/static/css/bootstrap-icons-1.11.3/unity.svg b/app/static/css/bootstrap-icons-1.11.3/unity.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/unity.svg rename to app/static/css/bootstrap-icons-1.11.3/unity.svg diff --git a/static/css/bootstrap-icons-1.11.3/universal-access-circle.svg b/app/static/css/bootstrap-icons-1.11.3/universal-access-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/universal-access-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/universal-access-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/universal-access.svg b/app/static/css/bootstrap-icons-1.11.3/universal-access.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/universal-access.svg rename to app/static/css/bootstrap-icons-1.11.3/universal-access.svg diff --git a/static/css/bootstrap-icons-1.11.3/unlock-fill.svg b/app/static/css/bootstrap-icons-1.11.3/unlock-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/unlock-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/unlock-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/unlock.svg b/app/static/css/bootstrap-icons-1.11.3/unlock.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/unlock.svg rename to app/static/css/bootstrap-icons-1.11.3/unlock.svg diff --git a/static/css/bootstrap-icons-1.11.3/upc-scan.svg b/app/static/css/bootstrap-icons-1.11.3/upc-scan.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/upc-scan.svg rename to app/static/css/bootstrap-icons-1.11.3/upc-scan.svg diff --git a/static/css/bootstrap-icons-1.11.3/upc.svg b/app/static/css/bootstrap-icons-1.11.3/upc.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/upc.svg rename to app/static/css/bootstrap-icons-1.11.3/upc.svg diff --git a/static/css/bootstrap-icons-1.11.3/upload.svg b/app/static/css/bootstrap-icons-1.11.3/upload.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/upload.svg rename to app/static/css/bootstrap-icons-1.11.3/upload.svg diff --git a/static/css/bootstrap-icons-1.11.3/usb-c-fill.svg b/app/static/css/bootstrap-icons-1.11.3/usb-c-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/usb-c-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/usb-c-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/usb-c.svg b/app/static/css/bootstrap-icons-1.11.3/usb-c.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/usb-c.svg rename to app/static/css/bootstrap-icons-1.11.3/usb-c.svg diff --git a/static/css/bootstrap-icons-1.11.3/usb-drive-fill.svg b/app/static/css/bootstrap-icons-1.11.3/usb-drive-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/usb-drive-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/usb-drive-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/usb-drive.svg b/app/static/css/bootstrap-icons-1.11.3/usb-drive.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/usb-drive.svg rename to app/static/css/bootstrap-icons-1.11.3/usb-drive.svg diff --git a/static/css/bootstrap-icons-1.11.3/usb-fill.svg b/app/static/css/bootstrap-icons-1.11.3/usb-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/usb-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/usb-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/usb-micro-fill.svg b/app/static/css/bootstrap-icons-1.11.3/usb-micro-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/usb-micro-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/usb-micro-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/usb-micro.svg b/app/static/css/bootstrap-icons-1.11.3/usb-micro.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/usb-micro.svg rename to app/static/css/bootstrap-icons-1.11.3/usb-micro.svg diff --git a/static/css/bootstrap-icons-1.11.3/usb-mini-fill.svg b/app/static/css/bootstrap-icons-1.11.3/usb-mini-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/usb-mini-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/usb-mini-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/usb-mini.svg b/app/static/css/bootstrap-icons-1.11.3/usb-mini.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/usb-mini.svg rename to app/static/css/bootstrap-icons-1.11.3/usb-mini.svg diff --git a/static/css/bootstrap-icons-1.11.3/usb-plug-fill.svg b/app/static/css/bootstrap-icons-1.11.3/usb-plug-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/usb-plug-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/usb-plug-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/usb-plug.svg b/app/static/css/bootstrap-icons-1.11.3/usb-plug.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/usb-plug.svg rename to app/static/css/bootstrap-icons-1.11.3/usb-plug.svg diff --git a/static/css/bootstrap-icons-1.11.3/usb-symbol.svg b/app/static/css/bootstrap-icons-1.11.3/usb-symbol.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/usb-symbol.svg rename to app/static/css/bootstrap-icons-1.11.3/usb-symbol.svg diff --git a/static/css/bootstrap-icons-1.11.3/usb.svg b/app/static/css/bootstrap-icons-1.11.3/usb.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/usb.svg rename to app/static/css/bootstrap-icons-1.11.3/usb.svg diff --git a/static/css/bootstrap-icons-1.11.3/valentine.svg b/app/static/css/bootstrap-icons-1.11.3/valentine.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/valentine.svg rename to app/static/css/bootstrap-icons-1.11.3/valentine.svg diff --git a/static/css/bootstrap-icons-1.11.3/valentine2.svg b/app/static/css/bootstrap-icons-1.11.3/valentine2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/valentine2.svg rename to app/static/css/bootstrap-icons-1.11.3/valentine2.svg diff --git a/static/css/bootstrap-icons-1.11.3/vector-pen.svg b/app/static/css/bootstrap-icons-1.11.3/vector-pen.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/vector-pen.svg rename to app/static/css/bootstrap-icons-1.11.3/vector-pen.svg diff --git a/static/css/bootstrap-icons-1.11.3/view-list.svg b/app/static/css/bootstrap-icons-1.11.3/view-list.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/view-list.svg rename to app/static/css/bootstrap-icons-1.11.3/view-list.svg diff --git a/static/css/bootstrap-icons-1.11.3/view-stacked.svg b/app/static/css/bootstrap-icons-1.11.3/view-stacked.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/view-stacked.svg rename to app/static/css/bootstrap-icons-1.11.3/view-stacked.svg diff --git a/static/css/bootstrap-icons-1.11.3/vignette.svg b/app/static/css/bootstrap-icons-1.11.3/vignette.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/vignette.svg rename to app/static/css/bootstrap-icons-1.11.3/vignette.svg diff --git a/static/css/bootstrap-icons-1.11.3/vimeo.svg b/app/static/css/bootstrap-icons-1.11.3/vimeo.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/vimeo.svg rename to app/static/css/bootstrap-icons-1.11.3/vimeo.svg diff --git a/static/css/bootstrap-icons-1.11.3/vinyl-fill.svg b/app/static/css/bootstrap-icons-1.11.3/vinyl-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/vinyl-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/vinyl-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/vinyl.svg b/app/static/css/bootstrap-icons-1.11.3/vinyl.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/vinyl.svg rename to app/static/css/bootstrap-icons-1.11.3/vinyl.svg diff --git a/static/css/bootstrap-icons-1.11.3/virus.svg b/app/static/css/bootstrap-icons-1.11.3/virus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/virus.svg rename to app/static/css/bootstrap-icons-1.11.3/virus.svg diff --git a/static/css/bootstrap-icons-1.11.3/virus2.svg b/app/static/css/bootstrap-icons-1.11.3/virus2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/virus2.svg rename to app/static/css/bootstrap-icons-1.11.3/virus2.svg diff --git a/static/css/bootstrap-icons-1.11.3/voicemail.svg b/app/static/css/bootstrap-icons-1.11.3/voicemail.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/voicemail.svg rename to app/static/css/bootstrap-icons-1.11.3/voicemail.svg diff --git a/static/css/bootstrap-icons-1.11.3/volume-down-fill.svg b/app/static/css/bootstrap-icons-1.11.3/volume-down-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/volume-down-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/volume-down-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/volume-down.svg b/app/static/css/bootstrap-icons-1.11.3/volume-down.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/volume-down.svg rename to app/static/css/bootstrap-icons-1.11.3/volume-down.svg diff --git a/static/css/bootstrap-icons-1.11.3/volume-mute-fill.svg b/app/static/css/bootstrap-icons-1.11.3/volume-mute-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/volume-mute-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/volume-mute-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/volume-mute.svg b/app/static/css/bootstrap-icons-1.11.3/volume-mute.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/volume-mute.svg rename to app/static/css/bootstrap-icons-1.11.3/volume-mute.svg diff --git a/static/css/bootstrap-icons-1.11.3/volume-off-fill.svg b/app/static/css/bootstrap-icons-1.11.3/volume-off-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/volume-off-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/volume-off-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/volume-off.svg b/app/static/css/bootstrap-icons-1.11.3/volume-off.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/volume-off.svg rename to app/static/css/bootstrap-icons-1.11.3/volume-off.svg diff --git a/static/css/bootstrap-icons-1.11.3/volume-up-fill.svg b/app/static/css/bootstrap-icons-1.11.3/volume-up-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/volume-up-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/volume-up-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/volume-up.svg b/app/static/css/bootstrap-icons-1.11.3/volume-up.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/volume-up.svg rename to app/static/css/bootstrap-icons-1.11.3/volume-up.svg diff --git a/static/css/bootstrap-icons-1.11.3/vr.svg b/app/static/css/bootstrap-icons-1.11.3/vr.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/vr.svg rename to app/static/css/bootstrap-icons-1.11.3/vr.svg diff --git a/static/css/bootstrap-icons-1.11.3/wallet-fill.svg b/app/static/css/bootstrap-icons-1.11.3/wallet-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/wallet-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/wallet-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/wallet.svg b/app/static/css/bootstrap-icons-1.11.3/wallet.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/wallet.svg rename to app/static/css/bootstrap-icons-1.11.3/wallet.svg diff --git a/static/css/bootstrap-icons-1.11.3/wallet2.svg b/app/static/css/bootstrap-icons-1.11.3/wallet2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/wallet2.svg rename to app/static/css/bootstrap-icons-1.11.3/wallet2.svg diff --git a/static/css/bootstrap-icons-1.11.3/watch.svg b/app/static/css/bootstrap-icons-1.11.3/watch.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/watch.svg rename to app/static/css/bootstrap-icons-1.11.3/watch.svg diff --git a/static/css/bootstrap-icons-1.11.3/water.svg b/app/static/css/bootstrap-icons-1.11.3/water.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/water.svg rename to app/static/css/bootstrap-icons-1.11.3/water.svg diff --git a/static/css/bootstrap-icons-1.11.3/webcam-fill.svg b/app/static/css/bootstrap-icons-1.11.3/webcam-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/webcam-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/webcam-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/webcam.svg b/app/static/css/bootstrap-icons-1.11.3/webcam.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/webcam.svg rename to app/static/css/bootstrap-icons-1.11.3/webcam.svg diff --git a/static/css/bootstrap-icons-1.11.3/wechat.svg b/app/static/css/bootstrap-icons-1.11.3/wechat.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/wechat.svg rename to app/static/css/bootstrap-icons-1.11.3/wechat.svg diff --git a/static/css/bootstrap-icons-1.11.3/whatsapp.svg b/app/static/css/bootstrap-icons-1.11.3/whatsapp.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/whatsapp.svg rename to app/static/css/bootstrap-icons-1.11.3/whatsapp.svg diff --git a/static/css/bootstrap-icons-1.11.3/wifi-1.svg b/app/static/css/bootstrap-icons-1.11.3/wifi-1.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/wifi-1.svg rename to app/static/css/bootstrap-icons-1.11.3/wifi-1.svg diff --git a/static/css/bootstrap-icons-1.11.3/wifi-2.svg b/app/static/css/bootstrap-icons-1.11.3/wifi-2.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/wifi-2.svg rename to app/static/css/bootstrap-icons-1.11.3/wifi-2.svg diff --git a/static/css/bootstrap-icons-1.11.3/wifi-off.svg b/app/static/css/bootstrap-icons-1.11.3/wifi-off.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/wifi-off.svg rename to app/static/css/bootstrap-icons-1.11.3/wifi-off.svg diff --git a/static/css/bootstrap-icons-1.11.3/wifi.svg b/app/static/css/bootstrap-icons-1.11.3/wifi.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/wifi.svg rename to app/static/css/bootstrap-icons-1.11.3/wifi.svg diff --git a/static/css/bootstrap-icons-1.11.3/wikipedia.svg b/app/static/css/bootstrap-icons-1.11.3/wikipedia.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/wikipedia.svg rename to app/static/css/bootstrap-icons-1.11.3/wikipedia.svg diff --git a/static/css/bootstrap-icons-1.11.3/wind.svg b/app/static/css/bootstrap-icons-1.11.3/wind.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/wind.svg rename to app/static/css/bootstrap-icons-1.11.3/wind.svg diff --git a/static/css/bootstrap-icons-1.11.3/window-dash.svg b/app/static/css/bootstrap-icons-1.11.3/window-dash.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/window-dash.svg rename to app/static/css/bootstrap-icons-1.11.3/window-dash.svg diff --git a/static/css/bootstrap-icons-1.11.3/window-desktop.svg b/app/static/css/bootstrap-icons-1.11.3/window-desktop.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/window-desktop.svg rename to app/static/css/bootstrap-icons-1.11.3/window-desktop.svg diff --git a/static/css/bootstrap-icons-1.11.3/window-dock.svg b/app/static/css/bootstrap-icons-1.11.3/window-dock.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/window-dock.svg rename to app/static/css/bootstrap-icons-1.11.3/window-dock.svg diff --git a/static/css/bootstrap-icons-1.11.3/window-fullscreen.svg b/app/static/css/bootstrap-icons-1.11.3/window-fullscreen.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/window-fullscreen.svg rename to app/static/css/bootstrap-icons-1.11.3/window-fullscreen.svg diff --git a/static/css/bootstrap-icons-1.11.3/window-plus.svg b/app/static/css/bootstrap-icons-1.11.3/window-plus.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/window-plus.svg rename to app/static/css/bootstrap-icons-1.11.3/window-plus.svg diff --git a/static/css/bootstrap-icons-1.11.3/window-sidebar.svg b/app/static/css/bootstrap-icons-1.11.3/window-sidebar.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/window-sidebar.svg rename to app/static/css/bootstrap-icons-1.11.3/window-sidebar.svg diff --git a/static/css/bootstrap-icons-1.11.3/window-split.svg b/app/static/css/bootstrap-icons-1.11.3/window-split.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/window-split.svg rename to app/static/css/bootstrap-icons-1.11.3/window-split.svg diff --git a/static/css/bootstrap-icons-1.11.3/window-stack.svg b/app/static/css/bootstrap-icons-1.11.3/window-stack.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/window-stack.svg rename to app/static/css/bootstrap-icons-1.11.3/window-stack.svg diff --git a/static/css/bootstrap-icons-1.11.3/window-x.svg b/app/static/css/bootstrap-icons-1.11.3/window-x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/window-x.svg rename to app/static/css/bootstrap-icons-1.11.3/window-x.svg diff --git a/static/css/bootstrap-icons-1.11.3/window.svg b/app/static/css/bootstrap-icons-1.11.3/window.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/window.svg rename to app/static/css/bootstrap-icons-1.11.3/window.svg diff --git a/static/css/bootstrap-icons-1.11.3/windows.svg b/app/static/css/bootstrap-icons-1.11.3/windows.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/windows.svg rename to app/static/css/bootstrap-icons-1.11.3/windows.svg diff --git a/static/css/bootstrap-icons-1.11.3/wordpress.svg b/app/static/css/bootstrap-icons-1.11.3/wordpress.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/wordpress.svg rename to app/static/css/bootstrap-icons-1.11.3/wordpress.svg diff --git a/static/css/bootstrap-icons-1.11.3/wrench-adjustable-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/wrench-adjustable-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/wrench-adjustable-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/wrench-adjustable-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/wrench-adjustable-circle.svg b/app/static/css/bootstrap-icons-1.11.3/wrench-adjustable-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/wrench-adjustable-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/wrench-adjustable-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/wrench-adjustable.svg b/app/static/css/bootstrap-icons-1.11.3/wrench-adjustable.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/wrench-adjustable.svg rename to app/static/css/bootstrap-icons-1.11.3/wrench-adjustable.svg diff --git a/static/css/bootstrap-icons-1.11.3/wrench.svg b/app/static/css/bootstrap-icons-1.11.3/wrench.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/wrench.svg rename to app/static/css/bootstrap-icons-1.11.3/wrench.svg diff --git a/static/css/bootstrap-icons-1.11.3/x-circle-fill.svg b/app/static/css/bootstrap-icons-1.11.3/x-circle-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/x-circle-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/x-circle-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/x-circle.svg b/app/static/css/bootstrap-icons-1.11.3/x-circle.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/x-circle.svg rename to app/static/css/bootstrap-icons-1.11.3/x-circle.svg diff --git a/static/css/bootstrap-icons-1.11.3/x-diamond-fill.svg b/app/static/css/bootstrap-icons-1.11.3/x-diamond-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/x-diamond-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/x-diamond-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/x-diamond.svg b/app/static/css/bootstrap-icons-1.11.3/x-diamond.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/x-diamond.svg rename to app/static/css/bootstrap-icons-1.11.3/x-diamond.svg diff --git a/static/css/bootstrap-icons-1.11.3/x-lg.svg b/app/static/css/bootstrap-icons-1.11.3/x-lg.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/x-lg.svg rename to app/static/css/bootstrap-icons-1.11.3/x-lg.svg diff --git a/static/css/bootstrap-icons-1.11.3/x-octagon-fill.svg b/app/static/css/bootstrap-icons-1.11.3/x-octagon-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/x-octagon-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/x-octagon-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/x-octagon.svg b/app/static/css/bootstrap-icons-1.11.3/x-octagon.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/x-octagon.svg rename to app/static/css/bootstrap-icons-1.11.3/x-octagon.svg diff --git a/static/css/bootstrap-icons-1.11.3/x-square-fill.svg b/app/static/css/bootstrap-icons-1.11.3/x-square-fill.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/x-square-fill.svg rename to app/static/css/bootstrap-icons-1.11.3/x-square-fill.svg diff --git a/static/css/bootstrap-icons-1.11.3/x-square.svg b/app/static/css/bootstrap-icons-1.11.3/x-square.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/x-square.svg rename to app/static/css/bootstrap-icons-1.11.3/x-square.svg diff --git a/static/css/bootstrap-icons-1.11.3/x.svg b/app/static/css/bootstrap-icons-1.11.3/x.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/x.svg rename to app/static/css/bootstrap-icons-1.11.3/x.svg diff --git a/static/css/bootstrap-icons-1.11.3/xbox.svg b/app/static/css/bootstrap-icons-1.11.3/xbox.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/xbox.svg rename to app/static/css/bootstrap-icons-1.11.3/xbox.svg diff --git a/static/css/bootstrap-icons-1.11.3/yelp.svg b/app/static/css/bootstrap-icons-1.11.3/yelp.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/yelp.svg rename to app/static/css/bootstrap-icons-1.11.3/yelp.svg diff --git a/static/css/bootstrap-icons-1.11.3/yin-yang.svg b/app/static/css/bootstrap-icons-1.11.3/yin-yang.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/yin-yang.svg rename to app/static/css/bootstrap-icons-1.11.3/yin-yang.svg diff --git a/static/css/bootstrap-icons-1.11.3/youtube.svg b/app/static/css/bootstrap-icons-1.11.3/youtube.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/youtube.svg rename to app/static/css/bootstrap-icons-1.11.3/youtube.svg diff --git a/static/css/bootstrap-icons-1.11.3/zoom-in.svg b/app/static/css/bootstrap-icons-1.11.3/zoom-in.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/zoom-in.svg rename to app/static/css/bootstrap-icons-1.11.3/zoom-in.svg diff --git a/static/css/bootstrap-icons-1.11.3/zoom-out.svg b/app/static/css/bootstrap-icons-1.11.3/zoom-out.svg similarity index 100% rename from static/css/bootstrap-icons-1.11.3/zoom-out.svg rename to app/static/css/bootstrap-icons-1.11.3/zoom-out.svg diff --git a/static/css/bootstrap-reboot.css b/app/static/css/bootstrap-reboot.css similarity index 100% rename from static/css/bootstrap-reboot.css rename to app/static/css/bootstrap-reboot.css diff --git a/static/css/bootstrap-reboot.css.map b/app/static/css/bootstrap-reboot.css.map similarity index 100% rename from static/css/bootstrap-reboot.css.map rename to app/static/css/bootstrap-reboot.css.map diff --git a/static/css/bootstrap-reboot.min.css b/app/static/css/bootstrap-reboot.min.css similarity index 100% rename from static/css/bootstrap-reboot.min.css rename to app/static/css/bootstrap-reboot.min.css diff --git a/static/css/bootstrap-reboot.min.css.map b/app/static/css/bootstrap-reboot.min.css.map similarity index 100% rename from static/css/bootstrap-reboot.min.css.map rename to app/static/css/bootstrap-reboot.min.css.map diff --git a/static/css/bootstrap-reboot.rtl.css b/app/static/css/bootstrap-reboot.rtl.css similarity index 100% rename from static/css/bootstrap-reboot.rtl.css rename to app/static/css/bootstrap-reboot.rtl.css diff --git a/static/css/bootstrap-reboot.rtl.css.map b/app/static/css/bootstrap-reboot.rtl.css.map similarity index 100% rename from static/css/bootstrap-reboot.rtl.css.map rename to app/static/css/bootstrap-reboot.rtl.css.map diff --git a/static/css/bootstrap-reboot.rtl.min.css b/app/static/css/bootstrap-reboot.rtl.min.css similarity index 100% rename from static/css/bootstrap-reboot.rtl.min.css rename to app/static/css/bootstrap-reboot.rtl.min.css diff --git a/static/css/bootstrap-reboot.rtl.min.css.map b/app/static/css/bootstrap-reboot.rtl.min.css.map similarity index 100% rename from static/css/bootstrap-reboot.rtl.min.css.map rename to app/static/css/bootstrap-reboot.rtl.min.css.map diff --git a/static/css/bootstrap-utilities.css b/app/static/css/bootstrap-utilities.css similarity index 100% rename from static/css/bootstrap-utilities.css rename to app/static/css/bootstrap-utilities.css diff --git a/static/css/bootstrap-utilities.css.map b/app/static/css/bootstrap-utilities.css.map similarity index 100% rename from static/css/bootstrap-utilities.css.map rename to app/static/css/bootstrap-utilities.css.map diff --git a/static/css/bootstrap-utilities.min.css b/app/static/css/bootstrap-utilities.min.css similarity index 100% rename from static/css/bootstrap-utilities.min.css rename to app/static/css/bootstrap-utilities.min.css diff --git a/static/css/bootstrap-utilities.min.css.map b/app/static/css/bootstrap-utilities.min.css.map similarity index 100% rename from static/css/bootstrap-utilities.min.css.map rename to app/static/css/bootstrap-utilities.min.css.map diff --git a/static/css/bootstrap-utilities.rtl.css b/app/static/css/bootstrap-utilities.rtl.css similarity index 100% rename from static/css/bootstrap-utilities.rtl.css rename to app/static/css/bootstrap-utilities.rtl.css diff --git a/static/css/bootstrap-utilities.rtl.css.map b/app/static/css/bootstrap-utilities.rtl.css.map similarity index 100% rename from static/css/bootstrap-utilities.rtl.css.map rename to app/static/css/bootstrap-utilities.rtl.css.map diff --git a/static/css/bootstrap-utilities.rtl.min.css b/app/static/css/bootstrap-utilities.rtl.min.css similarity index 100% rename from static/css/bootstrap-utilities.rtl.min.css rename to app/static/css/bootstrap-utilities.rtl.min.css diff --git a/static/css/bootstrap-utilities.rtl.min.css.map b/app/static/css/bootstrap-utilities.rtl.min.css.map similarity index 100% rename from static/css/bootstrap-utilities.rtl.min.css.map rename to app/static/css/bootstrap-utilities.rtl.min.css.map diff --git a/static/css/bootstrap.css b/app/static/css/bootstrap.css similarity index 100% rename from static/css/bootstrap.css rename to app/static/css/bootstrap.css diff --git a/static/css/bootstrap.css.map b/app/static/css/bootstrap.css.map similarity index 100% rename from static/css/bootstrap.css.map rename to app/static/css/bootstrap.css.map diff --git a/static/css/bootstrap.min.css b/app/static/css/bootstrap.min.css similarity index 100% rename from static/css/bootstrap.min.css rename to app/static/css/bootstrap.min.css diff --git a/static/css/bootstrap.min.css.map b/app/static/css/bootstrap.min.css.map similarity index 100% rename from static/css/bootstrap.min.css.map rename to app/static/css/bootstrap.min.css.map diff --git a/static/css/bootstrap.rtl.css b/app/static/css/bootstrap.rtl.css similarity index 100% rename from static/css/bootstrap.rtl.css rename to app/static/css/bootstrap.rtl.css diff --git a/static/css/bootstrap.rtl.css.map b/app/static/css/bootstrap.rtl.css.map similarity index 100% rename from static/css/bootstrap.rtl.css.map rename to app/static/css/bootstrap.rtl.css.map diff --git a/static/css/bootstrap.rtl.min.css b/app/static/css/bootstrap.rtl.min.css similarity index 100% rename from static/css/bootstrap.rtl.min.css rename to app/static/css/bootstrap.rtl.min.css diff --git a/static/css/bootstrap.rtl.min.css.map b/app/static/css/bootstrap.rtl.min.css.map similarity index 100% rename from static/css/bootstrap.rtl.min.css.map rename to app/static/css/bootstrap.rtl.min.css.map diff --git a/app/static/css/logs.css b/app/static/css/logs.css new file mode 100644 index 0000000..7e201ef --- /dev/null +++ b/app/static/css/logs.css @@ -0,0 +1,4 @@ +/* Курсор "рука" для иконки календаря (для Chrome и поддерживаемых браузеров) */ +input[type="date"]::-webkit-calendar-picker-indicator { + cursor: pointer; +} \ No newline at end of file diff --git a/static/css/regions.css b/app/static/css/regions.css similarity index 100% rename from static/css/regions.css rename to app/static/css/regions.css diff --git a/app/static/css/styles.css b/app/static/css/styles.css new file mode 100644 index 0000000..ed26e4d --- /dev/null +++ b/app/static/css/styles.css @@ -0,0 +1,18 @@ +body { + background-color: #f4f6f9; + font-family: "Poppins", sans-serif; +} + +.navbar-brand { + font-weight: bold; +} + +.btn-primary { + background-color: #007bff; + border-color: #007bff; +} + +.btn-primary:hover { + background-color: #0056b3; + border-color: #004085; +} diff --git a/static/css/toastr.min.css b/app/static/css/toastr.min.css similarity index 100% rename from static/css/toastr.min.css rename to app/static/css/toastr.min.css diff --git a/static/css/users.css b/app/static/css/users.css similarity index 100% rename from static/css/users.css rename to app/static/css/users.css diff --git a/static/js/bootstrap.bundle.js b/app/static/js/bootstrap.bundle.js similarity index 100% rename from static/js/bootstrap.bundle.js rename to app/static/js/bootstrap.bundle.js diff --git a/static/js/bootstrap.bundle.js.map b/app/static/js/bootstrap.bundle.js.map similarity index 100% rename from static/js/bootstrap.bundle.js.map rename to app/static/js/bootstrap.bundle.js.map diff --git a/static/js/bootstrap.bundle.min.js b/app/static/js/bootstrap.bundle.min.js similarity index 100% rename from static/js/bootstrap.bundle.min.js rename to app/static/js/bootstrap.bundle.min.js diff --git a/static/js/bootstrap.bundle.min.js.map b/app/static/js/bootstrap.bundle.min.js.map similarity index 100% rename from static/js/bootstrap.bundle.min.js.map rename to app/static/js/bootstrap.bundle.min.js.map diff --git a/static/js/bootstrap.esm.js b/app/static/js/bootstrap.esm.js similarity index 100% rename from static/js/bootstrap.esm.js rename to app/static/js/bootstrap.esm.js diff --git a/static/js/bootstrap.esm.js.map b/app/static/js/bootstrap.esm.js.map similarity index 100% rename from static/js/bootstrap.esm.js.map rename to app/static/js/bootstrap.esm.js.map diff --git a/static/js/bootstrap.esm.min.js b/app/static/js/bootstrap.esm.min.js similarity index 100% rename from static/js/bootstrap.esm.min.js rename to app/static/js/bootstrap.esm.min.js diff --git a/static/js/bootstrap.esm.min.js.map b/app/static/js/bootstrap.esm.min.js.map similarity index 100% rename from static/js/bootstrap.esm.min.js.map rename to app/static/js/bootstrap.esm.min.js.map diff --git a/static/js/bootstrap.js b/app/static/js/bootstrap.js similarity index 100% rename from static/js/bootstrap.js rename to app/static/js/bootstrap.js diff --git a/static/js/bootstrap.js.map b/app/static/js/bootstrap.js.map similarity index 100% rename from static/js/bootstrap.js.map rename to app/static/js/bootstrap.js.map diff --git a/static/js/bootstrap.min.js b/app/static/js/bootstrap.min.js similarity index 100% rename from static/js/bootstrap.min.js rename to app/static/js/bootstrap.min.js diff --git a/static/js/bootstrap.min.js.map b/app/static/js/bootstrap.min.js.map similarity index 100% rename from static/js/bootstrap.min.js.map rename to app/static/js/bootstrap.min.js.map diff --git a/static/js/jquery-3.6.0.js b/app/static/js/jquery-3.6.0.js similarity index 100% rename from static/js/jquery-3.6.0.js rename to app/static/js/jquery-3.6.0.js diff --git a/static/js/jquery-3.6.0.min.js b/app/static/js/jquery-3.6.0.min.js similarity index 100% rename from static/js/jquery-3.6.0.min.js rename to app/static/js/jquery-3.6.0.min.js diff --git a/app/static/js/regions.js b/app/static/js/regions.js new file mode 100644 index 0000000..7b3146a --- /dev/null +++ b/app/static/js/regions.js @@ -0,0 +1,649 @@ + + +const perPage=10 +let currentPage=1 +let totalPages=1 +let regionsCurrentPage=1 +let sortField="region_id" +let sortOrder="asc" +let currentFetchController=null +let currentSystemIdToDelete=null +let systemsCurrentPage=1 +let systemsTotalPages=1 +let systemsSortField="system_id" +let systemsSortOrder="asc" + + +// Предварительно создаём объекты модалей (чтобы не создавать каждый раз заново) +const editRegionNameModal = new bootstrap.Modal(document.getElementById('editRegionNameModal')); +const deleteRegionModal = new bootstrap.Modal(document.getElementById('deleteRegionModal')); +const regionSubscribersModal = new bootstrap.Modal(document.getElementById('regionSubscribersModal')); + +const editSystemNameModal = new bootstrap.Modal(document.getElementById('editSystemNameModal')); +const deleteSystemModal = new bootstrap.Modal(document.getElementById('deleteSystemModal')); + + +function loadRegions(e){ + if(e<1||e>totalPages)return; + currentPage=e; + let t=`/telezab/rest/api/regions?page=${currentPage}&per_page=${perPage}&sort_field=${sortField}&sort_order=${sortOrder}`; + currentFetchController&¤tFetchController.abort(), + safeFetch(t,{signal:(currentFetchController=new AbortController).signal}) + .then(e=>e.json()) + .then(e=>{ + currentFetchController=null, + totalPages=e.total_pages, + updateRegionsTable(e.regions), + updatePagination(e.current_page,e.total_pages,"pagination-regions") + }) + .catch(e=>{ + "AbortError"===e.name||console.error("Error fetching regions:",e), + currentFetchController=null + }) +} + +function updateRegionsTable(e){ + let t=document.getElementById("regions-table"); + if(!t) { + console.error("regions-table element not found!"); + return; + } + + t.innerHTML=""; + e.forEach(e=>{ + let n=document.createElement("tr"); + n.innerHTML=` + ${e.region_id} + ${e.name} + + ${e.active ? "Включен" : "Выключен"} + + +
+
+ + +
+ + + +
+ + `; + t.appendChild(n) + }); + setupRegionActions(); +} + +function setupRegionActions(){ + // Используем делегирование событий для избежания множественных обработчиков + const regionsTable = document.getElementById("regions-table"); + if (!regionsTable) return; + + // Удаляем старые обработчики событий с таблицы + const newTable = regionsTable.cloneNode(true); + regionsTable.parentNode.replaceChild(newTable, regionsTable); + + // Используем делегирование событий + newTable.addEventListener('click', function(e) { + const target = e.target.closest('button'); + if (!target) return; + + if (target.classList.contains('delete-btn')) { + e.preventDefault(); + deleteRegion(target.dataset.id); + } else if (target.classList.contains('edit-name-btn')) { + e.preventDefault(); + handleEditRegionName(target); + } else if (target.classList.contains('subscribers-btn')) { + e.preventDefault(); + showRegionSubscribers(target.dataset.id); + } + }); + + // Обработчик для переключателей статуса + newTable.addEventListener('change', function(e) { + if (e.target.classList.contains('region-status-switch')) { + let id = e.target.dataset.id; + let active = e.target.checked; + toggleRegionStatus(id, active); + document.getElementById(`region-status-label-${id}`).textContent = active ? "Включен" : "Выключен"; + } + }); + + // Обновляем заголовки для сортировки + document.querySelectorAll("th[data-sort]").forEach(e=>{ + const newHeader = e.cloneNode(true); + e.parentNode.replaceChild(newHeader, e); + newHeader.addEventListener("click", ()=>{ + let field = newHeader.dataset.sort; + if(field === sortField) { + sortOrder = sortOrder === "asc" ? "desc" : "asc"; + } else { + sortField = field; + sortOrder = "asc"; + } + loadRegions(currentPage); + }); + }); + const tooltipTriggerList = [].slice.call(document.querySelectorAll('[title]')); + tooltipTriggerList.map(el => new bootstrap.Tooltip(el)); +} + +function handleEditRegionName(e){ + let t = e.dataset.id, + n = e.dataset.name; + document.getElementById("old-region-name").value = n; + document.getElementById("new-region-name").value = n; + + editRegionNameModal.show(); + + let s = 5; + document.getElementById("edit-region-name-timer").textContent = s; + let a = setInterval(() => { + s--; + document.getElementById("edit-region-name-timer").textContent = s; + if (s === 0) { + clearInterval(a); + document.getElementById("save-region-name-btn").removeAttribute("disabled"); + } + }, 1000); + + let r = document.getElementById("save-region-name-btn"), + o = r.cloneNode(true); + r.parentNode.replaceChild(o, r); + o.addEventListener("click", () => { + updateRegionName(t, document.getElementById("new-region-name").value); + editRegionNameModal.hide(); + }); +} + +function showRegionSubscribers(e){ + safeFetch(`/telezab/rest/api/regions/${e}/subscribers`) + .then(res => res.json()) + .then(data => { + let t = document.getElementById("regionSubscribersTableBody"); + t.innerHTML = ""; + if(data.subscribers && data.subscribers.length > 0){ + data.subscribers.forEach(sub => { + let n = document.createElement("tr"); + n.innerHTML = ` + ${sub.telegram_id} + ${sub.email} + `; + t.appendChild(n); + }); + } else { + let n = document.createElement("tr"); + n.innerHTML = `Нет подписчиков для этого региона.`; + t.appendChild(n); + } + regionSubscribersModal.show(); + }) + .catch(err => { + console.error("Ошибка при получении подписчиков региона:", err); + toastr.error("Ошибка при получении подписчиков региона. Пожалуйста, попробуйте позже."); + }); +} + + +function updateRegionName(regionId, newName) { + safeFetch("/telezab/rest/api/regions/name", { + method:"PUT", + headers:{"Content-Type":"application/json"}, + body:JSON.stringify({region_id:regionId, name:newName}) + }) + .then(()=>{ + loadRegions(currentPage); + toastr.success("Название региона изменено."); + }) + .catch(e=>{ + console.error("Ошибка при изменении названия региона:",e); + toastr.error("Ошибка при изменении названия региона. Пожалуйста, попробуйте позже."); + }); +} + +function toggleRegionStatus(e,t){ + safeFetch("/telezab/rest/api/regions/status",{ + method:"PUT", + headers:{"Content-Type":"application/json"}, + body:JSON.stringify({region_id:e,active:t}) + }) + .then(()=>{ + loadRegions(currentPage); + t?toastr.success("Регион активирован."):toastr.success("Регион деактивирован."); + }) + .catch(e=>{ + console.error("Ошибка при изменении статуса региона:",e); + toastr.error("Ошибка при изменении статуса региона. Пожалуйста, попробуйте позже."); + }); +} + +function deleteRegion(e){ + deleteRegionModal.show(); + + let t = document.getElementById("deleteConfirmationInput"), + n = document.getElementById("confirmDeleteButton"), + s = document.getElementById("deleteRegionModal"), + a = t.cloneNode(true), + r = n.cloneNode(true); + + t.parentNode.replaceChild(a, t); + n.parentNode.replaceChild(r, n); + + a.addEventListener("input", function(){ + let val = this.value; + r.disabled = val === "УДАЛИТЬ" ? false : true; + }); + + r.addEventListener("click", function(){ + safeFetch(`/telezab/rest/api/regions/${e}`, { method: "DELETE" }) + .then(() => { + loadRegions(currentPage); + toastr.success("Регион успешно удален."); + deleteRegionModal.hide(); + }) + .catch(err => { + console.error("Ошибка при удалении региона:", err); + toastr.error("Ошибка при удалении региона. Пожалуйста, попробуйте позже."); + }); + }); + + s.addEventListener("hidden.bs.modal", function(){ + a.value = ""; + r.disabled = true; + }, { once: true }); +} + +function loadSystems(e){ + if(e<1||e>systemsTotalPages)return; + systemsCurrentPage=e; + let t=`/telezab/rest/api/systems?page=${systemsCurrentPage}&per_page=10&sort_field=${systemsSortField}&sort_order=${systemsSortOrder}`; + currentFetchController&¤tFetchController.abort(), + safeFetch(t,{signal:(currentFetchController=new AbortController).signal}) + .then(e=>e.json()) + .then(e=>{ + currentFetchController=null, + systemsTotalPages=e.total_pages, + updateSystemsTable(e.systems), + updatePagination(e.current_page,e.total_pages,"pagination-systems") + }) + .catch(e=>{ + "AbortError"===e.name||console.error("Error fetching systems:",e), + currentFetchController=null + }); +} + +function updateSystemsTable(e) { + let t = document.getElementById("systems-table"); + if (!t) { + console.error("systems-table element not found!"); + return; + } + + t.innerHTML = ""; + e.forEach(e => { + let n = document.createElement("tr"); + n.innerHTML = ` + ${e.system_id} + ${e.system_name} + ${e.name} + +
+ + +
+ + `; + t.appendChild(n); + }); + + setupSystemActions(); + + // Инициализация Bootstrap tooltips + const tooltipTriggerList = [].slice.call(document.querySelectorAll('[title]')); + tooltipTriggerList.map(el => new bootstrap.Tooltip(el)); +} + +function setupSystemActions(){ + // Используем делегирование событий для таблицы систем + const systemsTable = document.getElementById("systems-table"); + if (!systemsTable) return; + + // Удаляем старые обработчики событий с таблицы + const newTable = systemsTable.cloneNode(true); + systemsTable.parentNode.replaceChild(newTable, systemsTable); + + // Используем делегирование событий + newTable.addEventListener('click', function(e) { + const target = e.target.closest('button'); + if (!target) return; + + if (target.classList.contains('delete-btn')) { + e.preventDefault(); + deleteSystem(target.dataset.id); + } else if (target.classList.contains('edit-name-btn')) { + e.preventDefault(); + handleEditSystemName(target); + } + }); + + // Обновляем заголовки для сортировки + document.querySelectorAll("th[data-sort]").forEach(e=>{ + const newHeader = e.cloneNode(true); + e.parentNode.replaceChild(newHeader, e); + newHeader.addEventListener("click", ()=>{ + let field = newHeader.dataset.sort; + if(field === systemsSortField) { + systemsSortOrder = systemsSortOrder === "asc" ? "desc" : "asc"; + } else { + systemsSortField = field; + systemsSortOrder = "asc"; + } + loadSystems(systemsCurrentPage); + }); + }); +} + +function handleEditSystemName(e){ + let t = e.dataset.id, + n = e.dataset.latinName, + s = e.dataset.name; + + let a = document.getElementById("edit-system-id"), + r = document.getElementById("edit-system-name-lat"), + o = document.getElementById("old-system-name"), + l = document.getElementById("new-system-name"); + + if(!a || !r || !o || !l){ + console.error("❌ Один или несколько элементов не найдены:"); + !a && console.error(" - Не найден элемент #edit-system-id"); + !r && console.error(" - Не найден элемент #edit-system-name-lat"); + !o && console.error(" - Не найден элемент #old-system-name"); + !l && console.error(" - Не найден элемент #new-system-name"); + return; + } + + a.value = t; + r.value = n; + o.value = s; + l.value = s; + + editSystemNameModal.show(); + + let d = 5, + i = document.getElementById("edit-system-name-timer"); + i.textContent = d; + + let m = setInterval(() => { + d--; + i.textContent = d; + if(d === 0){ + clearInterval(m); + document.getElementById("saveSystemNameBtn").removeAttribute("disabled"); + } + }, 1000); + + let c = document.getElementById("saveSystemNameBtn"), + g = c.cloneNode(true); + c.parentNode.replaceChild(g, c); + + g.addEventListener("click", () => { + let id = a.value, + latinName = r.value, + newName = l.value.trim(); + + if(!newName){ + toastr.error("Введите новое название системы."); + return; + } + + updateSystemName(id, latinName, newName); + editSystemNameModal.hide(); + }); +} + + + +function updateSystemName(systemId, systemNameLat, nameCyr) { + if (!systemId || !systemNameLat || !nameCyr) { + toastr.error("Не все параметры заполнены."); + return; + } + + safeFetch("/telezab/rest/api/systems", { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + system_id: systemId, + system_name: systemNameLat, + name: nameCyr + }) + }) + .then(res => res.ok ? res.json() : res.json().then(e => { throw new Error(e.message || "Ошибка сервера") })) + .then(() => { + loadSystems(systemsCurrentPage); + toastr.success("Название системы успешно обновлено."); + }) + .catch(e => { + console.error("Ошибка при изменении названия системы:", e); + toastr.error(e.message || "Ошибка при изменении названия системы. Пожалуйста, попробуйте позже."); + }); +} + +function deleteSystem(e){ + deleteSystemModal.show(); + + let t = document.getElementById("deleteSystemConfirmationInput"), + n = document.getElementById("confirmDeleteSystemButton"), + s = document.getElementById("deleteSystemModal"), + a = t.cloneNode(true), + r = n.cloneNode(true); + + t.parentNode.replaceChild(a, t); + n.parentNode.replaceChild(r, n); + + a.addEventListener("input", function(){ + let val = this.value; + r.disabled = val === "УДАЛИТЬ" ? false : true; + }); + + r.addEventListener("click", function(){ + safeFetch(`/telezab/rest/api/systems/${e}`, { method: "DELETE" }) + .then(() => { + loadSystems(systemsCurrentPage); + toastr.success("Система успешно удалена."); + deleteSystemModal.hide(); + }) + .catch(err => { + console.error("Ошибка при удалении системы:", err); + toastr.error("Ошибка при удалении системы. Пожалуйста, попробуйте позже."); + }); + }); + + s.addEventListener("hidden.bs.modal", function(){ + a.value = ""; + r.disabled = true; + }, { once: true }); +} + + +function updatePagination(e,t,n){ + let s=document.getElementById(n); + if(!s){ + console.error(`Container with ID ${n} not found!`); + return; + } + s.innerHTML=""; + + let a=document.createElement("li"); + a.classList.add("page-item"); + a.classList.toggle("disabled",1===e); + a.innerHTML=`«`; + s.appendChild(a); + + for(let r=1;r<=t;r++){ + let o=document.createElement("li"); + o.classList.add("page-item"); + o.classList.toggle("active",r===e); + let l=document.createElement("a"); + l.classList.add("page-link"); + l.href="#"; + l.textContent=r; + l.onclick=()=>loadPage(r,n); + o.appendChild(l); + s.appendChild(o); + } + + let i=document.createElement("li"); + i.classList.add("page-item"); + i.classList.toggle("disabled",e===t); + i.innerHTML=`»`; + s.appendChild(i); +} + +function loadPage(e,t){ + "pagination-regions"===t?loadRegions(e):"pagination-systems"===t&&loadSystems(e); +} + +// Настройка toastr +toastr.options={ + closeButton:!0, + debug:!1, + newestOnTop:!1, + progressBar:!1, + positionClass:"toast-bottom-right", + preventDuplicates:!1, + onclick:null, + showDuration:"300", + hideDuration:"1000", + timeOut:"5000", + extendedTimeOut:"1000", + showEasing:"swing", + hideEasing:"linear", + showMethod:"fadeIn", + hideMethod:"fadeOut" +}; + +// Обработчики форм +document.getElementById("add-region-form").addEventListener("submit",e=>{ + e.preventDefault(); + let regionId=document.getElementById("region-id").value; + let regionName=document.getElementById("region-name").value; + let regionActive=document.getElementById("region-active").checked; + + if(!/^\d+$/.test(regionId)){ + toastr.error("ID региона должен содержать только числа."); + console.log("Ошибка: ID региона не является числом."); + return; + } + + safeFetch("/telezab/rest/api/regions",{ + method:"POST", + headers:{"Content-Type":"application/json"}, + body:JSON.stringify({region_id:regionId,name:regionName,active:regionActive}) + }) + .then(e=>e.ok?e.json():e.json().then(e=>{ + throw console.error("Ошибка от сервера:",e),new Error(e.message||"Ошибка добавления региона"); + })) + .then(e=>{ + if("success"===e.status){ + console.log("Регион успешно добавлен."); + document.getElementById("region-id").value=""; + document.getElementById("region-name").value=""; + document.getElementById("region-active").checked=!1; + loadRegions(regionsCurrentPage); + toastr.success(e.message); + $("#addRegionModal").modal("hide"); + }else{ + throw console.log("Ошибка: Статус ответа не 'success'."),new Error(e.message||"Неизвестная ошибка"); + } + }) + .catch(e=>{ + console.error("Ошибка при добавлении региона:",e); + toastr.error(e.message||"Ошибка при добавлении региона. Пожалуйста, попробуйте позже."); + }); +}); + +document.getElementById("add-system-form").addEventListener("submit",e=>{ + e.preventDefault(); + let systemId=document.getElementById("system-id").value; + let systemNameLat=document.getElementById("system-name-lat").value; + let systemNameCyr=document.getElementById("system-name-cyr").value; + + if(!/^\d+$/.test(systemId)){ + toastr.error("ID системы должен содержать только числа."); + return; + } + + safeFetch("/telezab/rest/api/systems",{ + method:"POST", + headers:{"Content-Type":"application/json"}, + body:JSON.stringify({system_id:systemId,system_name:systemNameLat,name:systemNameCyr}) + }) + .then(e=>e.ok?e.json():e.json().then(e=>{ + throw new Error(e.message||"Ошибка добавления системы"); + })) + .then(e=>{ + document.getElementById("system-id").value=""; + document.getElementById("system-name-lat").value=""; + document.getElementById("system-name-cyr").value=""; + loadSystems(systemsCurrentPage); + toastr.success("Система успешно добавлена."); + $("#addSystemModal").modal("hide"); + }) + .catch(e=>{ + console.error("Ошибка при добавлении системы:",e); + toastr.error(e.message||"Ошибка при добавлении системы. Пожалуйста, попробуйте позже."); + }); +}); + +// Инициализация при загрузке страницы +document.addEventListener("DOMContentLoaded",()=>{ + let regionsTab=document.getElementById("regions-tab"); + let systemsTab=document.getElementById("systems-tab"); + + regionsTab.addEventListener("shown.bs.tab",()=>{ + loadRegions(currentPage); + }); + + systemsTab.addEventListener("shown.bs.tab",()=>{ + loadSystems(systemsCurrentPage); + }); + + regionsTab.classList.contains("active")&&loadRegions(currentPage); + + // Очистка форм при закрытии модальных окон + let modalsConfig=[ + {modalId:"addRegionModal",formId:"add-region-form"}, + {modalId:"addSystemModal",formId:"add-system-form"}, + {modalId:"editRegionNameModal",formId:"edit-region-name-form"}, + {modalId:"editSystemNameModal",formId:"edit-system-name-form"} + ]; + + modalsConfig.forEach(({modalId,formId})=>{ + let modal=document.getElementById(modalId); + let form=document.getElementById(formId); + if(modal&&form){ + modal.addEventListener("hidden.bs.modal",()=>{ + form.reset(); + }); + } + }); +}); \ No newline at end of file diff --git a/static/js/toastr.js.map b/app/static/js/toastr.js.map similarity index 100% rename from static/js/toastr.js.map rename to app/static/js/toastr.js.map diff --git a/static/js/toastr.min.js b/app/static/js/toastr.min.js similarity index 100% rename from static/js/toastr.min.js rename to app/static/js/toastr.min.js diff --git a/static/js/users.js b/app/static/js/users.js similarity index 95% rename from static/js/users.js rename to app/static/js/users.js index 1a02122..28e1803 100644 --- a/static/js/users.js +++ b/app/static/js/users.js @@ -1,3 +1,5 @@ +// noinspection DuplicatedCode + let currentPage = 1; let totalPages = 1; let allUsers = []; // Добавляем массив для хранения всех пользователей @@ -124,7 +126,7 @@ function formatDate(isoString) { // Функция загрузки событий пользователя function loadUserEvents(chatId) { - fetch(`/telezab/rest/api/user_events/${chatId}`) + fetch(`/telezab/rest/api/users/${chatId}/user_events`) .then(response => response.json()) .then(data => { const tableBody = document.getElementById('userEventsTable').querySelector('tbody'); @@ -134,7 +136,7 @@ function loadUserEvents(chatId) { data.forEach(event => { const row = document.createElement('tr'); row.innerHTML = ` - ${event.action} + ${event.event_type} ${formatDate(event.timestamp)} `; tableBody.appendChild(row); @@ -314,7 +316,7 @@ $(document).ready(function() { // Отправка AJAX-запроса к API $.ajax({ - url: '/telezab/rest/api/user_events/' + chatId, + url: '/telezab/rest/api/' + chatId + '/user_events', type: 'GET', success: function(data) { // Обработка успешного ответа @@ -380,6 +382,19 @@ $('#searchUsersButton').click(function() { }); +const addUserModalEl = document.getElementById('addUserModal'); +addUserModalEl.addEventListener('hidden.bs.modal', () => { + document.getElementById("newUserId").value = ''; + document.getElementById("newUsername").value = ''; + document.getElementById("newUserEmail").value = ''; +}); + +// Очистка поля подтверждения удаления при закрытии модального окна удаления пользователя +const deleteModalEl = document.getElementById('deleteConfirmationModal'); +deleteModalEl.addEventListener('hidden.bs.modal', () => { + document.getElementById('confirmationText').value = ''; +}); + // Запуск загрузки данных document.addEventListener("DOMContentLoaded", () => { loadUsers(currentPage); diff --git a/app/static/js/utils.js b/app/static/js/utils.js new file mode 100644 index 0000000..2061ed5 --- /dev/null +++ b/app/static/js/utils.js @@ -0,0 +1,21 @@ + +window.safeFetch = function(url, options = {}) { + return fetch(url, options).then(response => { + if (response.status === 401) { + window.location.href = `${window.location.origin}/telezab/login`; + throw new Error("Unauthorized"); + } + return response; + }); +}; + + +window.safeFetchJson = function(url, options = {}) { + return fetch(url, options).then(response => { + if (response.status === 401) { + window.location.href = `${window.location.origin}/telezab/login`; + throw new Error("Unauthorized"); + } + return response.json(); + }); +}; \ No newline at end of file diff --git a/templates/base.html b/app/templates/base.html similarity index 87% rename from templates/base.html rename to app/templates/base.html index 4b18ff3..c609d0b 100644 --- a/templates/base.html +++ b/app/templates/base.html @@ -7,6 +7,9 @@ + + {# Блок для подключения дополнительных стилей на страницах #} + {% block styles %}{% endblock %} - + {# Модальное окно карточки пользователя #} diff --git a/app/workers/__init__.py b/app/workers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/workers/rabbitmq_worker.py b/app/workers/rabbitmq_worker.py new file mode 100644 index 0000000..22ac96d --- /dev/null +++ b/app/workers/rabbitmq_worker.py @@ -0,0 +1,57 @@ +import asyncio +import json +import logging +from aio_pika import connect_robust, exceptions as aio_exceptions +from app import create_app, db +from app.models import Users + +logger = logging.getLogger(__name__) +rate_limit_semaphore = asyncio.Semaphore(25) + +RABBITMQ_URL = "amqp://guest:guest@localhost/" +RABBITMQ_QUEUE = "your_queue" + +async def send_message(backend_bot, chat_id, message_text): + telegram_id = "unknown" + + try: + async with rate_limit_semaphore: + async def get_user(): + with app.app_context(): + user = Users.query.get(chat_id) + return user.telegram_id if user else "unknown" + + telegram_id = await asyncio.to_thread(get_user) + await asyncio.to_thread( + backend_bot.bot.send_message, + chat_id, + message_text, + parse_mode="HTML" + ) + logger.info(f"[RabbitMQ] Sent to {telegram_id} ({chat_id}): {message_text}") + + except Exception as e: + logger.error(f"Error sending message to {telegram_id} ({chat_id}): {e}") + +async def consume_from_queue(backend_bot): + while True: + try: + connection = await connect_robust(RABBITMQ_URL) + async with connection: + channel = await connection.channel() + queue = await channel.declare_queue(RABBITMQ_QUEUE, durable=True) + + async for message in queue: + async with message.process(): + try: + data = json.loads(message.body.decode('utf-8')) + await send_message(backend_bot, data["chat_id"], data["message"]) + except (json.JSONDecodeError, KeyError) as e: + logger.error(f"Error decoding message: {e}") + + except aio_exceptions.AMQPError as e: + logger.error(f"RabbitMQ AMQPError: {e}") + except Exception as e: + logger.error(f"Unhandled error in consumer: {e}") + finally: + await asyncio.sleep(5) diff --git a/backend/api.py b/backend/api.py deleted file mode 100644 index 2c2db4d..0000000 --- a/backend/api.py +++ /dev/null @@ -1,262 +0,0 @@ -from flask import jsonify, request, Blueprint -from flask_login import login_required - -from frontend.dashboard import user_manager, event_manager, region_manager, system_manager -from utilities.database import db -from utilities.web_logger import WebLogger - -bp_api = Blueprint('api', __name__, url_prefix='/telezab/rest/api') -web_logger = WebLogger(db) - - -@bp_api.route('/users', methods=['GET', 'POST']) -@login_required -def manage_users(): - if request.method == 'GET': - page = request.args.get('page', 1, type=int) - per_page = request.args.get('per_page', 20, type=int) - return jsonify(user_manager.get_users(page, per_page)) - elif request.method == 'POST': - user_data = request.get_json() - try: - result, status_code = user_manager.add_user(user_data) - if status_code == 201: - web_logger.log_web_action( - action='Добавление пользователя Telegram', - details=f'Telegram ID: {user_data.get("chat_id")}, Username: {user_data.get("username")}' - ) - return jsonify(result), status_code - except Exception as e: - return jsonify({'error': str(e)}), 500 - -@bp_api.route('/users/', methods=['GET']) -@login_required -def get_user(chat_id): - user = user_manager.get_user(chat_id) - if not user: - return jsonify({'error': 'Пользователь не найден'}), 404 - return jsonify(user) - - -@bp_api.route('/users//block', methods=['POST']) -@login_required -def block_user(chat_id): - user_info = user_manager.get_user(chat_id) - blocked = user_manager.toggle_block_user(chat_id) - if blocked is not None: - status = 'заблокирован' if blocked else 'разблокирован' - web_logger.log_web_action( - action=f'Блокировка/разблокировка пользователя Telegram', - details=f'Telegram ID: {chat_id}, Username: {user_info.get("username") if user_info else "неизвестно"}, Статус: {status}' - ) - return jsonify({'status': 'updated', 'new_status': blocked}) - else: - return jsonify({'status': 'error', 'message': 'User not found'}), 404 - - -@bp_api.route('/users/', methods=['DELETE']) -@login_required -def delete_user(chat_id): - user_info = user_manager.get_user(chat_id) - if user_manager.delete_user(chat_id): - web_logger.log_web_action( - action='Удаление пользователя Telegram', - details=f'Telegram ID: {chat_id}, Username: {user_info.get("username") if user_info else "неизвестно"}' - ) - return jsonify({'status': 'deleted'}) - else: - return jsonify({'status': 'error', 'message': 'User not found'}), 404 - - -@bp_api.route('/users//log', methods=['POST']) -@login_required -def log_user_action(chat_id): - action = request.json.get('action') - if action: - event_manager.log_user_action(chat_id, action) - return jsonify({'message': 'Действие сохранено'}), 200 - else: - return jsonify({'error': 'Не указано действие'}), 400 - -@bp_api.route('/users/search', methods=['GET']) -@login_required -def search_users(): - telegram_id = request.args.get('telegram_id') - email = request.args.get('email') - users = user_manager.search_users(telegram_id, email) - return jsonify(users) - -@bp_api.route('/user_events/', methods=['GET']) -@login_required -def handle_user_events(chat_id): - return event_manager.get_user_events(chat_id) - - - -@bp_api.route('/regions', methods=['GET', 'POST', 'PUT', 'DELETE']) -@login_required -def manage_regions(): - if request.method == 'POST': - region_data = request.get_json() - result = region_manager.add_region(region_data) - web_logger.log_web_action( - action='Добавление региона', - details=f'Название: {region_data.get("name")}, Номер: {region_data.get("number")}' - ) - return jsonify(result) - elif request.method == 'PUT': - region_data = request.get_json() - if 'active' in region_data: - result = region_manager.update_region_status(region_data) - status = 'активирован' if region_data.get('active') else 'деактивирован' - web_logger.log_web_action( - action='Изменение статуса региона', - details=f'ID: {region_data.get("region_id")}, Статус: {status}' - ) - return jsonify(result) - elif 'name' in region_data: - result = region_manager.update_region_name(region_data) - web_logger.log_web_action( - action='Изменение названия региона', - details=f'ID: {region_data.get("region_id")}, Новое название: {region_data.get("name")}' - ) - return jsonify(result) - else: - return jsonify({'status': 'error', 'message': 'Некорректный запрос'}), 400 - elif request.method == 'DELETE': - region_id = request.args.get('region_id') - region_info = region_manager.get_region(region_id) - result = region_manager.delete_region(region_id) - if result.get('status') == 'success': - web_logger.log_web_action( - action='Удаление региона', - details=f'ID: {region_id}, Название: {region_info.get("region_name") if region_info else "неизвестно"}' - ) - return jsonify(result) - -@bp_api.route('/regions//subscribers', methods=['GET']) -@login_required -def get_region_subscribers(region_id): - result, status_code = region_manager.get_region_subscribers(region_id) - return jsonify(result), status_code - -@bp_api.route('/systems', methods=['GET']) -@login_required -def get_systems(): - page = request.args.get('page', 1, type=int) - per_page = request.args.get('per_page', 10, type=int) - sort_field = request.args.get('sort_field', 'system_id') - sort_order = request.args.get('sort_order', 'asc') - - result = system_manager.get_systems(page, per_page, sort_field, sort_order) - return jsonify(result) - -@bp_api.route('/systems', methods=['POST', 'PUT', 'DELETE']) -@login_required -def manage_systems(): - if request.method == 'POST': - data = request.get_json() - result, status_code = system_manager.add_system(data) - if status_code == 201: - web_logger.log_web_action( - action='Добавление системы', - details=f'ID: {data.get("system_id")}, Название: {data.get("name")}' - ) - return jsonify(result), status_code - elif request.method == 'PUT': - data = request.get_json() - system_info_before = system_manager.get_system(data.get('system_id')) - result, status_code = system_manager.update_system_name(data) - if status_code == 200: - web_logger.log_web_action( - action='Изменение названия системы', - details=f'ID: {data.get("system_id")}, Старое название: {system_info_before.get("name") if system_info_before else "неизвестно"}, Новое название: {data.get("name")}' - ) - return jsonify(result), status_code - elif request.method == 'DELETE': - system_id = request.args.get('system_id') - system_info = system_manager.get_system(system_id) - result, status_code = system_manager.delete_system(system_id) - if status_code == 200: - web_logger.log_web_action( - action='Удаление системы', - details=f'ID: {system_id}, Название: {system_info.get("name") if system_info else "неизвестно"}' - ) - return jsonify(result), status_code - -@bp_api.route('/web_logs', methods=['GET']) -@login_required -def get_web_logs(): - page = request.args.get('page', 1, type=int) - per_page = request.args.get('per_page', 20, type=int) - ldap_user_id_filter = request.args.get('user_id', None, type=str) - action_filter = request.args.get('action', None, type=str) - - logs_data = web_logger.get_web_action_logs(page, per_page, ldap_user_id_filter, action_filter) - return jsonify(logs_data) - -# -# @bp_api.route('/systems', methods=['POST']) -# @login_required -# def add_system(): -# data = request.get_json() -# result, status_code = system_manager.add_system(data) -# return jsonify(result), status_code -# -# @bp_api.route('/systems', methods=['PUT']) -# @login_required -# def update_system(): -# data = request.get_json() -# result, status_code = system_manager.update_system_name(data) -# return jsonify(result), status_code -# -# @bp_api.route('/systems', methods=['DELETE']) -# @login_required -# def delete_system(): -# system_id = request.args.get('system_id') -# result, status_code = system_manager.delete_system(system_id) -# return jsonify(result), status_code - -@bp_api.route('/debug/log-level', methods=['POST']) -@login_required -def set_log_level(): - from telezab import log_manager - try: - data = request.get_json() - component = data.get('component').lower() - level = data.get('level').upper() - success, message = log_manager.change_log_level(component, level) - if success: - return jsonify({'status': 'success', 'message': message}), 200 - else: - return jsonify({'status': 'error', 'message': message}), 400 - - except Exception as e: - return jsonify({'status': 'error', 'message': str(e)}), 500 - - -@bp_api.route('/notifications', methods=['POST']) -def notification(): - from utilities.notification_manager import NotificationManager - from utilities.telegram_utilities import extract_region_number, format_message - from backend_flask import app - try: - data = request.get_json() - app.logger.info(f"Получены данные уведомления: {data}") - region_id = extract_region_number(data.get("host")) - if region_id is None: - app.logger.error(f"Не удалось извлечь номер региона из host: {data.get('host')}") - return jsonify({"status": "error", "message": "Invalid host format"}), 400 - app.logger.debug(f"Извлечён номер региона: {region_id}") - - manager = NotificationManager(app.logger) - subscribers = manager.get_subscribers(region_id, data['severity']) - if manager.is_region_active(region_id): - message = format_message(data) - manager.send_notifications(subscribers, message) - - return jsonify({"status": "success"}), 200 - - except Exception as e: - app.logger.error(f"Ошибка при обработке уведомления: {e}") - return jsonify({"status": "error", "message": "Внутренняя ошибка сервера"}), 500 \ No newline at end of file diff --git a/backend/auth.py b/backend/auth.py deleted file mode 100644 index 3c144b6..0000000 --- a/backend/auth.py +++ /dev/null @@ -1,129 +0,0 @@ -import logging -from flask import Blueprint, render_template, request, redirect, url_for, flash, session, current_app -from flask_ldap3_login import LDAP3LoginManager, AuthenticationResponseStatus -from flask_login import LoginManager, login_user, UserMixin, logout_user, current_user -from datetime import timedelta - -import config -from werkzeug.middleware.proxy_fix import ProxyFix - -bp_auth = Blueprint('auth', __name__, url_prefix='/telezab/') - -login_manager = LoginManager() -logging.getLogger('flask-login').setLevel(logging.DEBUG) -logging.getLogger('flask_ldap3_login').setLevel(logging.DEBUG) -logging.getLogger('ldap3').setLevel(logging.DEBUG) - -class User(UserMixin): - def __init__(self, user_id, user_name=None, user_surname=None, user_middle_name=None,display_name=None, email=None): - self.id = str(user_id) - self.user_name = user_name - self.user_surname = user_surname - self.user_middle_name = user_middle_name - self.display_name = display_name - self.email = email - -@login_manager.user_loader -def load_user(user_id): - logging.debug(f"load_user called for user_id: {user_id}") - display_name = session.get('display_name') # Получаем display_name из сессии - return User(user_id, display_name=display_name) - -@bp_auth.record_once -def on_load(state): - login_manager.init_app(state.app) - login_manager.login_view = 'auth.login' - init_ldap(state.app) - - -def init_ldap(app): - app.config['LDAP_HOST'] = config.LDAP_HOST - app.config['LDAP_PORT'] = config.LDAP_PORT - app.config['LDAP_USE_SSL'] = config.LDAP_USE_SSL - app.config['LDAP_BASE_DN'] = config.LDAP_BASE_DN - app.config['LDAP_BIND_DIRECT_CREDENTIALS'] = False - app.config['LDAP_BIND_USER_DN'] = config.LDAP_BIND_USER_DN - app.config['LDAP_BIND_USER_PASSWORD'] = config.LDAP_USER_PASSWORD - app.config['LDAP_USER_DN'] = config.LDAP_USER_DN - app.config['LDAP_USER_PASSWORD'] = config.LDAP_USER_PASSWORD - app.config['LDAP_USER_OBJECT_FILTER'] = config.LDAP_USER_OBJECT_FILTER - app.config['LDAP_USER_LOGIN_ATTR'] = config.LDAP_USER_LOGIN_ATTR - app.config['LDAP_USER_SEARCH_SCOPE'] = config.LDAP_USER_SEARCH_SCOPE - app.config['LDAP_SCHEMA'] = config.LDAP_SCHEMA - - ldap_manager = LDAP3LoginManager(app) - app.extensions['ldap3_login'] = ldap_manager - ldap_manager.init_app(app) - app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1) - -def get_attr(user_info, attr_name): - try: - value = user_info.get(attr_name) - if isinstance(value, list) and value: - return str(value[0]) - elif value: - return str(value) - else: - return None - except Exception as e: - logging.error(f"Error getting attribute {attr_name}: {e}") - return None - -@bp_auth.route('/login', methods=['GET', 'POST']) -def login(): - if 'user_id' in session: - return redirect(url_for('dashboard.dashboard')) - - if request.method == 'POST': - username = request.form['username'] - password = request.form['password'] - ldap_manager = current_app.extensions['ldap3_login'] - - try: - ldap_response = ldap_manager.authenticate(username, password) - logging.debug(f"ldap_response.status: {ldap_response.status}") - - if ldap_response.status == AuthenticationResponseStatus.success: - user_info = ldap_response.user_info - logging.debug(f"user_info: {user_info}") - - if not user_info: - logging.error("LDAP authentication succeeded but no user info was returned.") - flash("Failed to retrieve user details from LDAP.", "danger") - return render_template("login.html") - - sam_account_name = get_attr(user_info, "sAMAccountName") - # display_name = get_attr(user_info, "displayName") - email = get_attr(user_info, "mail") - user_name = get_attr(user_info, "givenName") - user_middle_name = get_attr(user_info, "middleName") - user_surname = get_attr(user_info, "sn") - display_name = f"{user_surname} {user_name} {user_middle_name}" - user = User(user_id=sam_account_name, - user_name=user_name, - user_surname=user_surname, - user_middle_name=user_middle_name, - display_name=display_name, - email=email - ) - - session.permanent = True - session['username'] = sam_account_name - session['display_name'] = display_name # Сохраняем display_name в сессии - login_user(user) - logging.debug(f"current_user: {current_user.__dict__}") - logging.info(f"User {user.id} logged in successfully.") - # log_user_action(action='Успешная авторизация', details=f'Username: {username}') # Логируем успешную авторизацию - flash("Logged in successfully!", "success") - return redirect(url_for("dashboard.dashboard")) - - elif ldap_response.status == AuthenticationResponseStatus.fail: - flash('Invalid username or password.', 'danger') - else: - flash(f"LDAP Error: {ldap_response.status}", 'danger') - - except Exception as e: - logging.error(f"Unexpected error during login: {e}") - flash("An unexpected error occurred. Please try again.", 'danger') - - return render_template('login.html') \ No newline at end of file diff --git a/backend_bot.py b/backend_bot.py index 80c795c..ad35c1c 100644 --- a/backend_bot.py +++ b/backend_bot.py @@ -1,10 +1,12 @@ -import sqlite3 import telebot + import telezab -from backend_locks import db_lock, bot -from bot_database import get_admins, is_whitelisted, format_regions_list, get_sorted_regions, log_user_event, \ +from app import app +from backend_locks import bot +from bot_database import is_whitelisted, format_regions_list, get_sorted_regions, log_user_event, \ get_user_subscribed_regions -from config import DB_PATH +from app.models import Regions, Subscriptions +from app.extensions.db import db from utilities.telegram_utilities import show_main_menu, show_settings_menu from handlers import handle_my_subscriptions_button, handle_active_regions_button, handle_notification_mode_button @@ -28,7 +30,6 @@ def handle_main_menu(message, chat_id, text): def handle_settings_menu(message, chat_id, text): """Обработка команд в меню настроек.""" - admins_list = get_admins() if text.lower() == 'подписаться': telezab.state.set_state(chat_id, "SUBSCRIBE") handle_subscribe_button(message) @@ -83,29 +84,40 @@ def process_subscription_button(message, chat_id, username): reply_markup=markup) bot.register_next_step_handler_by_chat_id(chat_id, process_subscription_button, chat_id, username) return - region_ids = message.text.split(',') - valid_region_ids = [region[0] for region in get_sorted_regions()] - with db_lock: - conn = sqlite3.connect(DB_PATH) - cursor = conn.cursor() + region_ids = [int(part.strip()) for part in message.text.split(',')] + + with app.app_context(): + # Получаем список валидных ID регионов из базы + valid_region_ids = [r.region_id for r in Regions.query.filter(Regions.active == True).all()] + for region_id in region_ids: - region_id = region_id.strip() if region_id not in valid_region_ids: - invalid_regions.append(region_id) + invalid_regions.append(str(region_id)) continue - cursor.execute( - 'INSERT OR IGNORE INTO subscriptions (chat_id, region_id, username, active) VALUES (?, ?, ?, TRUE)', - (chat_id, region_id, username)) - if cursor.rowcount == 0: - cursor.execute('UPDATE subscriptions SET active = TRUE WHERE chat_id = ? AND region_id = ?', - (chat_id, region_id)) - subbed_regions.append(region_id) - conn.commit() - if len(invalid_regions) > 0: - bot.send_message(chat_id, - f"Регион с ID {', '.join(invalid_regions)} не существует. Введите корректные номера или 'отмена'.") - bot.send_message(chat_id, f"Подписка на регионы: {', '.join(subbed_regions)} оформлена.") - log_user_event(chat_id, username, f"Subscribed to regions: {', '.join(subbed_regions)}") + + subscription = Subscriptions.query.filter_by(chat_id=chat_id, region_id=region_id).first() + if subscription: + if not subscription.active: + subscription.active = True + db.session.add(subscription) + subbed_regions.append(str(region_id)) + else: + # Уже подписан, можно тоже добавить для отчета + subbed_regions.append(str(region_id)) + else: + new_sub = Subscriptions(chat_id=chat_id, region_id=region_id, active=True) + db.session.add(new_sub) + subbed_regions.append(str(region_id)) + + db.session.commit() + + if invalid_regions: + bot.send_message(chat_id, f"Регион с ID {', '.join(invalid_regions)} не существует. Введите корректные номера или 'отмена'.") + + if subbed_regions: + bot.send_message(chat_id, f"Подписка на регионы: {', '.join(subbed_regions)} оформлена.") + log_user_event(chat_id, username, f"Subscribed to regions: {', '.join(subbed_regions)}") + telezab.state.set_state(chat_id, "SETTINGS_MENU") show_settings_menu(chat_id) @@ -141,34 +153,45 @@ def handle_unsubscribe_button(message): def process_unsubscription_button(message, chat_id, username): unsubbed_regions = [] invalid_regions = [] + markup = telebot.types.InlineKeyboardMarkup() - markup.add(telebot.types.InlineKeyboardButton(text="Отмена", callback_data=f"cancel_action")) + markup.add(telebot.types.InlineKeyboardButton(text="Отмена", callback_data="cancel_action")) + if message.text.lower() == 'отмена': bot.send_message(chat_id, "Действие отменено.") telezab.state.set_state(chat_id, "SETTINGS_MENU") return show_settings_menu(chat_id) - # Проверка, что введённая строка содержит только цифры и запятые + + # Проверка корректности формата ввода if not all(part.strip().isdigit() for part in message.text.split(',')): bot.send_message(chat_id, "Некорректный формат. Введите номера регионов через запятую.", reply_markup=markup) bot.register_next_step_handler_by_chat_id(chat_id, process_unsubscription_button, chat_id, username) return - region_ids = message.text.split(',') - valid_region_ids = [region[0] for region in get_user_subscribed_regions(chat_id)] - with db_lock: - conn = sqlite3.connect(DB_PATH) - cursor = conn.cursor() + + region_ids = [region_id.strip() for region_id in message.text.split(',')] + + with app.app_context(): + valid_region_ids = [str(region[0]) for region in get_user_subscribed_regions(chat_id)] # get_user_subscribed_regions уже внутри app_context + for region_id in region_ids: - region_id = region_id.strip() if region_id not in valid_region_ids: invalid_regions.append(region_id) continue - # Удаление подписки - query = 'UPDATE subscriptions SET active = FALSE WHERE chat_id = ? AND region_id = ?' - cursor.execute(query, (chat_id, region_id)) - unsubbed_regions.append(region_id) - conn.commit() - if len(invalid_regions) > 0: - bot.send_message(chat_id, f"Регион с ID {', '.join(invalid_regions)} не найден в ваших подписках.") + + subscription = db.session.query(Subscriptions).filter_by( + chat_id=chat_id, + region_id=int(region_id) + ).first() + + if subscription: + subscription.active = False + unsubbed_regions.append(region_id) + + db.session.commit() + + if invalid_regions: + bot.send_message(chat_id, f"Регион(ы) с ID {', '.join(invalid_regions)} не найдены в ваших подписках.") + bot.send_message(chat_id, f"Отписка от регионов: {', '.join(unsubbed_regions)} выполнена.") log_user_event(chat_id, username, f"Unsubscribed from regions: {', '.join(unsubbed_regions)}") telezab.state.set_state(chat_id, "SETTINGS_MENU") diff --git a/backend_flask.py b/backend_flask.py deleted file mode 100644 index 6324e21..0000000 --- a/backend_flask.py +++ /dev/null @@ -1,152 +0,0 @@ -import logging -import sqlite3 - -from flask import Flask, request, jsonify, redirect, url_for -from flask_login import LoginManager - -import config -from frontend.dashboard import bp_dashboard -from backend.api import bp_api -from backend.auth import bp_auth, User -from backend_locks import db_lock -from config import DB_PATH, TZ -from utilities.database import db -from utilities.telegram_utilities import extract_region_number, format_message - -login_manager = LoginManager() - -def create_app(): - app = Flask(__name__, static_url_path='/telezab/static', template_folder='templates') - app.config['SECRET_KEY'] = config.SECRET_KEY # Замените на надежный секретный ключ - app.config['SESSION_COOKIE_SECURE'] = config.SESSION_COOKIE_SECURE # Убедитесь, что установлено значение True - app.config['SESSION_COOKIE_HTTPONLY'] = config.SESSION_COOKIE_HTTPONLY # Убедитесь, что установлено значение True - app.config['SESSION_COOKIE_SAMESITE'] = config.SESSION_COOKIE_SAMESITE - app.config['SESSION_REFRESH_EACH_REQUEST'] = False - app.config['PERMANENT_SESSION_LIFETIME'] = config.PERMANENT_SESSION_LIFETIME - app.config['SESSION_COOKIE_MAX_AGE'] = 3600 - app.config['TIMEZONE'] = TZ - - @login_manager.unauthorized_handler - def unauthorized(): - logging.debug("Unauthorized access detected") - if request.path.startswith('/telezab/rest/api'): - return jsonify({'error': 'Не авторизован'}), 401 - else: - return redirect(url_for('auth.login')) - - app.register_blueprint(bp_dashboard) - app.register_blueprint(bp_auth) - app.register_blueprint(bp_api) - app.config['SQLALCHEMY_DATABASE_URI'] = config.SQLALCHEMY_DATABASE_URI - app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False - - db.init_app(app) - - with app.app_context(): - db.create_all() - - login_manager.init_app(app) # Инициализация login_manager - - @login_manager.user_loader - def load_user(user_id): - return User(user_id) - - return app - -app = create_app() - - - -@app.route('/telezab/webhook', methods=['POST']) -def webhook(): - try: - # Получаем данные и логируем - data = request.get_json() - app.logger.info(f"Получены данные: {data}") - - # Работа с базой данных в блоке синхронизации - with db_lock: - conn = sqlite3.connect(DB_PATH) - cursor = conn.cursor() - - # Проверяем количество записей в таблице событий - cursor.execute('SELECT COUNT(*) FROM events') - count = cursor.fetchone()[0] - app.logger.debug(f"Текущее количество записей в таблице events: {count}") - - # Если записей >= 200, удаляем самое старое событие - if count >= 200: - query = 'DELETE FROM events WHERE id = (SELECT MIN(id) FROM events)' - app.logger.debug(f"Удаление старого события: {query}") - cursor.execute(query) - - # Извлечение номера региона из поля host - region_id = extract_region_number(data.get("host")) - if region_id is None: - app.logger.error(f"Не удалось извлечь номер региона из host: {data.get('host')}") - return jsonify({"status": "error", "message": "Invalid host format"}), 400 - app.logger.debug(f"Извлечён номер региона: {region_id}") - - # Запрос подписчиков для отправки уведомления в зависимости от уровня критичности - if data['severity'] == 'Disaster': # Авария - query = 'SELECT chat_id, username FROM subscriptions WHERE region_id = ? AND active = TRUE' - else: # Высокая критичность - query = 'SELECT chat_id, username FROM subscriptions WHERE region_id = ? AND active = TRUE AND disaster_only = FALSE' - - app.logger.debug(f"Выполнение запроса: {query} для region_id={region_id}") - cursor.execute(query, (region_id,)) - results = cursor.fetchall() - - app.logger.debug(f"Найдено подписчиков: {len(results)} для региона {region_id}") - - # Проверка статуса региона (активен или нет) - query = 'SELECT active FROM regions WHERE region_id = ?' - cursor.execute(query, (region_id,)) - region_row = cursor.fetchone() - - if region_row and region_row[0]: # Если регион активен - app.logger.debug(f"Регион {region_id} активен. Начинаем рассылку сообщений.") - message = format_message(data) - undelivered = False - - # Отправляем сообщения подписчикам - for chat_id, username in results: - formatted_message = message.replace('\n', ' ').replace('\r', '') - - app.logger.info( - f"Формирование сообщения для пользователя {username} (chat_id={chat_id}) [{formatted_message}]") - try: - from utilities.rabbitmq import send_to_queue - send_to_queue({'chat_id': chat_id, 'username': username, 'message': message}) - app.logger.debug(f"Сообщение поставлено в очередь для {chat_id} (@{username})") - except Exception as e: - app.logger.error(f"Ошибка при отправке сообщения для {chat_id} (@{username}): {e}") - undelivered = True - - # Сохранение события, если были проблемы с доставкой - if undelivered: - query = 'INSERT OR IGNORE INTO events (hash, data, delivered) VALUES (?, ?, ?)' - app.logger.debug( - f"Сохранение события в базе данных: {query} (delivered={False})") - cursor.execute(query, (str(data), False)) - - # Коммитим изменения в базе данных - conn.commit() - app.logger.debug("Изменения в базе данных успешно сохранены.") - conn.close() - - # Возвращаем успешный ответ - return jsonify({"status": "success"}), 200 - - except sqlite3.OperationalError as e: - app.logger.error(f"Ошибка операции с базой данных: {e}") - return jsonify({"status": "error", "message": "Ошибка работы с базой данных"}), 500 - - except ValueError as e: - app.logger.error(f"Ошибка значения: {e}") - return jsonify({"status": "error", "message": "Некорректные данные"}), 400 - - except Exception as e: - app.logger.error(f"Неожиданная ошибка: {e}") - return jsonify({"status": "error", "message": "Внутренняя ошибка сервера"}), 500 - diff --git a/backend_locks.py b/backend_locks.py index 0da9c46..4c72901 100644 --- a/backend_locks.py +++ b/backend_locks.py @@ -1,9 +1,4 @@ -import threading - import telebot - -db_lock = threading.Lock() -# bot_instance.py from config import TOKEN bot = telebot.TeleBot(TOKEN) diff --git a/backend_zabbix.py b/backend_zabbix.py index da62f02..d76fd92 100644 --- a/backend_zabbix.py +++ b/backend_zabbix.py @@ -1,4 +1,5 @@ import logging +import os import re import time from datetime import datetime @@ -8,6 +9,7 @@ from pyzabbix import ZabbixAPI, ZabbixAPIException import backend_bot from config import ZABBIX_URL, ZABBIX_API_TOKEN from utilities.telegram_utilities import show_main_menu, escape_telegram_chars +verify_ssl = os.getenv("ZAPPI_IGNORE_SSL_VERIFY", "True").lower() not in ("false", "0", "no") zabbix_logger = logging.getLogger("pyzabbix") @@ -17,25 +19,22 @@ def get_triggers_for_group(chat_id, group_id): triggers = get_zabbix_triggers(group_id) if not triggers: backend_bot.bot.send_message(chat_id, "Нет активных событий.") - zabbix_logger.debug(f"No active triggers found for group {group_id}.") - show_main_menu(chat_id) else: send_triggers_to_user(triggers, chat_id) zabbix_logger.debug(f"Sent {len(triggers)} triggers to user {chat_id} for group {group_id}.") except ZabbixAPIException as e: zabbix_logger.error(f"Zabbix API error for group {group_id}: {e}") backend_bot.bot.send_message(chat_id, "Ошибка Zabbix API.") - show_main_menu(chat_id) except Exception as e: zabbix_logger.error(f"Error getting triggers for group {group_id}: {e}") backend_bot.bot.send_message(chat_id, "Ошибка при получении событий.") - show_main_menu(chat_id) def get_triggers_for_all_groups(chat_id, region_id): try: zapi = ZabbixAPI(ZABBIX_URL) zapi.login(api_token=ZABBIX_API_TOKEN) + zapi.session.verify = verify_ssl host_groups = zapi.hostgroup.get(output=["groupid", "name"], search={"name": region_id}) filtered_groups = [group for group in host_groups if 'test' not in group['name'].lower()] @@ -87,7 +86,7 @@ def get_zabbix_triggers(group_id): try: zapi = ZabbixAPI(ZABBIX_URL) zapi.login(api_token=ZABBIX_API_TOKEN) - + zapi.session.verify = verify_ssl problems = zapi.problem.get( severities=[4, 5], suppressed=0, diff --git a/bot_database.py b/bot_database.py index f0058c6..bf7b59c 100644 --- a/bot_database.py +++ b/bot_database.py @@ -1,13 +1,12 @@ -import sqlite3 -from datetime import datetime +from datetime import datetime, timezone from threading import Lock import telebot -from backend_flask import app -from config import DB_PATH -from models import UserEvents, Users -from utilities.database import db +from app import app +from app.models import UserEvents, Regions, Subscriptions +from app.models import Users +from app.extensions.db import db # Lock for database operations db_lock = Lock() @@ -28,105 +27,33 @@ def is_whitelisted(chat_id): telebot.logger.error(f"Ошибка при проверке пользователя: {e}") return False, "Произошла ошибка при проверке доступа." - -def rundeck_add_to_whitelist(chat_id, username, user_email): - with db_lock: - conn = sqlite3.connect(DB_PATH) - cursor = conn.cursor() - - # Проверка существования chat_id - check_query = 'SELECT COUNT(*) FROM whitelist WHERE chat_id = ?' - cursor.execute(check_query, (chat_id,)) - count = cursor.fetchone()[0] - - if count > 0: - conn.close() - return False # Пользователь уже существует - - # Вставка нового пользователя - insert_query = 'INSERT INTO whitelist (chat_id, username, user_email) VALUES (?, ?, ?)' - telebot.logger.info( - f"Rundeck executing query: {insert_query} with chat_id={chat_id}, username={username}, email={user_email}") - cursor.execute(insert_query, (chat_id, username, user_email)) - conn.commit() - conn.close() - return True # Успешное добавление - - -def remove_from_whitelist(chat_id): - with db_lock: - conn = sqlite3.connect(DB_PATH) - cursor = conn.cursor() - query = 'DELETE FROM whitelist WHERE chat_id = ?' - telebot.logger.info(f"Executing query: {query} with chat_id={chat_id}") - cursor.execute(query, (chat_id,)) - conn.commit() - conn.close() - - -def get_admins(): - with db_lock: - conn = sqlite3.connect(DB_PATH) - cursor = conn.cursor() - cursor.execute('SELECT chat_id FROM admins') - admins = cursor.fetchall() - admins = [i[0] for i in admins] - conn.close() - return admins - - def get_sorted_regions(): - with db_lock: - conn = sqlite3.connect(DB_PATH) - cursor = conn.cursor() - cursor.execute('SELECT region_id, region_name FROM regions WHERE active = TRUE') - regions = cursor.fetchall() - conn.close() - # Сортируем регионы по числовому значению region_id - regions.sort(key=lambda x: int(x[0])) - return regions - - -def region_exists(region_id): - with db_lock: - conn = sqlite3.connect(DB_PATH) - cursor = conn.cursor() - cursor.execute('SELECT COUNT(*) FROM regions WHERE region_id = ? AND active = TRUE', (region_id,)) - count = cursor.fetchone()[0] - conn.close() - return count > 0 + with app.app_context(): + regions = ( + db.session.query(Regions.region_id, Regions.region_name) + .filter(Regions.active == True) + .order_by(Regions.region_id.asc()) + .all() + ) + return regions def get_user_subscribed_regions(chat_id): - with db_lock: - conn = sqlite3.connect(DB_PATH) - cursor = conn.cursor() - cursor.execute(''' - SELECT regions.region_id, regions.region_name - FROM subscriptions - JOIN regions ON subscriptions.region_id = regions.region_id - WHERE subscriptions.chat_id = ? AND subscriptions.active = TRUE AND subscriptions.skip = FALSE - ORDER BY regions.region_id - ''', (chat_id,)) - regions = cursor.fetchall() - conn.close() - # Сортируем регионы по числовому значению region_id - regions.sort(key=lambda x: int(x[0])) - return regions + with app.app_context(): # если вызывается вне контекста Flask + results = ( + db.session.query(Regions.region_id, Regions.region_name) + .join(Subscriptions, Subscriptions.region_id == Regions.region_id) + .filter( + Subscriptions.chat_id == chat_id, + Subscriptions.active == True, + Subscriptions.skip == False + ) + .order_by(Regions.region_id.asc()) + .all() + ) - -def is_subscribed(chat_id, region_id): - with db_lock: - conn = sqlite3.connect(DB_PATH) - cursor = conn.cursor() - cursor.execute(''' - SELECT COUNT(*) - FROM subscriptions - WHERE chat_id = ? AND region_id = ? AND active = TRUE AND skip = FALSE - ''', (chat_id, region_id)) - count = cursor.fetchone()[0] - conn.close() - return count > 0 + # results — это список кортежей (region_id, region_name) + return results def format_regions_list(regions): @@ -137,7 +64,7 @@ def log_user_event(chat_id, username, action): """Логирует действие пользователя с использованием ORM.""" try: with app.app_context(): # Создаем контекст приложения - timestamp = datetime.now(datetime.UTC) # Оставляем объект datetime для БД + timestamp = datetime.now(timezone.utc) # Оставляем объект datetime для БД formatted_time = timestamp.strftime('%Y-%m-%d %H:%M:%S') # Форматируем для логов event = UserEvents( diff --git a/frontend/dashboard.py b/frontend/dashboard.py deleted file mode 100644 index 7273fb5..0000000 --- a/frontend/dashboard.py +++ /dev/null @@ -1,57 +0,0 @@ -import logging - -from flask import Blueprint, render_template, redirect, url_for, session -from sqlalchemy import create_engine -from config import DB_PATH -from utilities.database import db -from utilities.events_manager import EventManager -from utilities.region_manager import RegionManager -from utilities.system_manager import SystemManager -from utilities.users_manager import UserManager -from models import Users -from flask_login import logout_user, login_required - -# Создаём Blueprint -bp_dashboard = Blueprint('dashboard', __name__, url_prefix='/telezab/') - -db_engine = create_engine(f'sqlite:///{DB_PATH}') - - -region_manager = RegionManager() -user_manager = UserManager(db.session) -event_manager = EventManager(db) -system_manager = SystemManager() - - -# Роуты для отображения страниц -@bp_dashboard.route('/') -@login_required -def dashboard(): - return render_template('index.html') - -@bp_dashboard.route('/users') -@login_required -def users_page(): - users = Users.query.all() - return render_template('users.html', user=users) - -@bp_dashboard.route('/logs') -@login_required -def logs_page(): - return render_template('logs.html') - -@bp_dashboard.route('/regions') -@login_required -def regions_page(): - return render_template('regions.html') - -@bp_dashboard.route('/health') -def healthcheck(): - pass - -@bp_dashboard.route('/logout') -@login_required -def logout(): - logout_user() - session.clear() - return redirect(url_for('auth.login')) \ No newline at end of file diff --git a/frontend/models.py b/frontend/models.py deleted file mode 100644 index 85841e7..0000000 --- a/frontend/models.py +++ /dev/null @@ -1,19 +0,0 @@ -from utilities.database import db # Импортируем db из backend_flask.py - -class User(db.Model): - id = db.Column(db.Integer, primary_key=True) - username = db.Column(db.String(80), unique=True, nullable=False) - is_blocked = db.Column(db.Boolean, default=False) - actions = db.Column(db.String(500)) - subscriptions = db.Column(db.String(500)) - -class Region(db.Model): - id = db.Column(db.Integer, primary_key=True) - name = db.Column(db.String(80), nullable=False) - active = db.Column(db.Boolean, default=True) - -class Log(db.Model): - id = db.Column(db.Integer, primary_key=True) - username = db.Column(db.String(80), nullable=False) - action = db.Column(db.String(500), nullable=False) - timestamp = db.Column(db.DateTime, default=db.func.current_timestamp()) \ No newline at end of file diff --git a/frontend/routes/auth.py b/frontend/routes/auth.py deleted file mode 100644 index ec6e235..0000000 --- a/frontend/routes/auth.py +++ /dev/null @@ -1,14 +0,0 @@ -from flask import Blueprint, render_template, request, redirect, url_for - -auth_bp = Blueprint('auth', __name__) - -@auth_bp.route('/login', methods=['GET', 'POST']) -def login(): - if request.method == 'POST': - # Обработка логики авторизации - pass - return render_template('login.html') - -@auth_bp.route('/') -def index(): - return redirect(url_for('auth.login')) \ No newline at end of file diff --git a/frontend/routes/logs.py b/frontend/routes/logs.py deleted file mode 100644 index 4d1e250..0000000 --- a/frontend/routes/logs.py +++ /dev/null @@ -1,9 +0,0 @@ -from flask import Blueprint, render_template -from frontend.models import Log - -logs_bp = Blueprint('logs', __name__) - -@logs_bp.route('/logs') -def logs(): - logs = Log.query.all() - return render_template('logs.html', logs=logs) \ No newline at end of file diff --git a/frontend/routes/regions.py b/frontend/routes/regions.py deleted file mode 100644 index b2ac6b3..0000000 --- a/frontend/routes/regions.py +++ /dev/null @@ -1,9 +0,0 @@ -from flask import Blueprint, render_template -from frontend.models import Region - -regions_bp = Blueprint('regions', __name__) - -@regions_bp.route('/regions') -def regions(): - regions = Region.query.all() - return render_template('regions.html', regions=regions) \ No newline at end of file diff --git a/frontend/routes/users.py b/frontend/routes/users.py deleted file mode 100644 index 5eb3518..0000000 --- a/frontend/routes/users.py +++ /dev/null @@ -1,9 +0,0 @@ -from flask import Blueprint, render_template -from frontend.models import User - -users_bp = Blueprint('users', __name__) - -@users_bp.route('/users') -def users(): - user = User.query.all() - return render_template('users.html', users=user) \ No newline at end of file diff --git a/models.py b/models.py deleted file mode 100644 index 885323e..0000000 --- a/models.py +++ /dev/null @@ -1,63 +0,0 @@ -from datetime import datetime - -from sqlalchemy import PrimaryKeyConstraint, ForeignKey, Integer, String, DateTime -from sqlalchemy.orm import relationship, Mapped, mapped_column - -from utilities.database import db # Импортируем db из backend_flask.py - -class Users(db.Model): - chat_id = db.Column(db.Integer, primary_key=True) - telegram_id = db.Column(db.String(80), unique=True, nullable=False) - user_email = db.Column(db.String(255), unique=True, nullable=False) - is_blocked = db.Column(db.Boolean, default=False) - subscriptions = relationship("Subscriptions", backref="user", cascade="all, delete-orphan") # Добавлено cascade - -class Regions(db.Model): - region_id = db.Column(db.Integer, primary_key=True) - region_name = db.Column(db.String(255), nullable=False) - active = db.Column(db.Boolean, default=True) - -class Subscriptions(db.Model): - region_id = db.Column(db.Integer, nullable=False) - active = db.Column(db.Boolean, default=True) - skip = db.Column(db.Boolean, default=False) - disaster_only = db.Column(db.Boolean, default=False) - chat_id = db.Column(db.Integer, ForeignKey('users.chat_id', ondelete='CASCADE'), nullable=False) #Добавляем внешний ключ с ondelete - __table_args__ = ( - PrimaryKeyConstraint('chat_id', 'region_id'), - ) - -class UILogs(db.Model): - id = db.Column(db.Integer, primary_key=True) - chat_id = db.Column(db.Integer, nullable=False) - actions = db.Column(db.String(500), nullable=False) - timestamp = db.Column(db.DateTime, default=db.func.current_timestamp()) - -class UserEvents(db.Model): - id = db.Column(db.Integer, primary_key=True) - chat_id = db.Column(db.Integer, nullable=False) - telegram_id = db.Column(db.String(80), nullable=False) - action = db.Column(db.String(500), nullable=False) - timestamp = db.Column(db.DateTime, default=db.func.current_timestamp()) - -class Systems(db.Model): - __tablename__ = 'systems' - system_id = db.Column(db.String(255), primary_key=True) - system_name = db.Column(db.String(255), nullable=False) - name = db.Column(db.String(255), nullable=False) - - def __repr__(self): - return f'' - -class WebActionLog(db.Model): - __tablename__ = 'web_action_logs' - - id: Mapped[int] = mapped_column(Integer, primary_key=True) - ldap_user_id: Mapped[str] = mapped_column(String(255), nullable=False) - username: Mapped[str | None] = mapped_column(String(255)) - timestamp: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) - action: Mapped[str] = mapped_column(String(255), nullable=False) - details: Mapped[str | None] = mapped_column(String(1024)) - - def __repr__(self): - return f"" \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index c2eb338..6da10f7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,4 +7,5 @@ Flask-Login~=0.6.3 Werkzeug~=3.1.3 aio-pika~=9.5.5 pika~=1.3.2 -pytz~=2025.2 \ No newline at end of file +pytz~=2025.2 +concurrent-log-handler~=0.9.26 \ No newline at end of file diff --git a/static/css/bootstrap-icons-1.11.3/font/bootstrap-icons.min.css b/static/css/bootstrap-icons-1.11.3/font/bootstrap-icons.min.css deleted file mode 100644 index dadd6dc..0000000 --- a/static/css/bootstrap-icons-1.11.3/font/bootstrap-icons.min.css +++ /dev/null @@ -1,5 +0,0 @@ -/*! - * Bootstrap Icons v1.11.3 (https://icons.getbootstrap.com/) - * Copyright 2019-2024 The Bootstrap Authors - * Licensed under MIT (https://github.com/twbs/icons/blob/main/LICENSE) - */@font-face{font-display:block;font-family:bootstrap-icons;src:url("fonts/bootstrap-icons.woff2?dd67030699838ea613ee6dbda90effa6") format("woff2"),url("fonts/bootstrap-icons.woff?dd67030699838ea613ee6dbda90effa6") format("woff")}.bi::before,[class*=" bi-"]::before,[class^=bi-]::before{display:inline-block;font-family:bootstrap-icons!important;font-style:normal;font-weight:400!important;font-variant:normal;text-transform:none;line-height:1;vertical-align:-.125em;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.bi-123::before{content:"\f67f"}.bi-alarm-fill::before{content:"\f101"}.bi-alarm::before{content:"\f102"}.bi-align-bottom::before{content:"\f103"}.bi-align-center::before{content:"\f104"}.bi-align-end::before{content:"\f105"}.bi-align-middle::before{content:"\f106"}.bi-align-start::before{content:"\f107"}.bi-align-top::before{content:"\f108"}.bi-alt::before{content:"\f109"}.bi-app-indicator::before{content:"\f10a"}.bi-app::before{content:"\f10b"}.bi-archive-fill::before{content:"\f10c"}.bi-archive::before{content:"\f10d"}.bi-arrow-90deg-down::before{content:"\f10e"}.bi-arrow-90deg-left::before{content:"\f10f"}.bi-arrow-90deg-right::before{content:"\f110"}.bi-arrow-90deg-up::before{content:"\f111"}.bi-arrow-bar-down::before{content:"\f112"}.bi-arrow-bar-left::before{content:"\f113"}.bi-arrow-bar-right::before{content:"\f114"}.bi-arrow-bar-up::before{content:"\f115"}.bi-arrow-clockwise::before{content:"\f116"}.bi-arrow-counterclockwise::before{content:"\f117"}.bi-arrow-down-circle-fill::before{content:"\f118"}.bi-arrow-down-circle::before{content:"\f119"}.bi-arrow-down-left-circle-fill::before{content:"\f11a"}.bi-arrow-down-left-circle::before{content:"\f11b"}.bi-arrow-down-left-square-fill::before{content:"\f11c"}.bi-arrow-down-left-square::before{content:"\f11d"}.bi-arrow-down-left::before{content:"\f11e"}.bi-arrow-down-right-circle-fill::before{content:"\f11f"}.bi-arrow-down-right-circle::before{content:"\f120"}.bi-arrow-down-right-square-fill::before{content:"\f121"}.bi-arrow-down-right-square::before{content:"\f122"}.bi-arrow-down-right::before{content:"\f123"}.bi-arrow-down-short::before{content:"\f124"}.bi-arrow-down-square-fill::before{content:"\f125"}.bi-arrow-down-square::before{content:"\f126"}.bi-arrow-down-up::before{content:"\f127"}.bi-arrow-down::before{content:"\f128"}.bi-arrow-left-circle-fill::before{content:"\f129"}.bi-arrow-left-circle::before{content:"\f12a"}.bi-arrow-left-right::before{content:"\f12b"}.bi-arrow-left-short::before{content:"\f12c"}.bi-arrow-left-square-fill::before{content:"\f12d"}.bi-arrow-left-square::before{content:"\f12e"}.bi-arrow-left::before{content:"\f12f"}.bi-arrow-repeat::before{content:"\f130"}.bi-arrow-return-left::before{content:"\f131"}.bi-arrow-return-right::before{content:"\f132"}.bi-arrow-right-circle-fill::before{content:"\f133"}.bi-arrow-right-circle::before{content:"\f134"}.bi-arrow-right-short::before{content:"\f135"}.bi-arrow-right-square-fill::before{content:"\f136"}.bi-arrow-right-square::before{content:"\f137"}.bi-arrow-right::before{content:"\f138"}.bi-arrow-up-circle-fill::before{content:"\f139"}.bi-arrow-up-circle::before{content:"\f13a"}.bi-arrow-up-left-circle-fill::before{content:"\f13b"}.bi-arrow-up-left-circle::before{content:"\f13c"}.bi-arrow-up-left-square-fill::before{content:"\f13d"}.bi-arrow-up-left-square::before{content:"\f13e"}.bi-arrow-up-left::before{content:"\f13f"}.bi-arrow-up-right-circle-fill::before{content:"\f140"}.bi-arrow-up-right-circle::before{content:"\f141"}.bi-arrow-up-right-square-fill::before{content:"\f142"}.bi-arrow-up-right-square::before{content:"\f143"}.bi-arrow-up-right::before{content:"\f144"}.bi-arrow-up-short::before{content:"\f145"}.bi-arrow-up-square-fill::before{content:"\f146"}.bi-arrow-up-square::before{content:"\f147"}.bi-arrow-up::before{content:"\f148"}.bi-arrows-angle-contract::before{content:"\f149"}.bi-arrows-angle-expand::before{content:"\f14a"}.bi-arrows-collapse::before{content:"\f14b"}.bi-arrows-expand::before{content:"\f14c"}.bi-arrows-fullscreen::before{content:"\f14d"}.bi-arrows-move::before{content:"\f14e"}.bi-aspect-ratio-fill::before{content:"\f14f"}.bi-aspect-ratio::before{content:"\f150"}.bi-asterisk::before{content:"\f151"}.bi-at::before{content:"\f152"}.bi-award-fill::before{content:"\f153"}.bi-award::before{content:"\f154"}.bi-back::before{content:"\f155"}.bi-backspace-fill::before{content:"\f156"}.bi-backspace-reverse-fill::before{content:"\f157"}.bi-backspace-reverse::before{content:"\f158"}.bi-backspace::before{content:"\f159"}.bi-badge-3d-fill::before{content:"\f15a"}.bi-badge-3d::before{content:"\f15b"}.bi-badge-4k-fill::before{content:"\f15c"}.bi-badge-4k::before{content:"\f15d"}.bi-badge-8k-fill::before{content:"\f15e"}.bi-badge-8k::before{content:"\f15f"}.bi-badge-ad-fill::before{content:"\f160"}.bi-badge-ad::before{content:"\f161"}.bi-badge-ar-fill::before{content:"\f162"}.bi-badge-ar::before{content:"\f163"}.bi-badge-cc-fill::before{content:"\f164"}.bi-badge-cc::before{content:"\f165"}.bi-badge-hd-fill::before{content:"\f166"}.bi-badge-hd::before{content:"\f167"}.bi-badge-tm-fill::before{content:"\f168"}.bi-badge-tm::before{content:"\f169"}.bi-badge-vo-fill::before{content:"\f16a"}.bi-badge-vo::before{content:"\f16b"}.bi-badge-vr-fill::before{content:"\f16c"}.bi-badge-vr::before{content:"\f16d"}.bi-badge-wc-fill::before{content:"\f16e"}.bi-badge-wc::before{content:"\f16f"}.bi-bag-check-fill::before{content:"\f170"}.bi-bag-check::before{content:"\f171"}.bi-bag-dash-fill::before{content:"\f172"}.bi-bag-dash::before{content:"\f173"}.bi-bag-fill::before{content:"\f174"}.bi-bag-plus-fill::before{content:"\f175"}.bi-bag-plus::before{content:"\f176"}.bi-bag-x-fill::before{content:"\f177"}.bi-bag-x::before{content:"\f178"}.bi-bag::before{content:"\f179"}.bi-bar-chart-fill::before{content:"\f17a"}.bi-bar-chart-line-fill::before{content:"\f17b"}.bi-bar-chart-line::before{content:"\f17c"}.bi-bar-chart-steps::before{content:"\f17d"}.bi-bar-chart::before{content:"\f17e"}.bi-basket-fill::before{content:"\f17f"}.bi-basket::before{content:"\f180"}.bi-basket2-fill::before{content:"\f181"}.bi-basket2::before{content:"\f182"}.bi-basket3-fill::before{content:"\f183"}.bi-basket3::before{content:"\f184"}.bi-battery-charging::before{content:"\f185"}.bi-battery-full::before{content:"\f186"}.bi-battery-half::before{content:"\f187"}.bi-battery::before{content:"\f188"}.bi-bell-fill::before{content:"\f189"}.bi-bell::before{content:"\f18a"}.bi-bezier::before{content:"\f18b"}.bi-bezier2::before{content:"\f18c"}.bi-bicycle::before{content:"\f18d"}.bi-binoculars-fill::before{content:"\f18e"}.bi-binoculars::before{content:"\f18f"}.bi-blockquote-left::before{content:"\f190"}.bi-blockquote-right::before{content:"\f191"}.bi-book-fill::before{content:"\f192"}.bi-book-half::before{content:"\f193"}.bi-book::before{content:"\f194"}.bi-bookmark-check-fill::before{content:"\f195"}.bi-bookmark-check::before{content:"\f196"}.bi-bookmark-dash-fill::before{content:"\f197"}.bi-bookmark-dash::before{content:"\f198"}.bi-bookmark-fill::before{content:"\f199"}.bi-bookmark-heart-fill::before{content:"\f19a"}.bi-bookmark-heart::before{content:"\f19b"}.bi-bookmark-plus-fill::before{content:"\f19c"}.bi-bookmark-plus::before{content:"\f19d"}.bi-bookmark-star-fill::before{content:"\f19e"}.bi-bookmark-star::before{content:"\f19f"}.bi-bookmark-x-fill::before{content:"\f1a0"}.bi-bookmark-x::before{content:"\f1a1"}.bi-bookmark::before{content:"\f1a2"}.bi-bookmarks-fill::before{content:"\f1a3"}.bi-bookmarks::before{content:"\f1a4"}.bi-bookshelf::before{content:"\f1a5"}.bi-bootstrap-fill::before{content:"\f1a6"}.bi-bootstrap-reboot::before{content:"\f1a7"}.bi-bootstrap::before{content:"\f1a8"}.bi-border-all::before{content:"\f1a9"}.bi-border-bottom::before{content:"\f1aa"}.bi-border-center::before{content:"\f1ab"}.bi-border-inner::before{content:"\f1ac"}.bi-border-left::before{content:"\f1ad"}.bi-border-middle::before{content:"\f1ae"}.bi-border-outer::before{content:"\f1af"}.bi-border-right::before{content:"\f1b0"}.bi-border-style::before{content:"\f1b1"}.bi-border-top::before{content:"\f1b2"}.bi-border-width::before{content:"\f1b3"}.bi-border::before{content:"\f1b4"}.bi-bounding-box-circles::before{content:"\f1b5"}.bi-bounding-box::before{content:"\f1b6"}.bi-box-arrow-down-left::before{content:"\f1b7"}.bi-box-arrow-down-right::before{content:"\f1b8"}.bi-box-arrow-down::before{content:"\f1b9"}.bi-box-arrow-in-down-left::before{content:"\f1ba"}.bi-box-arrow-in-down-right::before{content:"\f1bb"}.bi-box-arrow-in-down::before{content:"\f1bc"}.bi-box-arrow-in-left::before{content:"\f1bd"}.bi-box-arrow-in-right::before{content:"\f1be"}.bi-box-arrow-in-up-left::before{content:"\f1bf"}.bi-box-arrow-in-up-right::before{content:"\f1c0"}.bi-box-arrow-in-up::before{content:"\f1c1"}.bi-box-arrow-left::before{content:"\f1c2"}.bi-box-arrow-right::before{content:"\f1c3"}.bi-box-arrow-up-left::before{content:"\f1c4"}.bi-box-arrow-up-right::before{content:"\f1c5"}.bi-box-arrow-up::before{content:"\f1c6"}.bi-box-seam::before{content:"\f1c7"}.bi-box::before{content:"\f1c8"}.bi-braces::before{content:"\f1c9"}.bi-bricks::before{content:"\f1ca"}.bi-briefcase-fill::before{content:"\f1cb"}.bi-briefcase::before{content:"\f1cc"}.bi-brightness-alt-high-fill::before{content:"\f1cd"}.bi-brightness-alt-high::before{content:"\f1ce"}.bi-brightness-alt-low-fill::before{content:"\f1cf"}.bi-brightness-alt-low::before{content:"\f1d0"}.bi-brightness-high-fill::before{content:"\f1d1"}.bi-brightness-high::before{content:"\f1d2"}.bi-brightness-low-fill::before{content:"\f1d3"}.bi-brightness-low::before{content:"\f1d4"}.bi-broadcast-pin::before{content:"\f1d5"}.bi-broadcast::before{content:"\f1d6"}.bi-brush-fill::before{content:"\f1d7"}.bi-brush::before{content:"\f1d8"}.bi-bucket-fill::before{content:"\f1d9"}.bi-bucket::before{content:"\f1da"}.bi-bug-fill::before{content:"\f1db"}.bi-bug::before{content:"\f1dc"}.bi-building::before{content:"\f1dd"}.bi-bullseye::before{content:"\f1de"}.bi-calculator-fill::before{content:"\f1df"}.bi-calculator::before{content:"\f1e0"}.bi-calendar-check-fill::before{content:"\f1e1"}.bi-calendar-check::before{content:"\f1e2"}.bi-calendar-date-fill::before{content:"\f1e3"}.bi-calendar-date::before{content:"\f1e4"}.bi-calendar-day-fill::before{content:"\f1e5"}.bi-calendar-day::before{content:"\f1e6"}.bi-calendar-event-fill::before{content:"\f1e7"}.bi-calendar-event::before{content:"\f1e8"}.bi-calendar-fill::before{content:"\f1e9"}.bi-calendar-minus-fill::before{content:"\f1ea"}.bi-calendar-minus::before{content:"\f1eb"}.bi-calendar-month-fill::before{content:"\f1ec"}.bi-calendar-month::before{content:"\f1ed"}.bi-calendar-plus-fill::before{content:"\f1ee"}.bi-calendar-plus::before{content:"\f1ef"}.bi-calendar-range-fill::before{content:"\f1f0"}.bi-calendar-range::before{content:"\f1f1"}.bi-calendar-week-fill::before{content:"\f1f2"}.bi-calendar-week::before{content:"\f1f3"}.bi-calendar-x-fill::before{content:"\f1f4"}.bi-calendar-x::before{content:"\f1f5"}.bi-calendar::before{content:"\f1f6"}.bi-calendar2-check-fill::before{content:"\f1f7"}.bi-calendar2-check::before{content:"\f1f8"}.bi-calendar2-date-fill::before{content:"\f1f9"}.bi-calendar2-date::before{content:"\f1fa"}.bi-calendar2-day-fill::before{content:"\f1fb"}.bi-calendar2-day::before{content:"\f1fc"}.bi-calendar2-event-fill::before{content:"\f1fd"}.bi-calendar2-event::before{content:"\f1fe"}.bi-calendar2-fill::before{content:"\f1ff"}.bi-calendar2-minus-fill::before{content:"\f200"}.bi-calendar2-minus::before{content:"\f201"}.bi-calendar2-month-fill::before{content:"\f202"}.bi-calendar2-month::before{content:"\f203"}.bi-calendar2-plus-fill::before{content:"\f204"}.bi-calendar2-plus::before{content:"\f205"}.bi-calendar2-range-fill::before{content:"\f206"}.bi-calendar2-range::before{content:"\f207"}.bi-calendar2-week-fill::before{content:"\f208"}.bi-calendar2-week::before{content:"\f209"}.bi-calendar2-x-fill::before{content:"\f20a"}.bi-calendar2-x::before{content:"\f20b"}.bi-calendar2::before{content:"\f20c"}.bi-calendar3-event-fill::before{content:"\f20d"}.bi-calendar3-event::before{content:"\f20e"}.bi-calendar3-fill::before{content:"\f20f"}.bi-calendar3-range-fill::before{content:"\f210"}.bi-calendar3-range::before{content:"\f211"}.bi-calendar3-week-fill::before{content:"\f212"}.bi-calendar3-week::before{content:"\f213"}.bi-calendar3::before{content:"\f214"}.bi-calendar4-event::before{content:"\f215"}.bi-calendar4-range::before{content:"\f216"}.bi-calendar4-week::before{content:"\f217"}.bi-calendar4::before{content:"\f218"}.bi-camera-fill::before{content:"\f219"}.bi-camera-reels-fill::before{content:"\f21a"}.bi-camera-reels::before{content:"\f21b"}.bi-camera-video-fill::before{content:"\f21c"}.bi-camera-video-off-fill::before{content:"\f21d"}.bi-camera-video-off::before{content:"\f21e"}.bi-camera-video::before{content:"\f21f"}.bi-camera::before{content:"\f220"}.bi-camera2::before{content:"\f221"}.bi-capslock-fill::before{content:"\f222"}.bi-capslock::before{content:"\f223"}.bi-card-checklist::before{content:"\f224"}.bi-card-heading::before{content:"\f225"}.bi-card-image::before{content:"\f226"}.bi-card-list::before{content:"\f227"}.bi-card-text::before{content:"\f228"}.bi-caret-down-fill::before{content:"\f229"}.bi-caret-down-square-fill::before{content:"\f22a"}.bi-caret-down-square::before{content:"\f22b"}.bi-caret-down::before{content:"\f22c"}.bi-caret-left-fill::before{content:"\f22d"}.bi-caret-left-square-fill::before{content:"\f22e"}.bi-caret-left-square::before{content:"\f22f"}.bi-caret-left::before{content:"\f230"}.bi-caret-right-fill::before{content:"\f231"}.bi-caret-right-square-fill::before{content:"\f232"}.bi-caret-right-square::before{content:"\f233"}.bi-caret-right::before{content:"\f234"}.bi-caret-up-fill::before{content:"\f235"}.bi-caret-up-square-fill::before{content:"\f236"}.bi-caret-up-square::before{content:"\f237"}.bi-caret-up::before{content:"\f238"}.bi-cart-check-fill::before{content:"\f239"}.bi-cart-check::before{content:"\f23a"}.bi-cart-dash-fill::before{content:"\f23b"}.bi-cart-dash::before{content:"\f23c"}.bi-cart-fill::before{content:"\f23d"}.bi-cart-plus-fill::before{content:"\f23e"}.bi-cart-plus::before{content:"\f23f"}.bi-cart-x-fill::before{content:"\f240"}.bi-cart-x::before{content:"\f241"}.bi-cart::before{content:"\f242"}.bi-cart2::before{content:"\f243"}.bi-cart3::before{content:"\f244"}.bi-cart4::before{content:"\f245"}.bi-cash-stack::before{content:"\f246"}.bi-cash::before{content:"\f247"}.bi-cast::before{content:"\f248"}.bi-chat-dots-fill::before{content:"\f249"}.bi-chat-dots::before{content:"\f24a"}.bi-chat-fill::before{content:"\f24b"}.bi-chat-left-dots-fill::before{content:"\f24c"}.bi-chat-left-dots::before{content:"\f24d"}.bi-chat-left-fill::before{content:"\f24e"}.bi-chat-left-quote-fill::before{content:"\f24f"}.bi-chat-left-quote::before{content:"\f250"}.bi-chat-left-text-fill::before{content:"\f251"}.bi-chat-left-text::before{content:"\f252"}.bi-chat-left::before{content:"\f253"}.bi-chat-quote-fill::before{content:"\f254"}.bi-chat-quote::before{content:"\f255"}.bi-chat-right-dots-fill::before{content:"\f256"}.bi-chat-right-dots::before{content:"\f257"}.bi-chat-right-fill::before{content:"\f258"}.bi-chat-right-quote-fill::before{content:"\f259"}.bi-chat-right-quote::before{content:"\f25a"}.bi-chat-right-text-fill::before{content:"\f25b"}.bi-chat-right-text::before{content:"\f25c"}.bi-chat-right::before{content:"\f25d"}.bi-chat-square-dots-fill::before{content:"\f25e"}.bi-chat-square-dots::before{content:"\f25f"}.bi-chat-square-fill::before{content:"\f260"}.bi-chat-square-quote-fill::before{content:"\f261"}.bi-chat-square-quote::before{content:"\f262"}.bi-chat-square-text-fill::before{content:"\f263"}.bi-chat-square-text::before{content:"\f264"}.bi-chat-square::before{content:"\f265"}.bi-chat-text-fill::before{content:"\f266"}.bi-chat-text::before{content:"\f267"}.bi-chat::before{content:"\f268"}.bi-check-all::before{content:"\f269"}.bi-check-circle-fill::before{content:"\f26a"}.bi-check-circle::before{content:"\f26b"}.bi-check-square-fill::before{content:"\f26c"}.bi-check-square::before{content:"\f26d"}.bi-check::before{content:"\f26e"}.bi-check2-all::before{content:"\f26f"}.bi-check2-circle::before{content:"\f270"}.bi-check2-square::before{content:"\f271"}.bi-check2::before{content:"\f272"}.bi-chevron-bar-contract::before{content:"\f273"}.bi-chevron-bar-down::before{content:"\f274"}.bi-chevron-bar-expand::before{content:"\f275"}.bi-chevron-bar-left::before{content:"\f276"}.bi-chevron-bar-right::before{content:"\f277"}.bi-chevron-bar-up::before{content:"\f278"}.bi-chevron-compact-down::before{content:"\f279"}.bi-chevron-compact-left::before{content:"\f27a"}.bi-chevron-compact-right::before{content:"\f27b"}.bi-chevron-compact-up::before{content:"\f27c"}.bi-chevron-contract::before{content:"\f27d"}.bi-chevron-double-down::before{content:"\f27e"}.bi-chevron-double-left::before{content:"\f27f"}.bi-chevron-double-right::before{content:"\f280"}.bi-chevron-double-up::before{content:"\f281"}.bi-chevron-down::before{content:"\f282"}.bi-chevron-expand::before{content:"\f283"}.bi-chevron-left::before{content:"\f284"}.bi-chevron-right::before{content:"\f285"}.bi-chevron-up::before{content:"\f286"}.bi-circle-fill::before{content:"\f287"}.bi-circle-half::before{content:"\f288"}.bi-circle-square::before{content:"\f289"}.bi-circle::before{content:"\f28a"}.bi-clipboard-check::before{content:"\f28b"}.bi-clipboard-data::before{content:"\f28c"}.bi-clipboard-minus::before{content:"\f28d"}.bi-clipboard-plus::before{content:"\f28e"}.bi-clipboard-x::before{content:"\f28f"}.bi-clipboard::before{content:"\f290"}.bi-clock-fill::before{content:"\f291"}.bi-clock-history::before{content:"\f292"}.bi-clock::before{content:"\f293"}.bi-cloud-arrow-down-fill::before{content:"\f294"}.bi-cloud-arrow-down::before{content:"\f295"}.bi-cloud-arrow-up-fill::before{content:"\f296"}.bi-cloud-arrow-up::before{content:"\f297"}.bi-cloud-check-fill::before{content:"\f298"}.bi-cloud-check::before{content:"\f299"}.bi-cloud-download-fill::before{content:"\f29a"}.bi-cloud-download::before{content:"\f29b"}.bi-cloud-drizzle-fill::before{content:"\f29c"}.bi-cloud-drizzle::before{content:"\f29d"}.bi-cloud-fill::before{content:"\f29e"}.bi-cloud-fog-fill::before{content:"\f29f"}.bi-cloud-fog::before{content:"\f2a0"}.bi-cloud-fog2-fill::before{content:"\f2a1"}.bi-cloud-fog2::before{content:"\f2a2"}.bi-cloud-hail-fill::before{content:"\f2a3"}.bi-cloud-hail::before{content:"\f2a4"}.bi-cloud-haze-fill::before{content:"\f2a6"}.bi-cloud-haze::before{content:"\f2a7"}.bi-cloud-haze2-fill::before{content:"\f2a8"}.bi-cloud-lightning-fill::before{content:"\f2a9"}.bi-cloud-lightning-rain-fill::before{content:"\f2aa"}.bi-cloud-lightning-rain::before{content:"\f2ab"}.bi-cloud-lightning::before{content:"\f2ac"}.bi-cloud-minus-fill::before{content:"\f2ad"}.bi-cloud-minus::before{content:"\f2ae"}.bi-cloud-moon-fill::before{content:"\f2af"}.bi-cloud-moon::before{content:"\f2b0"}.bi-cloud-plus-fill::before{content:"\f2b1"}.bi-cloud-plus::before{content:"\f2b2"}.bi-cloud-rain-fill::before{content:"\f2b3"}.bi-cloud-rain-heavy-fill::before{content:"\f2b4"}.bi-cloud-rain-heavy::before{content:"\f2b5"}.bi-cloud-rain::before{content:"\f2b6"}.bi-cloud-slash-fill::before{content:"\f2b7"}.bi-cloud-slash::before{content:"\f2b8"}.bi-cloud-sleet-fill::before{content:"\f2b9"}.bi-cloud-sleet::before{content:"\f2ba"}.bi-cloud-snow-fill::before{content:"\f2bb"}.bi-cloud-snow::before{content:"\f2bc"}.bi-cloud-sun-fill::before{content:"\f2bd"}.bi-cloud-sun::before{content:"\f2be"}.bi-cloud-upload-fill::before{content:"\f2bf"}.bi-cloud-upload::before{content:"\f2c0"}.bi-cloud::before{content:"\f2c1"}.bi-clouds-fill::before{content:"\f2c2"}.bi-clouds::before{content:"\f2c3"}.bi-cloudy-fill::before{content:"\f2c4"}.bi-cloudy::before{content:"\f2c5"}.bi-code-slash::before{content:"\f2c6"}.bi-code-square::before{content:"\f2c7"}.bi-code::before{content:"\f2c8"}.bi-collection-fill::before{content:"\f2c9"}.bi-collection-play-fill::before{content:"\f2ca"}.bi-collection-play::before{content:"\f2cb"}.bi-collection::before{content:"\f2cc"}.bi-columns-gap::before{content:"\f2cd"}.bi-columns::before{content:"\f2ce"}.bi-command::before{content:"\f2cf"}.bi-compass-fill::before{content:"\f2d0"}.bi-compass::before{content:"\f2d1"}.bi-cone-striped::before{content:"\f2d2"}.bi-cone::before{content:"\f2d3"}.bi-controller::before{content:"\f2d4"}.bi-cpu-fill::before{content:"\f2d5"}.bi-cpu::before{content:"\f2d6"}.bi-credit-card-2-back-fill::before{content:"\f2d7"}.bi-credit-card-2-back::before{content:"\f2d8"}.bi-credit-card-2-front-fill::before{content:"\f2d9"}.bi-credit-card-2-front::before{content:"\f2da"}.bi-credit-card-fill::before{content:"\f2db"}.bi-credit-card::before{content:"\f2dc"}.bi-crop::before{content:"\f2dd"}.bi-cup-fill::before{content:"\f2de"}.bi-cup-straw::before{content:"\f2df"}.bi-cup::before{content:"\f2e0"}.bi-cursor-fill::before{content:"\f2e1"}.bi-cursor-text::before{content:"\f2e2"}.bi-cursor::before{content:"\f2e3"}.bi-dash-circle-dotted::before{content:"\f2e4"}.bi-dash-circle-fill::before{content:"\f2e5"}.bi-dash-circle::before{content:"\f2e6"}.bi-dash-square-dotted::before{content:"\f2e7"}.bi-dash-square-fill::before{content:"\f2e8"}.bi-dash-square::before{content:"\f2e9"}.bi-dash::before{content:"\f2ea"}.bi-diagram-2-fill::before{content:"\f2eb"}.bi-diagram-2::before{content:"\f2ec"}.bi-diagram-3-fill::before{content:"\f2ed"}.bi-diagram-3::before{content:"\f2ee"}.bi-diamond-fill::before{content:"\f2ef"}.bi-diamond-half::before{content:"\f2f0"}.bi-diamond::before{content:"\f2f1"}.bi-dice-1-fill::before{content:"\f2f2"}.bi-dice-1::before{content:"\f2f3"}.bi-dice-2-fill::before{content:"\f2f4"}.bi-dice-2::before{content:"\f2f5"}.bi-dice-3-fill::before{content:"\f2f6"}.bi-dice-3::before{content:"\f2f7"}.bi-dice-4-fill::before{content:"\f2f8"}.bi-dice-4::before{content:"\f2f9"}.bi-dice-5-fill::before{content:"\f2fa"}.bi-dice-5::before{content:"\f2fb"}.bi-dice-6-fill::before{content:"\f2fc"}.bi-dice-6::before{content:"\f2fd"}.bi-disc-fill::before{content:"\f2fe"}.bi-disc::before{content:"\f2ff"}.bi-discord::before{content:"\f300"}.bi-display-fill::before{content:"\f301"}.bi-display::before{content:"\f302"}.bi-distribute-horizontal::before{content:"\f303"}.bi-distribute-vertical::before{content:"\f304"}.bi-door-closed-fill::before{content:"\f305"}.bi-door-closed::before{content:"\f306"}.bi-door-open-fill::before{content:"\f307"}.bi-door-open::before{content:"\f308"}.bi-dot::before{content:"\f309"}.bi-download::before{content:"\f30a"}.bi-droplet-fill::before{content:"\f30b"}.bi-droplet-half::before{content:"\f30c"}.bi-droplet::before{content:"\f30d"}.bi-earbuds::before{content:"\f30e"}.bi-easel-fill::before{content:"\f30f"}.bi-easel::before{content:"\f310"}.bi-egg-fill::before{content:"\f311"}.bi-egg-fried::before{content:"\f312"}.bi-egg::before{content:"\f313"}.bi-eject-fill::before{content:"\f314"}.bi-eject::before{content:"\f315"}.bi-emoji-angry-fill::before{content:"\f316"}.bi-emoji-angry::before{content:"\f317"}.bi-emoji-dizzy-fill::before{content:"\f318"}.bi-emoji-dizzy::before{content:"\f319"}.bi-emoji-expressionless-fill::before{content:"\f31a"}.bi-emoji-expressionless::before{content:"\f31b"}.bi-emoji-frown-fill::before{content:"\f31c"}.bi-emoji-frown::before{content:"\f31d"}.bi-emoji-heart-eyes-fill::before{content:"\f31e"}.bi-emoji-heart-eyes::before{content:"\f31f"}.bi-emoji-laughing-fill::before{content:"\f320"}.bi-emoji-laughing::before{content:"\f321"}.bi-emoji-neutral-fill::before{content:"\f322"}.bi-emoji-neutral::before{content:"\f323"}.bi-emoji-smile-fill::before{content:"\f324"}.bi-emoji-smile-upside-down-fill::before{content:"\f325"}.bi-emoji-smile-upside-down::before{content:"\f326"}.bi-emoji-smile::before{content:"\f327"}.bi-emoji-sunglasses-fill::before{content:"\f328"}.bi-emoji-sunglasses::before{content:"\f329"}.bi-emoji-wink-fill::before{content:"\f32a"}.bi-emoji-wink::before{content:"\f32b"}.bi-envelope-fill::before{content:"\f32c"}.bi-envelope-open-fill::before{content:"\f32d"}.bi-envelope-open::before{content:"\f32e"}.bi-envelope::before{content:"\f32f"}.bi-eraser-fill::before{content:"\f330"}.bi-eraser::before{content:"\f331"}.bi-exclamation-circle-fill::before{content:"\f332"}.bi-exclamation-circle::before{content:"\f333"}.bi-exclamation-diamond-fill::before{content:"\f334"}.bi-exclamation-diamond::before{content:"\f335"}.bi-exclamation-octagon-fill::before{content:"\f336"}.bi-exclamation-octagon::before{content:"\f337"}.bi-exclamation-square-fill::before{content:"\f338"}.bi-exclamation-square::before{content:"\f339"}.bi-exclamation-triangle-fill::before{content:"\f33a"}.bi-exclamation-triangle::before{content:"\f33b"}.bi-exclamation::before{content:"\f33c"}.bi-exclude::before{content:"\f33d"}.bi-eye-fill::before{content:"\f33e"}.bi-eye-slash-fill::before{content:"\f33f"}.bi-eye-slash::before{content:"\f340"}.bi-eye::before{content:"\f341"}.bi-eyedropper::before{content:"\f342"}.bi-eyeglasses::before{content:"\f343"}.bi-facebook::before{content:"\f344"}.bi-file-arrow-down-fill::before{content:"\f345"}.bi-file-arrow-down::before{content:"\f346"}.bi-file-arrow-up-fill::before{content:"\f347"}.bi-file-arrow-up::before{content:"\f348"}.bi-file-bar-graph-fill::before{content:"\f349"}.bi-file-bar-graph::before{content:"\f34a"}.bi-file-binary-fill::before{content:"\f34b"}.bi-file-binary::before{content:"\f34c"}.bi-file-break-fill::before{content:"\f34d"}.bi-file-break::before{content:"\f34e"}.bi-file-check-fill::before{content:"\f34f"}.bi-file-check::before{content:"\f350"}.bi-file-code-fill::before{content:"\f351"}.bi-file-code::before{content:"\f352"}.bi-file-diff-fill::before{content:"\f353"}.bi-file-diff::before{content:"\f354"}.bi-file-earmark-arrow-down-fill::before{content:"\f355"}.bi-file-earmark-arrow-down::before{content:"\f356"}.bi-file-earmark-arrow-up-fill::before{content:"\f357"}.bi-file-earmark-arrow-up::before{content:"\f358"}.bi-file-earmark-bar-graph-fill::before{content:"\f359"}.bi-file-earmark-bar-graph::before{content:"\f35a"}.bi-file-earmark-binary-fill::before{content:"\f35b"}.bi-file-earmark-binary::before{content:"\f35c"}.bi-file-earmark-break-fill::before{content:"\f35d"}.bi-file-earmark-break::before{content:"\f35e"}.bi-file-earmark-check-fill::before{content:"\f35f"}.bi-file-earmark-check::before{content:"\f360"}.bi-file-earmark-code-fill::before{content:"\f361"}.bi-file-earmark-code::before{content:"\f362"}.bi-file-earmark-diff-fill::before{content:"\f363"}.bi-file-earmark-diff::before{content:"\f364"}.bi-file-earmark-easel-fill::before{content:"\f365"}.bi-file-earmark-easel::before{content:"\f366"}.bi-file-earmark-excel-fill::before{content:"\f367"}.bi-file-earmark-excel::before{content:"\f368"}.bi-file-earmark-fill::before{content:"\f369"}.bi-file-earmark-font-fill::before{content:"\f36a"}.bi-file-earmark-font::before{content:"\f36b"}.bi-file-earmark-image-fill::before{content:"\f36c"}.bi-file-earmark-image::before{content:"\f36d"}.bi-file-earmark-lock-fill::before{content:"\f36e"}.bi-file-earmark-lock::before{content:"\f36f"}.bi-file-earmark-lock2-fill::before{content:"\f370"}.bi-file-earmark-lock2::before{content:"\f371"}.bi-file-earmark-medical-fill::before{content:"\f372"}.bi-file-earmark-medical::before{content:"\f373"}.bi-file-earmark-minus-fill::before{content:"\f374"}.bi-file-earmark-minus::before{content:"\f375"}.bi-file-earmark-music-fill::before{content:"\f376"}.bi-file-earmark-music::before{content:"\f377"}.bi-file-earmark-person-fill::before{content:"\f378"}.bi-file-earmark-person::before{content:"\f379"}.bi-file-earmark-play-fill::before{content:"\f37a"}.bi-file-earmark-play::before{content:"\f37b"}.bi-file-earmark-plus-fill::before{content:"\f37c"}.bi-file-earmark-plus::before{content:"\f37d"}.bi-file-earmark-post-fill::before{content:"\f37e"}.bi-file-earmark-post::before{content:"\f37f"}.bi-file-earmark-ppt-fill::before{content:"\f380"}.bi-file-earmark-ppt::before{content:"\f381"}.bi-file-earmark-richtext-fill::before{content:"\f382"}.bi-file-earmark-richtext::before{content:"\f383"}.bi-file-earmark-ruled-fill::before{content:"\f384"}.bi-file-earmark-ruled::before{content:"\f385"}.bi-file-earmark-slides-fill::before{content:"\f386"}.bi-file-earmark-slides::before{content:"\f387"}.bi-file-earmark-spreadsheet-fill::before{content:"\f388"}.bi-file-earmark-spreadsheet::before{content:"\f389"}.bi-file-earmark-text-fill::before{content:"\f38a"}.bi-file-earmark-text::before{content:"\f38b"}.bi-file-earmark-word-fill::before{content:"\f38c"}.bi-file-earmark-word::before{content:"\f38d"}.bi-file-earmark-x-fill::before{content:"\f38e"}.bi-file-earmark-x::before{content:"\f38f"}.bi-file-earmark-zip-fill::before{content:"\f390"}.bi-file-earmark-zip::before{content:"\f391"}.bi-file-earmark::before{content:"\f392"}.bi-file-easel-fill::before{content:"\f393"}.bi-file-easel::before{content:"\f394"}.bi-file-excel-fill::before{content:"\f395"}.bi-file-excel::before{content:"\f396"}.bi-file-fill::before{content:"\f397"}.bi-file-font-fill::before{content:"\f398"}.bi-file-font::before{content:"\f399"}.bi-file-image-fill::before{content:"\f39a"}.bi-file-image::before{content:"\f39b"}.bi-file-lock-fill::before{content:"\f39c"}.bi-file-lock::before{content:"\f39d"}.bi-file-lock2-fill::before{content:"\f39e"}.bi-file-lock2::before{content:"\f39f"}.bi-file-medical-fill::before{content:"\f3a0"}.bi-file-medical::before{content:"\f3a1"}.bi-file-minus-fill::before{content:"\f3a2"}.bi-file-minus::before{content:"\f3a3"}.bi-file-music-fill::before{content:"\f3a4"}.bi-file-music::before{content:"\f3a5"}.bi-file-person-fill::before{content:"\f3a6"}.bi-file-person::before{content:"\f3a7"}.bi-file-play-fill::before{content:"\f3a8"}.bi-file-play::before{content:"\f3a9"}.bi-file-plus-fill::before{content:"\f3aa"}.bi-file-plus::before{content:"\f3ab"}.bi-file-post-fill::before{content:"\f3ac"}.bi-file-post::before{content:"\f3ad"}.bi-file-ppt-fill::before{content:"\f3ae"}.bi-file-ppt::before{content:"\f3af"}.bi-file-richtext-fill::before{content:"\f3b0"}.bi-file-richtext::before{content:"\f3b1"}.bi-file-ruled-fill::before{content:"\f3b2"}.bi-file-ruled::before{content:"\f3b3"}.bi-file-slides-fill::before{content:"\f3b4"}.bi-file-slides::before{content:"\f3b5"}.bi-file-spreadsheet-fill::before{content:"\f3b6"}.bi-file-spreadsheet::before{content:"\f3b7"}.bi-file-text-fill::before{content:"\f3b8"}.bi-file-text::before{content:"\f3b9"}.bi-file-word-fill::before{content:"\f3ba"}.bi-file-word::before{content:"\f3bb"}.bi-file-x-fill::before{content:"\f3bc"}.bi-file-x::before{content:"\f3bd"}.bi-file-zip-fill::before{content:"\f3be"}.bi-file-zip::before{content:"\f3bf"}.bi-file::before{content:"\f3c0"}.bi-files-alt::before{content:"\f3c1"}.bi-files::before{content:"\f3c2"}.bi-film::before{content:"\f3c3"}.bi-filter-circle-fill::before{content:"\f3c4"}.bi-filter-circle::before{content:"\f3c5"}.bi-filter-left::before{content:"\f3c6"}.bi-filter-right::before{content:"\f3c7"}.bi-filter-square-fill::before{content:"\f3c8"}.bi-filter-square::before{content:"\f3c9"}.bi-filter::before{content:"\f3ca"}.bi-flag-fill::before{content:"\f3cb"}.bi-flag::before{content:"\f3cc"}.bi-flower1::before{content:"\f3cd"}.bi-flower2::before{content:"\f3ce"}.bi-flower3::before{content:"\f3cf"}.bi-folder-check::before{content:"\f3d0"}.bi-folder-fill::before{content:"\f3d1"}.bi-folder-minus::before{content:"\f3d2"}.bi-folder-plus::before{content:"\f3d3"}.bi-folder-symlink-fill::before{content:"\f3d4"}.bi-folder-symlink::before{content:"\f3d5"}.bi-folder-x::before{content:"\f3d6"}.bi-folder::before{content:"\f3d7"}.bi-folder2-open::before{content:"\f3d8"}.bi-folder2::before{content:"\f3d9"}.bi-fonts::before{content:"\f3da"}.bi-forward-fill::before{content:"\f3db"}.bi-forward::before{content:"\f3dc"}.bi-front::before{content:"\f3dd"}.bi-fullscreen-exit::before{content:"\f3de"}.bi-fullscreen::before{content:"\f3df"}.bi-funnel-fill::before{content:"\f3e0"}.bi-funnel::before{content:"\f3e1"}.bi-gear-fill::before{content:"\f3e2"}.bi-gear-wide-connected::before{content:"\f3e3"}.bi-gear-wide::before{content:"\f3e4"}.bi-gear::before{content:"\f3e5"}.bi-gem::before{content:"\f3e6"}.bi-geo-alt-fill::before{content:"\f3e7"}.bi-geo-alt::before{content:"\f3e8"}.bi-geo-fill::before{content:"\f3e9"}.bi-geo::before{content:"\f3ea"}.bi-gift-fill::before{content:"\f3eb"}.bi-gift::before{content:"\f3ec"}.bi-github::before{content:"\f3ed"}.bi-globe::before{content:"\f3ee"}.bi-globe2::before{content:"\f3ef"}.bi-google::before{content:"\f3f0"}.bi-graph-down::before{content:"\f3f1"}.bi-graph-up::before{content:"\f3f2"}.bi-grid-1x2-fill::before{content:"\f3f3"}.bi-grid-1x2::before{content:"\f3f4"}.bi-grid-3x2-gap-fill::before{content:"\f3f5"}.bi-grid-3x2-gap::before{content:"\f3f6"}.bi-grid-3x2::before{content:"\f3f7"}.bi-grid-3x3-gap-fill::before{content:"\f3f8"}.bi-grid-3x3-gap::before{content:"\f3f9"}.bi-grid-3x3::before{content:"\f3fa"}.bi-grid-fill::before{content:"\f3fb"}.bi-grid::before{content:"\f3fc"}.bi-grip-horizontal::before{content:"\f3fd"}.bi-grip-vertical::before{content:"\f3fe"}.bi-hammer::before{content:"\f3ff"}.bi-hand-index-fill::before{content:"\f400"}.bi-hand-index-thumb-fill::before{content:"\f401"}.bi-hand-index-thumb::before{content:"\f402"}.bi-hand-index::before{content:"\f403"}.bi-hand-thumbs-down-fill::before{content:"\f404"}.bi-hand-thumbs-down::before{content:"\f405"}.bi-hand-thumbs-up-fill::before{content:"\f406"}.bi-hand-thumbs-up::before{content:"\f407"}.bi-handbag-fill::before{content:"\f408"}.bi-handbag::before{content:"\f409"}.bi-hash::before{content:"\f40a"}.bi-hdd-fill::before{content:"\f40b"}.bi-hdd-network-fill::before{content:"\f40c"}.bi-hdd-network::before{content:"\f40d"}.bi-hdd-rack-fill::before{content:"\f40e"}.bi-hdd-rack::before{content:"\f40f"}.bi-hdd-stack-fill::before{content:"\f410"}.bi-hdd-stack::before{content:"\f411"}.bi-hdd::before{content:"\f412"}.bi-headphones::before{content:"\f413"}.bi-headset::before{content:"\f414"}.bi-heart-fill::before{content:"\f415"}.bi-heart-half::before{content:"\f416"}.bi-heart::before{content:"\f417"}.bi-heptagon-fill::before{content:"\f418"}.bi-heptagon-half::before{content:"\f419"}.bi-heptagon::before{content:"\f41a"}.bi-hexagon-fill::before{content:"\f41b"}.bi-hexagon-half::before{content:"\f41c"}.bi-hexagon::before{content:"\f41d"}.bi-hourglass-bottom::before{content:"\f41e"}.bi-hourglass-split::before{content:"\f41f"}.bi-hourglass-top::before{content:"\f420"}.bi-hourglass::before{content:"\f421"}.bi-house-door-fill::before{content:"\f422"}.bi-house-door::before{content:"\f423"}.bi-house-fill::before{content:"\f424"}.bi-house::before{content:"\f425"}.bi-hr::before{content:"\f426"}.bi-hurricane::before{content:"\f427"}.bi-image-alt::before{content:"\f428"}.bi-image-fill::before{content:"\f429"}.bi-image::before{content:"\f42a"}.bi-images::before{content:"\f42b"}.bi-inbox-fill::before{content:"\f42c"}.bi-inbox::before{content:"\f42d"}.bi-inboxes-fill::before{content:"\f42e"}.bi-inboxes::before{content:"\f42f"}.bi-info-circle-fill::before{content:"\f430"}.bi-info-circle::before{content:"\f431"}.bi-info-square-fill::before{content:"\f432"}.bi-info-square::before{content:"\f433"}.bi-info::before{content:"\f434"}.bi-input-cursor-text::before{content:"\f435"}.bi-input-cursor::before{content:"\f436"}.bi-instagram::before{content:"\f437"}.bi-intersect::before{content:"\f438"}.bi-journal-album::before{content:"\f439"}.bi-journal-arrow-down::before{content:"\f43a"}.bi-journal-arrow-up::before{content:"\f43b"}.bi-journal-bookmark-fill::before{content:"\f43c"}.bi-journal-bookmark::before{content:"\f43d"}.bi-journal-check::before{content:"\f43e"}.bi-journal-code::before{content:"\f43f"}.bi-journal-medical::before{content:"\f440"}.bi-journal-minus::before{content:"\f441"}.bi-journal-plus::before{content:"\f442"}.bi-journal-richtext::before{content:"\f443"}.bi-journal-text::before{content:"\f444"}.bi-journal-x::before{content:"\f445"}.bi-journal::before{content:"\f446"}.bi-journals::before{content:"\f447"}.bi-joystick::before{content:"\f448"}.bi-justify-left::before{content:"\f449"}.bi-justify-right::before{content:"\f44a"}.bi-justify::before{content:"\f44b"}.bi-kanban-fill::before{content:"\f44c"}.bi-kanban::before{content:"\f44d"}.bi-key-fill::before{content:"\f44e"}.bi-key::before{content:"\f44f"}.bi-keyboard-fill::before{content:"\f450"}.bi-keyboard::before{content:"\f451"}.bi-ladder::before{content:"\f452"}.bi-lamp-fill::before{content:"\f453"}.bi-lamp::before{content:"\f454"}.bi-laptop-fill::before{content:"\f455"}.bi-laptop::before{content:"\f456"}.bi-layer-backward::before{content:"\f457"}.bi-layer-forward::before{content:"\f458"}.bi-layers-fill::before{content:"\f459"}.bi-layers-half::before{content:"\f45a"}.bi-layers::before{content:"\f45b"}.bi-layout-sidebar-inset-reverse::before{content:"\f45c"}.bi-layout-sidebar-inset::before{content:"\f45d"}.bi-layout-sidebar-reverse::before{content:"\f45e"}.bi-layout-sidebar::before{content:"\f45f"}.bi-layout-split::before{content:"\f460"}.bi-layout-text-sidebar-reverse::before{content:"\f461"}.bi-layout-text-sidebar::before{content:"\f462"}.bi-layout-text-window-reverse::before{content:"\f463"}.bi-layout-text-window::before{content:"\f464"}.bi-layout-three-columns::before{content:"\f465"}.bi-layout-wtf::before{content:"\f466"}.bi-life-preserver::before{content:"\f467"}.bi-lightbulb-fill::before{content:"\f468"}.bi-lightbulb-off-fill::before{content:"\f469"}.bi-lightbulb-off::before{content:"\f46a"}.bi-lightbulb::before{content:"\f46b"}.bi-lightning-charge-fill::before{content:"\f46c"}.bi-lightning-charge::before{content:"\f46d"}.bi-lightning-fill::before{content:"\f46e"}.bi-lightning::before{content:"\f46f"}.bi-link-45deg::before{content:"\f470"}.bi-link::before{content:"\f471"}.bi-linkedin::before{content:"\f472"}.bi-list-check::before{content:"\f473"}.bi-list-nested::before{content:"\f474"}.bi-list-ol::before{content:"\f475"}.bi-list-stars::before{content:"\f476"}.bi-list-task::before{content:"\f477"}.bi-list-ul::before{content:"\f478"}.bi-list::before{content:"\f479"}.bi-lock-fill::before{content:"\f47a"}.bi-lock::before{content:"\f47b"}.bi-mailbox::before{content:"\f47c"}.bi-mailbox2::before{content:"\f47d"}.bi-map-fill::before{content:"\f47e"}.bi-map::before{content:"\f47f"}.bi-markdown-fill::before{content:"\f480"}.bi-markdown::before{content:"\f481"}.bi-mask::before{content:"\f482"}.bi-megaphone-fill::before{content:"\f483"}.bi-megaphone::before{content:"\f484"}.bi-menu-app-fill::before{content:"\f485"}.bi-menu-app::before{content:"\f486"}.bi-menu-button-fill::before{content:"\f487"}.bi-menu-button-wide-fill::before{content:"\f488"}.bi-menu-button-wide::before{content:"\f489"}.bi-menu-button::before{content:"\f48a"}.bi-menu-down::before{content:"\f48b"}.bi-menu-up::before{content:"\f48c"}.bi-mic-fill::before{content:"\f48d"}.bi-mic-mute-fill::before{content:"\f48e"}.bi-mic-mute::before{content:"\f48f"}.bi-mic::before{content:"\f490"}.bi-minecart-loaded::before{content:"\f491"}.bi-minecart::before{content:"\f492"}.bi-moisture::before{content:"\f493"}.bi-moon-fill::before{content:"\f494"}.bi-moon-stars-fill::before{content:"\f495"}.bi-moon-stars::before{content:"\f496"}.bi-moon::before{content:"\f497"}.bi-mouse-fill::before{content:"\f498"}.bi-mouse::before{content:"\f499"}.bi-mouse2-fill::before{content:"\f49a"}.bi-mouse2::before{content:"\f49b"}.bi-mouse3-fill::before{content:"\f49c"}.bi-mouse3::before{content:"\f49d"}.bi-music-note-beamed::before{content:"\f49e"}.bi-music-note-list::before{content:"\f49f"}.bi-music-note::before{content:"\f4a0"}.bi-music-player-fill::before{content:"\f4a1"}.bi-music-player::before{content:"\f4a2"}.bi-newspaper::before{content:"\f4a3"}.bi-node-minus-fill::before{content:"\f4a4"}.bi-node-minus::before{content:"\f4a5"}.bi-node-plus-fill::before{content:"\f4a6"}.bi-node-plus::before{content:"\f4a7"}.bi-nut-fill::before{content:"\f4a8"}.bi-nut::before{content:"\f4a9"}.bi-octagon-fill::before{content:"\f4aa"}.bi-octagon-half::before{content:"\f4ab"}.bi-octagon::before{content:"\f4ac"}.bi-option::before{content:"\f4ad"}.bi-outlet::before{content:"\f4ae"}.bi-paint-bucket::before{content:"\f4af"}.bi-palette-fill::before{content:"\f4b0"}.bi-palette::before{content:"\f4b1"}.bi-palette2::before{content:"\f4b2"}.bi-paperclip::before{content:"\f4b3"}.bi-paragraph::before{content:"\f4b4"}.bi-patch-check-fill::before{content:"\f4b5"}.bi-patch-check::before{content:"\f4b6"}.bi-patch-exclamation-fill::before{content:"\f4b7"}.bi-patch-exclamation::before{content:"\f4b8"}.bi-patch-minus-fill::before{content:"\f4b9"}.bi-patch-minus::before{content:"\f4ba"}.bi-patch-plus-fill::before{content:"\f4bb"}.bi-patch-plus::before{content:"\f4bc"}.bi-patch-question-fill::before{content:"\f4bd"}.bi-patch-question::before{content:"\f4be"}.bi-pause-btn-fill::before{content:"\f4bf"}.bi-pause-btn::before{content:"\f4c0"}.bi-pause-circle-fill::before{content:"\f4c1"}.bi-pause-circle::before{content:"\f4c2"}.bi-pause-fill::before{content:"\f4c3"}.bi-pause::before{content:"\f4c4"}.bi-peace-fill::before{content:"\f4c5"}.bi-peace::before{content:"\f4c6"}.bi-pen-fill::before{content:"\f4c7"}.bi-pen::before{content:"\f4c8"}.bi-pencil-fill::before{content:"\f4c9"}.bi-pencil-square::before{content:"\f4ca"}.bi-pencil::before{content:"\f4cb"}.bi-pentagon-fill::before{content:"\f4cc"}.bi-pentagon-half::before{content:"\f4cd"}.bi-pentagon::before{content:"\f4ce"}.bi-people-fill::before{content:"\f4cf"}.bi-people::before{content:"\f4d0"}.bi-percent::before{content:"\f4d1"}.bi-person-badge-fill::before{content:"\f4d2"}.bi-person-badge::before{content:"\f4d3"}.bi-person-bounding-box::before{content:"\f4d4"}.bi-person-check-fill::before{content:"\f4d5"}.bi-person-check::before{content:"\f4d6"}.bi-person-circle::before{content:"\f4d7"}.bi-person-dash-fill::before{content:"\f4d8"}.bi-person-dash::before{content:"\f4d9"}.bi-person-fill::before{content:"\f4da"}.bi-person-lines-fill::before{content:"\f4db"}.bi-person-plus-fill::before{content:"\f4dc"}.bi-person-plus::before{content:"\f4dd"}.bi-person-square::before{content:"\f4de"}.bi-person-x-fill::before{content:"\f4df"}.bi-person-x::before{content:"\f4e0"}.bi-person::before{content:"\f4e1"}.bi-phone-fill::before{content:"\f4e2"}.bi-phone-landscape-fill::before{content:"\f4e3"}.bi-phone-landscape::before{content:"\f4e4"}.bi-phone-vibrate-fill::before{content:"\f4e5"}.bi-phone-vibrate::before{content:"\f4e6"}.bi-phone::before{content:"\f4e7"}.bi-pie-chart-fill::before{content:"\f4e8"}.bi-pie-chart::before{content:"\f4e9"}.bi-pin-angle-fill::before{content:"\f4ea"}.bi-pin-angle::before{content:"\f4eb"}.bi-pin-fill::before{content:"\f4ec"}.bi-pin::before{content:"\f4ed"}.bi-pip-fill::before{content:"\f4ee"}.bi-pip::before{content:"\f4ef"}.bi-play-btn-fill::before{content:"\f4f0"}.bi-play-btn::before{content:"\f4f1"}.bi-play-circle-fill::before{content:"\f4f2"}.bi-play-circle::before{content:"\f4f3"}.bi-play-fill::before{content:"\f4f4"}.bi-play::before{content:"\f4f5"}.bi-plug-fill::before{content:"\f4f6"}.bi-plug::before{content:"\f4f7"}.bi-plus-circle-dotted::before{content:"\f4f8"}.bi-plus-circle-fill::before{content:"\f4f9"}.bi-plus-circle::before{content:"\f4fa"}.bi-plus-square-dotted::before{content:"\f4fb"}.bi-plus-square-fill::before{content:"\f4fc"}.bi-plus-square::before{content:"\f4fd"}.bi-plus::before{content:"\f4fe"}.bi-power::before{content:"\f4ff"}.bi-printer-fill::before{content:"\f500"}.bi-printer::before{content:"\f501"}.bi-puzzle-fill::before{content:"\f502"}.bi-puzzle::before{content:"\f503"}.bi-question-circle-fill::before{content:"\f504"}.bi-question-circle::before{content:"\f505"}.bi-question-diamond-fill::before{content:"\f506"}.bi-question-diamond::before{content:"\f507"}.bi-question-octagon-fill::before{content:"\f508"}.bi-question-octagon::before{content:"\f509"}.bi-question-square-fill::before{content:"\f50a"}.bi-question-square::before{content:"\f50b"}.bi-question::before{content:"\f50c"}.bi-rainbow::before{content:"\f50d"}.bi-receipt-cutoff::before{content:"\f50e"}.bi-receipt::before{content:"\f50f"}.bi-reception-0::before{content:"\f510"}.bi-reception-1::before{content:"\f511"}.bi-reception-2::before{content:"\f512"}.bi-reception-3::before{content:"\f513"}.bi-reception-4::before{content:"\f514"}.bi-record-btn-fill::before{content:"\f515"}.bi-record-btn::before{content:"\f516"}.bi-record-circle-fill::before{content:"\f517"}.bi-record-circle::before{content:"\f518"}.bi-record-fill::before{content:"\f519"}.bi-record::before{content:"\f51a"}.bi-record2-fill::before{content:"\f51b"}.bi-record2::before{content:"\f51c"}.bi-reply-all-fill::before{content:"\f51d"}.bi-reply-all::before{content:"\f51e"}.bi-reply-fill::before{content:"\f51f"}.bi-reply::before{content:"\f520"}.bi-rss-fill::before{content:"\f521"}.bi-rss::before{content:"\f522"}.bi-rulers::before{content:"\f523"}.bi-save-fill::before{content:"\f524"}.bi-save::before{content:"\f525"}.bi-save2-fill::before{content:"\f526"}.bi-save2::before{content:"\f527"}.bi-scissors::before{content:"\f528"}.bi-screwdriver::before{content:"\f529"}.bi-search::before{content:"\f52a"}.bi-segmented-nav::before{content:"\f52b"}.bi-server::before{content:"\f52c"}.bi-share-fill::before{content:"\f52d"}.bi-share::before{content:"\f52e"}.bi-shield-check::before{content:"\f52f"}.bi-shield-exclamation::before{content:"\f530"}.bi-shield-fill-check::before{content:"\f531"}.bi-shield-fill-exclamation::before{content:"\f532"}.bi-shield-fill-minus::before{content:"\f533"}.bi-shield-fill-plus::before{content:"\f534"}.bi-shield-fill-x::before{content:"\f535"}.bi-shield-fill::before{content:"\f536"}.bi-shield-lock-fill::before{content:"\f537"}.bi-shield-lock::before{content:"\f538"}.bi-shield-minus::before{content:"\f539"}.bi-shield-plus::before{content:"\f53a"}.bi-shield-shaded::before{content:"\f53b"}.bi-shield-slash-fill::before{content:"\f53c"}.bi-shield-slash::before{content:"\f53d"}.bi-shield-x::before{content:"\f53e"}.bi-shield::before{content:"\f53f"}.bi-shift-fill::before{content:"\f540"}.bi-shift::before{content:"\f541"}.bi-shop-window::before{content:"\f542"}.bi-shop::before{content:"\f543"}.bi-shuffle::before{content:"\f544"}.bi-signpost-2-fill::before{content:"\f545"}.bi-signpost-2::before{content:"\f546"}.bi-signpost-fill::before{content:"\f547"}.bi-signpost-split-fill::before{content:"\f548"}.bi-signpost-split::before{content:"\f549"}.bi-signpost::before{content:"\f54a"}.bi-sim-fill::before{content:"\f54b"}.bi-sim::before{content:"\f54c"}.bi-skip-backward-btn-fill::before{content:"\f54d"}.bi-skip-backward-btn::before{content:"\f54e"}.bi-skip-backward-circle-fill::before{content:"\f54f"}.bi-skip-backward-circle::before{content:"\f550"}.bi-skip-backward-fill::before{content:"\f551"}.bi-skip-backward::before{content:"\f552"}.bi-skip-end-btn-fill::before{content:"\f553"}.bi-skip-end-btn::before{content:"\f554"}.bi-skip-end-circle-fill::before{content:"\f555"}.bi-skip-end-circle::before{content:"\f556"}.bi-skip-end-fill::before{content:"\f557"}.bi-skip-end::before{content:"\f558"}.bi-skip-forward-btn-fill::before{content:"\f559"}.bi-skip-forward-btn::before{content:"\f55a"}.bi-skip-forward-circle-fill::before{content:"\f55b"}.bi-skip-forward-circle::before{content:"\f55c"}.bi-skip-forward-fill::before{content:"\f55d"}.bi-skip-forward::before{content:"\f55e"}.bi-skip-start-btn-fill::before{content:"\f55f"}.bi-skip-start-btn::before{content:"\f560"}.bi-skip-start-circle-fill::before{content:"\f561"}.bi-skip-start-circle::before{content:"\f562"}.bi-skip-start-fill::before{content:"\f563"}.bi-skip-start::before{content:"\f564"}.bi-slack::before{content:"\f565"}.bi-slash-circle-fill::before{content:"\f566"}.bi-slash-circle::before{content:"\f567"}.bi-slash-square-fill::before{content:"\f568"}.bi-slash-square::before{content:"\f569"}.bi-slash::before{content:"\f56a"}.bi-sliders::before{content:"\f56b"}.bi-smartwatch::before{content:"\f56c"}.bi-snow::before{content:"\f56d"}.bi-snow2::before{content:"\f56e"}.bi-snow3::before{content:"\f56f"}.bi-sort-alpha-down-alt::before{content:"\f570"}.bi-sort-alpha-down::before{content:"\f571"}.bi-sort-alpha-up-alt::before{content:"\f572"}.bi-sort-alpha-up::before{content:"\f573"}.bi-sort-down-alt::before{content:"\f574"}.bi-sort-down::before{content:"\f575"}.bi-sort-numeric-down-alt::before{content:"\f576"}.bi-sort-numeric-down::before{content:"\f577"}.bi-sort-numeric-up-alt::before{content:"\f578"}.bi-sort-numeric-up::before{content:"\f579"}.bi-sort-up-alt::before{content:"\f57a"}.bi-sort-up::before{content:"\f57b"}.bi-soundwave::before{content:"\f57c"}.bi-speaker-fill::before{content:"\f57d"}.bi-speaker::before{content:"\f57e"}.bi-speedometer::before{content:"\f57f"}.bi-speedometer2::before{content:"\f580"}.bi-spellcheck::before{content:"\f581"}.bi-square-fill::before{content:"\f582"}.bi-square-half::before{content:"\f583"}.bi-square::before{content:"\f584"}.bi-stack::before{content:"\f585"}.bi-star-fill::before{content:"\f586"}.bi-star-half::before{content:"\f587"}.bi-star::before{content:"\f588"}.bi-stars::before{content:"\f589"}.bi-stickies-fill::before{content:"\f58a"}.bi-stickies::before{content:"\f58b"}.bi-sticky-fill::before{content:"\f58c"}.bi-sticky::before{content:"\f58d"}.bi-stop-btn-fill::before{content:"\f58e"}.bi-stop-btn::before{content:"\f58f"}.bi-stop-circle-fill::before{content:"\f590"}.bi-stop-circle::before{content:"\f591"}.bi-stop-fill::before{content:"\f592"}.bi-stop::before{content:"\f593"}.bi-stoplights-fill::before{content:"\f594"}.bi-stoplights::before{content:"\f595"}.bi-stopwatch-fill::before{content:"\f596"}.bi-stopwatch::before{content:"\f597"}.bi-subtract::before{content:"\f598"}.bi-suit-club-fill::before{content:"\f599"}.bi-suit-club::before{content:"\f59a"}.bi-suit-diamond-fill::before{content:"\f59b"}.bi-suit-diamond::before{content:"\f59c"}.bi-suit-heart-fill::before{content:"\f59d"}.bi-suit-heart::before{content:"\f59e"}.bi-suit-spade-fill::before{content:"\f59f"}.bi-suit-spade::before{content:"\f5a0"}.bi-sun-fill::before{content:"\f5a1"}.bi-sun::before{content:"\f5a2"}.bi-sunglasses::before{content:"\f5a3"}.bi-sunrise-fill::before{content:"\f5a4"}.bi-sunrise::before{content:"\f5a5"}.bi-sunset-fill::before{content:"\f5a6"}.bi-sunset::before{content:"\f5a7"}.bi-symmetry-horizontal::before{content:"\f5a8"}.bi-symmetry-vertical::before{content:"\f5a9"}.bi-table::before{content:"\f5aa"}.bi-tablet-fill::before{content:"\f5ab"}.bi-tablet-landscape-fill::before{content:"\f5ac"}.bi-tablet-landscape::before{content:"\f5ad"}.bi-tablet::before{content:"\f5ae"}.bi-tag-fill::before{content:"\f5af"}.bi-tag::before{content:"\f5b0"}.bi-tags-fill::before{content:"\f5b1"}.bi-tags::before{content:"\f5b2"}.bi-telegram::before{content:"\f5b3"}.bi-telephone-fill::before{content:"\f5b4"}.bi-telephone-forward-fill::before{content:"\f5b5"}.bi-telephone-forward::before{content:"\f5b6"}.bi-telephone-inbound-fill::before{content:"\f5b7"}.bi-telephone-inbound::before{content:"\f5b8"}.bi-telephone-minus-fill::before{content:"\f5b9"}.bi-telephone-minus::before{content:"\f5ba"}.bi-telephone-outbound-fill::before{content:"\f5bb"}.bi-telephone-outbound::before{content:"\f5bc"}.bi-telephone-plus-fill::before{content:"\f5bd"}.bi-telephone-plus::before{content:"\f5be"}.bi-telephone-x-fill::before{content:"\f5bf"}.bi-telephone-x::before{content:"\f5c0"}.bi-telephone::before{content:"\f5c1"}.bi-terminal-fill::before{content:"\f5c2"}.bi-terminal::before{content:"\f5c3"}.bi-text-center::before{content:"\f5c4"}.bi-text-indent-left::before{content:"\f5c5"}.bi-text-indent-right::before{content:"\f5c6"}.bi-text-left::before{content:"\f5c7"}.bi-text-paragraph::before{content:"\f5c8"}.bi-text-right::before{content:"\f5c9"}.bi-textarea-resize::before{content:"\f5ca"}.bi-textarea-t::before{content:"\f5cb"}.bi-textarea::before{content:"\f5cc"}.bi-thermometer-half::before{content:"\f5cd"}.bi-thermometer-high::before{content:"\f5ce"}.bi-thermometer-low::before{content:"\f5cf"}.bi-thermometer-snow::before{content:"\f5d0"}.bi-thermometer-sun::before{content:"\f5d1"}.bi-thermometer::before{content:"\f5d2"}.bi-three-dots-vertical::before{content:"\f5d3"}.bi-three-dots::before{content:"\f5d4"}.bi-toggle-off::before{content:"\f5d5"}.bi-toggle-on::before{content:"\f5d6"}.bi-toggle2-off::before{content:"\f5d7"}.bi-toggle2-on::before{content:"\f5d8"}.bi-toggles::before{content:"\f5d9"}.bi-toggles2::before{content:"\f5da"}.bi-tools::before{content:"\f5db"}.bi-tornado::before{content:"\f5dc"}.bi-trash-fill::before{content:"\f5dd"}.bi-trash::before{content:"\f5de"}.bi-trash2-fill::before{content:"\f5df"}.bi-trash2::before{content:"\f5e0"}.bi-tree-fill::before{content:"\f5e1"}.bi-tree::before{content:"\f5e2"}.bi-triangle-fill::before{content:"\f5e3"}.bi-triangle-half::before{content:"\f5e4"}.bi-triangle::before{content:"\f5e5"}.bi-trophy-fill::before{content:"\f5e6"}.bi-trophy::before{content:"\f5e7"}.bi-tropical-storm::before{content:"\f5e8"}.bi-truck-flatbed::before{content:"\f5e9"}.bi-truck::before{content:"\f5ea"}.bi-tsunami::before{content:"\f5eb"}.bi-tv-fill::before{content:"\f5ec"}.bi-tv::before{content:"\f5ed"}.bi-twitch::before{content:"\f5ee"}.bi-twitter::before{content:"\f5ef"}.bi-type-bold::before{content:"\f5f0"}.bi-type-h1::before{content:"\f5f1"}.bi-type-h2::before{content:"\f5f2"}.bi-type-h3::before{content:"\f5f3"}.bi-type-italic::before{content:"\f5f4"}.bi-type-strikethrough::before{content:"\f5f5"}.bi-type-underline::before{content:"\f5f6"}.bi-type::before{content:"\f5f7"}.bi-ui-checks-grid::before{content:"\f5f8"}.bi-ui-checks::before{content:"\f5f9"}.bi-ui-radios-grid::before{content:"\f5fa"}.bi-ui-radios::before{content:"\f5fb"}.bi-umbrella-fill::before{content:"\f5fc"}.bi-umbrella::before{content:"\f5fd"}.bi-union::before{content:"\f5fe"}.bi-unlock-fill::before{content:"\f5ff"}.bi-unlock::before{content:"\f600"}.bi-upc-scan::before{content:"\f601"}.bi-upc::before{content:"\f602"}.bi-upload::before{content:"\f603"}.bi-vector-pen::before{content:"\f604"}.bi-view-list::before{content:"\f605"}.bi-view-stacked::before{content:"\f606"}.bi-vinyl-fill::before{content:"\f607"}.bi-vinyl::before{content:"\f608"}.bi-voicemail::before{content:"\f609"}.bi-volume-down-fill::before{content:"\f60a"}.bi-volume-down::before{content:"\f60b"}.bi-volume-mute-fill::before{content:"\f60c"}.bi-volume-mute::before{content:"\f60d"}.bi-volume-off-fill::before{content:"\f60e"}.bi-volume-off::before{content:"\f60f"}.bi-volume-up-fill::before{content:"\f610"}.bi-volume-up::before{content:"\f611"}.bi-vr::before{content:"\f612"}.bi-wallet-fill::before{content:"\f613"}.bi-wallet::before{content:"\f614"}.bi-wallet2::before{content:"\f615"}.bi-watch::before{content:"\f616"}.bi-water::before{content:"\f617"}.bi-whatsapp::before{content:"\f618"}.bi-wifi-1::before{content:"\f619"}.bi-wifi-2::before{content:"\f61a"}.bi-wifi-off::before{content:"\f61b"}.bi-wifi::before{content:"\f61c"}.bi-wind::before{content:"\f61d"}.bi-window-dock::before{content:"\f61e"}.bi-window-sidebar::before{content:"\f61f"}.bi-window::before{content:"\f620"}.bi-wrench::before{content:"\f621"}.bi-x-circle-fill::before{content:"\f622"}.bi-x-circle::before{content:"\f623"}.bi-x-diamond-fill::before{content:"\f624"}.bi-x-diamond::before{content:"\f625"}.bi-x-octagon-fill::before{content:"\f626"}.bi-x-octagon::before{content:"\f627"}.bi-x-square-fill::before{content:"\f628"}.bi-x-square::before{content:"\f629"}.bi-x::before{content:"\f62a"}.bi-youtube::before{content:"\f62b"}.bi-zoom-in::before{content:"\f62c"}.bi-zoom-out::before{content:"\f62d"}.bi-bank::before{content:"\f62e"}.bi-bank2::before{content:"\f62f"}.bi-bell-slash-fill::before{content:"\f630"}.bi-bell-slash::before{content:"\f631"}.bi-cash-coin::before{content:"\f632"}.bi-check-lg::before{content:"\f633"}.bi-coin::before{content:"\f634"}.bi-currency-bitcoin::before{content:"\f635"}.bi-currency-dollar::before{content:"\f636"}.bi-currency-euro::before{content:"\f637"}.bi-currency-exchange::before{content:"\f638"}.bi-currency-pound::before{content:"\f639"}.bi-currency-yen::before{content:"\f63a"}.bi-dash-lg::before{content:"\f63b"}.bi-exclamation-lg::before{content:"\f63c"}.bi-file-earmark-pdf-fill::before{content:"\f63d"}.bi-file-earmark-pdf::before{content:"\f63e"}.bi-file-pdf-fill::before{content:"\f63f"}.bi-file-pdf::before{content:"\f640"}.bi-gender-ambiguous::before{content:"\f641"}.bi-gender-female::before{content:"\f642"}.bi-gender-male::before{content:"\f643"}.bi-gender-trans::before{content:"\f644"}.bi-headset-vr::before{content:"\f645"}.bi-info-lg::before{content:"\f646"}.bi-mastodon::before{content:"\f647"}.bi-messenger::before{content:"\f648"}.bi-piggy-bank-fill::before{content:"\f649"}.bi-piggy-bank::before{content:"\f64a"}.bi-pin-map-fill::before{content:"\f64b"}.bi-pin-map::before{content:"\f64c"}.bi-plus-lg::before{content:"\f64d"}.bi-question-lg::before{content:"\f64e"}.bi-recycle::before{content:"\f64f"}.bi-reddit::before{content:"\f650"}.bi-safe-fill::before{content:"\f651"}.bi-safe2-fill::before{content:"\f652"}.bi-safe2::before{content:"\f653"}.bi-sd-card-fill::before{content:"\f654"}.bi-sd-card::before{content:"\f655"}.bi-skype::before{content:"\f656"}.bi-slash-lg::before{content:"\f657"}.bi-translate::before{content:"\f658"}.bi-x-lg::before{content:"\f659"}.bi-safe::before{content:"\f65a"}.bi-apple::before{content:"\f65b"}.bi-microsoft::before{content:"\f65d"}.bi-windows::before{content:"\f65e"}.bi-behance::before{content:"\f65c"}.bi-dribbble::before{content:"\f65f"}.bi-line::before{content:"\f660"}.bi-medium::before{content:"\f661"}.bi-paypal::before{content:"\f662"}.bi-pinterest::before{content:"\f663"}.bi-signal::before{content:"\f664"}.bi-snapchat::before{content:"\f665"}.bi-spotify::before{content:"\f666"}.bi-stack-overflow::before{content:"\f667"}.bi-strava::before{content:"\f668"}.bi-wordpress::before{content:"\f669"}.bi-vimeo::before{content:"\f66a"}.bi-activity::before{content:"\f66b"}.bi-easel2-fill::before{content:"\f66c"}.bi-easel2::before{content:"\f66d"}.bi-easel3-fill::before{content:"\f66e"}.bi-easel3::before{content:"\f66f"}.bi-fan::before{content:"\f670"}.bi-fingerprint::before{content:"\f671"}.bi-graph-down-arrow::before{content:"\f672"}.bi-graph-up-arrow::before{content:"\f673"}.bi-hypnotize::before{content:"\f674"}.bi-magic::before{content:"\f675"}.bi-person-rolodex::before{content:"\f676"}.bi-person-video::before{content:"\f677"}.bi-person-video2::before{content:"\f678"}.bi-person-video3::before{content:"\f679"}.bi-person-workspace::before{content:"\f67a"}.bi-radioactive::before{content:"\f67b"}.bi-webcam-fill::before{content:"\f67c"}.bi-webcam::before{content:"\f67d"}.bi-yin-yang::before{content:"\f67e"}.bi-bandaid-fill::before{content:"\f680"}.bi-bandaid::before{content:"\f681"}.bi-bluetooth::before{content:"\f682"}.bi-body-text::before{content:"\f683"}.bi-boombox::before{content:"\f684"}.bi-boxes::before{content:"\f685"}.bi-dpad-fill::before{content:"\f686"}.bi-dpad::before{content:"\f687"}.bi-ear-fill::before{content:"\f688"}.bi-ear::before{content:"\f689"}.bi-envelope-check-fill::before{content:"\f68b"}.bi-envelope-check::before{content:"\f68c"}.bi-envelope-dash-fill::before{content:"\f68e"}.bi-envelope-dash::before{content:"\f68f"}.bi-envelope-exclamation-fill::before{content:"\f691"}.bi-envelope-exclamation::before{content:"\f692"}.bi-envelope-plus-fill::before{content:"\f693"}.bi-envelope-plus::before{content:"\f694"}.bi-envelope-slash-fill::before{content:"\f696"}.bi-envelope-slash::before{content:"\f697"}.bi-envelope-x-fill::before{content:"\f699"}.bi-envelope-x::before{content:"\f69a"}.bi-explicit-fill::before{content:"\f69b"}.bi-explicit::before{content:"\f69c"}.bi-git::before{content:"\f69d"}.bi-infinity::before{content:"\f69e"}.bi-list-columns-reverse::before{content:"\f69f"}.bi-list-columns::before{content:"\f6a0"}.bi-meta::before{content:"\f6a1"}.bi-nintendo-switch::before{content:"\f6a4"}.bi-pc-display-horizontal::before{content:"\f6a5"}.bi-pc-display::before{content:"\f6a6"}.bi-pc-horizontal::before{content:"\f6a7"}.bi-pc::before{content:"\f6a8"}.bi-playstation::before{content:"\f6a9"}.bi-plus-slash-minus::before{content:"\f6aa"}.bi-projector-fill::before{content:"\f6ab"}.bi-projector::before{content:"\f6ac"}.bi-qr-code-scan::before{content:"\f6ad"}.bi-qr-code::before{content:"\f6ae"}.bi-quora::before{content:"\f6af"}.bi-quote::before{content:"\f6b0"}.bi-robot::before{content:"\f6b1"}.bi-send-check-fill::before{content:"\f6b2"}.bi-send-check::before{content:"\f6b3"}.bi-send-dash-fill::before{content:"\f6b4"}.bi-send-dash::before{content:"\f6b5"}.bi-send-exclamation-fill::before{content:"\f6b7"}.bi-send-exclamation::before{content:"\f6b8"}.bi-send-fill::before{content:"\f6b9"}.bi-send-plus-fill::before{content:"\f6ba"}.bi-send-plus::before{content:"\f6bb"}.bi-send-slash-fill::before{content:"\f6bc"}.bi-send-slash::before{content:"\f6bd"}.bi-send-x-fill::before{content:"\f6be"}.bi-send-x::before{content:"\f6bf"}.bi-send::before{content:"\f6c0"}.bi-steam::before{content:"\f6c1"}.bi-terminal-dash::before{content:"\f6c3"}.bi-terminal-plus::before{content:"\f6c4"}.bi-terminal-split::before{content:"\f6c5"}.bi-ticket-detailed-fill::before{content:"\f6c6"}.bi-ticket-detailed::before{content:"\f6c7"}.bi-ticket-fill::before{content:"\f6c8"}.bi-ticket-perforated-fill::before{content:"\f6c9"}.bi-ticket-perforated::before{content:"\f6ca"}.bi-ticket::before{content:"\f6cb"}.bi-tiktok::before{content:"\f6cc"}.bi-window-dash::before{content:"\f6cd"}.bi-window-desktop::before{content:"\f6ce"}.bi-window-fullscreen::before{content:"\f6cf"}.bi-window-plus::before{content:"\f6d0"}.bi-window-split::before{content:"\f6d1"}.bi-window-stack::before{content:"\f6d2"}.bi-window-x::before{content:"\f6d3"}.bi-xbox::before{content:"\f6d4"}.bi-ethernet::before{content:"\f6d5"}.bi-hdmi-fill::before{content:"\f6d6"}.bi-hdmi::before{content:"\f6d7"}.bi-usb-c-fill::before{content:"\f6d8"}.bi-usb-c::before{content:"\f6d9"}.bi-usb-fill::before{content:"\f6da"}.bi-usb-plug-fill::before{content:"\f6db"}.bi-usb-plug::before{content:"\f6dc"}.bi-usb-symbol::before{content:"\f6dd"}.bi-usb::before{content:"\f6de"}.bi-boombox-fill::before{content:"\f6df"}.bi-displayport::before{content:"\f6e1"}.bi-gpu-card::before{content:"\f6e2"}.bi-memory::before{content:"\f6e3"}.bi-modem-fill::before{content:"\f6e4"}.bi-modem::before{content:"\f6e5"}.bi-motherboard-fill::before{content:"\f6e6"}.bi-motherboard::before{content:"\f6e7"}.bi-optical-audio-fill::before{content:"\f6e8"}.bi-optical-audio::before{content:"\f6e9"}.bi-pci-card::before{content:"\f6ea"}.bi-router-fill::before{content:"\f6eb"}.bi-router::before{content:"\f6ec"}.bi-thunderbolt-fill::before{content:"\f6ef"}.bi-thunderbolt::before{content:"\f6f0"}.bi-usb-drive-fill::before{content:"\f6f1"}.bi-usb-drive::before{content:"\f6f2"}.bi-usb-micro-fill::before{content:"\f6f3"}.bi-usb-micro::before{content:"\f6f4"}.bi-usb-mini-fill::before{content:"\f6f5"}.bi-usb-mini::before{content:"\f6f6"}.bi-cloud-haze2::before{content:"\f6f7"}.bi-device-hdd-fill::before{content:"\f6f8"}.bi-device-hdd::before{content:"\f6f9"}.bi-device-ssd-fill::before{content:"\f6fa"}.bi-device-ssd::before{content:"\f6fb"}.bi-displayport-fill::before{content:"\f6fc"}.bi-mortarboard-fill::before{content:"\f6fd"}.bi-mortarboard::before{content:"\f6fe"}.bi-terminal-x::before{content:"\f6ff"}.bi-arrow-through-heart-fill::before{content:"\f700"}.bi-arrow-through-heart::before{content:"\f701"}.bi-badge-sd-fill::before{content:"\f702"}.bi-badge-sd::before{content:"\f703"}.bi-bag-heart-fill::before{content:"\f704"}.bi-bag-heart::before{content:"\f705"}.bi-balloon-fill::before{content:"\f706"}.bi-balloon-heart-fill::before{content:"\f707"}.bi-balloon-heart::before{content:"\f708"}.bi-balloon::before{content:"\f709"}.bi-box2-fill::before{content:"\f70a"}.bi-box2-heart-fill::before{content:"\f70b"}.bi-box2-heart::before{content:"\f70c"}.bi-box2::before{content:"\f70d"}.bi-braces-asterisk::before{content:"\f70e"}.bi-calendar-heart-fill::before{content:"\f70f"}.bi-calendar-heart::before{content:"\f710"}.bi-calendar2-heart-fill::before{content:"\f711"}.bi-calendar2-heart::before{content:"\f712"}.bi-chat-heart-fill::before{content:"\f713"}.bi-chat-heart::before{content:"\f714"}.bi-chat-left-heart-fill::before{content:"\f715"}.bi-chat-left-heart::before{content:"\f716"}.bi-chat-right-heart-fill::before{content:"\f717"}.bi-chat-right-heart::before{content:"\f718"}.bi-chat-square-heart-fill::before{content:"\f719"}.bi-chat-square-heart::before{content:"\f71a"}.bi-clipboard-check-fill::before{content:"\f71b"}.bi-clipboard-data-fill::before{content:"\f71c"}.bi-clipboard-fill::before{content:"\f71d"}.bi-clipboard-heart-fill::before{content:"\f71e"}.bi-clipboard-heart::before{content:"\f71f"}.bi-clipboard-minus-fill::before{content:"\f720"}.bi-clipboard-plus-fill::before{content:"\f721"}.bi-clipboard-pulse::before{content:"\f722"}.bi-clipboard-x-fill::before{content:"\f723"}.bi-clipboard2-check-fill::before{content:"\f724"}.bi-clipboard2-check::before{content:"\f725"}.bi-clipboard2-data-fill::before{content:"\f726"}.bi-clipboard2-data::before{content:"\f727"}.bi-clipboard2-fill::before{content:"\f728"}.bi-clipboard2-heart-fill::before{content:"\f729"}.bi-clipboard2-heart::before{content:"\f72a"}.bi-clipboard2-minus-fill::before{content:"\f72b"}.bi-clipboard2-minus::before{content:"\f72c"}.bi-clipboard2-plus-fill::before{content:"\f72d"}.bi-clipboard2-plus::before{content:"\f72e"}.bi-clipboard2-pulse-fill::before{content:"\f72f"}.bi-clipboard2-pulse::before{content:"\f730"}.bi-clipboard2-x-fill::before{content:"\f731"}.bi-clipboard2-x::before{content:"\f732"}.bi-clipboard2::before{content:"\f733"}.bi-emoji-kiss-fill::before{content:"\f734"}.bi-emoji-kiss::before{content:"\f735"}.bi-envelope-heart-fill::before{content:"\f736"}.bi-envelope-heart::before{content:"\f737"}.bi-envelope-open-heart-fill::before{content:"\f738"}.bi-envelope-open-heart::before{content:"\f739"}.bi-envelope-paper-fill::before{content:"\f73a"}.bi-envelope-paper-heart-fill::before{content:"\f73b"}.bi-envelope-paper-heart::before{content:"\f73c"}.bi-envelope-paper::before{content:"\f73d"}.bi-filetype-aac::before{content:"\f73e"}.bi-filetype-ai::before{content:"\f73f"}.bi-filetype-bmp::before{content:"\f740"}.bi-filetype-cs::before{content:"\f741"}.bi-filetype-css::before{content:"\f742"}.bi-filetype-csv::before{content:"\f743"}.bi-filetype-doc::before{content:"\f744"}.bi-filetype-docx::before{content:"\f745"}.bi-filetype-exe::before{content:"\f746"}.bi-filetype-gif::before{content:"\f747"}.bi-filetype-heic::before{content:"\f748"}.bi-filetype-html::before{content:"\f749"}.bi-filetype-java::before{content:"\f74a"}.bi-filetype-jpg::before{content:"\f74b"}.bi-filetype-js::before{content:"\f74c"}.bi-filetype-jsx::before{content:"\f74d"}.bi-filetype-key::before{content:"\f74e"}.bi-filetype-m4p::before{content:"\f74f"}.bi-filetype-md::before{content:"\f750"}.bi-filetype-mdx::before{content:"\f751"}.bi-filetype-mov::before{content:"\f752"}.bi-filetype-mp3::before{content:"\f753"}.bi-filetype-mp4::before{content:"\f754"}.bi-filetype-otf::before{content:"\f755"}.bi-filetype-pdf::before{content:"\f756"}.bi-filetype-php::before{content:"\f757"}.bi-filetype-png::before{content:"\f758"}.bi-filetype-ppt::before{content:"\f75a"}.bi-filetype-psd::before{content:"\f75b"}.bi-filetype-py::before{content:"\f75c"}.bi-filetype-raw::before{content:"\f75d"}.bi-filetype-rb::before{content:"\f75e"}.bi-filetype-sass::before{content:"\f75f"}.bi-filetype-scss::before{content:"\f760"}.bi-filetype-sh::before{content:"\f761"}.bi-filetype-svg::before{content:"\f762"}.bi-filetype-tiff::before{content:"\f763"}.bi-filetype-tsx::before{content:"\f764"}.bi-filetype-ttf::before{content:"\f765"}.bi-filetype-txt::before{content:"\f766"}.bi-filetype-wav::before{content:"\f767"}.bi-filetype-woff::before{content:"\f768"}.bi-filetype-xls::before{content:"\f76a"}.bi-filetype-xml::before{content:"\f76b"}.bi-filetype-yml::before{content:"\f76c"}.bi-heart-arrow::before{content:"\f76d"}.bi-heart-pulse-fill::before{content:"\f76e"}.bi-heart-pulse::before{content:"\f76f"}.bi-heartbreak-fill::before{content:"\f770"}.bi-heartbreak::before{content:"\f771"}.bi-hearts::before{content:"\f772"}.bi-hospital-fill::before{content:"\f773"}.bi-hospital::before{content:"\f774"}.bi-house-heart-fill::before{content:"\f775"}.bi-house-heart::before{content:"\f776"}.bi-incognito::before{content:"\f777"}.bi-magnet-fill::before{content:"\f778"}.bi-magnet::before{content:"\f779"}.bi-person-heart::before{content:"\f77a"}.bi-person-hearts::before{content:"\f77b"}.bi-phone-flip::before{content:"\f77c"}.bi-plugin::before{content:"\f77d"}.bi-postage-fill::before{content:"\f77e"}.bi-postage-heart-fill::before{content:"\f77f"}.bi-postage-heart::before{content:"\f780"}.bi-postage::before{content:"\f781"}.bi-postcard-fill::before{content:"\f782"}.bi-postcard-heart-fill::before{content:"\f783"}.bi-postcard-heart::before{content:"\f784"}.bi-postcard::before{content:"\f785"}.bi-search-heart-fill::before{content:"\f786"}.bi-search-heart::before{content:"\f787"}.bi-sliders2-vertical::before{content:"\f788"}.bi-sliders2::before{content:"\f789"}.bi-trash3-fill::before{content:"\f78a"}.bi-trash3::before{content:"\f78b"}.bi-valentine::before{content:"\f78c"}.bi-valentine2::before{content:"\f78d"}.bi-wrench-adjustable-circle-fill::before{content:"\f78e"}.bi-wrench-adjustable-circle::before{content:"\f78f"}.bi-wrench-adjustable::before{content:"\f790"}.bi-filetype-json::before{content:"\f791"}.bi-filetype-pptx::before{content:"\f792"}.bi-filetype-xlsx::before{content:"\f793"}.bi-1-circle-fill::before{content:"\f796"}.bi-1-circle::before{content:"\f797"}.bi-1-square-fill::before{content:"\f798"}.bi-1-square::before{content:"\f799"}.bi-2-circle-fill::before{content:"\f79c"}.bi-2-circle::before{content:"\f79d"}.bi-2-square-fill::before{content:"\f79e"}.bi-2-square::before{content:"\f79f"}.bi-3-circle-fill::before{content:"\f7a2"}.bi-3-circle::before{content:"\f7a3"}.bi-3-square-fill::before{content:"\f7a4"}.bi-3-square::before{content:"\f7a5"}.bi-4-circle-fill::before{content:"\f7a8"}.bi-4-circle::before{content:"\f7a9"}.bi-4-square-fill::before{content:"\f7aa"}.bi-4-square::before{content:"\f7ab"}.bi-5-circle-fill::before{content:"\f7ae"}.bi-5-circle::before{content:"\f7af"}.bi-5-square-fill::before{content:"\f7b0"}.bi-5-square::before{content:"\f7b1"}.bi-6-circle-fill::before{content:"\f7b4"}.bi-6-circle::before{content:"\f7b5"}.bi-6-square-fill::before{content:"\f7b6"}.bi-6-square::before{content:"\f7b7"}.bi-7-circle-fill::before{content:"\f7ba"}.bi-7-circle::before{content:"\f7bb"}.bi-7-square-fill::before{content:"\f7bc"}.bi-7-square::before{content:"\f7bd"}.bi-8-circle-fill::before{content:"\f7c0"}.bi-8-circle::before{content:"\f7c1"}.bi-8-square-fill::before{content:"\f7c2"}.bi-8-square::before{content:"\f7c3"}.bi-9-circle-fill::before{content:"\f7c6"}.bi-9-circle::before{content:"\f7c7"}.bi-9-square-fill::before{content:"\f7c8"}.bi-9-square::before{content:"\f7c9"}.bi-airplane-engines-fill::before{content:"\f7ca"}.bi-airplane-engines::before{content:"\f7cb"}.bi-airplane-fill::before{content:"\f7cc"}.bi-airplane::before{content:"\f7cd"}.bi-alexa::before{content:"\f7ce"}.bi-alipay::before{content:"\f7cf"}.bi-android::before{content:"\f7d0"}.bi-android2::before{content:"\f7d1"}.bi-box-fill::before{content:"\f7d2"}.bi-box-seam-fill::before{content:"\f7d3"}.bi-browser-chrome::before{content:"\f7d4"}.bi-browser-edge::before{content:"\f7d5"}.bi-browser-firefox::before{content:"\f7d6"}.bi-browser-safari::before{content:"\f7d7"}.bi-c-circle-fill::before{content:"\f7da"}.bi-c-circle::before{content:"\f7db"}.bi-c-square-fill::before{content:"\f7dc"}.bi-c-square::before{content:"\f7dd"}.bi-capsule-pill::before{content:"\f7de"}.bi-capsule::before{content:"\f7df"}.bi-car-front-fill::before{content:"\f7e0"}.bi-car-front::before{content:"\f7e1"}.bi-cassette-fill::before{content:"\f7e2"}.bi-cassette::before{content:"\f7e3"}.bi-cc-circle-fill::before{content:"\f7e6"}.bi-cc-circle::before{content:"\f7e7"}.bi-cc-square-fill::before{content:"\f7e8"}.bi-cc-square::before{content:"\f7e9"}.bi-cup-hot-fill::before{content:"\f7ea"}.bi-cup-hot::before{content:"\f7eb"}.bi-currency-rupee::before{content:"\f7ec"}.bi-dropbox::before{content:"\f7ed"}.bi-escape::before{content:"\f7ee"}.bi-fast-forward-btn-fill::before{content:"\f7ef"}.bi-fast-forward-btn::before{content:"\f7f0"}.bi-fast-forward-circle-fill::before{content:"\f7f1"}.bi-fast-forward-circle::before{content:"\f7f2"}.bi-fast-forward-fill::before{content:"\f7f3"}.bi-fast-forward::before{content:"\f7f4"}.bi-filetype-sql::before{content:"\f7f5"}.bi-fire::before{content:"\f7f6"}.bi-google-play::before{content:"\f7f7"}.bi-h-circle-fill::before{content:"\f7fa"}.bi-h-circle::before{content:"\f7fb"}.bi-h-square-fill::before{content:"\f7fc"}.bi-h-square::before{content:"\f7fd"}.bi-indent::before{content:"\f7fe"}.bi-lungs-fill::before{content:"\f7ff"}.bi-lungs::before{content:"\f800"}.bi-microsoft-teams::before{content:"\f801"}.bi-p-circle-fill::before{content:"\f804"}.bi-p-circle::before{content:"\f805"}.bi-p-square-fill::before{content:"\f806"}.bi-p-square::before{content:"\f807"}.bi-pass-fill::before{content:"\f808"}.bi-pass::before{content:"\f809"}.bi-prescription::before{content:"\f80a"}.bi-prescription2::before{content:"\f80b"}.bi-r-circle-fill::before{content:"\f80e"}.bi-r-circle::before{content:"\f80f"}.bi-r-square-fill::before{content:"\f810"}.bi-r-square::before{content:"\f811"}.bi-repeat-1::before{content:"\f812"}.bi-repeat::before{content:"\f813"}.bi-rewind-btn-fill::before{content:"\f814"}.bi-rewind-btn::before{content:"\f815"}.bi-rewind-circle-fill::before{content:"\f816"}.bi-rewind-circle::before{content:"\f817"}.bi-rewind-fill::before{content:"\f818"}.bi-rewind::before{content:"\f819"}.bi-train-freight-front-fill::before{content:"\f81a"}.bi-train-freight-front::before{content:"\f81b"}.bi-train-front-fill::before{content:"\f81c"}.bi-train-front::before{content:"\f81d"}.bi-train-lightrail-front-fill::before{content:"\f81e"}.bi-train-lightrail-front::before{content:"\f81f"}.bi-truck-front-fill::before{content:"\f820"}.bi-truck-front::before{content:"\f821"}.bi-ubuntu::before{content:"\f822"}.bi-unindent::before{content:"\f823"}.bi-unity::before{content:"\f824"}.bi-universal-access-circle::before{content:"\f825"}.bi-universal-access::before{content:"\f826"}.bi-virus::before{content:"\f827"}.bi-virus2::before{content:"\f828"}.bi-wechat::before{content:"\f829"}.bi-yelp::before{content:"\f82a"}.bi-sign-stop-fill::before{content:"\f82b"}.bi-sign-stop-lights-fill::before{content:"\f82c"}.bi-sign-stop-lights::before{content:"\f82d"}.bi-sign-stop::before{content:"\f82e"}.bi-sign-turn-left-fill::before{content:"\f82f"}.bi-sign-turn-left::before{content:"\f830"}.bi-sign-turn-right-fill::before{content:"\f831"}.bi-sign-turn-right::before{content:"\f832"}.bi-sign-turn-slight-left-fill::before{content:"\f833"}.bi-sign-turn-slight-left::before{content:"\f834"}.bi-sign-turn-slight-right-fill::before{content:"\f835"}.bi-sign-turn-slight-right::before{content:"\f836"}.bi-sign-yield-fill::before{content:"\f837"}.bi-sign-yield::before{content:"\f838"}.bi-ev-station-fill::before{content:"\f839"}.bi-ev-station::before{content:"\f83a"}.bi-fuel-pump-diesel-fill::before{content:"\f83b"}.bi-fuel-pump-diesel::before{content:"\f83c"}.bi-fuel-pump-fill::before{content:"\f83d"}.bi-fuel-pump::before{content:"\f83e"}.bi-0-circle-fill::before{content:"\f83f"}.bi-0-circle::before{content:"\f840"}.bi-0-square-fill::before{content:"\f841"}.bi-0-square::before{content:"\f842"}.bi-rocket-fill::before{content:"\f843"}.bi-rocket-takeoff-fill::before{content:"\f844"}.bi-rocket-takeoff::before{content:"\f845"}.bi-rocket::before{content:"\f846"}.bi-stripe::before{content:"\f847"}.bi-subscript::before{content:"\f848"}.bi-superscript::before{content:"\f849"}.bi-trello::before{content:"\f84a"}.bi-envelope-at-fill::before{content:"\f84b"}.bi-envelope-at::before{content:"\f84c"}.bi-regex::before{content:"\f84d"}.bi-text-wrap::before{content:"\f84e"}.bi-sign-dead-end-fill::before{content:"\f84f"}.bi-sign-dead-end::before{content:"\f850"}.bi-sign-do-not-enter-fill::before{content:"\f851"}.bi-sign-do-not-enter::before{content:"\f852"}.bi-sign-intersection-fill::before{content:"\f853"}.bi-sign-intersection-side-fill::before{content:"\f854"}.bi-sign-intersection-side::before{content:"\f855"}.bi-sign-intersection-t-fill::before{content:"\f856"}.bi-sign-intersection-t::before{content:"\f857"}.bi-sign-intersection-y-fill::before{content:"\f858"}.bi-sign-intersection-y::before{content:"\f859"}.bi-sign-intersection::before{content:"\f85a"}.bi-sign-merge-left-fill::before{content:"\f85b"}.bi-sign-merge-left::before{content:"\f85c"}.bi-sign-merge-right-fill::before{content:"\f85d"}.bi-sign-merge-right::before{content:"\f85e"}.bi-sign-no-left-turn-fill::before{content:"\f85f"}.bi-sign-no-left-turn::before{content:"\f860"}.bi-sign-no-parking-fill::before{content:"\f861"}.bi-sign-no-parking::before{content:"\f862"}.bi-sign-no-right-turn-fill::before{content:"\f863"}.bi-sign-no-right-turn::before{content:"\f864"}.bi-sign-railroad-fill::before{content:"\f865"}.bi-sign-railroad::before{content:"\f866"}.bi-building-add::before{content:"\f867"}.bi-building-check::before{content:"\f868"}.bi-building-dash::before{content:"\f869"}.bi-building-down::before{content:"\f86a"}.bi-building-exclamation::before{content:"\f86b"}.bi-building-fill-add::before{content:"\f86c"}.bi-building-fill-check::before{content:"\f86d"}.bi-building-fill-dash::before{content:"\f86e"}.bi-building-fill-down::before{content:"\f86f"}.bi-building-fill-exclamation::before{content:"\f870"}.bi-building-fill-gear::before{content:"\f871"}.bi-building-fill-lock::before{content:"\f872"}.bi-building-fill-slash::before{content:"\f873"}.bi-building-fill-up::before{content:"\f874"}.bi-building-fill-x::before{content:"\f875"}.bi-building-fill::before{content:"\f876"}.bi-building-gear::before{content:"\f877"}.bi-building-lock::before{content:"\f878"}.bi-building-slash::before{content:"\f879"}.bi-building-up::before{content:"\f87a"}.bi-building-x::before{content:"\f87b"}.bi-buildings-fill::before{content:"\f87c"}.bi-buildings::before{content:"\f87d"}.bi-bus-front-fill::before{content:"\f87e"}.bi-bus-front::before{content:"\f87f"}.bi-ev-front-fill::before{content:"\f880"}.bi-ev-front::before{content:"\f881"}.bi-globe-americas::before{content:"\f882"}.bi-globe-asia-australia::before{content:"\f883"}.bi-globe-central-south-asia::before{content:"\f884"}.bi-globe-europe-africa::before{content:"\f885"}.bi-house-add-fill::before{content:"\f886"}.bi-house-add::before{content:"\f887"}.bi-house-check-fill::before{content:"\f888"}.bi-house-check::before{content:"\f889"}.bi-house-dash-fill::before{content:"\f88a"}.bi-house-dash::before{content:"\f88b"}.bi-house-down-fill::before{content:"\f88c"}.bi-house-down::before{content:"\f88d"}.bi-house-exclamation-fill::before{content:"\f88e"}.bi-house-exclamation::before{content:"\f88f"}.bi-house-gear-fill::before{content:"\f890"}.bi-house-gear::before{content:"\f891"}.bi-house-lock-fill::before{content:"\f892"}.bi-house-lock::before{content:"\f893"}.bi-house-slash-fill::before{content:"\f894"}.bi-house-slash::before{content:"\f895"}.bi-house-up-fill::before{content:"\f896"}.bi-house-up::before{content:"\f897"}.bi-house-x-fill::before{content:"\f898"}.bi-house-x::before{content:"\f899"}.bi-person-add::before{content:"\f89a"}.bi-person-down::before{content:"\f89b"}.bi-person-exclamation::before{content:"\f89c"}.bi-person-fill-add::before{content:"\f89d"}.bi-person-fill-check::before{content:"\f89e"}.bi-person-fill-dash::before{content:"\f89f"}.bi-person-fill-down::before{content:"\f8a0"}.bi-person-fill-exclamation::before{content:"\f8a1"}.bi-person-fill-gear::before{content:"\f8a2"}.bi-person-fill-lock::before{content:"\f8a3"}.bi-person-fill-slash::before{content:"\f8a4"}.bi-person-fill-up::before{content:"\f8a5"}.bi-person-fill-x::before{content:"\f8a6"}.bi-person-gear::before{content:"\f8a7"}.bi-person-lock::before{content:"\f8a8"}.bi-person-slash::before{content:"\f8a9"}.bi-person-up::before{content:"\f8aa"}.bi-scooter::before{content:"\f8ab"}.bi-taxi-front-fill::before{content:"\f8ac"}.bi-taxi-front::before{content:"\f8ad"}.bi-amd::before{content:"\f8ae"}.bi-database-add::before{content:"\f8af"}.bi-database-check::before{content:"\f8b0"}.bi-database-dash::before{content:"\f8b1"}.bi-database-down::before{content:"\f8b2"}.bi-database-exclamation::before{content:"\f8b3"}.bi-database-fill-add::before{content:"\f8b4"}.bi-database-fill-check::before{content:"\f8b5"}.bi-database-fill-dash::before{content:"\f8b6"}.bi-database-fill-down::before{content:"\f8b7"}.bi-database-fill-exclamation::before{content:"\f8b8"}.bi-database-fill-gear::before{content:"\f8b9"}.bi-database-fill-lock::before{content:"\f8ba"}.bi-database-fill-slash::before{content:"\f8bb"}.bi-database-fill-up::before{content:"\f8bc"}.bi-database-fill-x::before{content:"\f8bd"}.bi-database-fill::before{content:"\f8be"}.bi-database-gear::before{content:"\f8bf"}.bi-database-lock::before{content:"\f8c0"}.bi-database-slash::before{content:"\f8c1"}.bi-database-up::before{content:"\f8c2"}.bi-database-x::before{content:"\f8c3"}.bi-database::before{content:"\f8c4"}.bi-houses-fill::before{content:"\f8c5"}.bi-houses::before{content:"\f8c6"}.bi-nvidia::before{content:"\f8c7"}.bi-person-vcard-fill::before{content:"\f8c8"}.bi-person-vcard::before{content:"\f8c9"}.bi-sina-weibo::before{content:"\f8ca"}.bi-tencent-qq::before{content:"\f8cb"}.bi-wikipedia::before{content:"\f8cc"}.bi-alphabet-uppercase::before{content:"\f2a5"}.bi-alphabet::before{content:"\f68a"}.bi-amazon::before{content:"\f68d"}.bi-arrows-collapse-vertical::before{content:"\f690"}.bi-arrows-expand-vertical::before{content:"\f695"}.bi-arrows-vertical::before{content:"\f698"}.bi-arrows::before{content:"\f6a2"}.bi-ban-fill::before{content:"\f6a3"}.bi-ban::before{content:"\f6b6"}.bi-bing::before{content:"\f6c2"}.bi-cake::before{content:"\f6e0"}.bi-cake2::before{content:"\f6ed"}.bi-cookie::before{content:"\f6ee"}.bi-copy::before{content:"\f759"}.bi-crosshair::before{content:"\f769"}.bi-crosshair2::before{content:"\f794"}.bi-emoji-astonished-fill::before{content:"\f795"}.bi-emoji-astonished::before{content:"\f79a"}.bi-emoji-grimace-fill::before{content:"\f79b"}.bi-emoji-grimace::before{content:"\f7a0"}.bi-emoji-grin-fill::before{content:"\f7a1"}.bi-emoji-grin::before{content:"\f7a6"}.bi-emoji-surprise-fill::before{content:"\f7a7"}.bi-emoji-surprise::before{content:"\f7ac"}.bi-emoji-tear-fill::before{content:"\f7ad"}.bi-emoji-tear::before{content:"\f7b2"}.bi-envelope-arrow-down-fill::before{content:"\f7b3"}.bi-envelope-arrow-down::before{content:"\f7b8"}.bi-envelope-arrow-up-fill::before{content:"\f7b9"}.bi-envelope-arrow-up::before{content:"\f7be"}.bi-feather::before{content:"\f7bf"}.bi-feather2::before{content:"\f7c4"}.bi-floppy-fill::before{content:"\f7c5"}.bi-floppy::before{content:"\f7d8"}.bi-floppy2-fill::before{content:"\f7d9"}.bi-floppy2::before{content:"\f7e4"}.bi-gitlab::before{content:"\f7e5"}.bi-highlighter::before{content:"\f7f8"}.bi-marker-tip::before{content:"\f802"}.bi-nvme-fill::before{content:"\f803"}.bi-nvme::before{content:"\f80c"}.bi-opencollective::before{content:"\f80d"}.bi-pci-card-network::before{content:"\f8cd"}.bi-pci-card-sound::before{content:"\f8ce"}.bi-radar::before{content:"\f8cf"}.bi-send-arrow-down-fill::before{content:"\f8d0"}.bi-send-arrow-down::before{content:"\f8d1"}.bi-send-arrow-up-fill::before{content:"\f8d2"}.bi-send-arrow-up::before{content:"\f8d3"}.bi-sim-slash-fill::before{content:"\f8d4"}.bi-sim-slash::before{content:"\f8d5"}.bi-sourceforge::before{content:"\f8d6"}.bi-substack::before{content:"\f8d7"}.bi-threads-fill::before{content:"\f8d8"}.bi-threads::before{content:"\f8d9"}.bi-transparency::before{content:"\f8da"}.bi-twitter-x::before{content:"\f8db"}.bi-type-h4::before{content:"\f8dc"}.bi-type-h5::before{content:"\f8dd"}.bi-type-h6::before{content:"\f8de"}.bi-backpack-fill::before{content:"\f8df"}.bi-backpack::before{content:"\f8e0"}.bi-backpack2-fill::before{content:"\f8e1"}.bi-backpack2::before{content:"\f8e2"}.bi-backpack3-fill::before{content:"\f8e3"}.bi-backpack3::before{content:"\f8e4"}.bi-backpack4-fill::before{content:"\f8e5"}.bi-backpack4::before{content:"\f8e6"}.bi-brilliance::before{content:"\f8e7"}.bi-cake-fill::before{content:"\f8e8"}.bi-cake2-fill::before{content:"\f8e9"}.bi-duffle-fill::before{content:"\f8ea"}.bi-duffle::before{content:"\f8eb"}.bi-exposure::before{content:"\f8ec"}.bi-gender-neuter::before{content:"\f8ed"}.bi-highlights::before{content:"\f8ee"}.bi-luggage-fill::before{content:"\f8ef"}.bi-luggage::before{content:"\f8f0"}.bi-mailbox-flag::before{content:"\f8f1"}.bi-mailbox2-flag::before{content:"\f8f2"}.bi-noise-reduction::before{content:"\f8f3"}.bi-passport-fill::before{content:"\f8f4"}.bi-passport::before{content:"\f8f5"}.bi-person-arms-up::before{content:"\f8f6"}.bi-person-raised-hand::before{content:"\f8f7"}.bi-person-standing-dress::before{content:"\f8f8"}.bi-person-standing::before{content:"\f8f9"}.bi-person-walking::before{content:"\f8fa"}.bi-person-wheelchair::before{content:"\f8fb"}.bi-shadows::before{content:"\f8fc"}.bi-suitcase-fill::before{content:"\f8fd"}.bi-suitcase-lg-fill::before{content:"\f8fe"}.bi-suitcase-lg::before{content:"\f8ff"}.bi-suitcase::before{content:"\f900"}.bi-suitcase2-fill::before{content:"\f901"}.bi-suitcase2::before{content:"\f902"}.bi-vignette::before{content:"\f903"} \ No newline at end of file diff --git a/static/css/styles.css b/static/css/styles.css deleted file mode 100644 index 057e894..0000000 --- a/static/css/styles.css +++ /dev/null @@ -1,102 +0,0 @@ -/* Обнуляем отступы для более гибкого макета */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -/* Основные контейнеры */ -html, body { - height: 100%; - width: 100%; -} - -body { - font-family: Arial, sans-serif; - display: flex; - flex-direction: column; -} - -/* Основной контейнер, занимает весь экран */ -.container { - display: flex; - height: 100%; - width: 100%; - padding: 20px; - box-sizing: border-box; -} - -/* Контейнер для списка пользователей */ -.user-list-container { - width: 30%; /* Список пользователей занимает 30% ширины */ - display: flex; - flex-direction: column; - margin-right: 20px; -} - -/* Прокручивающийся список пользователей */ -.user-list { - flex: 1; - max-height: 100%; - overflow-y: auto; - border: 1px solid #ddd; - padding: 10px; - margin-bottom: 10px; -} - -.user-item { - margin: 10px 0; - padding: 10px; - border: 1px solid #ddd; - cursor: pointer; -} - -.user-item.selected { - background-color: #f0f0f0; -} - -/* Блок управления */ -.controls { - display: flex; - flex-direction: column; - width: 70%; /* Блок с информацией и кнопкой занимает 70% ширины */ -} - -#show-events { - margin-bottom: 20px; - padding: 10px 20px; - font-size: 16px; - cursor: pointer; -} - -#user-info { - margin-top: 10px; -} - -#events { - margin-top: 10px; - max-height: 300px; - overflow-y: auto; - border: 1px solid #ddd; - padding: 10px; -} - -#events ul { - list-style: none; - padding: 0; -} - -#events ul li { - margin-bottom: 5px; -} - -/* Контейнер для строки поиска */ -.search-container { - margin-bottom: 10px; -} - -.search-container input { - width: 100%; - padding: 8px; - box-sizing: border-box; -} \ No newline at end of file diff --git a/static/js/regions.js b/static/js/regions.js deleted file mode 100644 index 87f0350..0000000 --- a/static/js/regions.js +++ /dev/null @@ -1,575 +0,0 @@ -let currentPage = 1; -let totalPages = 1; -const perPage = 10; -let sortField = 'region_id'; -let sortOrder = 'asc'; -let currentFetchController = null; - - -// Переменные для систем -let systemsCurrentPage = 1; -let systemsTotalPages = 1; -let systemsSortField = 'system_id'; -let systemsSortOrder = 'asc'; - - -// Инициализация Toastr -toastr.options = { - "closeButton": true, - "debug": false, - "newestOnTop": false, - "progressBar": false, - "positionClass": "toast-bottom-right", - "preventDuplicates": false, - "onclick": null, - "showDuration": "300", - "hideDuration": "1000", - "timeOut": "5000", - "extendedTimeOut": "1000", - "showEasing": "swing", - "hideEasing": "linear", - "showMethod": "fadeIn", - "hideMethod": "fadeOut" -}; - -// Функция загрузки регионов -function loadRegions(page) { - if (page < 1 || page > totalPages) return; - currentPage = page; - - const url = `/telezab/rest/api/regions?page=${currentPage}&per_page=${perPage}&sort_field=${sortField}&sort_order=${sortOrder}`; - - if (currentFetchController) { - currentFetchController.abort(); - } - currentFetchController = new AbortController(); - - fetch(url, { signal: currentFetchController.signal }) - .then(response => response.json()) - .then(data => { - currentFetchController = null; - totalPages = data.total_pages; - updateRegionsTable(data.regions); - updatePagination(data.current_page, data.total_pages); - }) - .catch(error => { - if (error.name === 'AbortError') { - } else { - console.error('Error fetching regions:', error); - } - currentFetchController = null; - }); -} - -function updateRegionsTable(regions) { - const tableBody = document.getElementById('regions-table'); - if (tableBody) { - tableBody.innerHTML = ''; - - regions.forEach(region => { - const row = document.createElement('tr'); - row.innerHTML = ` - ${region.region_id} - ${region.name} - - ${region.active ? 'Включен' : 'Выключен'} - - -
-
- - -
- - - -
- - `; - tableBody.appendChild(row); - }); - - setupRegionActions(); - } else { - console.error("regions-table element not found!"); - } -} - -function setupRegionActions() { - document.querySelectorAll('th[data-sort]').forEach(th => { - th.replaceWith(th.cloneNode(true)); // Удаляем все обработчики - }); - - document.querySelectorAll('.delete-btn').forEach(button => { - button.addEventListener('click', () => deleteRegion(button.dataset.id)); - }); - document.querySelectorAll('.region-status-switch').forEach(switchElement => { - switchElement.addEventListener('change', (event) => { - const regionId = event.target.dataset.id; - const active = event.target.checked; - toggleRegionStatus(regionId, active); - document.getElementById(`region-status-label-${regionId}`).textContent = active ? 'Включен' : 'Выключен'; - }); - }); - document.querySelectorAll('.edit-name-btn').forEach(button => { - button.addEventListener('click', () => { - const regionId = button.dataset.id; - const regionName = button.dataset.name; - document.getElementById('old-region-name').value = regionName; - document.getElementById('new-region-name').value = regionName; - $('#editRegionNameModal').modal('show'); - - let timer = 5; - document.getElementById('edit-region-name-timer').textContent = timer; - const timerInterval = setInterval(() => { - timer--; - document.getElementById('edit-region-name-timer').textContent = timer; - if (timer === 0) { - clearInterval(timerInterval); - document.getElementById('save-region-name-btn').removeAttribute('disabled'); - } - }, 1000); - - document.getElementById('save-region-name-btn').addEventListener('click', () => { - const newName = document.getElementById('new-region-name').value; - updateRegionName(regionId, newName); - $('#editRegionNameModal').modal('hide'); - }, { once: true }); // Удаляем обработчик после первого клика - }); - }); - - document.querySelectorAll('.subscribers-btn').forEach(button => { - button.addEventListener('click', () => { - const regionId = button.dataset.id; - showRegionSubscribers(regionId); - }); - }); - - function showRegionSubscribers(regionId) { - fetch(`/telezab/rest/api/regions/${regionId}/subscribers`) - .then(response => { - return response.json(); - }) - .then(data => { - - - const tableBody = document.getElementById('regionSubscribersTableBody'); - tableBody.innerHTML = ''; - - if (data.subscribers && data.subscribers.length > 0) { - data.subscribers.forEach(user => { - const row = document.createElement('tr'); - row.innerHTML = ` - ${user.telegram_id} - ${user.email} - `; - tableBody.appendChild(row); - }); - } else { - const row = document.createElement('tr'); - row.innerHTML = `Нет подписчиков для этого региона.`; - tableBody.appendChild(row); - } - - $('#regionSubscribersModal').modal('show'); - }) - .catch(error => { - console.error('Ошибка при получении подписчиков региона:', error); - toastr.error('Ошибка при получении подписчиков региона. Пожалуйста, попробуйте позже.'); - }); - } - - function updateRegionName(regionId, newName) { - fetch('/telezab/rest/api/regions', { - method: 'PUT', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ region_id: regionId, name: newName }) - }) - .then(() => { - loadRegions(currentPage); - toastr.success('Название региона изменено.'); - }) - .catch(error => { - console.error('Ошибка при изменении названия региона:', error); - toastr.error('Ошибка при изменении названия региона. Пожалуйста, попробуйте позже.'); - }); - } - - document.querySelectorAll('th[data-sort]').forEach(th => { - th.addEventListener('click', () => { - const field = th.dataset.sort; - if (field === sortField) { - sortOrder = sortOrder === 'asc' ? 'desc' : 'asc'; - } else { - sortField = field; - sortOrder = 'asc'; - } - loadRegions(currentPage); - }); - }); -} - -function toggleRegionStatus(regionId, active) { - fetch('/telezab/rest/api/regions', { - method: 'PUT', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ region_id: regionId, active: active }) - }) - .then(() => { - loadRegions(currentPage); - if (active) { - toastr.success('Регион активирован.'); - } else { - toastr.success('Регион деактивирован.'); - } - }) - .catch(error => { - console.error('Ошибка при изменении статуса региона:', error); - toastr.error('Ошибка при изменении статуса региона. Пожалуйста, попробуйте позже.'); - }); -} - -function deleteRegion(regionId) { - $('#deleteRegionModal').modal('show'); // Открываем модальное окно - - $(document).ready(function() { - // Обработчик события input для текстового поля подтверждения - $('#deleteConfirmationInput').on('input', function() { - const inputValue = $(this).val(); - if (inputValue === 'УДАЛИТЬ') { - $('#confirmDeleteButton').prop('disabled', false); // Активируем кнопку "Удалить" - } else { - $('#confirmDeleteButton').prop('disabled', true); // Деактивируем кнопку "Удалить" - } - }); - - // Обработчик события click для кнопки "Удалить" - $('#confirmDeleteButton').on('click', function() { - fetch(`/telezab/rest/api/regions?region_id=${regionId}`, { method: 'DELETE' }) - .then(() => { - loadRegions(currentPage); - toastr.success('Регион успешно удален.'); - $('#deleteRegionModal').modal('hide'); // Закрываем модальное окно - }) - .catch(error => { - console.error('Ошибка при удалении региона:', error); - toastr.error('Ошибка при удалении региона. Пожалуйста, попробуйте позже.'); - }); - }); - - // Обработчик события hidden.bs.modal для модального окна - $('#deleteRegionModal').on('hidden.bs.modal', function() { - $('#deleteConfirmationInput').val(''); // Очищаем текстовое поле при закрытии модального окна - $('#confirmDeleteButton').prop('disabled', true); // Деактивируем кнопку "Удалить" - }); - }); -} - - -document.getElementById('add-region-form').addEventListener('submit', (event) => { - event.preventDefault(); - const regionId = document.getElementById('region-id').value; - const regionName = document.getElementById('region-name').value; - const regionActive = document.getElementById('region-active').checked; - - // Проверка, что все символы в regionId являются числами - if (!/^\d+$/.test(regionId)) { - toastr.error('ID региона должен содержать только числа.'); - return; // Прерываем выполнение функции - } - - fetch('/telezab/rest/api/regions', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ region_id: regionId, name: regionName, active: regionActive }) - }) - .then(response => response.json()) - .then(data => { - - - const responseData = data[0]; - const statusCode = data[1]; - - if (statusCode === 409) { - toastr.error(responseData.message); - throw new Error(responseData.message); - } else if (statusCode === 201) { - document.getElementById('region-id').value = ''; - document.getElementById('region-name').value = ''; - document.getElementById('region-active').checked = true; - loadRegions(currentPage); - toastr.success('Регион успешно добавлен.'); - $('#addRegionModal').modal('hide'); - } else { - throw new Error('Неизвестный код состояния ответа'); - } - }) - .catch(error => { - console.error('Ошибка при добавлении региона:', error); - if (error.message !== 'Регион с таким ID уже существует') { - toastr.error('Ошибка при добавлении региона. Пожалуйста, попробуйте позже.'); - } - }); -}); - -// Функция обновления пагинации -function updatePagination(currentPage, totalPages) { - const paginationContainer = document.getElementById('pagination'); - paginationContainer.innerHTML = ''; - - const prevButton = document.createElement('li'); - prevButton.classList.add('page-item'); - prevButton.classList.toggle('disabled', currentPage === 1); - prevButton.innerHTML = `«`; - paginationContainer.appendChild(prevButton); - - for (let page = 1; page <= totalPages; page++) { - const pageItem = document.createElement('li'); - pageItem.classList.add('page-item'); - pageItem.classList.toggle('active', page === currentPage); - - const pageLink = document.createElement('a'); - pageLink.classList.add('page-link'); - pageLink.href = "#"; - pageLink.textContent = page; - pageLink.onclick = () => loadRegions(page); - - pageItem.appendChild(pageLink); - paginationContainer.appendChild(pageItem); - } - - const nextButton = document.createElement('li'); - nextButton.classList.add('page-item'); - nextButton.classList.toggle('disabled', currentPage === totalPages); - nextButton.innerHTML = `»`; - paginationContainer.appendChild(nextButton); -} - -// Функция загрузки систем -function loadSystems(page) { - if (page < 1 || page > systemsTotalPages) return; - systemsCurrentPage = page; - - const url = `/telezab/rest/api/systems?page=${systemsCurrentPage}&per_page=${perPage}&sort_field=${systemsSortField}&sort_order=${systemsSortOrder}`; - - if (currentFetchController) { - currentFetchController.abort(); - } - currentFetchController = new AbortController(); - - fetch(url, { signal: currentFetchController.signal }) - .then(response => response.json()) - .then(data => { - currentFetchController = null; - systemsTotalPages = data.total_pages; - updateSystemsTable(data.systems); - updatePagination(data.current_page, data.total_pages); - }) - .catch(error => { - if (error.name === 'AbortError') { - } else { - console.error('Error fetching systems:', error); - } - currentFetchController = null; - }); -} - -// Функция обновления таблицы систем -function updateSystemsTable(systems) { - const tableBody = document.getElementById('systems-table'); - if (tableBody) { - tableBody.innerHTML = ''; - - systems.forEach(system => { - const row = document.createElement('tr'); - row.innerHTML = ` - ${system.system_id} - ${system.system_name} - ${system.name} - -
- - -
- - `; - tableBody.appendChild(row); - }); - - setupSystemActions(); - } else { - console.error("systems-table element not found!"); - } -} - -// Функция настройки действий для систем -function setupSystemActions() { - document.querySelectorAll('th[data-sort]').forEach(th => { - th.replaceWith(th.cloneNode(true)); // Удаляем все обработчики - }); - - document.querySelectorAll('.delete-btn').forEach(button => { - button.addEventListener('click', () => deleteSystem(button.dataset.id)); - }); - - document.querySelectorAll('.edit-name-btn').forEach(button => { - button.addEventListener('click', () => { - const systemId = button.dataset.id; - const systemName = button.dataset.name; - document.getElementById('old-system-name').value = systemName; - document.getElementById('new-system-name').value = systemName; - $('#editSystemNameModal').modal('show'); - - let timer = 5; - document.getElementById('edit-system-name-timer').textContent = timer; - const timerInterval = setInterval(() => { - timer--; - document.getElementById('edit-system-name-timer').textContent = timer; - if (timer === 0) { - clearInterval(timerInterval); - document.getElementById('saveSystemNameBtn').removeAttribute('disabled'); // Изменяем идентификатор - } - }, 1000); - - document.getElementById('saveSystemNameBtn').addEventListener('click', () => { // Изменяем идентификатор - const newName = document.getElementById('new-system-name').value; - updateSystemName(systemId, newName); - $('#editSystemNameModal').modal('hide'); - }, { once: true }); - }); - }); - - function updateSystemName(systemId, newName) { - fetch('/telezab/rest/api/systems', { - method: 'PUT', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ system_id: systemId, name: newName }) - }) - .then(() => { - loadSystems(systemsCurrentPage); - toastr.success('Название системы изменено.'); - }) - .catch(error => { - console.error('Ошибка при изменении названия системы:', error); - toastr.error('Ошибка при изменении названия системы. Пожалуйста, попробуйте позже.'); - }); - } - - function deleteSystem(systemId) { - $('#deleteSystemModal').modal('show'); // Открываем модальное окно - - $(document).ready(function() { - console.log(document.getElementById('deleteSystemConfirmationInput')); - // Обработчик события input для текстового поля подтверждения - $('#deleteSystemConfirmationInput').on('input', function() { - const inputValue = $(this).val(); - console.log('inputValue:', inputValue); // Логируем значение inputValue - if (inputValue === 'УДАЛИТЬ') { - $('#confirmDeleteSystemButton').prop('disabled', false); - console.log('Кнопка активирована'); // Логируем активацию кнопки - } else { - $('#confirmDeleteSystemButton').prop('disabled', true); - console.log('Кнопка деактивирована'); // Логируем деактивацию кнопки - } - }); - - // Обработчик события click для кнопки "Удалить" - $('#confirmDeleteSystemButton').on('click', function() { - fetch(`/telezab/rest/api/systems?system_id=${systemId}`, { method: 'DELETE' }) - .then(() => { - loadSystems(systemsCurrentPage); - toastr.success('Система успешно удалена.'); - $('#deleteSystemModal').modal('hide'); // Закрываем модальное окно - }) - .catch(error => { - console.error('Ошибка при удалении системы:', error); - toastr.error('Ошибка при удалении системы. Пожалуйста, попробуйте позже.'); - }); - }); - - // Обработчик события hidden.bs.modal для модального окна - $('#deleteSystemModal').on('hidden.bs.modal', function() { - $('#deleteSystemConfirmationInput').val(''); // Очищаем текстовое поле при закрытии модального окна - $('#confirmDeleteSystemButton').prop('disabled', true); // Деактивируем кнопку "Удалить" - }); - }); - } - - document.querySelectorAll('th[data-sort]').forEach(th => { - th.addEventListener('click', () => { - const field = th.dataset.sort; - if (field === systemsSortField) { - systemsSortOrder = systemsSortOrder === 'asc' ? 'desc' : 'asc'; - } else { - systemsSortField = field; - systemsSortOrder = 'asc'; - } - loadSystems(systemsCurrentPage); - }); - }); -} - -// Функция добавления системы -document.getElementById('add-system-form').addEventListener('submit', (event) => { - event.preventDefault(); - const systemId = document.getElementById('system-id').value; - const systemNameLat = document.getElementById('system-name-lat').value; - const systemNameCyr = document.getElementById('system-name-cyr').value; - - if (!/^\d+$/.test(systemId)) { - toastr.error('ID системы должен содержать только числа.'); - return; - } - - fetch('/telezab/rest/api/systems', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ system_id: systemId, system_name: systemNameLat, name: systemNameCyr }) - }) - .then(response => { - if (!response.ok) { - // Если статус ответа не OK, обрабатываем ошибку - return response.json().then(errorData => { - throw new Error(errorData.message || 'Ошибка добавления системы'); - }); - } - return response.json(); - }) - .then(data => { - // Обрабатываем успешное добавление системы - document.getElementById('system-id').value = ''; - document.getElementById('system-name-lat').value = ''; - document.getElementById('system-name-cyr').value = ''; - loadSystems(systemsCurrentPage); // Обновляем таблицу систем - toastr.success('Система успешно добавлена.'); - $('#addSystemModal').modal('hide'); - }) - .catch(error => { - // Обрабатываем ошибки - console.error('Ошибка при добавлении системы:', error); - toastr.error(error.message || 'Ошибка при добавлении системы. Пожалуйста, попробуйте позже.'); - }); -}); - - - -// Запуск загрузки данных -document.addEventListener("DOMContentLoaded", () => { - const regionsTab = document.getElementById('regions-tab'); - const systemsTab = document.getElementById('systems-tab'); - - // Обработчик для вкладки "Регионы" - regionsTab.addEventListener('shown.bs.tab', () => { - loadRegions(currentPage); - }); - - // Обработчик для вкладки "Системы" - systemsTab.addEventListener('shown.bs.tab', () => { - loadSystems(systemsCurrentPage); - }); - - // Инициализация загрузки данных для активной вкладки - if (regionsTab.classList.contains('active')) { - loadRegions(currentPage); - } -}); \ No newline at end of file diff --git a/telezab.py b/telezab.py index 829f6af..49c901e 100644 --- a/telezab.py +++ b/telezab.py @@ -1,19 +1,19 @@ -import asyncio import logging -from threading import Thread +from multiprocessing import Process import telebot from pyzabbix import ZabbixAPI from telebot import types import backend_bot import bot_database -from backend_flask import app +from app import app, create_app +from app.bot.telezab_bot import run_bot from backend_locks import bot from backend_zabbix import get_triggers_for_group, get_triggers_for_all_groups from config import * -from models import Subscriptions -from utilities.database import db +from app.models import Subscriptions +from app.extensions.db import db from utilities.log_manager import LogManager -from utilities.rabbitmq import consume_from_queue +# from utilities.rabbitmq import consume_from_queue from utilities.telegram_utilities import show_main_menu, show_settings_menu from utilities.user_state_manager import UserStateManager @@ -22,13 +22,13 @@ from utilities.user_state_manager import UserStateManager state = UserStateManager() # Инициализация LogManager -log_manager = LogManager(log_dir='logs', retention_days=30) +log_manager = LogManager() # Настройка pyTelegramBotAPI logger telebot.logger = logging.getLogger('telebot') # Важно: вызов schedule_log_rotation для планировки ротации и архивации логов -log_manager.schedule_log_rotation() +# log_manager.schedule_log_rotation() # Handle /help command to provide instructions @bot.message_handler(commands=['help']) @@ -64,49 +64,6 @@ def handle_register(message): backend_bot.bot.send_message(chat_id, text, parse_mode="HTML") bot_database.log_user_event(chat_id, username, "Requested registration") -# Handle /start command -@bot.message_handler(commands=['start']) -def handle_start(message): - chat_id = message.chat.id - if bot_database.is_whitelisted(chat_id)[0]: - show_main_menu(chat_id) - else: - # Отображаем только кнопку "Регистрация" - markup = types.ReplyKeyboardMarkup(resize_keyboard=True, row_width=1) - item = types.KeyboardButton("Регистрация") - markup.add(item) - backend_bot.bot.send_message(chat_id, "Пожалуйста, зарегистрируйтесь для использования бота.", reply_markup=markup) - state.set_state(chat_id, "REGISTRATION") - -# Основной обработчик меню -@bot.message_handler(func=lambda message: True) -def handle_menu_selection(message): - chat_id = message.chat.id - text = message.text.strip() - username = message.from_user.username - - # Проверка авторизации - if not bot_database.is_whitelisted(chat_id)[0] and text != 'Регистрация': - backend_bot.bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.") - return - - # Получаем текущее состояние пользователя - current_state = state.get_state(chat_id) - - # Обработка команд в зависимости от состояния - if current_state == "MAIN_MENU": - backend_bot.handle_main_menu(message, chat_id, text) - elif current_state == "REGISTRATION": - handle_register(message) - elif current_state == "SETTINGS_MENU": - backend_bot.handle_settings_menu(message, chat_id, text) - elif current_state == "SUBSCRIBE": - backend_bot.process_subscription_button(message, chat_id, username) - elif current_state == "UNSUBSCRIBE": - backend_bot.process_unsubscription_button(message, chat_id, username) - else: - backend_bot.bot.send_message(chat_id, "Команда не распознана.") - show_main_menu(chat_id) @bot.callback_query_handler(func=lambda call: call.data == "cancel_action") @@ -195,13 +152,22 @@ def create_region_keyboard(regions, start_index, regions_per_page=10): markup = types.InlineKeyboardMarkup() end_index = min(start_index + regions_per_page, len(regions)) - # Создаём кнопки для регионов for i in range(start_index, end_index): region_id, region_name = regions[i] - button = types.InlineKeyboardButton(text=f"{region_id}: {region_name}", callback_data=f"region_{region_id}") + + # Форматируем region_id: добавляем ведущий 0 только если < 10 + if 0 <= int(region_id) < 10: + region_id_str = f"0{region_id}" + else: + region_id_str = str(region_id) + + button = types.InlineKeyboardButton( + text=f"{region_id_str}: {region_name}", + callback_data=f"region_{region_id_str}" + ) markup.add(button) - # Добавляем кнопки для переключения страниц + # Кнопки навигации navigation_row = [] if start_index > 0: navigation_row.append(types.InlineKeyboardButton(text="<", callback_data=f"prev_{start_index}")) @@ -210,7 +176,10 @@ def create_region_keyboard(regions, start_index, regions_per_page=10): if navigation_row: markup.row(*navigation_row) + + # Кнопка отмены markup.row(types.InlineKeyboardButton(text='Отмена', callback_data='cancel_active_triggers')) + return markup @@ -228,6 +197,7 @@ def handle_region_pagination(call): # Если был выбран регион, то убираем клавиатуру и продолжаем выполнение функции if data.startswith("region_"): region_id = data.split("_")[1] + telebot.logger.debug(region_id) bot.edit_message_reply_markup(chat_id=chat_id, message_id=message_id, reply_markup=None) handle_region_selection(call, region_id) # Продолжаем выполнение функции после выбора региона @@ -250,7 +220,7 @@ def handle_region_pagination(call): # Фаза 2: Обработка выбора региона и предложить выбор группы def handle_region_selection(call, region_id): chat_id = call.message.chat.id - + telebot.logger.debug(f"{type(region_id)}, {region_id}, {call.data}") try: # Получаем группы хостов для выбранного региона zapi = ZabbixAPI(ZABBIX_URL) @@ -260,6 +230,7 @@ def handle_region_selection(call, region_id): filtered_groups = [group for group in host_groups if 'test' not in group['name'].lower() and f'_{region_id}' in group['name']] + # Если нет групп if not filtered_groups: backend_bot.bot.send_message(chat_id, "Нет групп хостов для этого региона.") @@ -302,27 +273,38 @@ def handle_group_or_all_groups(call): show_main_menu(chat_id) -def run_polling(): - bot.infinity_polling(timeout=10, long_polling_timeout=5) +# def run_polling(): +# bot.infinity_polling(timeout=10, long_polling_timeout=5) # Запуск Flask-приложения -def run_flask(): - app.run(port=5000, host='0.0.0.0', debug=True, use_reloader=False) +# def run_flask(): +# app.run(port=5000, host='0.0.0.0', debug=True, use_reloader=False) -# Основная функция для запуска -def main(): - # Инициализация базы данных - # bot_database.init_db() - # Запуск Flask и бота в отдельных потоках +# # Основная функция для запуска +# def main(): +# # Инициализация базы данных +# # bot_database.init_db() +# # Запуск Flask и бота в отдельных потоках +# +# Thread(target=run_flask, daemon=True).start() +# Thread(target=run_polling, daemon=True).start() +# # Запуск асинхронных задач +# +# asyncio.run(consume_from_queue()) - Thread(target=run_flask, daemon=True).start() - Thread(target=run_polling, daemon=True).start() - # Запуск асинхронных задач - - asyncio.run(consume_from_queue()) +def start_flask(): + app = create_app() + app.run(host="0.0.0.0", port=5000) if __name__ == '__main__': - main() + flask_process = Process(target=start_flask) + bot_process = Process(target=run_bot) + + flask_process.start() + bot_process.start() + + flask_process.join() + bot_process.join() diff --git a/templates/dashboard.html b/templates/dashboard.html deleted file mode 100644 index 95cdcbb..0000000 --- a/templates/dashboard.html +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - Dashboard - - - -
-

Панель управления

- -

Пользователи

- - - - - - - - - - - - - -
IDИмяEmailПодпискиРежим
- - - -
- - - -{##} - - - diff --git a/templates/login.html b/templates/login.html deleted file mode 100644 index e9dbfb2..0000000 --- a/templates/login.html +++ /dev/null @@ -1,21 +0,0 @@ -{% extends "base.html" %} - -{% block content %} -
-
-

Login

-
-
- - -
-
- - -
- -
-
-
-{% endblock %} - diff --git a/templates/logs.html b/templates/logs.html deleted file mode 100644 index 8c2335c..0000000 --- a/templates/logs.html +++ /dev/null @@ -1,10 +0,0 @@ - -{% extends "base.html" %} -{% block title %}Логи{% endblock %} -{% block content %} -

Логи

-

-{% endblock %}
-{% block scripts %}
-    
-{% endblock %}
\ No newline at end of file
diff --git a/templates/users_old.html b/templates/users_old.html
deleted file mode 100644
index 601bd1d..0000000
--- a/templates/users_old.html
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-    
-    
-    Сотрудники
-    
-    
-    
-    
-    
-
-
-    
-
-
-
    - -
-
-
-
-

-
Подписки на регионы
-
    - -
-
Действия
-
- -
-
-
-
-
- - diff --git a/utilities/database.py b/utilities/database.py deleted file mode 100644 index 4c14ad6..0000000 --- a/utilities/database.py +++ /dev/null @@ -1,3 +0,0 @@ -from flask_sqlalchemy import SQLAlchemy - -db = SQLAlchemy() # Создаем экземпляр SQLAlchemy \ No newline at end of file diff --git a/utilities/events_manager.py b/utilities/events_manager.py deleted file mode 100644 index d2a8863..0000000 --- a/utilities/events_manager.py +++ /dev/null @@ -1,34 +0,0 @@ -from datetime import datetime, UTC - -from flask import jsonify - -from models import UserEvents - - -class EventManager: - def __init__(self, db): - self.db = db - - def get_user_events(self, chat_id): - """Режим GET: возвращает список действий пользователя.""" - events = UserEvents.query.filter_by(chat_id=chat_id).order_by(UserEvents.timestamp.desc()).all() - return [{'action': event.action, 'timestamp': event.timestamp.isoformat()} for event in events] - - def log_user_action(self, chat_id, action): - """Режим WRITE: сохраняет действие пользователя.""" - event = UserEvents(chat_id=chat_id, action=action, timestamp=datetime.now(UTC)) - self.db.session.add(event) - self.db.session.commit() - - def handle_request(self, chat_id, request_type, action=None): - """Обрабатывает запросы в режимах GET и WRITE.""" - if request_type == 'GET': - return jsonify({'events': self.get_user_events(chat_id)}) - elif request_type == 'WRITE': - if action: - self.log_user_action(chat_id, action) - return jsonify({'message': 'Действие сохранено'}), 200 - else: - return jsonify({'error': 'Не указано действие'}), 400 - else: - return jsonify({'error': 'Неверный тип запроса'}), 400 \ No newline at end of file diff --git a/utilities/log_manager.py b/utilities/log_manager.py index a381064..e68594f 100644 --- a/utilities/log_manager.py +++ b/utilities/log_manager.py @@ -1,15 +1,12 @@ import logging -import os -import zipfile -from datetime import datetime, timedelta +import sys from logging.config import dictConfig -from logging.handlers import TimedRotatingFileHandler class UTF8StreamHandler(logging.StreamHandler): def __init__(self, stream=None): - super().__init__(stream) - self.setStream(stream) + super().__init__(stream or sys.stdout) + self.setStream(stream or sys.stdout) def setStream(self, stream): super().setStream(stream) @@ -24,24 +21,7 @@ class FilterByMessage(logging.Filter): class LogManager: - def __init__(self, log_dir='logs', retention_days=30): - self.log_dir = log_dir - self.retention_days = retention_days - self.log_files = { - 'flask': os.path.join(self.log_dir, 'flask.log'), - 'flask_error': os.path.join(self.log_dir, 'flask_error.log'), - 'app': os.path.join(self.log_dir, 'app.log'), - 'app_error': os.path.join(self.log_dir, 'app_error.log'), - 'zabbix': os.path.join(self.log_dir, 'zabbix.log'), - 'zabbix_error': os.path.join(self.log_dir, 'zabbix_error.log'), - 'debug': os.path.join(self.log_dir, 'debug.log'), - } - - # Ensure the log directory exists - if not os.path.exists(self.log_dir): - os.makedirs(self.log_dir) - - # Setup logging configuration + def __init__(self): self.setup_logging() def setup_logging(self): @@ -52,12 +32,6 @@ class LogManager: 'default': { 'format': '[%(asctime)s] %(levelname)s %(module)s: %(message)s', }, - 'error': { - 'format': '[%(asctime)s] %(levelname)s %(module)s: %(message)s', - }, - 'werkzeug': { - 'format': '[%(asctime)s] %(levelname)s %(message)s' - }, 'debug': { 'format': '[%(asctime)s] %(levelname)s %(module)s [%(funcName)s:%(lineno)d]: %(message)s' } @@ -68,112 +42,71 @@ class LogManager: } }, 'handlers': { - 'telebot_console': { - 'class': 'utilities.log_manager.UTF8StreamHandler', + 'console': { + '()': UTF8StreamHandler, 'stream': 'ext://sys.stdout', 'formatter': 'default', 'filters': ['filter_by_message'], }, - 'flask_console': { - 'class': 'utilities.log_manager.UTF8StreamHandler', - 'stream': 'ext://sys.stdout', - 'formatter': 'werkzeug', - }, - 'flask_file': { - 'class': 'logging.handlers.TimedRotatingFileHandler', - 'filename': self.log_files['flask'], - 'when': 'midnight', - 'backupCount': self.retention_days, - 'formatter': 'werkzeug', - 'encoding': 'utf-8', - }, - 'flask_error_file': { - 'class': 'logging.handlers.TimedRotatingFileHandler', - 'filename': self.log_files['flask_error'], - 'when': 'midnight', - 'backupCount': self.retention_days, - 'formatter': 'werkzeug', - 'encoding': 'utf-8', - 'level': 'ERROR', - }, - 'app_file': { - 'class': 'logging.handlers.TimedRotatingFileHandler', - 'filename': self.log_files['app'], - 'when': 'midnight', - 'backupCount': self.retention_days, - 'formatter': 'default', - 'encoding': 'utf-8', - }, - 'app_error_file': { - 'class': 'logging.handlers.TimedRotatingFileHandler', - 'filename': self.log_files['app_error'], - 'when': 'midnight', - 'backupCount': self.retention_days, - 'formatter': 'error', - 'encoding': 'utf-8', - 'level': 'ERROR', - }, - 'zabbix_file': { - 'class': 'logging.handlers.TimedRotatingFileHandler', - 'filename': self.log_files['zabbix'], - 'when': 'midnight', - 'backupCount': self.retention_days, - 'formatter': 'default', - 'encoding': 'utf-8', - }, - 'zabbix_error_file': { - 'class': 'logging.handlers.TimedRotatingFileHandler', - 'filename': self.log_files['zabbix_error'], - 'when': 'midnight', - 'backupCount': self.retention_days, - 'formatter': 'error', - 'encoding': 'utf-8', - 'level': 'ERROR', - }, - 'debug_file': { - 'class': 'logging.handlers.TimedRotatingFileHandler', - 'filename': self.log_files['debug'], - 'when': 'midnight', - 'backupCount': self.retention_days, - 'formatter': 'debug', - 'encoding': 'utf-8', - 'level': 'DEBUG', - }, + }, + 'root': { + 'level': 'WARNING', + 'handlers': ['console'] }, 'loggers': { 'flask': { 'level': 'DEBUG', - 'handlers': ['flask_file', 'flask_error_file', 'flask_console'], + 'handlers': ['console'], 'propagate': False, }, 'telebot': { - 'level': 'DEBUG', - 'handlers': ['app_file', 'app_error_file', 'telebot_console'], + 'level': 'INFO', + 'handlers': ['console'], 'propagate': False, }, 'werkzeug': { 'level': 'DEBUG', - 'handlers': ['flask_file', 'flask_error_file', 'flask_console'], + 'handlers': ['console'], 'propagate': False, }, 'flask_ldap3_login': { 'level': 'DEBUG', - 'handlers': ['flask_file', 'flask_error_file', 'flask_console'], + 'handlers': ['console'], 'propagate': False, }, 'flask_login': { 'level': 'DEBUG', - 'handlers': ['flask_file', 'flask_error_file', 'flask_console'], + 'handlers': ['console'], 'propagate': False, }, 'pyzabbix': { - 'level': 'ERROR', - 'handlers': ['zabbix_file', 'zabbix_error_file', 'flask_console'], + 'level': 'DEBUG', + 'handlers': ['console'], + 'propagate': False, + }, + 'app': { + 'level': 'DEBUG', + 'handlers': ['console'], + 'propagate': False, + }, + 'pika': { + 'level': 'INFO', + 'handlers': ['console'], + 'propagate': False, + }, + 'users_service': { + 'level': 'DEBUG', + 'handlers': ['console'], + 'propagate': False, + }, + 'regions_service': { + 'level': 'DEBUG', + 'handlers': ['console'], 'propagate': False, }, 'debug': { 'level': 'DEBUG', - 'handlers': ['debug_file'], + 'handlers': ['console'], 'propagate': False, }, } @@ -198,72 +131,3 @@ class LogManager: def get_all_loggers(self): """Returns a list of all configured loggers.""" return list(logging.Logger.manager.loggerDict.keys()) - - def archive_old_logs(self): - """Archives old log files and removes logs older than retention_days.""" - yesterday_date = (datetime.now() - timedelta(days=1)).strftime('%Y-%m-%d') - - for log_name, log_file in self.log_files.items(): - if os.path.exists(log_file): - # Get the logger and its handlers - logger = logging.getLogger(log_name if log_name in logging.Logger.manager.loggerDict else 'telebot' if log_name in ['app', 'app_error'] else 'flask') - handlers = logger.handlers[:] # Create a copy to avoid modification during iteration - - # Close and remove the file handler - for handler in handlers: - if isinstance(handler, TimedRotatingFileHandler) and handler.baseFilename == log_file: - handler.close() - logger.removeHandler(handler) - - archive_name = f"{log_name}_{yesterday_date}.zip" - archive_path = os.path.join(self.log_dir, archive_name) - - # Archive the log file - with zipfile.ZipFile(archive_path, 'w', zipfile.ZIP_DEFLATED) as zipf: - zipf.write(log_file, arcname=os.path.basename(log_file)) - - # Remove the old log file after archiving - os.remove(log_file) - - # Clean up old archives - self.cleanup_old_archives() - - def configure_werkzeug_logging(self): - """Отключаем встроенный логгер Werkzeug и задаём собственные настройки логирования.""" - werkzeug_logger = logging.getLogger('werkzeug') - werkzeug_logger.handlers = [] # Удаляем существующие обработчики - - # Добавляем кастомный обработчик для форматирования логов - handler = TimedRotatingFileHandler(self.log_files['flask'], when='midnight', backupCount=self.retention_days, - encoding='utf-8') - handler.setFormatter(logging.Formatter('[%(asctime)s] %(levelname)s %(message)s')) - werkzeug_logger.addHandler(handler) - - # Отключаем дублирование логов - werkzeug_logger.propagate = False - - def cleanup_old_archives(self): - """Deletes archived logs older than retention_days.""" - now = datetime.now() - cutoff = now - timedelta(days=self.retention_days) - - for file in os.listdir(self.log_dir): - if file.endswith('.zip'): - file_path = os.path.join(self.log_dir, file) - file_time = datetime.fromtimestamp(os.path.getmtime(file_path)) - if file_time < cutoff: - os.remove(file_path) - - def schedule_log_rotation(self): - """Schedules daily log rotation and archiving.""" - from threading import Timer - now = datetime.now() - next_midnight = now.replace(hour=0, minute=0, second=0, microsecond=0) + timedelta(days=1) - delay = (next_midnight - now).total_seconds() - - Timer(delay, self.rotate_and_archive_logs).start() - - def rotate_and_archive_logs(self): - """Rotates and archives logs.""" - self.archive_old_logs() - self.schedule_log_rotation() # Schedule the next rotation \ No newline at end of file diff --git a/utilities/log_user_action.py b/utilities/log_user_action.py deleted file mode 100644 index 1559bff..0000000 --- a/utilities/log_user_action.py +++ /dev/null @@ -1,34 +0,0 @@ -from flask import session, request -from your_app import db # Импортируйте ваш экземпляр SQLAlchemy -from your_app.models import AuditLog # Импортируйте вашу модель AuditLog -from datetime import datetime - -def log_user_action(action_type, description, result=None, details=None): - """Записывает действие пользователя в таблицу audit_log.""" - user_id = None - user_name = None - user_surname = None - user_middle_name = None - - if 'username' in session: - user_id = session.get('username') # Используем username как user_id (логин) - user_name = session.get('user_name') - user_surname = session.get('user_surname') - user_middle_name = session.get('user_middle_name') - - ip_address = request.remote_addr - - log_entry = AuditLog( - timestamp=datetime.now(), - user_id=user_id, - user_name=user_name if user_name else '', - user_surname=user_surname if user_surname else '', - user_middle_name=user_middle_name if user_middle_name else '', - ip_address=ip_address, - action_type=action_type, - description=description, - result=result, - details=details - ) - db.session.add(log_entry) - db.session.commit() \ No newline at end of file diff --git a/utilities/notification_manager.py b/utilities/notification_manager.py index 29d08c2..019be35 100644 --- a/utilities/notification_manager.py +++ b/utilities/notification_manager.py @@ -1,6 +1,7 @@ from utilities.rabbitmq import send_to_queue -from models import Users, Regions, Subscriptions -from utilities.database import db +from app.models import Regions, Subscriptions +from app.models import Users +from app.extensions.db import db class NotificationManager: def __init__(self, logger): @@ -14,7 +15,7 @@ class NotificationManager: if severity != 'Disaster': query = query.filter(Subscriptions.disaster_only == False) - self.logger.debug(f"Выполнение запроса: {query} для region_id={region_id}") + self.logger.debug(f"Выполнение запроса: {query} для региона {region_id}") results = query.all() self.logger.debug(f"Найдено подписчиков: {len(results)} для региона {region_id}") return results @@ -29,13 +30,13 @@ class NotificationManager: user = Users.query.get(chat_id) if user and not user.is_blocked: formatted_message = message.replace('\n', ' ').replace('\r', '') - self.logger.info(f"Формирование сообщения для пользователя {username} (chat_id={chat_id}) [{formatted_message}]") + self.logger.info(f"Формирование сообщения для пользователя {username} ({chat_id}) [{formatted_message}]") try: send_to_queue({'chat_id': chat_id, 'username': username, 'message': message}) - self.logger.debug(f"Сообщение поставлено в очередь для {chat_id} (@{username})") + self.logger.debug(f"Сообщение поставлено в очередь для {username} ({chat_id})") except Exception as e: - self.logger.error(f"Ошибка при отправке сообщения для {chat_id} (@{username}): {e}") + self.logger.error(f"Ошибка при отправке сообщения для {username} ({chat_id})): {e}") undelivered = True else: - self.logger.warning(f"Пользователь {username} (chat_id={chat_id}) заблокирован или не найден. Уведомление не отправлено.") + self.logger.warning(f"Пользователь {username} ({chat_id}) заблокирован или не найден. Уведомление не отправлено.") return undelivered \ No newline at end of file diff --git a/utilities/rabbitmq.py b/utilities/rabbitmq.py index 6951089..1150c71 100644 --- a/utilities/rabbitmq.py +++ b/utilities/rabbitmq.py @@ -1,11 +1,14 @@ import asyncio import json +from flask import current_app +from app.models.users import Users import aio_pika import telebot import pika import backend_bot + from config import RABBITMQ_LOGIN, RABBITMQ_PASS, RABBITMQ_HOST, RABBITMQ_QUEUE, RABBITMQ_URL_FULL # Semaphore for rate limiting @@ -61,21 +64,56 @@ async def consume_from_queue(): finally: await asyncio.sleep(5) +# async def send_message(chat_id, message, is_notification=False): +# try: +# if is_notification: +# await rate_limit_semaphore.acquire() +# await asyncio.to_thread(backend_bot.bot.send_message, chat_id, message, parse_mode='HTML') +# formatted_message = message.replace('\n', ' ').replace('\r', '') # Добавляем форматирование сообщения +# telebot.logger.info(f'Send notification to {chat_id} from RabbitMQ [{formatted_message}]') # Добавляем логирование +# except telebot.apihelper.ApiTelegramException as e: +# if "429" in str(e): +# await asyncio.sleep(1) +# await send_message(chat_id, message, is_notification) +# else: +# telebot.logger.error(f"Failed to send message: {e}") +# except Exception as e: +# telebot.logger.error(f"Unexpected error: {e}") +# finally: +# if is_notification: +# rate_limit_semaphore.release() + async def send_message(chat_id, message, is_notification=False): + telegram_id = "unknown" try: if is_notification: await rate_limit_semaphore.acquire() + + # Получение telegram_id через app_context + def get_user(): + with current_app.app_context(): + user = Users.query.get(chat_id) + return user.telegram_id if user else "unknown" + + telegram_id = await asyncio.to_thread(get_user) + + # Отправка сообщения await asyncio.to_thread(backend_bot.bot.send_message, chat_id, message, parse_mode='HTML') - formatted_message = message.replace('\n', ' ').replace('\r', '') # Добавляем форматирование сообщения - telebot.logger.info(f'Send notification to {chat_id} from RabbitMQ [{formatted_message}]') # Добавляем логирование + + # Форматирование и лог + formatted_message = message.replace('\n', ' ').replace('\r', '') + telebot.logger.info(f'Send notification to {telegram_id} ({chat_id}) from RabbitMQ [{formatted_message}]') + + + except telebot.apihelper.ApiTelegramException as e: if "429" in str(e): await asyncio.sleep(1) await send_message(chat_id, message, is_notification) else: - telebot.logger.error(f"Failed to send message: {e}") + telebot.logger.error(f"Failed to send message to {telegram_id} ({chat_id}): {e}") except Exception as e: - telebot.logger.error(f"Unexpected error: {e}") + telebot.logger.error(f"Unexpected error sending message to {telegram_id} ({chat_id}): {e}") finally: if is_notification: rate_limit_semaphore.release() diff --git a/utilities/region_manager.py b/utilities/region_manager.py deleted file mode 100644 index 93c8129..0000000 --- a/utilities/region_manager.py +++ /dev/null @@ -1,156 +0,0 @@ -import backend_flask as bf -from models import Regions, Users, Subscriptions -from utilities.database import db -from sqlalchemy import asc, desc - -class RegionManager: - def __init__(self): - self.db = db - - def get_regions(self, page=1, per_page=10, sort_field='region_id', sort_order='asc'): - bf.app.logger.info(f"Получение регионов: page={page}, per_page={per_page}, sort_field={sort_field}, sort_order={sort_order}") - - # Определение порядка сортировки - sort_func = asc if sort_order == 'asc' else desc - - # Получение атрибута модели для сортировки - if sort_field: - sort_attr = getattr(Regions, sort_field, Regions.region_id) # По умолчанию сортируем по region_id - else: - sort_attr = Regions.region_id - - # Запрос к базе данных с учетом сортировки и пагинации - if sort_field == 'region_id': - regions_query = Regions.query.order_by(sort_func(Regions.region_id.cast(db.Integer))).paginate(page=page, per_page=per_page, error_out=False) - elif sort_field == 'name': - regions_query = Regions.query.order_by(sort_func(Regions.region_name)).paginate(page=page, per_page=per_page, error_out=False) - else: - regions_query = Regions.query.order_by(sort_func(sort_attr)).paginate(page=page, per_page=per_page, error_out=False) - - regions_list = [{ - 'region_id': r.region_id, - 'name': r.region_name, - 'active': r.active - } for r in regions_query.items] - - bf.app.logger.info(f"Получены регионы: {len(regions_list)} элементов") - - return { - 'regions': regions_list, - 'total_regions': regions_query.total, - 'total_pages': regions_query.pages, - 'current_page': regions_query.page, - 'per_page': regions_query.per_page - } - - def get_region_subscribers(self, region_id): - bf.app.logger.info(f"Получение подписчиков региона: region_id={region_id}") - - try: - region = Regions.query.get(region_id) - if not region: - bf.app.logger.warning(f"Регион с ID {region_id} не найден") - return {'status': 'error', 'message': 'Регион не найден'}, 404 - - subscribers = self.db.session.query(Users).join(Subscriptions).filter(Subscriptions.region_id == region_id).all() - - subscribers_list = [{ - 'chat_id': user.chat_id, - 'telegram_id': user.telegram_id, - 'email': user.user_email - } for user in subscribers] - - bf.app.logger.info(f"Получены подписчики региона {region_id}: {len(subscribers_list)} элементов") - - return {'status': 'success', 'subscribers': subscribers_list}, 200 - except Exception as e: - bf.app.logger.error(f"Ошибка при получении подписчиков региона: {e}") - return {'status': 'error', 'message': str(e)}, 500 - - def add_region(self, data): - region_id = data.get('region_id') - name = data.get('name') - active = data.get('active', True) - - bf.app.logger.info(f"Добавление региона: region_id={region_id}, name={name}, active={active}") - - try: - # Проверка, что все символы в region_id являются числами - if not region_id.isdigit(): - bf.app.logger.warning(f"ID региона {region_id} содержит нечисловые символы") - return {'status': 'error', 'message': 'ID региона должен содержать только числа.'}, 400 # Возвращаем код 400 Bad Request - - existing_region = Regions.query.get(region_id) - if existing_region: - bf.app.logger.warning(f"Регион с ID {region_id} уже существует") - return {'status': 'error', 'message': 'Регион с таким ID уже существует'}, 409 - - region = Regions(region_id=region_id, region_name=name, active=active) - self.db.session.add(region) - self.db.session.commit() - bf.app.logger.info(f"Регион {region_id} успешно добавлен") - return {'status': 'success', 'message': 'Регион добавлен'}, 201 - except Exception as e: - self.db.session.rollback() - bf.app.logger.error(f"Ошибка при добавлении региона: {e}") - return {'status': 'error', 'message': str(e)}, 500 - - def update_region_status(self, data): - region_id = data.get('region_id') - active = data.get('active') - - bf.app.logger.info(f"Изменение статуса региона: region_id={region_id}, active={active}") - - try: - region = Regions.query.get(region_id) - if region: - region.active = active - self.db.session.commit() - bf.app.logger.info(f"Статус региона {region_id} изменен на {active}") - return {'status': 'success', 'message': 'Статус региона изменен'}, 200 - else: - bf.app.logger.warning(f"Регион с ID {region_id} не найден") - return {'status': 'error', 'message': 'Регион не найден'}, 404 - except Exception as e: - self.db.session.rollback() - bf.app.logger.error(f"Ошибка при изменении статуса региона: {e}") - return {'status': 'error', 'message': str(e)}, 500 - - def update_region_name(self, data): - region_id = data.get('region_id') - name = data.get('name') - - bf.app.logger.info(f"Изменение названия региона: region_id={region_id}, name={name}") - - try: - region = Regions.query.get(region_id) - if region: - region.region_name = name - self.db.session.commit() - bf.app.logger.info(f"Название региона {region_id} изменено на {name}") - return {'status': 'success', 'message': 'Название региона изменено'}, 200 - else: - bf.app.logger.warning(f"Попытка изменить название несуществующего региона с ID {region_id}") - return {'status': 'error', 'message': 'Регион не найден'}, 404 - except Exception as e: - self.db.session.rollback() - bf.app.logger.error(f"Ошибка при изменении названия региона: {e}") - return {'status': 'error', 'message': str(e)}, 500 - - def delete_region(self, region_id): - bf.app.logger.info(f"Удаление региона: region_id={region_id}") - - try: - region = Regions.query.get(region_id) - if region: - self.db.session.delete(region) - self.db.session.commit() - bf.app.logger.info(f"Регион {region_id} успешно удален") - return {'status': 'success', 'message': 'Регион удален'}, 200 - else: - bf.app.logger.warning(f"Регион с ID {region_id} не найден") - return {'status': 'error', 'message': 'Регион не найден'}, 404 - except Exception as e: - self.db.session.rollback() - bf.app.logger.error(f"Ошибка при удалении региона: {e}") - return {'status': 'error', 'message': str(e)}, 500 \ No newline at end of file diff --git a/utilities/system_manager.py b/utilities/system_manager.py deleted file mode 100644 index 824830d..0000000 --- a/utilities/system_manager.py +++ /dev/null @@ -1,113 +0,0 @@ -import backend_flask as bf -from models import Systems -from utilities.database import db -from sqlalchemy import asc, desc - -class SystemManager: - def __init__(self): - self.db = db - - def get_systems(self, page=1, per_page=10, sort_field='system_id', sort_order='asc'): - bf.app.logger.info(f"Получение систем: page={page}, per_page={per_page}, sort_field={sort_field}, sort_order={sort_order}") - - # Определение порядка сортировки - sort_func = asc if sort_order == 'asc' else desc - - # Получение атрибута модели для сортировки - if sort_field: - sort_attr = getattr(Systems, sort_field, Systems.system_id) # По умолчанию сортируем по system_id - else: - sort_attr = Systems.system_id - - # Запрос к базе данных с учетом сортировки и пагинации - if sort_field == 'system_id': - systems_query = Systems.query.order_by(sort_func(Systems.system_id.cast(db.Integer))).paginate(page=page, per_page=per_page, error_out=False) - elif sort_field == 'name': - systems_query = Systems.query.order_by(sort_func(Systems.name)).paginate(page=page, per_page=per_page, error_out=False) - else: - systems_query = Systems.query.order_by(sort_func(sort_attr)).paginate(page=page, per_page=per_page, error_out=False) - - systems_list = [{ - 'system_id': s.system_id, - 'system_name': s.system_name, - 'name': s.name, - } for s in systems_query.items] - - bf.app.logger.info(f"Получены системы: {len(systems_list)} элементов") - - return { - 'systems': systems_list, - 'total_systems': systems_query.total, - 'total_pages': systems_query.pages, - 'current_page': systems_query.page, - 'per_page': systems_query.per_page - } - - def add_system(self, data): - system_id = data.get('system_id') - system_name = data.get('system_name') - name = data.get('name') - - bf.app.logger.info(f"Добавление системы: system_id={system_id}, system_name={system_name}, name={name}") - - try: - # Проверка, что все символы в system_id являются числами - if not system_id.isdigit(): - bf.app.logger.warning(f"ID системы {system_id} содержит нечисловые символы") - return {'status': 'error', 'message': 'ID системы должен содержать только числа.'}, 400 # Возвращаем код 400 Bad Request - - existing_system = Systems.query.get(system_id) - if existing_system: - bf.app.logger.warning(f"Система с ID {system_id} уже существует") - return {'status': 'error', 'message': 'Система с таким ID уже существует'}, 409 - - system = Systems(system_id=system_id, system_name=system_name, name=name) - self.db.session.add(system) - self.db.session.commit() - bf.app.logger.info(f"Система {system_id} {system_name} {name} успешно добавлена") - return {'status': 'success', 'message': 'Система добавлена'}, 201 - except Exception as e: - self.db.session.rollback() - bf.app.logger.error(f"Ошибка при добавлении системы: {e}") - return {'status': 'error', 'message': str(e)}, 500 - - def update_system_name(self, data): - system_id = data.get('system_id') - system_name = data.get('system_name') - name = data.get('name') - - bf.app.logger.info(f"Изменение названия системы: system_id={system_id}, system_name={system_name} name={name}") - - try: - system = Systems.query.get(system_id) - if system: - system.name = name - system.system_name = system_name - self.db.session.commit() - bf.app.logger.info(f"Название системы {system_id} изменено на {system_name} {name}") - return {'status': 'success', 'message': 'Название системы изменено'}, 200 - else: - bf.app.logger.warning(f"Попытка изменить название несуществующей системы с ID {system_id}") - return {'status': 'error', 'message': 'Система не найдена'}, 404 - except Exception as e: - self.db.session.rollback() - bf.app.logger.error(f"Ошибка при изменении названия системы: {e}") - return {'status': 'error', 'message': str(e)}, 500 - - def delete_system(self, system_id): - bf.app.logger.info(f"Удаление системы: system_id={system_id}") - - try: - system = Systems.query.get(system_id) - if system: - self.db.session.delete(system) - self.db.session.commit() - bf.app.logger.info(f"Система {system_id} успешно удалена") - return {'status': 'success', 'message': 'Система удалена'}, 200 - else: - bf.app.logger.warning(f"Система с ID {system_id} не найдена") - return {'status': 'error', 'message': 'Система не найдена'}, 404 - except Exception as e: - self.db.session.rollback() - bf.app.logger.error(f"Ошибка при удалении системы: {e}") - return {'status': 'error', 'message': str(e)}, 500 \ No newline at end of file diff --git a/utilities/telegram_utilities.py b/utilities/telegram_utilities.py index 2891c9e..fc1ce9f 100644 --- a/utilities/telegram_utilities.py +++ b/utilities/telegram_utilities.py @@ -4,7 +4,6 @@ import time import telebot import backend_bot -import backend_flask import bot_database import telezab @@ -54,7 +53,6 @@ def format_message(data): message += f'URL: Ссылка на график' return message except KeyError as e: - backend_flask.app.logger.error(f"Missing key in data: {e}") raise ValueError(f"Missing key in data: {e}") @@ -99,7 +97,7 @@ def show_main_menu(chat_id): backend_bot.bot.send_message(chat_id, "Выберите действие:", reply_markup=markup) -def create_settings_keyboard(chat_id, admins_list): +def create_settings_keyboard(): markup = telebot.types.ReplyKeyboardMarkup(one_time_keyboard=True, resize_keyboard=True) markup.row('Подписаться', 'Отписаться') markup.row('Мои подписки', 'Режим уведомлений') @@ -112,8 +110,7 @@ def show_settings_menu(chat_id): telezab.state.set_state(chat_id, "REGISTRATION") backend_bot.bot.send_message(chat_id, "Вы неавторизованы для использования этого бота") return - admins_list = bot_database.get_admins() - markup = create_settings_keyboard(chat_id, admins_list) + markup = create_settings_keyboard() backend_bot.bot.send_message(chat_id, "Вы находитесь в режиме настроек. Выберите действие:", reply_markup=markup) diff --git a/utilities/users_manager.py b/utilities/users_manager.py deleted file mode 100644 index a6874c8..0000000 --- a/utilities/users_manager.py +++ /dev/null @@ -1,169 +0,0 @@ -import logging -import re -from typing import Dict, List, Optional, Tuple, Any - -from sqlalchemy.exc import IntegrityError -from sqlalchemy.orm import joinedload -from sqlalchemy.orm.query import Query -from sqlalchemy.orm.scoping import scoped_session - -from models import Users - -# Настройка логирования -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - -class UserManager: - def __init__(self, db: scoped_session) -> None: - self.db: scoped_session = db - - def get_users(self, page: int, per_page: int) -> Dict[str, Any]: - logger.debug(f"Получение пользователей: page={page}, per_page={per_page}") - - users_query: Query = self.db.query(Users).options(joinedload(Users.subscriptions)) - # noinspection PyUnresolvedReferences - users_paginated: Any = users_query.paginate(page=page, per_page=per_page, error_out=False) - - users_list: List[Dict[str, Any]] = [] - for user in users_paginated.items: - user_data: Dict[str, Any] = { - 'chat_id': user.chat_id, - 'telegram_id': user.telegram_id, - 'email': user.user_email, - 'subscriptions': [], - 'disaster_only': "Все уведомления", - 'status': "Активен" if not user.is_blocked else "Заблокирован", - 'blocked': user.is_blocked - } - - if user.subscriptions: - for subscription in user.subscriptions: - if subscription.active: - user_data['subscriptions'].append(subscription.region_id) - if subscription.disaster_only: - user_data['disaster_only'] = "Только критические уведомления" - - users_list.append(user_data) - - logger.debug(f"Получено пользователей: {len(users_list)} элементов") - - return { - 'users': users_list, - 'total_users': users_paginated.total, - 'total_pages': users_paginated.pages, - 'current_page': users_paginated.page, - 'per_page': users_paginated.per_page - } - - def get_user(self, chat_id: int) -> Optional[Dict[str, Any]]: - logger.debug(f"Получение пользователя: chat_id={chat_id}") - - user: Optional[Users] = Users.query.filter_by(chat_id=chat_id).first() - if user: - user_data: Dict[str, Any] = { - 'chat_id': user.chat_id, - 'telegram_id': user.telegram_id, - 'email': user.user_email, - 'blocked': user.is_blocked - } - logger.debug(f"Пользователь найден: chat_id={chat_id}") - return user_data - else: - logger.warning(f"Пользователь не найден: chat_id={chat_id}") - return None - - def toggle_block_user(self, chat_id: int) -> bool: - logger.debug(f"Переключение блокировки пользователя: chat_id={chat_id}") - - user: Optional[Users] = Users.query.filter_by(chat_id=chat_id).first() - if user: - user.is_blocked = not user.is_blocked - self.db.commit() - logger.info(f"Пользователь {chat_id} заблокирован") - return True - else: - logger.warning(f"Пользователь не найден: chat_id={chat_id}") - return False - - def delete_user(self, chat_id: int) -> bool: - logger.info(f"Удаление пользователя: chat_id={chat_id}") - - user: Optional[Users] = Users.query.filter_by(chat_id=chat_id).first() - if user: - self.db.delete(user) - self.db.commit() - logger.info(f"Пользователь удален: chat_id={chat_id}") - return True - else: - logger.warning(f"Пользователь не найден: chat_id={chat_id}") - return False - - def add_user(self, user_data: Dict[str, Any]) -> Tuple[Dict[str, str], Optional[int]]: - logger.info(f"Добавление пользователя: {user_data}") - try: - try: - chat_id = int(user_data['chat_id']) - except ValueError: - logger.warning("Chat ID должен быть числом") - return {'error': 'Chat ID должен быть числом'}, 400 - - if not re.match(r'^@.*$', user_data['telegram_id']): - logger.warning("Telegram ID должен начинаться с символа @") - return {'error': 'Telegram ID должен начинаться с символа @'}, 400 - if not re.match(r'.*@rtmis.ru$', user_data['user_email']): - logger.warning("Email должен содержать домен @rtmis.ru") - return {'error': 'Email должен содержать домен @rtmis.ru'}, 400 - - # Проверка на существование пользователя - if Users.query.filter_by(user_email=user_data['user_email']).first(): - logger.warning(f"Пользователь с email {user_data['user_email']} уже существует") - return {'error': 'Пользователь с таким email уже существует'}, 409 - if Users.query.filter_by(telegram_id=user_data['telegram_id']).first(): - logger.warning(f"Пользователь с Telegram ID {user_data['telegram_id']} уже существует") - return {'error': 'Пользователь с таким Telegram ID уже существует'}, 409 - if Users.query.filter_by(chat_id=chat_id).first(): - logger.warning(f"Пользователь с Chat ID {chat_id} уже существует") - return {'error': 'Пользователь с таким Chat ID уже существует'}, 409 - - new_user: Users = Users( - chat_id=chat_id, - telegram_id=user_data['telegram_id'], - user_email=user_data['user_email'], - is_blocked=user_data.get('is_blocked', False) - ) - self.db.add(new_user) - self.db.commit() - logger.info(f"Пользователь добавлен успешно: {new_user.user_email}") - return {'message': 'Пользователь добавлен успешно'}, 201 - except IntegrityError as e: - self.db.rollback() - logger.error(f"Ошибка уникальности при добавлении пользователя: {e}") - return {'error': 'Ошибка уникальности данных'}, 409 - except Exception as e: - self.db.rollback() - logger.error(f"Ошибка при добавлении пользователя: {type(e).__name__}: {e}") - return {'error': 'Ошибка при добавлении пользователя'}, 500 - - def search_users(self, telegram_id: Optional[str] = None, email: Optional[str] = None) -> List[Dict[str, Any]]: - logger.debug(f"Поиск пользователей: telegram_id={telegram_id}, email={email}") - - query: Query = self.db.query(Users) - if telegram_id: - query = query.filter(Users.telegram_id.ilike(f"%{telegram_id}%")) - if email: - query = query.filter(Users.user_email.ilike(f"%{email}%")) - - users: List[Users] = query.all() - - users_list: List[Dict[str, Any]] = [] - for user in users: - user_data: Dict[str, Any] = { - 'chat_id': user.chat_id, - 'telegram_id': user.telegram_id, - 'email': user.user_email, - 'blocked': user.is_blocked - } - users_list.append(user_data) - - logger.debug(f"Найдено пользователей: {len(users_list)}") - return users_list diff --git a/utilities/web_logger.py b/utilities/web_logger.py deleted file mode 100644 index e17d642..0000000 --- a/utilities/web_logger.py +++ /dev/null @@ -1,52 +0,0 @@ -from datetime import datetime -from models import WebActionLog -from flask_login import current_user -from utilities.database import db # Убедитесь, что импортируете db - -class WebLogger: - def __init__(self, db_session): - self.db = db_session - - def log_web_action(self, action, details=None): - """Сохраняет лог действия пользователя веб-интерфейса.""" - if current_user.is_authenticated: - log_entry = WebActionLog( - ldap_user_id=current_user.id, - username=getattr(current_user, 'display_name', None), - action=action, - details=details - ) - self.db.session.add(log_entry) - self.db.session.commit() - return True - return False - - def get_web_action_logs(self, page, per_page, ldap_user_id_filter=None, action_filter=None): - """Получает логи действий веб-интерфейса с пагинацией и фильтрацией.""" - query = WebActionLog.query.order_by(WebActionLog.timestamp.desc()) - - if ldap_user_id_filter: - query = query.filter_by(ldap_user_id=ldap_user_id_filter) - - if action_filter: - query = query.filter(WebActionLog.action.like(f'%{action_filter}%')) - - pagination = query.paginate(page=page, per_page=per_page) - logs = [ - { - 'id': log.id, - 'ldap_user_id': log.ldap_user_id, - 'username': log.username, - 'timestamp': log.timestamp.isoformat(), - 'action': log.action, - 'details': log.details - } - for log in pagination.items - ] - return { - 'logs': logs, - 'total': pagination.total, - 'pages': pagination.pages, - 'current_page': pagination.page, - 'per_page': pagination.per_page - } \ No newline at end of file