diff --git a/app/Article.py b/app/Article.py new file mode 100644 index 0000000..7f41b1e --- /dev/null +++ b/app/Article.py @@ -0,0 +1,137 @@ +from WordFreq import WordFreq +from wordfreqCMD import youdao_link, sort_in_descending_order +from UseSqlite import InsertQuery, RecordQuery +import pickle_idea, pickle_idea2 +import os +import random, glob +import hashlib +from datetime import datetime +from flask import Flask, request, redirect, render_template, url_for, session, abort, flash, get_flashed_messages +from difficulty import get_difficulty_level, text_difficulty_level, user_difficulty_level + + +path_prefix = '/var/www/wordfreq/wordfreq/' +path_prefix = './' # comment this line in deployment + + +def total_number_of_essays(): + rq = RecordQuery(path_prefix + 'static/wordfreqapp.db') + rq.instructions("SELECT * FROM article") + rq.do() + result = rq.get_results() + return len(result) + + +def get_article_title(s): + return s.split('\n')[0] + + +def get_article_body(s): + lst = s.split('\n') + lst.pop(0) # remove the first line + return '\n'.join(lst) + + +def get_today_article(user_word_list, articleID): + rq = RecordQuery(path_prefix + 'static/wordfreqapp.db') + if articleID == None: + rq.instructions("SELECT * FROM article") + else: + rq.instructions('SELECT * FROM article WHERE article_id=%d' % (articleID)) + rq.do() + result = rq.get_results() + random.shuffle(result) + + # Choose article according to reader's level + d1 = load_freq_history(path_prefix + 'static/frequency/frequency.p') + d2 = load_freq_history(path_prefix + 'static/words_and_tests.p') + d3 = get_difficulty_level(d1, d2) + + d = {} + d_user = load_freq_history(user_word_list) + user_level = user_difficulty_level(d_user, + d3) # more consideration as user's behaviour is dynamic. Time factor should be considered. + random.shuffle(result) # shuffle list + d = random.choice(result) + text_level = text_difficulty_level(d['text'], d3) + if articleID == None: + for reading in result: + text_level = text_difficulty_level(reading['text'], d3) + factor = random.gauss(0.8, + 0.1) # a number drawn from Gaussian distribution with a mean of 0.8 and a stand deviation of 1 + if within_range(text_level, user_level, (8.0 - user_level) * factor): + d = reading + break + + s = '' % ( + user_level, text_level) + s += '

Article added on: %s

' % (d['date']) + s += '
' + article_title = get_article_title(d['text']) + article_body = get_article_body(d['text']) + s += '

%s

' % (article_title) + s += '

%s

' % (article_body) + s += '

%s

' % (d['source']) + s += '

%s

' % (get_question_part(d['question'])) + s = s.replace('\n', '
') + s += '%s' % (get_answer_part(d['question'])) + s += '
' + session['articleID'] = d['article_id'] + return s + + +def load_freq_history(path): + d = {} + if os.path.exists(path): + d = pickle_idea.load_record(path) + return d + + +def within_range(x, y, r): + return x > y and abs(x - y) <= r + + +def get_question_part(s): + s = s.strip() + result = [] + flag = 0 + for line in s.split('\n'): + line = line.strip() + if line == 'QUESTION': + result.append(line) + flag = 1 + elif line == 'ANSWER': + flag = 0 + elif flag == 1: + result.append(line) + return '\n'.join(result) + + +def get_answer_part(s): + s = s.strip() + result = [] + flag = 0 + for line in s.split('\n'): + line = line.strip() + if line == 'ANSWER': + flag = 1 + elif flag == 1: + result.append(line) + # https://css-tricks.com/snippets/javascript/showhide-element/ + js = ''' + + ''' + html_code = js + html_code += '\n' + html_code += '\n' + html_code += '\n' % ('\n'.join(result)) + return html_code \ No newline at end of file diff --git a/app/Login.py b/app/Login.py new file mode 100644 index 0000000..c06a1b2 --- /dev/null +++ b/app/Login.py @@ -0,0 +1,73 @@ +import hashlib +from datetime import datetime + +from UseSqlite import InsertQuery, RecordQuery + +path_prefix = '/var/www/wordfreq/wordfreq/' +path_prefix = './' # comment this line in deployment + + +def verify_user(username, password): + rq = RecordQuery(path_prefix + 'static/wordfreqapp.db') + password = md5(username + password) + rq.instructions_with_parameters("SELECT * FROM user WHERE name=? AND password=?", (username, password)) + rq.do_with_parameters() + result = rq.get_results() + return result != [] + + +def add_user(username, password): + start_date = datetime.now().strftime('%Y%m%d') + expiry_date = '20221230' + # 将用户名和密码一起加密,以免暴露不同用户的相同密码 + password = md5(username + password) + rq = InsertQuery(path_prefix + 'static/wordfreqapp.db') + rq.instructions("INSERT INTO user VALUES ('%s', '%s', '%s', '%s')" % (username, password, start_date, expiry_date)) + rq.do() + + +def check_username_availability(username): + rq = RecordQuery(path_prefix + 'static/wordfreqapp.db') + rq.instructions("SELECT * FROM user WHERE name='%s'" % (username)) + rq.do() + result = rq.get_results() + return result == [] + + +def change_password(username, old_password, new_password): + ''' + 修改密码 + :param username: 用户名 + :param old_password: 旧的密码 + :param new_password: 新密码 + :return: 修改成功:True 否则:False + ''' + if not verify_user(username, old_password): # 旧密码错误 + return False + # 将用户名和密码一起加密,以免暴露不同用户的相同密码 + password = md5(username + new_password) + rq = InsertQuery(path_prefix + 'static/wordfreqapp.db') + rq.instructions("UPDATE user SET password = '%s' WHERE name = '%s'" % (password, username)) + rq.do() + return True + + +def get_expiry_date(username): + rq = RecordQuery(path_prefix + 'static/wordfreqapp.db') + rq.instructions("SELECT expiry_date FROM user WHERE name='%s'" % (username)) + rq.do() + result = rq.get_results() + if len(result) > 0: + return result[0]['expiry_date'] + else: + return '20191024' + + +def md5(s): + ''' + MD5摘要 + :param str: 字符串 + :return: 经MD5以后的字符串 + ''' + h = hashlib.md5(s.encode(encoding='utf-8')) + return h.hexdigest() \ No newline at end of file diff --git a/app/UseSqlite.py b/app/UseSqlite.py index 67133ce..660710f 100644 --- a/app/UseSqlite.py +++ b/app/UseSqlite.py @@ -1,87 +1,87 @@ -########################################################################### -# Copyright 2019 (C) Hui Lan -# Written permission must be obtained from the author for commercial uses. -########################################################################### - - -# Reference: Dusty Phillips. Python 3 Objected-oriented Programming Second Edition. Pages 326-328. -# Copyright (C) 2019 Hui Lan - -import sqlite3 - -class Sqlite3Template: - def __init__(self, db_fname): - self.db_fname = db_fname - - def connect(self, db_fname): - self.conn = sqlite3.connect(self.db_fname) - - def instructions(self, query_statement): - raise NotImplementedError() - - def operate(self): - self.conn.row_factory = sqlite3.Row - self.results = self.conn.execute(self.query) # self.query is to be given in the child classes - self.conn.commit() - - def format_results(self): - raise NotImplementedError() - - def do(self): - self.connect(self.db_fname) - self.instructions(self.query) - self.operate() - - def instructions_with_parameters(self, query_statement, parameters): - self.query = query_statement - self.parameters = parameters - - def do_with_parameters(self): - self.connect(self.db_fname) - self.instructions_with_parameters(self.query, self.parameters) - self.operate_with_parameters() - - def operate_with_parameters(self): - self.conn.row_factory = sqlite3.Row - self.results = self.conn.execute(self.query, self.parameters) # self.query is to be given in the child classes - self.conn.commit() - - -class InsertQuery(Sqlite3Template): - def instructions(self, query): - self.query = query - - -class RecordQuery(Sqlite3Template): - def instructions(self, query): - self.query = query - - def format_results(self): - output = [] - for row_dict in self.results.fetchall(): - lst = [] - for k in dict(row_dict): - lst.append( row_dict[k] ) - output.append(', '.join(lst)) - return '\n\n'.join(output) - - def get_results(self): - result = [] - for row_dict in self.results.fetchall(): - result.append( dict(row_dict) ) - return result - - - -if __name__ == '__main__': - - #iq = InsertQuery('RiskDB.db') - #iq.instructions("INSERT INTO inspection Values ('FoodSupplies', 'RI2019051301', '2019-05-13', '{}')") - #iq.do() - #iq.instructions("INSERT INTO inspection Values ('CarSupplies', 'RI2019051302', '2019-05-13', '{[{\"risk_name\":\"elevator\"}]}')") - #iq.do() - - rq = RecordQuery('wordfreqapp.db') - rq.instructions("SELECT * FROM article WHERE level=3") - rq.do() - #print(rq.format_results()) +########################################################################### +# Copyright 2019 (C) Hui Lan +# Written permission must be obtained from the author for commercial uses. +########################################################################### + + +# Reference: Dusty Phillips. Python 3 Objected-oriented Programming Second Edition. Pages 326-328. +# Copyright (C) 2019 Hui Lan + +import sqlite3 + +class Sqlite3Template: + def __init__(self, db_fname): + self.db_fname = db_fname + + def connect(self, db_fname): + self.conn = sqlite3.connect(self.db_fname) + + def instructions(self, query_statement): + raise NotImplementedError() + + def operate(self): + self.conn.row_factory = sqlite3.Row + self.results = self.conn.execute(self.query) # self.query is to be given in the child classes + self.conn.commit() + + def format_results(self): + raise NotImplementedError() + + def do(self): + self.connect(self.db_fname) + self.instructions(self.query) + self.operate() + + def instructions_with_parameters(self, query_statement, parameters): + self.query = query_statement + self.parameters = parameters + + def do_with_parameters(self): + self.connect(self.db_fname) + self.instructions_with_parameters(self.query, self.parameters) + self.operate_with_parameters() + + def operate_with_parameters(self): + self.conn.row_factory = sqlite3.Row + self.results = self.conn.execute(self.query, self.parameters) # self.query is to be given in the child classes + self.conn.commit() + + +class InsertQuery(Sqlite3Template): + def instructions(self, query): + self.query = query + + +class RecordQuery(Sqlite3Template): + def instructions(self, query): + self.query = query + + def format_results(self): + output = [] + for row_dict in self.results.fetchall(): + lst = [] + for k in dict(row_dict): + lst.append( row_dict[k] ) + output.append(', '.join(lst)) + return '\n\n'.join(output) + + def get_results(self): + result = [] + for row_dict in self.results.fetchall(): + result.append( dict(row_dict) ) + return result + + + +if __name__ == '__main__': + + #iq = InsertQuery('RiskDB.db') + #iq.instructions("INSERT INTO inspection Values ('FoodSupplies', 'RI2019051301', '2019-05-13', '{}')") + #iq.do() + #iq.instructions("INSERT INTO inspection Values ('CarSupplies', 'RI2019051302', '2019-05-13', '{[{\"risk_name\":\"elevator\"}]}')") + #iq.do() + + rq = RecordQuery('wordfreqapp.db') + rq.instructions("SELECT * FROM article WHERE level=3") + rq.do() + #print(rq.format_results()) diff --git a/app/Yaml.py b/app/Yaml.py new file mode 100644 index 0000000..1bd226e --- /dev/null +++ b/app/Yaml.py @@ -0,0 +1,27 @@ +''' +Yaml.py +配置文件包括: + ./static/config.yml + ./layout/partial/header.html + ./layout/partial/footer.html +''' +import yaml as YAML +import os + +path_prefix = './' # comment this line in deployment + +# YAML文件路径 +ymlPath = path_prefix + 'static/config.yml' + +# partial文件夹路径 +partialPath = path_prefix + 'layout/partial/' +f = open(ymlPath, 'r', encoding='utf-8') # 以'UTF-8'格式打开YAML文件 +cont = f.read() # 以文本形式读取YAML + +yml = YAML.load(cont, Loader=YAML.FullLoader) # 加载YAML + +with open(partialPath + 'header.html', 'r', encoding='utf-8') as f: + yml['header'] = f.read() # header内的文本会被直接添加到所有页面的head标签内 + +with open(partialPath + 'footer.html', 'r', encoding='utf-8') as f: + yml['footer'] = f.read() # footer内的文本会被直接添加到所有页面的最底部 \ No newline at end of file diff --git a/app/account_service.py b/app/account_service.py new file mode 100644 index 0000000..3f5cf60 --- /dev/null +++ b/app/account_service.py @@ -0,0 +1,129 @@ +from flask import * +from Login import check_username_availability, verify_user, add_user, get_expiry_date, change_password + +# 初始化蓝图 +accountService = Blueprint("accountService", __name__) + + +### Sign-up, login, logout ### +@accountService.route("/signup", methods=['GET', 'POST']) +def signup(): + ''' + 注册 + :return: 根据注册是否成功返回不同界面 + ''' + if request.method == 'GET': + # GET方法直接返回注册页面 + return render_template('signup.html') + elif request.method == 'POST': + # POST方法需判断是否注册成功,再根据结果返回不同的内容 + username = request.form['username'] + password = request.form['password'] + + available = check_username_availability(username) + if not available: # 用户名不可用 + flash('用户名 %s 已经被注册。' % (username)) + return render_template('signup.html') + elif len(password.strip()) < 4: # 密码过短 + return '密码过于简单。' + else: # 添加账户信息 + add_user(username, password) + verified = verify_user(username, password) + if verified: + # 写入session + session['logged_in'] = True + session[username] = username + session['username'] = username + session['expiry_date'] = get_expiry_date(username) + session['articleID'] = None + return '

恭喜,你已成功注册, 你的用户名是 %s

\ +

开始使用 返回首页

' % (username, username, username) + else: + return '用户名密码验证失败。' + + +@accountService.route("/login", methods=['GET', 'POST']) +def login(): + ''' + 登录 + :return: 根据登录是否成功返回不同页面 + ''' + if request.method == 'GET': + # GET请求 + if not session.get('logged_in'): + # 未登录,返回登录页面 + return render_template('login.html') + else: + # 已登录,提示信息并显示登出按钮 + return '你已登录 %s。 登出点击这里。' % ( + session['username'], session['username']) + elif request.method == 'POST': + # POST方法用于判断登录是否成功 + # check database and verify user + username = request.form['username'] + password = request.form['password'] + verified = verify_user(username, password) + if verified: + # 登录成功,写入session + session['logged_in'] = True + session[username] = username + session['username'] = username + user_expiry_date = get_expiry_date(username) + session['expiry_date'] = user_expiry_date + session['articleID'] = None + return redirect(url_for('user_bp.userpage', username=username)) + else: + return '无法通过验证。' + + +@accountService.route("/logout", methods=['GET', 'POST']) +def logout(): + ''' + 登出 + :return: 重定位到主界面 + ''' + # 将session标记为登出状态 + session['logged_in'] = False + return redirect(url_for('mainpage')) + + +@accountService.route("/reset", methods=['GET', 'POST']) +def reset(): + ''' + 重设密码 + :return: 返回适当的页面 + ''' + # 下列方法用于防止未登录状态下的修改密码 + if not session.get('logged_in'): + return render_template('login.html') + username = session['username'] + if username == '': + return redirect('/login') + if request.method == 'GET': + # GET请求返回修改密码页面 + return render_template('reset.html', username=session['username'], state='wait') + else: + # POST请求用于提交修改后信息 + old_psd = request.form['old-psd'] + new_psd = request.form['new-psd'] + flag = change_password(username, old_psd, new_psd) # flag表示是否修改成功 + if flag: + session['logged_in'] = False + return \ +''' + + +''' + + else: + return \ +''' + + +''' \ No newline at end of file diff --git a/app/layout/partial/footer.html b/app/layout/partial/footer.html new file mode 100644 index 0000000..329d585 --- /dev/null +++ b/app/layout/partial/footer.html @@ -0,0 +1,21 @@ + + \ No newline at end of file diff --git a/app/layout/partial/header.html b/app/layout/partial/header.html new file mode 100644 index 0000000..3d0f70a --- /dev/null +++ b/app/layout/partial/header.html @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/app/main.py b/app/main.py index 301d1bb..d903bf4 100644 --- a/app/main.py +++ b/app/main.py @@ -1,498 +1,114 @@ -#! /usr/bin/python3 -# -*- coding: utf-8 -*- - -########################################################################### -# Copyright 2019 (C) Hui Lan -# Written permission must be obtained from the author for commercial uses. -########################################################################### - -from WordFreq import WordFreq -from wordfreqCMD import youdao_link, sort_in_descending_order -from UseSqlite import InsertQuery, RecordQuery -import pickle_idea, pickle_idea2 -import os -import random, glob -from datetime import datetime -from flask import Flask, request, redirect, render_template, url_for, session, abort, flash, get_flashed_messages -from difficulty import get_difficulty_level, text_difficulty_level, user_difficulty_level - -app = Flask(__name__) -app.secret_key = 'lunch.time!' - -path_prefix = '/var/www/wordfreq/wordfreq/' -path_prefix = './' # comment this line in deployment - -def get_random_image(path): - img_path = random.choice(glob.glob(os.path.join(path, '*.jpg'))) - return img_path[img_path.rfind('/static'):] - -def get_random_ads(): - ads = random.choice(['个性化分析精准提升', '你的专有单词本', '智能捕捉阅读弱点,针对性提高你的阅读水平']) - return ads + '。 试试吧!' - -def total_number_of_essays(): - rq = RecordQuery(path_prefix + 'static/wordfreqapp.db') - rq.instructions("SELECT * FROM article") - rq.do() - result = rq.get_results() - return len(result) - -def load_freq_history(path): - d = {} - if os.path.exists(path): - d = pickle_idea.load_record(path) - return d - -def verify_user(username, password): - rq = RecordQuery(path_prefix + 'static/wordfreqapp.db') - rq.instructions_with_parameters("SELECT * FROM user WHERE name=? AND password=?", (username, password)) - rq.do_with_parameters() - result = rq.get_results() - return result != [] - -def add_user(username, password): - start_date = datetime.now().strftime('%Y%m%d') - expiry_date = '20211230' - rq = InsertQuery(path_prefix + 'static/wordfreqapp.db') - rq.instructions("INSERT INTO user Values ('%s', '%s', '%s', '%s')" % (username, password, start_date, expiry_date)) - rq.do() - - -def check_username_availability(username): - rq = RecordQuery(path_prefix + 'static/wordfreqapp.db') - rq.instructions("SELECT * FROM user WHERE name='%s'" % (username)) - rq.do() - result = rq.get_results() - return result == [] - -def get_expiry_date(username): - rq = RecordQuery(path_prefix + 'static/wordfreqapp.db') - rq.instructions("SELECT expiry_date FROM user WHERE name='%s'" % (username)) - rq.do() - result = rq.get_results() - if len(result) > 0: - return result[0]['expiry_date'] - else: - return '20191024' - - - -def within_range(x, y, r): - return x > y and abs(x - y) <= r - - -def get_article_title(s): - return s.split('\n')[0] - - -def get_article_body(s): - lst = s.split('\n') - lst.pop(0) # remove the first line - return '\n'.join(lst) - -def get_today_article(user_word_list, articleID): - - rq = RecordQuery(path_prefix + 'static/wordfreqapp.db') - if articleID == None: - rq.instructions("SELECT * FROM article") - else: - rq.instructions('SELECT * FROM article WHERE article_id=%d' % (articleID)) - rq.do() - result = rq.get_results() - random.shuffle(result) - - # Choose article according to reader's level - d1 = load_freq_history(path_prefix + 'static/frequency/frequency.p') - d2 = load_freq_history(path_prefix + 'static/words_and_tests.p') - d3 = get_difficulty_level(d1, d2) - - d = {} - d_user = load_freq_history(user_word_list) - user_level = user_difficulty_level(d_user, d3) # more consideration as user's behaviour is dynamic. Time factor should be considered. - random.shuffle(result) # shuffle list - d = random.choice(result) - text_level = text_difficulty_level(d['text'], d3) - if articleID == None: - for reading in result: - text_level = text_difficulty_level(reading['text'], d3) - factor = random.gauss(0.8, 0.1) # a number drawn from Gaussian distribution with a mean of 0.8 and a stand deviation of 1 - if within_range(text_level, user_level, (8.0 - user_level)*factor): - d = reading - break - - s = '

' % (user_level, text_level) - s += '

Article added on: %s

' % (d['date']) - s += '
' - article_title = get_article_title(d['text']) - article_body = get_article_body(d['text']) - s += '

%s

' % (article_title) - s += '

%s

' % (article_body) - s += '

%s

' % (d['source']) - s += '

%s

' % (get_question_part(d['question'])) - s = s.replace('\n', '
') - s += '%s' % (get_answer_part(d['question'])) - s += '
' - session['articleID'] = d['article_id'] - return s - - -def appears_in_test(word, d): - if not word in d: - return '' - else: - return ','.join(d[word]) - - -def get_time(): - return datetime.now().strftime('%Y%m%d%H%M') # upper to minutes - - -def get_question_part(s): - s = s.strip() - result = [] - flag = 0 - for line in s.split('\n'): - line = line.strip() - if line == 'QUESTION': - result.append(line) - flag = 1 - elif line == 'ANSWER': - flag = 0 - elif flag == 1: - result.append(line) - return '\n'.join(result) - - -def get_answer_part(s): - s = s.strip() - result = [] - flag = 0 - for line in s.split('\n'): - line = line.strip() - if line == 'ANSWER': - flag = 1 - elif flag == 1: - result.append(line) - # https://css-tricks.com/snippets/javascript/showhide-element/ - js = ''' - - ''' - html_code = js - html_code += '\n' - html_code += '\n' - html_code += '\n' % ('\n'.join(result)) - return html_code - - -def get_flashed_messages_if_any(): - messages = get_flashed_messages() - s = '' - for message in messages: - s += '' - return s - - -@app.route("//reset", methods=['GET', 'POST']) -def user_reset(username): - if request.method == 'GET': - session['articleID'] = None - return redirect(url_for('userpage', username=username)) - else: - return 'Under construction' - - -@app.route("/mark", methods=['GET', 'POST']) -def mark_word(): - if request.method == 'POST': - d = load_freq_history(path_prefix + 'static/frequency/frequency.p') - lst_history = pickle_idea.dict2lst(d) - lst = [] - for word in request.form.getlist('marked'): - lst.append((word, 1)) - d = pickle_idea.merge_frequency(lst, lst_history) - pickle_idea.save_frequency_to_pickle(d, path_prefix + 'static/frequency/frequency.p') - return redirect(url_for('mainpage')) - else: - return 'Under construction' - - - -@app.route("/", methods=['GET', 'POST']) -def mainpage(): - if request.method == 'POST': # when we submit a form - content = request.form['content'] - f = WordFreq(content) - lst = f.get_freq() - page = '
\n' - count = 1 - for x in lst: - page += '

%d: %s (%d)

\n' % (count, youdao_link(x[0]), x[0], x[1], x[0]) - count += 1 - page += ' \n' - page += '
\n' - # save history - d = load_freq_history(path_prefix + 'static/frequency/frequency.p') - lst_history = pickle_idea.dict2lst(d) - d = pickle_idea.merge_frequency(lst, lst_history) - pickle_idea.save_frequency_to_pickle(d, path_prefix + 'static/frequency/frequency.p') - - return page - elif request.method == 'GET': # when we load a html page - page = ''' - - - - - - - EnglishPal 英文单词高效记 - - - - ''' - page += '
' - page += '

English Pal - Learn English smartly!

' - if session.get('logged_in'): - page += ' %s

\n' % (session['username'], session['username']) - else: - page += '

登录 成为会员 使用说明

\n' - #page += '

advertisement

' % (get_random_image(path_prefix + 'static/img/')) - page += '

%s

' % (get_random_ads()) - page += '' % (total_number_of_essays()) - page += '

粘帖1篇文章 (English only)

' - page += '
' - page += '
' - page += ' ' - page += ' ' - page += '
' - d = load_freq_history(path_prefix + 'static/frequency/frequency.p') - if len(d) > 0: - page += '

最常见的词

' - for x in sort_in_descending_order(pickle_idea.dict2lst(d)): - if x[1] <= 99: - break - page += '%s %d\n' % (youdao_link(x[0]), x[0], x[1]) - - page += ' ' - page += '
' - page += '' - return page - - -@app.route("//mark", methods=['GET', 'POST']) -def user_mark_word(username): - username = session[username] - user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username) - if request.method == 'POST': - d = load_freq_history(user_freq_record) - lst_history = pickle_idea2.dict2lst(d) - lst = [] - for word in request.form.getlist('marked'): - lst.append((word, [get_time()])) - d = pickle_idea2.merge_frequency(lst, lst_history) - pickle_idea2.save_frequency_to_pickle(d, user_freq_record) - return redirect(url_for('userpage', username=username)) - else: - return 'Under construction' - - -@app.route("///unfamiliar", methods=['GET', 'POST']) -def unfamiliar(username,word): - user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username) - pickle_idea.unfamiliar(user_freq_record,word) - session['thisWord'] = word # 1. put a word into session - session['time'] = 1 - return redirect(url_for('userpage', username=username)) - -@app.route("///familiar", methods=['GET', 'POST']) -def familiar(username,word): - user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username) - pickle_idea.familiar(user_freq_record,word) - session['thisWord'] = word # 1. put a word into session - session['time'] = 1 - return redirect(url_for('userpage', username=username)) - -@app.route("///del", methods=['GET', 'POST']) -def deleteword(username,word): - user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username) - pickle_idea2.deleteRecord(user_freq_record,word) - flash(f'{word} is no longer in your word list.') - return redirect(url_for('userpage', username=username)) - -@app.route("/", methods=['GET', 'POST']) -def userpage(username): - - if not session.get('logged_in'): - return '

请先登录

' - - user_expiry_date = session.get('expiry_date') - if datetime.now().strftime('%Y%m%d') > user_expiry_date: - return '

账号 %s 过期。

为了提高服务质量,English Pal 收取会员费用, 每天0元。

请决定你要试用的时间长度,扫描下面支付宝二维码支付。 支付时请注明English Pal Membership Fee。 我们会于12小时内激活账号。

支付宝二维码

如果有问题,请加开发者微信 torontohui。

登出

' % (username) - - - username = session.get('username') - - user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username) - - if request.method == 'POST': # when we submit a form - content = request.form['content'] - f = WordFreq(content) - lst = f.get_freq() - page = '' - page += '' - page += '

勾选不认识的单词

' - page += '
\n' % (username) - page += ' \n' - count = 1 - words_tests_dict = pickle_idea.load_record(path_prefix + 'static/words_and_tests.p') - for x in lst: - page += '

%d: %s (%d)

\n' % (count, youdao_link(x[0]), appears_in_test(x[0], words_tests_dict), x[0], x[1], x[0]) - count += 1 - page += '
\n' - return page - - elif request.method == 'GET': # when we load a html page - page = '\n' - page += '\n' - page += '\n' # forbid treating numbers as cell numbers in smart phones - page += '' - page += 'EnglishPal Study Room for %s' % (username) - page += '
' - page += '

English Pal for %s 登出

' % (username) - page += get_flashed_messages_if_any() - page += '

阅读文章并回答问题

\n' - page += '

下一篇 Next Article

' % (username) - page += '
%s
' % (get_today_article(user_freq_record, session['articleID'])) - page += '

收集生词吧 (可以在正文中划词,也可以复制黏贴)

' - page += '
' % (username) - page += '
' - page += ' ' - page += ' ' - page += '
\n' - page += ''' - - ''' - if session.get('thisWord'): - page += ''' - - ''' - - d = load_freq_history(user_freq_record) - if len(d) > 0: - page += '

我的生词簿

' - lst = pickle_idea2.dict2lst(d) - lst2 = [] - for t in lst: - lst2.append((t[0], len(t[1]))) - for x in sort_in_descending_order(lst2): - word = x[0] - freq = x[1] - if session.get('thisWord') == x[0] and session.get('time') == 1: - page += '' # 3. anchor - session['time'] = 0 # discard anchor - if isinstance(d[word], list): # d[word] is a list of dates - if freq > 1: - page += '

%s(%d) 熟悉 不熟悉 删除

\n' % (youdao_link(word), word, '; '.join(d[word]), freq,username, word,username,word, username,word) - else: - page += '

%s(%d) 熟悉 不熟悉 删除

\n' % (youdao_link(word), word, '; '.join(d[word]), freq,username, word,username,word, username,word) - elif isinstance(d[word], int): # d[word] is a frequency. to migrate from old format. - page += '%s%d\n' % (youdao_link(word), word, freq) - page += '' - page += '
' - return page - -### Sign-up, login, logout ### -@app.route("/signup", methods=['GET', 'POST']) -def signup(): - if request.method == 'GET': - return render_template('signup.html') - elif request.method == 'POST': - username = request.form['username'] - password = request.form['password'] - - available = check_username_availability(username) - if not available: - flash('用户名 %s 已经被注册。' % (username)) - return render_template('signup.html') - elif len(password.strip()) < 4: - return '密码过于简单。' - else: - add_user(username, password) - verified = verify_user(username, password) - if verified: - session['logged_in'] = True - session[username] = username - session['username'] = username - session['expiry_date'] = get_expiry_date(username) - session['articleID'] = None - return '

恭喜,你已成功注册, 你的用户名是 %s

\ -

开始使用 返回首页

' % (username, username, username) - else: - return '用户名密码验证失败。' - - -@app.route("/login", methods=['GET', 'POST']) -def login(): - if request.method == 'GET': - if not session.get('logged_in'): - return render_template('login.html') - else: - return '你已登录 %s。 登出点击这里。' % (session['username'], session['username']) - elif request.method == 'POST': - # check database and verify user - username = request.form['username'] - password = request.form['password'] - verified = verify_user(username, password) - if verified: - session['logged_in'] = True - session[username] = username - session['username'] = username - user_expiry_date = get_expiry_date(username) - session['expiry_date'] = user_expiry_date - session['articleID'] = None - return redirect(url_for('userpage', username=username)) - else: - return '无法通过验证。' - - -@app.route("/logout", methods=['GET', 'POST']) -def logout(): - session['logged_in'] = False - return redirect(url_for('mainpage')) - - -if __name__ == '__main__': - #app.secret_key = os.urandom(16) - #app.run(debug=False, port='6000') - app.run(debug=True) - #app.run(debug=True, port='6000') - #app.run(host='0.0.0.0', debug=True, port='6000') +#! /usr/bin/python3 +# -*- coding: utf-8 -*- + +########################################################################### +# Copyright 2019 (C) Hui Lan +# Written permission must be obtained from the author for commercial uses. +########################################################################### + +from Login import * +from Article import * +import Yaml +from user_service import userService +from account_service import accountService +app = Flask(__name__) +app.secret_key = 'lunch.time!' + +# 将蓝图注册到Lab app +app.register_blueprint(userService) +app.register_blueprint(accountService) + +path_prefix = '/var/www/wordfreq/wordfreq/' +path_prefix = './' # comment this line in deployment + + +def get_random_image(path): + ''' + 返回随机图 + :param path: 图片文件(JPEG格式),不包含后缀名 + :return: + ''' + img_path = random.choice(glob.glob(os.path.join(path, '*.jpg'))) + + return img_path[img_path.rfind('/static'):] + + +def get_random_ads(): + ''' + 返回随机广告 + :return: 一个广告(包含HTML标签) + ''' + ads = random.choice(['个性化分析精准提升', '你的专有单词本', '智能捕捉阅读弱点,针对性提高你的阅读水平']) + return ads + '。 试试吧!' + + +def appears_in_test(word, d): + ''' + 如果字符串里没有指定的单词,则返回逗号加单词 + :param word: 指定单词 + :param d: 字符串 + :return: 逗号加单词 + ''' + if not word in d: + return '' + else: + return ','.join(d[word]) + + +@app.route("/mark", methods=['GET', 'POST']) +def mark_word(): + ''' + 标记单词 + :return: 重定位到主界面 + ''' + if request.method == 'POST': + d = load_freq_history(path_prefix + 'static/frequency/frequency.p') + lst_history = pickle_idea.dict2lst(d) + lst = [] + for word in request.form.getlist('marked'): + lst.append((word, 1)) + d = pickle_idea.merge_frequency(lst, lst_history) + pickle_idea.save_frequency_to_pickle(d, path_prefix + 'static/frequency/frequency.p') + return redirect(url_for('mainpage')) + else: # 不回应GET请求 + return 'Under construction' + + +@app.route("/", methods=['GET', 'POST']) +def mainpage(): + ''' + 根据GET或POST方法来返回不同的主界面 + :return: 主界面 + ''' + if request.method == 'POST': # when we submit a form + content = request.form['content'] + f = WordFreq(content) + lst = f.get_freq() + # save history + d = load_freq_history(path_prefix + 'static/frequency/frequency.p') + lst_history = pickle_idea.dict2lst(d) + d = pickle_idea.merge_frequency(lst, lst_history) + pickle_idea.save_frequency_to_pickle(d, path_prefix + 'static/frequency/frequency.p') + return render_template('mainpage_post.html', lst=lst, yml=Yaml.yml) + + elif request.method == 'GET': # when we load a html page + random_ads = get_random_ads() + number_of_essays = total_number_of_essays() + d = load_freq_history(path_prefix + 'static/frequency/frequency.p') + d_len = len(d) + lst = sort_in_descending_order(pickle_idea.dict2lst(d)) + return render_template('mainpage_get.html', random_ads=random_ads, number_of_essays=number_of_essays, + d_len=d_len, lst=lst, yml=Yaml.yml) + + + +if __name__ == '__main__': + ''' + 运行程序 + ''' + # app.secret_key = os.urandom(16) + # app.run(debug=False, port='6000') + app.run(debug=True) + # app.run(debug=True, port='6000') + # app.run(host='0.0.0.0', debug=True, port='6000') + # print(mod5('123')) diff --git a/app/static/config.yml b/app/static/config.yml new file mode 100644 index 0000000..1ab8290 --- /dev/null +++ b/app/static/config.yml @@ -0,0 +1,17 @@ +# 全局引入的css文件地址 +css: + item: + - static/css/bootstrap.css + +# 全局引入的js文件地址 +js: + head: # 在页面加载之前加载 + # - static/js/APlayer.js + # - static/js/Meting.js + bottom: # 在页面加载完之后加载 + - static/js/fillword.js + - static/js/highlight.js + +# 高亮样式,目前仅支持修改颜色 +highlight: + color: ff0000 \ No newline at end of file diff --git a/app/static/css/bootstrap.css b/app/static/css/bootstrap.css new file mode 100644 index 0000000..dcde7a8 --- /dev/null +++ b/app/static/css/bootstrap.css @@ -0,0 +1,11192 @@ +@charset "UTF-8"; +/*! + * Bootstrap v5.0.2 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +:root { + --bs-blue: #0d6efd; + --bs-indigo: #6610f2; + --bs-purple: #6f42c1; + --bs-pink: #d63384; + --bs-red: #dc3545; + --bs-orange: #fd7e14; + --bs-yellow: #ffc107; + --bs-green: #198754; + --bs-teal: #20c997; + --bs-cyan: #0dcaf0; + --bs-white: #fff; + --bs-gray: #6c757d; + --bs-gray-dark: #343a40; + --bs-primary: #0d6efd; + --bs-secondary: #6c757d; + --bs-success: #198754; + --bs-info: #0dcaf0; + --bs-warning: #ffc107; + --bs-danger: #dc3545; + --bs-light: #f8f9fa; + --bs-dark: #212529; + --bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)) +} + +*, ::after, ::before { + box-sizing: border-box +} + +@media (prefers-reduced-motion: no-preference) { + :root { + scroll-behavior: smooth + } +} + +body { + margin: 0; + font-family: var(--bs-font-sans-serif); + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + background-color: #fff; + -webkit-text-size-adjust: 100%; + -webkit-tap-highlight-color: transparent +} + +hr { + margin: 1rem 0; + color: inherit; + background-color: currentColor; + border: 0; + opacity: .25 +} + +hr:not([size]) { + height: 1px +} + +.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { + margin-top: 0; + margin-bottom: .5rem; + font-weight: 500; + line-height: 1.2 +} + +.h1, h1 { + font-size: calc(1.375rem + 1.5vw) +} + +@media (min-width: 1200px) { + .h1, h1 { + font-size: 2.5rem + } +} + +.h2, h2 { + font-size: calc(1.325rem + .9vw) +} + +@media (min-width: 1200px) { + .h2, h2 { + font-size: 2rem + } +} + +.h3, h3 { + font-size: calc(1.3rem + .6vw) +} + +@media (min-width: 1200px) { + .h3, h3 { + font-size: 1.75rem + } +} + +.h4, h4 { + font-size: calc(1.275rem + .3vw) +} + +@media (min-width: 1200px) { + .h4, h4 { + font-size: 1.5rem + } +} + +.h5, h5 { + font-size: 1.25rem +} + +.h6, h6 { + font-size: 1rem +} + +p { + margin-top: 0; + margin-bottom: 1rem +} + +abbr[data-bs-original-title], abbr[title] { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; + cursor: help; + -webkit-text-decoration-skip-ink: none; + text-decoration-skip-ink: none +} + +address { + margin-bottom: 1rem; + font-style: normal; + line-height: inherit +} + +ol, ul { + padding-left: 2rem +} + +dl, ol, ul { + margin-top: 0; + margin-bottom: 1rem +} + +ol ol, ol ul, ul ol, ul ul { + margin-bottom: 0 +} + +dt { + font-weight: 700 +} + +dd { + margin-bottom: .5rem; + margin-left: 0 +} + +blockquote { + margin: 0 0 1rem +} + +b, strong { + font-weight: bolder +} + +.small, small { + font-size: .875em +} + +.mark, mark { + background-color: #FFFF00 +} + +sub, sup { + position: relative; + font-size: .75em; + line-height: 0; + vertical-align: baseline +} + +sub { + bottom: -.25em +} + +sup { + top: -.5em +} + +a { + color: #0d6efd; + text-decoration: underline +} + +a:hover { + color: #0a58ca +} + +a:not([href]):not([class]), a:not([href]):not([class]):hover { + color: inherit; + text-decoration: none +} + +code, kbd, pre, samp { + font-family: var(--bs-font-monospace); + font-size: 1em; + direction: ltr; + unicode-bidi: bidi-override +} + +pre { + display: block; + margin-top: 0; + margin-bottom: 1rem; + overflow: auto; + font-size: .875em +} + +pre code { + font-size: inherit; + color: inherit; + word-break: normal +} + +code { + font-size: .875em; + color: #d63384; + word-wrap: break-word +} + +a > code { + color: inherit +} + +kbd { + padding: .2rem .4rem; + font-size: .875em; + color: #fff; + background-color: #212529; + border-radius: .2rem +} + +kbd kbd { + padding: 0; + font-size: 1em; + font-weight: 700 +} + +figure { + margin: 0 0 1rem +} + +img, svg { + vertical-align: middle +} + +table { + caption-side: bottom; + border-collapse: collapse +} + +caption { + padding-top: .5rem; + padding-bottom: .5rem; + color: #6c757d; + text-align: left +} + +th { + text-align: inherit; + text-align: -webkit-match-parent +} + +tbody, td, tfoot, th, thead, tr { + border-color: inherit; + border-style: solid; + border-width: 0 +} + +label { + display: inline-block +} + +button { + border-radius: 0 +} + +button:focus:not(:focus-visible) { + outline: 0 +} + +button, input, optgroup, select, textarea { + margin: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit +} + +button, select { + text-transform: none +} + +[role=button] { + cursor: pointer +} + +select { + word-wrap: normal +} + +select:disabled { + opacity: 1 +} + +[list]::-webkit-calendar-picker-indicator { + display: none +} + +[type=button], [type=reset], [type=submit], button { + -webkit-appearance: button +} + +[type=button]:not(:disabled), [type=reset]:not(:disabled), [type=submit]:not(:disabled), button:not(:disabled) { + cursor: pointer +} + +::-moz-focus-inner { + padding: 0; + border-style: none +} + +textarea { + resize: vertical +} + +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0 +} + +legend { + float: left; + width: 100%; + padding: 0; + margin-bottom: .5rem; + font-size: calc(1.275rem + .3vw); + line-height: inherit +} + +@media (min-width: 1200px) { + legend { + font-size: 1.5rem + } +} + +legend + * { + clear: left +} + +::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-fields-wrapper, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-text, ::-webkit-datetime-edit-year-field { + padding: 0 +} + +::-webkit-inner-spin-button { + height: auto +} + +[type=search] { + outline-offset: -2px; + -webkit-appearance: textfield +} + +::-webkit-search-decoration { + -webkit-appearance: none +} + +::-webkit-color-swatch-wrapper { + padding: 0 +} + +::file-selector-button { + font: inherit +} + +::-webkit-file-upload-button { + font: inherit; + -webkit-appearance: button +} + +output { + display: inline-block +} + +iframe { + border: 0 +} + +summary { + display: list-item; + cursor: pointer +} + +progress { + vertical-align: baseline +} + +[hidden] { + display: none !important +} + +.lead { + font-size: 1.25rem; + font-weight: 300 +} + +.display-1 { + font-size: calc(1.625rem + 4.5vw); + font-weight: 300; + line-height: 1.2 +} + +@media (min-width: 1200px) { + .display-1 { + font-size: 5rem + } +} + +.display-2 { + font-size: calc(1.575rem + 3.9vw); + font-weight: 300; + line-height: 1.2 +} + +@media (min-width: 1200px) { + .display-2 { + font-size: 4.5rem + } +} + +.display-3 { + font-size: calc(1.525rem + 3.3vw); + font-weight: 300; + line-height: 1.2 +} + +@media (min-width: 1200px) { + .display-3 { + font-size: 4rem + } +} + +.display-4 { + font-size: calc(1.475rem + 2.7vw); + font-weight: 300; + line-height: 1.2 +} + +@media (min-width: 1200px) { + .display-4 { + font-size: 3.5rem + } +} + +.display-5 { + font-size: calc(1.425rem + 2.1vw); + font-weight: 300; + line-height: 1.2 +} + +@media (min-width: 1200px) { + .display-5 { + font-size: 3rem + } +} + +.display-6 { + font-size: calc(1.375rem + 1.5vw); + font-weight: 300; + line-height: 1.2 +} + +@media (min-width: 1200px) { + .display-6 { + font-size: 2.5rem + } +} + +.list-unstyled { + padding-left: 0; + list-style: none +} + +.list-inline { + padding-left: 0; + list-style: none +} + +.list-inline-item { + display: inline-block +} + +.list-inline-item:not(:last-child) { + margin-right: .5rem +} + +.initialism { + font-size: .875em; + text-transform: uppercase +} + +.blockquote { + margin-bottom: 1rem; + font-size: 1.25rem +} + +.blockquote > :last-child { + margin-bottom: 0 +} + +.blockquote-footer { + margin-top: -1rem; + margin-bottom: 1rem; + font-size: .875em; + color: #6c757d +} + +.blockquote-footer::before { + content: "— " +} + +.img-fluid { + max-width: 100%; + height: auto +} + +.img-thumbnail { + padding: .25rem; + background-color: #fff; + border: 1px solid #dee2e6; + border-radius: .25rem; + max-width: 100%; + height: auto +} + +.figure { + display: inline-block +} + +.figure-img { + margin-bottom: .5rem; + line-height: 1 +} + +.figure-caption { + font-size: .875em; + color: #6c757d +} + +.container, .container-fluid, .container-lg, .container-md, .container-sm, .container-xl, .container-xxl { + width: 100%; + padding-right: var(--bs-gutter-x, .75rem); + padding-left: var(--bs-gutter-x, .75rem); + margin-right: auto; + margin-left: auto +} + +@media (min-width: 576px) { + .container, .container-sm { + max-width: 540px + } +} + +@media (min-width: 768px) { + .container, .container-md, .container-sm { + max-width: 720px + } +} + +@media (min-width: 992px) { + .container, .container-lg, .container-md, .container-sm { + max-width: 960px + } +} + +@media (min-width: 1200px) { + .container, .container-lg, .container-md, .container-sm, .container-xl { + max-width: 1140px + } +} + +@media (min-width: 1400px) { + .container, .container-lg, .container-md, .container-sm, .container-xl, .container-xxl { + max-width: 1320px + } +} + +.row { + --bs-gutter-x: 1.5rem; + --bs-gutter-y: 0; + display: flex; + flex-wrap: wrap; + margin-top: calc(var(--bs-gutter-y) * -1); + margin-right: calc(var(--bs-gutter-x) * -.5); + margin-left: calc(var(--bs-gutter-x) * -.5) +} + +.row > * { + flex-shrink: 0; + width: 100%; + max-width: 100%; + padding-right: calc(var(--bs-gutter-x) * .5); + padding-left: calc(var(--bs-gutter-x) * .5); + margin-top: var(--bs-gutter-y) +} + +.col { + flex: 1 0 0% +} + +.row-cols-auto > * { + flex: 0 0 auto; + width: auto +} + +.row-cols-1 > * { + flex: 0 0 auto; + width: 100% +} + +.row-cols-2 > * { + flex: 0 0 auto; + width: 50% +} + +.row-cols-3 > * { + flex: 0 0 auto; + width: 33.3333333333% +} + +.row-cols-4 > * { + flex: 0 0 auto; + width: 25% +} + +.row-cols-5 > * { + flex: 0 0 auto; + width: 20% +} + +.row-cols-6 > * { + flex: 0 0 auto; + width: 16.6666666667% +} + +@media (min-width: 576px) { + .col-sm { + flex: 1 0 0% + } + + .row-cols-sm-auto > * { + flex: 0 0 auto; + width: auto + } + + .row-cols-sm-1 > * { + flex: 0 0 auto; + width: 100% + } + + .row-cols-sm-2 > * { + flex: 0 0 auto; + width: 50% + } + + .row-cols-sm-3 > * { + flex: 0 0 auto; + width: 33.3333333333% + } + + .row-cols-sm-4 > * { + flex: 0 0 auto; + width: 25% + } + + .row-cols-sm-5 > * { + flex: 0 0 auto; + width: 20% + } + + .row-cols-sm-6 > * { + flex: 0 0 auto; + width: 16.6666666667% + } +} + +@media (min-width: 768px) { + .col-md { + flex: 1 0 0% + } + + .row-cols-md-auto > * { + flex: 0 0 auto; + width: auto + } + + .row-cols-md-1 > * { + flex: 0 0 auto; + width: 100% + } + + .row-cols-md-2 > * { + flex: 0 0 auto; + width: 50% + } + + .row-cols-md-3 > * { + flex: 0 0 auto; + width: 33.3333333333% + } + + .row-cols-md-4 > * { + flex: 0 0 auto; + width: 25% + } + + .row-cols-md-5 > * { + flex: 0 0 auto; + width: 20% + } + + .row-cols-md-6 > * { + flex: 0 0 auto; + width: 16.6666666667% + } +} + +@media (min-width: 992px) { + .col-lg { + flex: 1 0 0% + } + + .row-cols-lg-auto > * { + flex: 0 0 auto; + width: auto + } + + .row-cols-lg-1 > * { + flex: 0 0 auto; + width: 100% + } + + .row-cols-lg-2 > * { + flex: 0 0 auto; + width: 50% + } + + .row-cols-lg-3 > * { + flex: 0 0 auto; + width: 33.3333333333% + } + + .row-cols-lg-4 > * { + flex: 0 0 auto; + width: 25% + } + + .row-cols-lg-5 > * { + flex: 0 0 auto; + width: 20% + } + + .row-cols-lg-6 > * { + flex: 0 0 auto; + width: 16.6666666667% + } +} + +@media (min-width: 1200px) { + .col-xl { + flex: 1 0 0% + } + + .row-cols-xl-auto > * { + flex: 0 0 auto; + width: auto + } + + .row-cols-xl-1 > * { + flex: 0 0 auto; + width: 100% + } + + .row-cols-xl-2 > * { + flex: 0 0 auto; + width: 50% + } + + .row-cols-xl-3 > * { + flex: 0 0 auto; + width: 33.3333333333% + } + + .row-cols-xl-4 > * { + flex: 0 0 auto; + width: 25% + } + + .row-cols-xl-5 > * { + flex: 0 0 auto; + width: 20% + } + + .row-cols-xl-6 > * { + flex: 0 0 auto; + width: 16.6666666667% + } +} + +@media (min-width: 1400px) { + .col-xxl { + flex: 1 0 0% + } + + .row-cols-xxl-auto > * { + flex: 0 0 auto; + width: auto + } + + .row-cols-xxl-1 > * { + flex: 0 0 auto; + width: 100% + } + + .row-cols-xxl-2 > * { + flex: 0 0 auto; + width: 50% + } + + .row-cols-xxl-3 > * { + flex: 0 0 auto; + width: 33.3333333333% + } + + .row-cols-xxl-4 > * { + flex: 0 0 auto; + width: 25% + } + + .row-cols-xxl-5 > * { + flex: 0 0 auto; + width: 20% + } + + .row-cols-xxl-6 > * { + flex: 0 0 auto; + width: 16.6666666667% + } +} + +.col-auto { + flex: 0 0 auto; + width: auto +} + +.col-1 { + flex: 0 0 auto; + width: 8.33333333% +} + +.col-2 { + flex: 0 0 auto; + width: 16.66666667% +} + +.col-3 { + flex: 0 0 auto; + width: 25% +} + +.col-4 { + flex: 0 0 auto; + width: 33.33333333% +} + +.col-5 { + flex: 0 0 auto; + width: 41.66666667% +} + +.col-6 { + flex: 0 0 auto; + width: 50% +} + +.col-7 { + flex: 0 0 auto; + width: 58.33333333% +} + +.col-8 { + flex: 0 0 auto; + width: 66.66666667% +} + +.col-9 { + flex: 0 0 auto; + width: 75% +} + +.col-10 { + flex: 0 0 auto; + width: 83.33333333% +} + +.col-11 { + flex: 0 0 auto; + width: 91.66666667% +} + +.col-12 { + flex: 0 0 auto; + width: 100% +} + +.offset-1 { + margin-left: 8.33333333% +} + +.offset-2 { + margin-left: 16.66666667% +} + +.offset-3 { + margin-left: 25% +} + +.offset-4 { + margin-left: 33.33333333% +} + +.offset-5 { + margin-left: 41.66666667% +} + +.offset-6 { + margin-left: 50% +} + +.offset-7 { + margin-left: 58.33333333% +} + +.offset-8 { + margin-left: 66.66666667% +} + +.offset-9 { + margin-left: 75% +} + +.offset-10 { + margin-left: 83.33333333% +} + +.offset-11 { + margin-left: 91.66666667% +} + +.g-0, .gx-0 { + --bs-gutter-x: 0 +} + +.g-0, .gy-0 { + --bs-gutter-y: 0 +} + +.g-1, .gx-1 { + --bs-gutter-x: 0.25rem +} + +.g-1, .gy-1 { + --bs-gutter-y: 0.25rem +} + +.g-2, .gx-2 { + --bs-gutter-x: 0.5rem +} + +.g-2, .gy-2 { + --bs-gutter-y: 0.5rem +} + +.g-3, .gx-3 { + --bs-gutter-x: 1rem +} + +.g-3, .gy-3 { + --bs-gutter-y: 1rem +} + +.g-4, .gx-4 { + --bs-gutter-x: 1.5rem +} + +.g-4, .gy-4 { + --bs-gutter-y: 1.5rem +} + +.g-5, .gx-5 { + --bs-gutter-x: 3rem +} + +.g-5, .gy-5 { + --bs-gutter-y: 3rem +} + +@media (min-width: 576px) { + .col-sm-auto { + flex: 0 0 auto; + width: auto + } + + .col-sm-1 { + flex: 0 0 auto; + width: 8.33333333% + } + + .col-sm-2 { + flex: 0 0 auto; + width: 16.66666667% + } + + .col-sm-3 { + flex: 0 0 auto; + width: 25% + } + + .col-sm-4 { + flex: 0 0 auto; + width: 33.33333333% + } + + .col-sm-5 { + flex: 0 0 auto; + width: 41.66666667% + } + + .col-sm-6 { + flex: 0 0 auto; + width: 50% + } + + .col-sm-7 { + flex: 0 0 auto; + width: 58.33333333% + } + + .col-sm-8 { + flex: 0 0 auto; + width: 66.66666667% + } + + .col-sm-9 { + flex: 0 0 auto; + width: 75% + } + + .col-sm-10 { + flex: 0 0 auto; + width: 83.33333333% + } + + .col-sm-11 { + flex: 0 0 auto; + width: 91.66666667% + } + + .col-sm-12 { + flex: 0 0 auto; + width: 100% + } + + .offset-sm-0 { + margin-left: 0 + } + + .offset-sm-1 { + margin-left: 8.33333333% + } + + .offset-sm-2 { + margin-left: 16.66666667% + } + + .offset-sm-3 { + margin-left: 25% + } + + .offset-sm-4 { + margin-left: 33.33333333% + } + + .offset-sm-5 { + margin-left: 41.66666667% + } + + .offset-sm-6 { + margin-left: 50% + } + + .offset-sm-7 { + margin-left: 58.33333333% + } + + .offset-sm-8 { + margin-left: 66.66666667% + } + + .offset-sm-9 { + margin-left: 75% + } + + .offset-sm-10 { + margin-left: 83.33333333% + } + + .offset-sm-11 { + margin-left: 91.66666667% + } + + .g-sm-0, .gx-sm-0 { + --bs-gutter-x: 0 + } + + .g-sm-0, .gy-sm-0 { + --bs-gutter-y: 0 + } + + .g-sm-1, .gx-sm-1 { + --bs-gutter-x: 0.25rem + } + + .g-sm-1, .gy-sm-1 { + --bs-gutter-y: 0.25rem + } + + .g-sm-2, .gx-sm-2 { + --bs-gutter-x: 0.5rem + } + + .g-sm-2, .gy-sm-2 { + --bs-gutter-y: 0.5rem + } + + .g-sm-3, .gx-sm-3 { + --bs-gutter-x: 1rem + } + + .g-sm-3, .gy-sm-3 { + --bs-gutter-y: 1rem + } + + .g-sm-4, .gx-sm-4 { + --bs-gutter-x: 1.5rem + } + + .g-sm-4, .gy-sm-4 { + --bs-gutter-y: 1.5rem + } + + .g-sm-5, .gx-sm-5 { + --bs-gutter-x: 3rem + } + + .g-sm-5, .gy-sm-5 { + --bs-gutter-y: 3rem + } +} + +@media (min-width: 768px) { + .col-md-auto { + flex: 0 0 auto; + width: auto + } + + .col-md-1 { + flex: 0 0 auto; + width: 8.33333333% + } + + .col-md-2 { + flex: 0 0 auto; + width: 16.66666667% + } + + .col-md-3 { + flex: 0 0 auto; + width: 25% + } + + .col-md-4 { + flex: 0 0 auto; + width: 33.33333333% + } + + .col-md-5 { + flex: 0 0 auto; + width: 41.66666667% + } + + .col-md-6 { + flex: 0 0 auto; + width: 50% + } + + .col-md-7 { + flex: 0 0 auto; + width: 58.33333333% + } + + .col-md-8 { + flex: 0 0 auto; + width: 66.66666667% + } + + .col-md-9 { + flex: 0 0 auto; + width: 75% + } + + .col-md-10 { + flex: 0 0 auto; + width: 83.33333333% + } + + .col-md-11 { + flex: 0 0 auto; + width: 91.66666667% + } + + .col-md-12 { + flex: 0 0 auto; + width: 100% + } + + .offset-md-0 { + margin-left: 0 + } + + .offset-md-1 { + margin-left: 8.33333333% + } + + .offset-md-2 { + margin-left: 16.66666667% + } + + .offset-md-3 { + margin-left: 25% + } + + .offset-md-4 { + margin-left: 33.33333333% + } + + .offset-md-5 { + margin-left: 41.66666667% + } + + .offset-md-6 { + margin-left: 50% + } + + .offset-md-7 { + margin-left: 58.33333333% + } + + .offset-md-8 { + margin-left: 66.66666667% + } + + .offset-md-9 { + margin-left: 75% + } + + .offset-md-10 { + margin-left: 83.33333333% + } + + .offset-md-11 { + margin-left: 91.66666667% + } + + .g-md-0, .gx-md-0 { + --bs-gutter-x: 0 + } + + .g-md-0, .gy-md-0 { + --bs-gutter-y: 0 + } + + .g-md-1, .gx-md-1 { + --bs-gutter-x: 0.25rem + } + + .g-md-1, .gy-md-1 { + --bs-gutter-y: 0.25rem + } + + .g-md-2, .gx-md-2 { + --bs-gutter-x: 0.5rem + } + + .g-md-2, .gy-md-2 { + --bs-gutter-y: 0.5rem + } + + .g-md-3, .gx-md-3 { + --bs-gutter-x: 1rem + } + + .g-md-3, .gy-md-3 { + --bs-gutter-y: 1rem + } + + .g-md-4, .gx-md-4 { + --bs-gutter-x: 1.5rem + } + + .g-md-4, .gy-md-4 { + --bs-gutter-y: 1.5rem + } + + .g-md-5, .gx-md-5 { + --bs-gutter-x: 3rem + } + + .g-md-5, .gy-md-5 { + --bs-gutter-y: 3rem + } +} + +@media (min-width: 992px) { + .col-lg-auto { + flex: 0 0 auto; + width: auto + } + + .col-lg-1 { + flex: 0 0 auto; + width: 8.33333333% + } + + .col-lg-2 { + flex: 0 0 auto; + width: 16.66666667% + } + + .col-lg-3 { + flex: 0 0 auto; + width: 25% + } + + .col-lg-4 { + flex: 0 0 auto; + width: 33.33333333% + } + + .col-lg-5 { + flex: 0 0 auto; + width: 41.66666667% + } + + .col-lg-6 { + flex: 0 0 auto; + width: 50% + } + + .col-lg-7 { + flex: 0 0 auto; + width: 58.33333333% + } + + .col-lg-8 { + flex: 0 0 auto; + width: 66.66666667% + } + + .col-lg-9 { + flex: 0 0 auto; + width: 75% + } + + .col-lg-10 { + flex: 0 0 auto; + width: 83.33333333% + } + + .col-lg-11 { + flex: 0 0 auto; + width: 91.66666667% + } + + .col-lg-12 { + flex: 0 0 auto; + width: 100% + } + + .offset-lg-0 { + margin-left: 0 + } + + .offset-lg-1 { + margin-left: 8.33333333% + } + + .offset-lg-2 { + margin-left: 16.66666667% + } + + .offset-lg-3 { + margin-left: 25% + } + + .offset-lg-4 { + margin-left: 33.33333333% + } + + .offset-lg-5 { + margin-left: 41.66666667% + } + + .offset-lg-6 { + margin-left: 50% + } + + .offset-lg-7 { + margin-left: 58.33333333% + } + + .offset-lg-8 { + margin-left: 66.66666667% + } + + .offset-lg-9 { + margin-left: 75% + } + + .offset-lg-10 { + margin-left: 83.33333333% + } + + .offset-lg-11 { + margin-left: 91.66666667% + } + + .g-lg-0, .gx-lg-0 { + --bs-gutter-x: 0 + } + + .g-lg-0, .gy-lg-0 { + --bs-gutter-y: 0 + } + + .g-lg-1, .gx-lg-1 { + --bs-gutter-x: 0.25rem + } + + .g-lg-1, .gy-lg-1 { + --bs-gutter-y: 0.25rem + } + + .g-lg-2, .gx-lg-2 { + --bs-gutter-x: 0.5rem + } + + .g-lg-2, .gy-lg-2 { + --bs-gutter-y: 0.5rem + } + + .g-lg-3, .gx-lg-3 { + --bs-gutter-x: 1rem + } + + .g-lg-3, .gy-lg-3 { + --bs-gutter-y: 1rem + } + + .g-lg-4, .gx-lg-4 { + --bs-gutter-x: 1.5rem + } + + .g-lg-4, .gy-lg-4 { + --bs-gutter-y: 1.5rem + } + + .g-lg-5, .gx-lg-5 { + --bs-gutter-x: 3rem + } + + .g-lg-5, .gy-lg-5 { + --bs-gutter-y: 3rem + } +} + +@media (min-width: 1200px) { + .col-xl-auto { + flex: 0 0 auto; + width: auto + } + + .col-xl-1 { + flex: 0 0 auto; + width: 8.33333333% + } + + .col-xl-2 { + flex: 0 0 auto; + width: 16.66666667% + } + + .col-xl-3 { + flex: 0 0 auto; + width: 25% + } + + .col-xl-4 { + flex: 0 0 auto; + width: 33.33333333% + } + + .col-xl-5 { + flex: 0 0 auto; + width: 41.66666667% + } + + .col-xl-6 { + flex: 0 0 auto; + width: 50% + } + + .col-xl-7 { + flex: 0 0 auto; + width: 58.33333333% + } + + .col-xl-8 { + flex: 0 0 auto; + width: 66.66666667% + } + + .col-xl-9 { + flex: 0 0 auto; + width: 75% + } + + .col-xl-10 { + flex: 0 0 auto; + width: 83.33333333% + } + + .col-xl-11 { + flex: 0 0 auto; + width: 91.66666667% + } + + .col-xl-12 { + flex: 0 0 auto; + width: 100% + } + + .offset-xl-0 { + margin-left: 0 + } + + .offset-xl-1 { + margin-left: 8.33333333% + } + + .offset-xl-2 { + margin-left: 16.66666667% + } + + .offset-xl-3 { + margin-left: 25% + } + + .offset-xl-4 { + margin-left: 33.33333333% + } + + .offset-xl-5 { + margin-left: 41.66666667% + } + + .offset-xl-6 { + margin-left: 50% + } + + .offset-xl-7 { + margin-left: 58.33333333% + } + + .offset-xl-8 { + margin-left: 66.66666667% + } + + .offset-xl-9 { + margin-left: 75% + } + + .offset-xl-10 { + margin-left: 83.33333333% + } + + .offset-xl-11 { + margin-left: 91.66666667% + } + + .g-xl-0, .gx-xl-0 { + --bs-gutter-x: 0 + } + + .g-xl-0, .gy-xl-0 { + --bs-gutter-y: 0 + } + + .g-xl-1, .gx-xl-1 { + --bs-gutter-x: 0.25rem + } + + .g-xl-1, .gy-xl-1 { + --bs-gutter-y: 0.25rem + } + + .g-xl-2, .gx-xl-2 { + --bs-gutter-x: 0.5rem + } + + .g-xl-2, .gy-xl-2 { + --bs-gutter-y: 0.5rem + } + + .g-xl-3, .gx-xl-3 { + --bs-gutter-x: 1rem + } + + .g-xl-3, .gy-xl-3 { + --bs-gutter-y: 1rem + } + + .g-xl-4, .gx-xl-4 { + --bs-gutter-x: 1.5rem + } + + .g-xl-4, .gy-xl-4 { + --bs-gutter-y: 1.5rem + } + + .g-xl-5, .gx-xl-5 { + --bs-gutter-x: 3rem + } + + .g-xl-5, .gy-xl-5 { + --bs-gutter-y: 3rem + } +} + +@media (min-width: 1400px) { + .col-xxl-auto { + flex: 0 0 auto; + width: auto + } + + .col-xxl-1 { + flex: 0 0 auto; + width: 8.33333333% + } + + .col-xxl-2 { + flex: 0 0 auto; + width: 16.66666667% + } + + .col-xxl-3 { + flex: 0 0 auto; + width: 25% + } + + .col-xxl-4 { + flex: 0 0 auto; + width: 33.33333333% + } + + .col-xxl-5 { + flex: 0 0 auto; + width: 41.66666667% + } + + .col-xxl-6 { + flex: 0 0 auto; + width: 50% + } + + .col-xxl-7 { + flex: 0 0 auto; + width: 58.33333333% + } + + .col-xxl-8 { + flex: 0 0 auto; + width: 66.66666667% + } + + .col-xxl-9 { + flex: 0 0 auto; + width: 75% + } + + .col-xxl-10 { + flex: 0 0 auto; + width: 83.33333333% + } + + .col-xxl-11 { + flex: 0 0 auto; + width: 91.66666667% + } + + .col-xxl-12 { + flex: 0 0 auto; + width: 100% + } + + .offset-xxl-0 { + margin-left: 0 + } + + .offset-xxl-1 { + margin-left: 8.33333333% + } + + .offset-xxl-2 { + margin-left: 16.66666667% + } + + .offset-xxl-3 { + margin-left: 25% + } + + .offset-xxl-4 { + margin-left: 33.33333333% + } + + .offset-xxl-5 { + margin-left: 41.66666667% + } + + .offset-xxl-6 { + margin-left: 50% + } + + .offset-xxl-7 { + margin-left: 58.33333333% + } + + .offset-xxl-8 { + margin-left: 66.66666667% + } + + .offset-xxl-9 { + margin-left: 75% + } + + .offset-xxl-10 { + margin-left: 83.33333333% + } + + .offset-xxl-11 { + margin-left: 91.66666667% + } + + .g-xxl-0, .gx-xxl-0 { + --bs-gutter-x: 0 + } + + .g-xxl-0, .gy-xxl-0 { + --bs-gutter-y: 0 + } + + .g-xxl-1, .gx-xxl-1 { + --bs-gutter-x: 0.25rem + } + + .g-xxl-1, .gy-xxl-1 { + --bs-gutter-y: 0.25rem + } + + .g-xxl-2, .gx-xxl-2 { + --bs-gutter-x: 0.5rem + } + + .g-xxl-2, .gy-xxl-2 { + --bs-gutter-y: 0.5rem + } + + .g-xxl-3, .gx-xxl-3 { + --bs-gutter-x: 1rem + } + + .g-xxl-3, .gy-xxl-3 { + --bs-gutter-y: 1rem + } + + .g-xxl-4, .gx-xxl-4 { + --bs-gutter-x: 1.5rem + } + + .g-xxl-4, .gy-xxl-4 { + --bs-gutter-y: 1.5rem + } + + .g-xxl-5, .gx-xxl-5 { + --bs-gutter-x: 3rem + } + + .g-xxl-5, .gy-xxl-5 { + --bs-gutter-y: 3rem + } +} + +.table { + --bs-table-bg: transparent; + --bs-table-accent-bg: transparent; + --bs-table-striped-color: #212529; + --bs-table-striped-bg: rgba(0, 0, 0, 0.05); + --bs-table-active-color: #212529; + --bs-table-active-bg: rgba(0, 0, 0, 0.1); + --bs-table-hover-color: #212529; + --bs-table-hover-bg: rgba(0, 0, 0, 0.075); + width: 100%; + margin-bottom: 1rem; + color: #212529; + vertical-align: top; + border-color: #dee2e6 +} + +.table > :not(caption) > * > * { + padding: .5rem .5rem; + background-color: var(--bs-table-bg); + border-bottom-width: 1px; + box-shadow: inset 0 0 0 9999px var(--bs-table-accent-bg) +} + +.table > tbody { + vertical-align: inherit +} + +.table > thead { + vertical-align: bottom +} + +.table > :not(:last-child) > :last-child > * { + border-bottom-color: currentColor +} + +.caption-top { + caption-side: top +} + +.table-sm > :not(caption) > * > * { + padding: .25rem .25rem +} + +.table-bordered > :not(caption) > * { + border-width: 1px 0 +} + +.table-bordered > :not(caption) > * > * { + border-width: 0 1px +} + +.table-borderless > :not(caption) > * > * { + border-bottom-width: 0 +} + +.table-striped > tbody > tr:nth-of-type(odd) { + --bs-table-accent-bg: var(--bs-table-striped-bg); + color: var(--bs-table-striped-color) +} + +.table-active { + --bs-table-accent-bg: var(--bs-table-active-bg); + color: var(--bs-table-active-color) +} + +.table-hover > tbody > tr:hover { + --bs-table-accent-bg: var(--bs-table-hover-bg); + color: var(--bs-table-hover-color) +} + +.table-primary { + --bs-table-bg: #cfe2ff; + --bs-table-striped-bg: #c5d7f2; + --bs-table-striped-color: #000; + --bs-table-active-bg: #bacbe6; + --bs-table-active-color: #000; + --bs-table-hover-bg: #bfd1ec; + --bs-table-hover-color: #000; + color: #000; + border-color: #bacbe6 +} + +.table-secondary { + --bs-table-bg: #e2e3e5; + --bs-table-striped-bg: #d7d8da; + --bs-table-striped-color: #000; + --bs-table-active-bg: #cbccce; + --bs-table-active-color: #000; + --bs-table-hover-bg: #d1d2d4; + --bs-table-hover-color: #000; + color: #000; + border-color: #cbccce +} + +.table-success { + --bs-table-bg: #d1e7dd; + --bs-table-striped-bg: #c7dbd2; + --bs-table-striped-color: #000; + --bs-table-active-bg: #bcd0c7; + --bs-table-active-color: #000; + --bs-table-hover-bg: #c1d6cc; + --bs-table-hover-color: #000; + color: #000; + border-color: #bcd0c7 +} + +.table-info { + --bs-table-bg: #cff4fc; + --bs-table-striped-bg: #c5e8ef; + --bs-table-striped-color: #000; + --bs-table-active-bg: #badce3; + --bs-table-active-color: #000; + --bs-table-hover-bg: #bfe2e9; + --bs-table-hover-color: #000; + color: #000; + border-color: #badce3 +} + +.table-warning { + --bs-table-bg: #fff3cd; + --bs-table-striped-bg: #f2e7c3; + --bs-table-striped-color: #000; + --bs-table-active-bg: #e6dbb9; + --bs-table-active-color: #000; + --bs-table-hover-bg: #ece1be; + --bs-table-hover-color: #000; + color: #000; + border-color: #e6dbb9 +} + +.table-danger { + --bs-table-bg: #f8d7da; + --bs-table-striped-bg: #eccccf; + --bs-table-striped-color: #000; + --bs-table-active-bg: #dfc2c4; + --bs-table-active-color: #000; + --bs-table-hover-bg: #e5c7ca; + --bs-table-hover-color: #000; + color: #000; + border-color: #dfc2c4 +} + +.table-light { + --bs-table-bg: #f8f9fa; + --bs-table-striped-bg: #ecedee; + --bs-table-striped-color: #000; + --bs-table-active-bg: #dfe0e1; + --bs-table-active-color: #000; + --bs-table-hover-bg: #e5e6e7; + --bs-table-hover-color: #000; + color: #000; + border-color: #dfe0e1 +} + +.table-dark { + --bs-table-bg: #212529; + --bs-table-striped-bg: #2c3034; + --bs-table-striped-color: #fff; + --bs-table-active-bg: #373b3e; + --bs-table-active-color: #fff; + --bs-table-hover-bg: #323539; + --bs-table-hover-color: #fff; + color: #fff; + border-color: #373b3e +} + +.table-responsive { + overflow-x: auto; + -webkit-overflow-scrolling: touch +} + +@media (max-width: 575.98px) { + .table-responsive-sm { + overflow-x: auto; + -webkit-overflow-scrolling: touch + } +} + +@media (max-width: 767.98px) { + .table-responsive-md { + overflow-x: auto; + -webkit-overflow-scrolling: touch + } +} + +@media (max-width: 991.98px) { + .table-responsive-lg { + overflow-x: auto; + -webkit-overflow-scrolling: touch + } +} + +@media (max-width: 1199.98px) { + .table-responsive-xl { + overflow-x: auto; + -webkit-overflow-scrolling: touch + } +} + +@media (max-width: 1399.98px) { + .table-responsive-xxl { + overflow-x: auto; + -webkit-overflow-scrolling: touch + } +} + +.form-label { + margin-bottom: .5rem +} + +.col-form-label { + padding-top: calc(.375rem + 1px); + padding-bottom: calc(.375rem + 1px); + margin-bottom: 0; + font-size: inherit; + line-height: 1.5 +} + +.col-form-label-lg { + padding-top: calc(.5rem + 1px); + padding-bottom: calc(.5rem + 1px); + font-size: 1.25rem +} + +.col-form-label-sm { + padding-top: calc(.25rem + 1px); + padding-bottom: calc(.25rem + 1px); + font-size: .875rem +} + +.form-text { + margin-top: .25rem; + font-size: .875em; + color: #6c757d +} + +.form-control { + display: block; + width: 100%; + padding: .375rem .75rem; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ced4da; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + border-radius: .25rem; + transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out +} + +@media (prefers-reduced-motion: reduce) { + .form-control { + transition: none + } +} + +.form-control[type=file] { + overflow: hidden +} + +.form-control[type=file]:not(:disabled):not([readonly]) { + cursor: pointer +} + +.form-control:focus { + color: #212529; + background-color: #fff; + border-color: #86b7fe; + outline: 0; + box-shadow: 0 0 0 .25rem rgba(13, 110, 253, .25) +} + +.form-control::-webkit-date-and-time-value { + height: 1.5em +} + +.form-control::-moz-placeholder { + color: #6c757d; + opacity: 1 +} + +.form-control::placeholder { + color: #6c757d; + opacity: 1 +} + +.form-control:disabled, .form-control[readonly] { + background-color: #e9ecef; + opacity: 1 +} + +.form-control::file-selector-button { + padding: .375rem .75rem; + margin: -.375rem -.75rem; + -webkit-margin-end: .75rem; + margin-inline-end: .75rem; + color: #212529; + background-color: #e9ecef; + pointer-events: none; + border-color: inherit; + border-style: solid; + border-width: 0; + border-inline-end-width: 1px; + border-radius: 0; + transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out +} + +@media (prefers-reduced-motion: reduce) { + .form-control::file-selector-button { + transition: none + } +} + +.form-control:hover:not(:disabled):not([readonly])::file-selector-button { + background-color: #dde0e3 +} + +.form-control::-webkit-file-upload-button { + padding: .375rem .75rem; + margin: -.375rem -.75rem; + -webkit-margin-end: .75rem; + margin-inline-end: .75rem; + color: #212529; + background-color: #e9ecef; + pointer-events: none; + border-color: inherit; + border-style: solid; + border-width: 0; + border-inline-end-width: 1px; + border-radius: 0; + -webkit-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; + transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out +} + +@media (prefers-reduced-motion: reduce) { + .form-control::-webkit-file-upload-button { + -webkit-transition: none; + transition: none + } +} + +.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button { + background-color: #dde0e3 +} + +.form-control-plaintext { + display: block; + width: 100%; + padding: .375rem 0; + margin-bottom: 0; + line-height: 1.5; + color: #212529; + background-color: transparent; + border: solid transparent; + border-width: 1px 0 +} + +.form-control-plaintext.form-control-lg, .form-control-plaintext.form-control-sm { + padding-right: 0; + padding-left: 0 +} + +.form-control-sm { + min-height: calc(1.5em + (.5rem + 2px)); + padding: .25rem .5rem; + font-size: .875rem; + border-radius: .2rem +} + +.form-control-sm::file-selector-button { + padding: .25rem .5rem; + margin: -.25rem -.5rem; + -webkit-margin-end: .5rem; + margin-inline-end: .5rem +} + +.form-control-sm::-webkit-file-upload-button { + padding: .25rem .5rem; + margin: -.25rem -.5rem; + -webkit-margin-end: .5rem; + margin-inline-end: .5rem +} + +.form-control-lg { + min-height: calc(1.5em + (1rem + 2px)); + padding: .5rem 1rem; + font-size: 1.25rem; + border-radius: .3rem +} + +.form-control-lg::file-selector-button { + padding: .5rem 1rem; + margin: -.5rem -1rem; + -webkit-margin-end: 1rem; + margin-inline-end: 1rem +} + +.form-control-lg::-webkit-file-upload-button { + padding: .5rem 1rem; + margin: -.5rem -1rem; + -webkit-margin-end: 1rem; + margin-inline-end: 1rem +} + +textarea.form-control { + min-height: calc(1.5em + (.75rem + 2px)) +} + +textarea.form-control-sm { + min-height: calc(1.5em + (.5rem + 2px)) +} + +textarea.form-control-lg { + min-height: calc(1.5em + (1rem + 2px)) +} + +.form-control-color { + max-width: 3rem; + height: auto; + padding: .375rem +} + +.form-control-color:not(:disabled):not([readonly]) { + cursor: pointer +} + +.form-control-color::-moz-color-swatch { + height: 1.5em; + border-radius: .25rem +} + +.form-control-color::-webkit-color-swatch { + height: 1.5em; + border-radius: .25rem +} + +.form-select { + display: block; + width: 100%; + padding: .375rem 2.25rem .375rem .75rem; + -moz-padding-start: calc(0.75rem - 3px); + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + background-color: #fff; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right .75rem center; + background-size: 16px 12px; + border: 1px solid #ced4da; + border-radius: .25rem; + transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none +} + +@media (prefers-reduced-motion: reduce) { + .form-select { + transition: none + } +} + +.form-select:focus { + border-color: #86b7fe; + outline: 0; + box-shadow: 0 0 0 .25rem rgba(13, 110, 253, .25) +} + +.form-select[multiple], .form-select[size]:not([size="1"]) { + padding-right: .75rem; + background-image: none +} + +.form-select:disabled { + background-color: #e9ecef +} + +.form-select:-moz-focusring { + color: transparent; + text-shadow: 0 0 0 #212529 +} + +.form-select-sm { + padding-top: .25rem; + padding-bottom: .25rem; + padding-left: .5rem; + font-size: .875rem +} + +.form-select-lg { + padding-top: .5rem; + padding-bottom: .5rem; + padding-left: 1rem; + font-size: 1.25rem +} + +.form-check { + display: block; + min-height: 1.5rem; + padding-left: 1.5em; + margin-bottom: .125rem +} + +.form-check .form-check-input { + float: left; + margin-left: -1.5em +} + +.form-check-input { + width: 1em; + height: 1em; + margin-top: .25em; + vertical-align: top; + background-color: #fff; + background-repeat: no-repeat; + background-position: center; + background-size: contain; + border: 1px solid rgba(0, 0, 0, .25); + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + -webkit-print-color-adjust: exact; + color-adjust: exact +} + +.form-check-input[type=checkbox] { + border-radius: .25em +} + +.form-check-input[type=radio] { + border-radius: 50% +} + +.form-check-input:active { + filter: brightness(90%) +} + +.form-check-input:focus { + border-color: #86b7fe; + outline: 0; + box-shadow: 0 0 0 .25rem rgba(13, 110, 253, .25) +} + +.form-check-input:checked { + background-color: #0d6efd; + border-color: #0d6efd +} + +.form-check-input:checked[type=checkbox] { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/%3e%3c/svg%3e") +} + +.form-check-input:checked[type=radio] { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e") +} + +.form-check-input[type=checkbox]:indeterminate { + background-color: #0d6efd; + border-color: #0d6efd; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e") +} + +.form-check-input:disabled { + pointer-events: none; + filter: none; + opacity: .5 +} + +.form-check-input:disabled ~ .form-check-label, .form-check-input[disabled] ~ .form-check-label { + opacity: .5 +} + +.form-switch { + padding-left: 2.5em +} + +.form-switch .form-check-input { + width: 2em; + margin-left: -2.5em; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e"); + background-position: left center; + border-radius: 2em; + transition: background-position .15s ease-in-out +} + +@media (prefers-reduced-motion: reduce) { + .form-switch .form-check-input { + transition: none + } +} + +.form-switch .form-check-input:focus { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e") +} + +.form-switch .form-check-input:checked { + background-position: right center; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e") +} + +.form-check-inline { + display: inline-block; + margin-right: 1rem +} + +.btn-check { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none +} + +.btn-check:disabled + .btn, .btn-check[disabled] + .btn { + pointer-events: none; + filter: none; + opacity: .65 +} + +.form-range { + width: 100%; + height: 1.5rem; + padding: 0; + background-color: transparent; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none +} + +.form-range:focus { + outline: 0 +} + +.form-range:focus::-webkit-slider-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 .25rem rgba(13, 110, 253, .25) +} + +.form-range:focus::-moz-range-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 .25rem rgba(13, 110, 253, .25) +} + +.form-range::-moz-focus-outer { + border: 0 +} + +.form-range::-webkit-slider-thumb { + width: 1rem; + height: 1rem; + margin-top: -.25rem; + background-color: #0d6efd; + border: 0; + border-radius: 1rem; + -webkit-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; + transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; + -webkit-appearance: none; + appearance: none +} + +@media (prefers-reduced-motion: reduce) { + .form-range::-webkit-slider-thumb { + -webkit-transition: none; + transition: none + } +} + +.form-range::-webkit-slider-thumb:active { + background-color: #b6d4fe +} + +.form-range::-webkit-slider-runnable-track { + width: 100%; + height: .5rem; + color: transparent; + cursor: pointer; + background-color: #dee2e6; + border-color: transparent; + border-radius: 1rem +} + +.form-range::-moz-range-thumb { + width: 1rem; + height: 1rem; + background-color: #0d6efd; + border: 0; + border-radius: 1rem; + -moz-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; + transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; + -moz-appearance: none; + appearance: none +} + +@media (prefers-reduced-motion: reduce) { + .form-range::-moz-range-thumb { + -moz-transition: none; + transition: none + } +} + +.form-range::-moz-range-thumb:active { + background-color: #b6d4fe +} + +.form-range::-moz-range-track { + width: 100%; + height: .5rem; + color: transparent; + cursor: pointer; + background-color: #dee2e6; + border-color: transparent; + border-radius: 1rem +} + +.form-range:disabled { + pointer-events: none +} + +.form-range:disabled::-webkit-slider-thumb { + background-color: #adb5bd +} + +.form-range:disabled::-moz-range-thumb { + background-color: #adb5bd +} + +.form-floating { + position: relative +} + +.form-floating > .form-control, .form-floating > .form-select { + height: calc(3.5rem + 2px); + line-height: 1.25 +} + +.form-floating > label { + position: absolute; + top: 0; + left: 0; + height: 100%; + padding: 1rem .75rem; + pointer-events: none; + border: 1px solid transparent; + transform-origin: 0 0; + transition: opacity .1s ease-in-out, transform .1s ease-in-out +} + +@media (prefers-reduced-motion: reduce) { + .form-floating > label { + transition: none + } +} + +.form-floating > .form-control { + padding: 1rem .75rem +} + +.form-floating > .form-control::-moz-placeholder { + color: transparent +} + +.form-floating > .form-control::placeholder { + color: transparent +} + +.form-floating > .form-control:not(:-moz-placeholder-shown) { + padding-top: 1.625rem; + padding-bottom: .625rem +} + +.form-floating > .form-control:focus, .form-floating > .form-control:not(:placeholder-shown) { + padding-top: 1.625rem; + padding-bottom: .625rem +} + +.form-floating > .form-control:-webkit-autofill { + padding-top: 1.625rem; + padding-bottom: .625rem +} + +.form-floating > .form-select { + padding-top: 1.625rem; + padding-bottom: .625rem +} + +.form-floating > .form-control:not(:-moz-placeholder-shown) ~ label { + opacity: .65; + transform: scale(.85) translateY(-.5rem) translateX(.15rem) +} + +.form-floating > .form-control:focus ~ label, .form-floating > .form-control:not(:placeholder-shown) ~ label, .form-floating > .form-select ~ label { + opacity: .65; + transform: scale(.85) translateY(-.5rem) translateX(.15rem) +} + +.form-floating > .form-control:-webkit-autofill ~ label { + opacity: .65; + transform: scale(.85) translateY(-.5rem) translateX(.15rem) +} + +.input-group { + position: relative; + display: flex; + flex-wrap: wrap; + align-items: stretch; + width: 100% +} + +.input-group > .form-control, .input-group > .form-select { + position: relative; + flex: 1 1 auto; + width: 1%; + min-width: 0 +} + +.input-group > .form-control:focus, .input-group > .form-select:focus { + z-index: 3 +} + +.input-group .btn { + position: relative; + z-index: 2 +} + +.input-group .btn:focus { + z-index: 3 +} + +.input-group-text { + display: flex; + align-items: center; + padding: .375rem .75rem; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + text-align: center; + white-space: nowrap; + background-color: #e9ecef; + border: 1px solid #ced4da; + border-radius: .25rem +} + +.input-group-lg > .btn, .input-group-lg > .form-control, .input-group-lg > .form-select, .input-group-lg > .input-group-text { + padding: .5rem 1rem; + font-size: 1.25rem; + border-radius: .3rem +} + +.input-group-sm > .btn, .input-group-sm > .form-control, .input-group-sm > .form-select, .input-group-sm > .input-group-text { + padding: .25rem .5rem; + font-size: .875rem; + border-radius: .2rem +} + +.input-group-lg > .form-select, .input-group-sm > .form-select { + padding-right: 3rem +} + +.input-group:not(.has-validation) > .dropdown-toggle:nth-last-child(n+3), .input-group:not(.has-validation) > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu) { + border-top-right-radius: 0; + border-bottom-right-radius: 0 +} + +.input-group.has-validation > .dropdown-toggle:nth-last-child(n+4), .input-group.has-validation > :nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu) { + border-top-right-radius: 0; + border-bottom-right-radius: 0 +} + +.input-group > :not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) { + margin-left: -1px; + border-top-left-radius: 0; + border-bottom-left-radius: 0 +} + +.valid-feedback { + display: none; + width: 100%; + margin-top: .25rem; + font-size: .875em; + color: #198754 +} + +.valid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: .25rem .5rem; + margin-top: .1rem; + font-size: .875rem; + color: #fff; + background-color: rgba(25, 135, 84, .9); + border-radius: .25rem +} + +.is-valid ~ .valid-feedback, .is-valid ~ .valid-tooltip, .was-validated :valid ~ .valid-feedback, .was-validated :valid ~ .valid-tooltip { + display: block +} + +.form-control.is-valid, .was-validated .form-control:valid { + border-color: #198754; + padding-right: calc(1.5em + .75rem); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right calc(.375em + .1875rem) center; + background-size: calc(.75em + .375rem) calc(.75em + .375rem) +} + +.form-control.is-valid:focus, .was-validated .form-control:valid:focus { + border-color: #198754; + box-shadow: 0 0 0 .25rem rgba(25, 135, 84, .25) +} + +.was-validated textarea.form-control:valid, textarea.form-control.is-valid { + padding-right: calc(1.5em + .75rem); + background-position: top calc(.375em + .1875rem) right calc(.375em + .1875rem) +} + +.form-select.is-valid, .was-validated .form-select:valid { + border-color: #198754 +} + +.form-select.is-valid:not([multiple]):not([size]), .form-select.is-valid:not([multiple])[size="1"], .was-validated .form-select:valid:not([multiple]):not([size]), .was-validated .form-select:valid:not([multiple])[size="1"] { + padding-right: 4.125rem; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); + background-position: right .75rem center, center right 2.25rem; + background-size: 16px 12px, calc(.75em + .375rem) calc(.75em + .375rem) +} + +.form-select.is-valid:focus, .was-validated .form-select:valid:focus { + border-color: #198754; + box-shadow: 0 0 0 .25rem rgba(25, 135, 84, .25) +} + +.form-check-input.is-valid, .was-validated .form-check-input:valid { + border-color: #198754 +} + +.form-check-input.is-valid:checked, .was-validated .form-check-input:valid:checked { + background-color: #198754 +} + +.form-check-input.is-valid:focus, .was-validated .form-check-input:valid:focus { + box-shadow: 0 0 0 .25rem rgba(25, 135, 84, .25) +} + +.form-check-input.is-valid ~ .form-check-label, .was-validated .form-check-input:valid ~ .form-check-label { + color: #198754 +} + +.form-check-inline .form-check-input ~ .valid-feedback { + margin-left: .5em +} + +.input-group .form-control.is-valid, .input-group .form-select.is-valid, .was-validated .input-group .form-control:valid, .was-validated .input-group .form-select:valid { + z-index: 1 +} + +.input-group .form-control.is-valid:focus, .input-group .form-select.is-valid:focus, .was-validated .input-group .form-control:valid:focus, .was-validated .input-group .form-select:valid:focus { + z-index: 3 +} + +.invalid-feedback { + display: none; + width: 100%; + margin-top: .25rem; + font-size: .875em; + color: #dc3545 +} + +.invalid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: .25rem .5rem; + margin-top: .1rem; + font-size: .875rem; + color: #fff; + background-color: rgba(220, 53, 69, .9); + border-radius: .25rem +} + +.is-invalid ~ .invalid-feedback, .is-invalid ~ .invalid-tooltip, .was-validated :invalid ~ .invalid-feedback, .was-validated :invalid ~ .invalid-tooltip { + display: block +} + +.form-control.is-invalid, .was-validated .form-control:invalid { + border-color: #dc3545; + padding-right: calc(1.5em + .75rem); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right calc(.375em + .1875rem) center; + background-size: calc(.75em + .375rem) calc(.75em + .375rem) +} + +.form-control.is-invalid:focus, .was-validated .form-control:invalid:focus { + border-color: #dc3545; + box-shadow: 0 0 0 .25rem rgba(220, 53, 69, .25) +} + +.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid { + padding-right: calc(1.5em + .75rem); + background-position: top calc(.375em + .1875rem) right calc(.375em + .1875rem) +} + +.form-select.is-invalid, .was-validated .form-select:invalid { + border-color: #dc3545 +} + +.form-select.is-invalid:not([multiple]):not([size]), .form-select.is-invalid:not([multiple])[size="1"], .was-validated .form-select:invalid:not([multiple]):not([size]), .was-validated .form-select:invalid:not([multiple])[size="1"] { + padding-right: 4.125rem; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e"); + background-position: right .75rem center, center right 2.25rem; + background-size: 16px 12px, calc(.75em + .375rem) calc(.75em + .375rem) +} + +.form-select.is-invalid:focus, .was-validated .form-select:invalid:focus { + border-color: #dc3545; + box-shadow: 0 0 0 .25rem rgba(220, 53, 69, .25) +} + +.form-check-input.is-invalid, .was-validated .form-check-input:invalid { + border-color: #dc3545 +} + +.form-check-input.is-invalid:checked, .was-validated .form-check-input:invalid:checked { + background-color: #dc3545 +} + +.form-check-input.is-invalid:focus, .was-validated .form-check-input:invalid:focus { + box-shadow: 0 0 0 .25rem rgba(220, 53, 69, .25) +} + +.form-check-input.is-invalid ~ .form-check-label, .was-validated .form-check-input:invalid ~ .form-check-label { + color: #dc3545 +} + +.form-check-inline .form-check-input ~ .invalid-feedback { + margin-left: .5em +} + +.input-group .form-control.is-invalid, .input-group .form-select.is-invalid, .was-validated .input-group .form-control:invalid, .was-validated .input-group .form-select:invalid { + z-index: 2 +} + +.input-group .form-control.is-invalid:focus, .input-group .form-select.is-invalid:focus, .was-validated .input-group .form-control:invalid:focus, .was-validated .input-group .form-select:invalid:focus { + z-index: 3 +} + +.btn { + display: inline-block; + font-weight: 400; + line-height: 1.5; + color: #212529; + text-align: center; + text-decoration: none; + vertical-align: middle; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + background-color: transparent; + border: 1px solid transparent; + padding: .375rem .75rem; + font-size: 1rem; + border-radius: .25rem; + transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out +} + +@media (prefers-reduced-motion: reduce) { + .btn { + transition: none + } +} + +.btn:hover { + color: #212529 +} + +.btn-check:focus + .btn, .btn:focus { + outline: 0; + box-shadow: 0 0 0 .25rem rgba(13, 110, 253, .25) +} + +.btn.disabled, .btn:disabled, fieldset:disabled .btn { + pointer-events: none; + opacity: .65 +} + +.btn-primary { + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd +} + +.btn-primary:hover { + color: #fff; + background-color: #0b5ed7; + border-color: #0a58ca +} + +.btn-check:focus + .btn-primary, .btn-primary:focus { + color: #fff; + background-color: #0b5ed7; + border-color: #0a58ca; + box-shadow: 0 0 0 .25rem rgba(49, 132, 253, .5) +} + +.btn-check:active + .btn-primary, .btn-check:checked + .btn-primary, .btn-primary.active, .btn-primary:active, .show > .btn-primary.dropdown-toggle { + color: #fff; + background-color: #0a58ca; + border-color: #0a53be +} + +.btn-check:active + .btn-primary:focus, .btn-check:checked + .btn-primary:focus, .btn-primary.active:focus, .btn-primary:active:focus, .show > .btn-primary.dropdown-toggle:focus { + box-shadow: 0 0 0 .25rem rgba(49, 132, 253, .5) +} + +.btn-primary.disabled, .btn-primary:disabled { + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd +} + +.btn-secondary { + color: #fff; + background-color: #6c757d; + border-color: #6c757d +} + +.btn-secondary:hover { + color: #fff; + background-color: #5c636a; + border-color: #565e64 +} + +.btn-check:focus + .btn-secondary, .btn-secondary:focus { + color: #fff; + background-color: #5c636a; + border-color: #565e64; + box-shadow: 0 0 0 .25rem rgba(130, 138, 145, .5) +} + +.btn-check:active + .btn-secondary, .btn-check:checked + .btn-secondary, .btn-secondary.active, .btn-secondary:active, .show > .btn-secondary.dropdown-toggle { + color: #fff; + background-color: #565e64; + border-color: #51585e +} + +.btn-check:active + .btn-secondary:focus, .btn-check:checked + .btn-secondary:focus, .btn-secondary.active:focus, .btn-secondary:active:focus, .show > .btn-secondary.dropdown-toggle:focus { + box-shadow: 0 0 0 .25rem rgba(130, 138, 145, .5) +} + +.btn-secondary.disabled, .btn-secondary:disabled { + color: #fff; + background-color: #6c757d; + border-color: #6c757d +} + +.btn-success { + color: #fff; + background-color: #198754; + border-color: #198754 +} + +.btn-success:hover { + color: #fff; + background-color: #157347; + border-color: #146c43 +} + +.btn-check:focus + .btn-success, .btn-success:focus { + color: #fff; + background-color: #157347; + border-color: #146c43; + box-shadow: 0 0 0 .25rem rgba(60, 153, 110, .5) +} + +.btn-check:active + .btn-success, .btn-check:checked + .btn-success, .btn-success.active, .btn-success:active, .show > .btn-success.dropdown-toggle { + color: #fff; + background-color: #146c43; + border-color: #13653f +} + +.btn-check:active + .btn-success:focus, .btn-check:checked + .btn-success:focus, .btn-success.active:focus, .btn-success:active:focus, .show > .btn-success.dropdown-toggle:focus { + box-shadow: 0 0 0 .25rem rgba(60, 153, 110, .5) +} + +.btn-success.disabled, .btn-success:disabled { + color: #fff; + background-color: #198754; + border-color: #198754 +} + +.btn-info { + color: #000; + background-color: #0dcaf0; + border-color: #0dcaf0 +} + +.btn-info:hover { + color: #000; + background-color: #31d2f2; + border-color: #25cff2 +} + +.btn-check:focus + .btn-info, .btn-info:focus { + color: #000; + background-color: #31d2f2; + border-color: #25cff2; + box-shadow: 0 0 0 .25rem rgba(11, 172, 204, .5) +} + +.btn-check:active + .btn-info, .btn-check:checked + .btn-info, .btn-info.active, .btn-info:active, .show > .btn-info.dropdown-toggle { + color: #000; + background-color: #3dd5f3; + border-color: #25cff2 +} + +.btn-check:active + .btn-info:focus, .btn-check:checked + .btn-info:focus, .btn-info.active:focus, .btn-info:active:focus, .show > .btn-info.dropdown-toggle:focus { + box-shadow: 0 0 0 .25rem rgba(11, 172, 204, .5) +} + +.btn-info.disabled, .btn-info:disabled { + color: #000; + background-color: #0dcaf0; + border-color: #0dcaf0 +} + +.btn-warning { + color: #000; + background-color: #ffc107; + border-color: #ffc107 +} + +.btn-warning:hover { + color: #000; + background-color: #ffca2c; + border-color: #ffc720 +} + +.btn-check:focus + .btn-warning, .btn-warning:focus { + color: #000; + background-color: #ffca2c; + border-color: #ffc720; + box-shadow: 0 0 0 .25rem rgba(217, 164, 6, .5) +} + +.btn-check:active + .btn-warning, .btn-check:checked + .btn-warning, .btn-warning.active, .btn-warning:active, .show > .btn-warning.dropdown-toggle { + color: #000; + background-color: #ffcd39; + border-color: #ffc720 +} + +.btn-check:active + .btn-warning:focus, .btn-check:checked + .btn-warning:focus, .btn-warning.active:focus, .btn-warning:active:focus, .show > .btn-warning.dropdown-toggle:focus { + box-shadow: 0 0 0 .25rem rgba(217, 164, 6, .5) +} + +.btn-warning.disabled, .btn-warning:disabled { + color: #000; + background-color: #ffc107; + border-color: #ffc107 +} + +.btn-danger { + color: #fff; + background-color: #dc3545; + border-color: #dc3545 +} + +.btn-danger:hover { + color: #fff; + background-color: #bb2d3b; + border-color: #b02a37 +} + +.btn-check:focus + .btn-danger, .btn-danger:focus { + color: #fff; + background-color: #bb2d3b; + border-color: #b02a37; + box-shadow: 0 0 0 .25rem rgba(225, 83, 97, .5) +} + +.btn-check:active + .btn-danger, .btn-check:checked + .btn-danger, .btn-danger.active, .btn-danger:active, .show > .btn-danger.dropdown-toggle { + color: #fff; + background-color: #b02a37; + border-color: #a52834 +} + +.btn-check:active + .btn-danger:focus, .btn-check:checked + .btn-danger:focus, .btn-danger.active:focus, .btn-danger:active:focus, .show > .btn-danger.dropdown-toggle:focus { + box-shadow: 0 0 0 .25rem rgba(225, 83, 97, .5) +} + +.btn-danger.disabled, .btn-danger:disabled { + color: #fff; + background-color: #dc3545; + border-color: #dc3545 +} + +.btn-light { + color: #000; + background-color: #f8f9fa; + border-color: #f8f9fa +} + +.btn-light:hover { + color: #000; + background-color: #f9fafb; + border-color: #f9fafb +} + +.btn-check:focus + .btn-light, .btn-light:focus { + color: #000; + background-color: #f9fafb; + border-color: #f9fafb; + box-shadow: 0 0 0 .25rem rgba(211, 212, 213, .5) +} + +.btn-check:active + .btn-light, .btn-check:checked + .btn-light, .btn-light.active, .btn-light:active, .show > .btn-light.dropdown-toggle { + color: #000; + background-color: #f9fafb; + border-color: #f9fafb +} + +.btn-check:active + .btn-light:focus, .btn-check:checked + .btn-light:focus, .btn-light.active:focus, .btn-light:active:focus, .show > .btn-light.dropdown-toggle:focus { + box-shadow: 0 0 0 .25rem rgba(211, 212, 213, .5) +} + +.btn-light.disabled, .btn-light:disabled { + color: #000; + background-color: #f8f9fa; + border-color: #f8f9fa +} + +.btn-dark { + color: #fff; + background-color: #212529; + border-color: #212529 +} + +.btn-dark:hover { + color: #fff; + background-color: #1c1f23; + border-color: #1a1e21 +} + +.btn-check:focus + .btn-dark, .btn-dark:focus { + color: #fff; + background-color: #1c1f23; + border-color: #1a1e21; + box-shadow: 0 0 0 .25rem rgba(66, 70, 73, .5) +} + +.btn-check:active + .btn-dark, .btn-check:checked + .btn-dark, .btn-dark.active, .btn-dark:active, .show > .btn-dark.dropdown-toggle { + color: #fff; + background-color: #1a1e21; + border-color: #191c1f +} + +.btn-check:active + .btn-dark:focus, .btn-check:checked + .btn-dark:focus, .btn-dark.active:focus, .btn-dark:active:focus, .show > .btn-dark.dropdown-toggle:focus { + box-shadow: 0 0 0 .25rem rgba(66, 70, 73, .5) +} + +.btn-dark.disabled, .btn-dark:disabled { + color: #fff; + background-color: #212529; + border-color: #212529 +} + +.btn-outline-primary { + color: #0d6efd; + border-color: #0d6efd +} + +.btn-outline-primary:hover { + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd +} + +.btn-check:focus + .btn-outline-primary, .btn-outline-primary:focus { + box-shadow: 0 0 0 .25rem rgba(13, 110, 253, .5) +} + +.btn-check:active + .btn-outline-primary, .btn-check:checked + .btn-outline-primary, .btn-outline-primary.active, .btn-outline-primary.dropdown-toggle.show, .btn-outline-primary:active { + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd +} + +.btn-check:active + .btn-outline-primary:focus, .btn-check:checked + .btn-outline-primary:focus, .btn-outline-primary.active:focus, .btn-outline-primary.dropdown-toggle.show:focus, .btn-outline-primary:active:focus { + box-shadow: 0 0 0 .25rem rgba(13, 110, 253, .5) +} + +.btn-outline-primary.disabled, .btn-outline-primary:disabled { + color: #0d6efd; + background-color: transparent +} + +.btn-outline-secondary { + color: #6c757d; + border-color: #6c757d +} + +.btn-outline-secondary:hover { + color: #fff; + background-color: #6c757d; + border-color: #6c757d +} + +.btn-check:focus + .btn-outline-secondary, .btn-outline-secondary:focus { + box-shadow: 0 0 0 .25rem rgba(108, 117, 125, .5) +} + +.btn-check:active + .btn-outline-secondary, .btn-check:checked + .btn-outline-secondary, .btn-outline-secondary.active, .btn-outline-secondary.dropdown-toggle.show, .btn-outline-secondary:active { + color: #fff; + background-color: #6c757d; + border-color: #6c757d +} + +.btn-check:active + .btn-outline-secondary:focus, .btn-check:checked + .btn-outline-secondary:focus, .btn-outline-secondary.active:focus, .btn-outline-secondary.dropdown-toggle.show:focus, .btn-outline-secondary:active:focus { + box-shadow: 0 0 0 .25rem rgba(108, 117, 125, .5) +} + +.btn-outline-secondary.disabled, .btn-outline-secondary:disabled { + color: #6c757d; + background-color: transparent +} + +.btn-outline-success { + color: #198754; + border-color: #198754 +} + +.btn-outline-success:hover { + color: #fff; + background-color: #198754; + border-color: #198754 +} + +.btn-check:focus + .btn-outline-success, .btn-outline-success:focus { + box-shadow: 0 0 0 .25rem rgba(25, 135, 84, .5) +} + +.btn-check:active + .btn-outline-success, .btn-check:checked + .btn-outline-success, .btn-outline-success.active, .btn-outline-success.dropdown-toggle.show, .btn-outline-success:active { + color: #fff; + background-color: #198754; + border-color: #198754 +} + +.btn-check:active + .btn-outline-success:focus, .btn-check:checked + .btn-outline-success:focus, .btn-outline-success.active:focus, .btn-outline-success.dropdown-toggle.show:focus, .btn-outline-success:active:focus { + box-shadow: 0 0 0 .25rem rgba(25, 135, 84, .5) +} + +.btn-outline-success.disabled, .btn-outline-success:disabled { + color: #198754; + background-color: transparent +} + +.btn-outline-info { + color: #0dcaf0; + border-color: #0dcaf0 +} + +.btn-outline-info:hover { + color: #000; + background-color: #0dcaf0; + border-color: #0dcaf0 +} + +.btn-check:focus + .btn-outline-info, .btn-outline-info:focus { + box-shadow: 0 0 0 .25rem rgba(13, 202, 240, .5) +} + +.btn-check:active + .btn-outline-info, .btn-check:checked + .btn-outline-info, .btn-outline-info.active, .btn-outline-info.dropdown-toggle.show, .btn-outline-info:active { + color: #000; + background-color: #0dcaf0; + border-color: #0dcaf0 +} + +.btn-check:active + .btn-outline-info:focus, .btn-check:checked + .btn-outline-info:focus, .btn-outline-info.active:focus, .btn-outline-info.dropdown-toggle.show:focus, .btn-outline-info:active:focus { + box-shadow: 0 0 0 .25rem rgba(13, 202, 240, .5) +} + +.btn-outline-info.disabled, .btn-outline-info:disabled { + color: #0dcaf0; + background-color: transparent +} + +.btn-outline-warning { + color: #ffc107; + border-color: #ffc107 +} + +.btn-outline-warning:hover { + color: #000; + background-color: #ffc107; + border-color: #ffc107 +} + +.btn-check:focus + .btn-outline-warning, .btn-outline-warning:focus { + box-shadow: 0 0 0 .25rem rgba(255, 193, 7, .5) +} + +.btn-check:active + .btn-outline-warning, .btn-check:checked + .btn-outline-warning, .btn-outline-warning.active, .btn-outline-warning.dropdown-toggle.show, .btn-outline-warning:active { + color: #000; + background-color: #ffc107; + border-color: #ffc107 +} + +.btn-check:active + .btn-outline-warning:focus, .btn-check:checked + .btn-outline-warning:focus, .btn-outline-warning.active:focus, .btn-outline-warning.dropdown-toggle.show:focus, .btn-outline-warning:active:focus { + box-shadow: 0 0 0 .25rem rgba(255, 193, 7, .5) +} + +.btn-outline-warning.disabled, .btn-outline-warning:disabled { + color: #ffc107; + background-color: transparent +} + +.btn-outline-danger { + color: #dc3545; + border-color: #dc3545 +} + +.btn-outline-danger:hover { + color: #fff; + background-color: #dc3545; + border-color: #dc3545 +} + +.btn-check:focus + .btn-outline-danger, .btn-outline-danger:focus { + box-shadow: 0 0 0 .25rem rgba(220, 53, 69, .5) +} + +.btn-check:active + .btn-outline-danger, .btn-check:checked + .btn-outline-danger, .btn-outline-danger.active, .btn-outline-danger.dropdown-toggle.show, .btn-outline-danger:active { + color: #fff; + background-color: #dc3545; + border-color: #dc3545 +} + +.btn-check:active + .btn-outline-danger:focus, .btn-check:checked + .btn-outline-danger:focus, .btn-outline-danger.active:focus, .btn-outline-danger.dropdown-toggle.show:focus, .btn-outline-danger:active:focus { + box-shadow: 0 0 0 .25rem rgba(220, 53, 69, .5) +} + +.btn-outline-danger.disabled, .btn-outline-danger:disabled { + color: #dc3545; + background-color: transparent +} + +.btn-outline-light { + color: #f8f9fa; + border-color: #f8f9fa +} + +.btn-outline-light:hover { + color: #000; + background-color: #f8f9fa; + border-color: #f8f9fa +} + +.btn-check:focus + .btn-outline-light, .btn-outline-light:focus { + box-shadow: 0 0 0 .25rem rgba(248, 249, 250, .5) +} + +.btn-check:active + .btn-outline-light, .btn-check:checked + .btn-outline-light, .btn-outline-light.active, .btn-outline-light.dropdown-toggle.show, .btn-outline-light:active { + color: #000; + background-color: #f8f9fa; + border-color: #f8f9fa +} + +.btn-check:active + .btn-outline-light:focus, .btn-check:checked + .btn-outline-light:focus, .btn-outline-light.active:focus, .btn-outline-light.dropdown-toggle.show:focus, .btn-outline-light:active:focus { + box-shadow: 0 0 0 .25rem rgba(248, 249, 250, .5) +} + +.btn-outline-light.disabled, .btn-outline-light:disabled { + color: #f8f9fa; + background-color: transparent +} + +.btn-outline-dark { + color: #212529; + border-color: #212529 +} + +.btn-outline-dark:hover { + color: #fff; + background-color: #212529; + border-color: #212529 +} + +.btn-check:focus + .btn-outline-dark, .btn-outline-dark:focus { + box-shadow: 0 0 0 .25rem rgba(33, 37, 41, .5) +} + +.btn-check:active + .btn-outline-dark, .btn-check:checked + .btn-outline-dark, .btn-outline-dark.active, .btn-outline-dark.dropdown-toggle.show, .btn-outline-dark:active { + color: #fff; + background-color: #212529; + border-color: #212529 +} + +.btn-check:active + .btn-outline-dark:focus, .btn-check:checked + .btn-outline-dark:focus, .btn-outline-dark.active:focus, .btn-outline-dark.dropdown-toggle.show:focus, .btn-outline-dark:active:focus { + box-shadow: 0 0 0 .25rem rgba(33, 37, 41, .5) +} + +.btn-outline-dark.disabled, .btn-outline-dark:disabled { + color: #212529; + background-color: transparent +} + +.btn-link { + font-weight: 400; + color: #0d6efd; + text-decoration: underline +} + +.btn-link:hover { + color: #0a58ca +} + +.btn-link.disabled, .btn-link:disabled { + color: #6c757d +} + +.btn-group-lg > .btn, .btn-lg { + padding: .5rem 1rem; + font-size: 1.25rem; + border-radius: .3rem +} + +.btn-group-sm > .btn, .btn-sm { + padding: .25rem .5rem; + font-size: .875rem; + border-radius: .2rem +} + +.fade { + transition: opacity .15s linear +} + +@media (prefers-reduced-motion: reduce) { + .fade { + transition: none + } +} + +.fade:not(.show) { + opacity: 0 +} + +.collapse:not(.show) { + display: none +} + +.collapsing { + height: 0; + overflow: hidden; + transition: height .35s ease +} + +@media (prefers-reduced-motion: reduce) { + .collapsing { + transition: none + } +} + +.dropdown, .dropend, .dropstart, .dropup { + position: relative +} + +.dropdown-toggle { + white-space: nowrap +} + +.dropdown-toggle::after { + display: inline-block; + margin-left: .255em; + vertical-align: .255em; + content: ""; + border-top: .3em solid; + border-right: .3em solid transparent; + border-bottom: 0; + border-left: .3em solid transparent +} + +.dropdown-toggle:empty::after { + margin-left: 0 +} + +.dropdown-menu { + position: absolute; + z-index: 1000; + display: none; + min-width: 10rem; + padding: .5rem 0; + margin: 0; + font-size: 1rem; + color: #212529; + text-align: left; + list-style: none; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, .15); + border-radius: .25rem +} + +.dropdown-menu[data-bs-popper] { + top: 100%; + left: 0; + margin-top: .125rem +} + +.dropdown-menu-start { + --bs-position: start +} + +.dropdown-menu-start[data-bs-popper] { + right: auto; + left: 0 +} + +.dropdown-menu-end { + --bs-position: end +} + +.dropdown-menu-end[data-bs-popper] { + right: 0; + left: auto +} + +@media (min-width: 576px) { + .dropdown-menu-sm-start { + --bs-position: start + } + + .dropdown-menu-sm-start[data-bs-popper] { + right: auto; + left: 0 + } + + .dropdown-menu-sm-end { + --bs-position: end + } + + .dropdown-menu-sm-end[data-bs-popper] { + right: 0; + left: auto + } +} + +@media (min-width: 768px) { + .dropdown-menu-md-start { + --bs-position: start + } + + .dropdown-menu-md-start[data-bs-popper] { + right: auto; + left: 0 + } + + .dropdown-menu-md-end { + --bs-position: end + } + + .dropdown-menu-md-end[data-bs-popper] { + right: 0; + left: auto + } +} + +@media (min-width: 992px) { + .dropdown-menu-lg-start { + --bs-position: start + } + + .dropdown-menu-lg-start[data-bs-popper] { + right: auto; + left: 0 + } + + .dropdown-menu-lg-end { + --bs-position: end + } + + .dropdown-menu-lg-end[data-bs-popper] { + right: 0; + left: auto + } +} + +@media (min-width: 1200px) { + .dropdown-menu-xl-start { + --bs-position: start + } + + .dropdown-menu-xl-start[data-bs-popper] { + right: auto; + left: 0 + } + + .dropdown-menu-xl-end { + --bs-position: end + } + + .dropdown-menu-xl-end[data-bs-popper] { + right: 0; + left: auto + } +} + +@media (min-width: 1400px) { + .dropdown-menu-xxl-start { + --bs-position: start + } + + .dropdown-menu-xxl-start[data-bs-popper] { + right: auto; + left: 0 + } + + .dropdown-menu-xxl-end { + --bs-position: end + } + + .dropdown-menu-xxl-end[data-bs-popper] { + right: 0; + left: auto + } +} + +.dropup .dropdown-menu[data-bs-popper] { + top: auto; + bottom: 100%; + margin-top: 0; + margin-bottom: .125rem +} + +.dropup .dropdown-toggle::after { + display: inline-block; + margin-left: .255em; + vertical-align: .255em; + content: ""; + border-top: 0; + border-right: .3em solid transparent; + border-bottom: .3em solid; + border-left: .3em solid transparent +} + +.dropup .dropdown-toggle:empty::after { + margin-left: 0 +} + +.dropend .dropdown-menu[data-bs-popper] { + top: 0; + right: auto; + left: 100%; + margin-top: 0; + margin-left: .125rem +} + +.dropend .dropdown-toggle::after { + display: inline-block; + margin-left: .255em; + vertical-align: .255em; + content: ""; + border-top: .3em solid transparent; + border-right: 0; + border-bottom: .3em solid transparent; + border-left: .3em solid +} + +.dropend .dropdown-toggle:empty::after { + margin-left: 0 +} + +.dropend .dropdown-toggle::after { + vertical-align: 0 +} + +.dropstart .dropdown-menu[data-bs-popper] { + top: 0; + right: 100%; + left: auto; + margin-top: 0; + margin-right: .125rem +} + +.dropstart .dropdown-toggle::after { + display: inline-block; + margin-left: .255em; + vertical-align: .255em; + content: "" +} + +.dropstart .dropdown-toggle::after { + display: none +} + +.dropstart .dropdown-toggle::before { + display: inline-block; + margin-right: .255em; + vertical-align: .255em; + content: ""; + border-top: .3em solid transparent; + border-right: .3em solid; + border-bottom: .3em solid transparent +} + +.dropstart .dropdown-toggle:empty::after { + margin-left: 0 +} + +.dropstart .dropdown-toggle::before { + vertical-align: 0 +} + +.dropdown-divider { + height: 0; + margin: .5rem 0; + overflow: hidden; + border-top: 1px solid rgba(0, 0, 0, .15) +} + +.dropdown-item { + display: block; + width: 100%; + padding: .25rem 1rem; + clear: both; + font-weight: 400; + color: #212529; + text-align: inherit; + text-decoration: none; + white-space: nowrap; + background-color: transparent; + border: 0 +} + +.dropdown-item:focus, .dropdown-item:hover { + color: #1e2125; + background-color: #e9ecef +} + +.dropdown-item.active, .dropdown-item:active { + color: #fff; + text-decoration: none; + background-color: #0d6efd +} + +.dropdown-item.disabled, .dropdown-item:disabled { + color: #adb5bd; + pointer-events: none; + background-color: transparent +} + +.dropdown-menu.show { + display: block +} + +.dropdown-header { + display: block; + padding: .5rem 1rem; + margin-bottom: 0; + font-size: .875rem; + color: #6c757d; + white-space: nowrap +} + +.dropdown-item-text { + display: block; + padding: .25rem 1rem; + color: #212529 +} + +.dropdown-menu-dark { + color: #dee2e6; + background-color: #343a40; + border-color: rgba(0, 0, 0, .15) +} + +.dropdown-menu-dark .dropdown-item { + color: #dee2e6 +} + +.dropdown-menu-dark .dropdown-item:focus, .dropdown-menu-dark .dropdown-item:hover { + color: #fff; + background-color: rgba(255, 255, 255, .15) +} + +.dropdown-menu-dark .dropdown-item.active, .dropdown-menu-dark .dropdown-item:active { + color: #fff; + background-color: #0d6efd +} + +.dropdown-menu-dark .dropdown-item.disabled, .dropdown-menu-dark .dropdown-item:disabled { + color: #adb5bd +} + +.dropdown-menu-dark .dropdown-divider { + border-color: rgba(0, 0, 0, .15) +} + +.dropdown-menu-dark .dropdown-item-text { + color: #dee2e6 +} + +.dropdown-menu-dark .dropdown-header { + color: #adb5bd +} + +.btn-group, .btn-group-vertical { + position: relative; + display: inline-flex; + vertical-align: middle +} + +.btn-group-vertical > .btn, .btn-group > .btn { + position: relative; + flex: 1 1 auto +} + +.btn-group-vertical > .btn-check:checked + .btn, .btn-group-vertical > .btn-check:focus + .btn, .btn-group-vertical > .btn.active, .btn-group-vertical > .btn:active, .btn-group-vertical > .btn:focus, .btn-group-vertical > .btn:hover, .btn-group > .btn-check:checked + .btn, .btn-group > .btn-check:focus + .btn, .btn-group > .btn.active, .btn-group > .btn:active, .btn-group > .btn:focus, .btn-group > .btn:hover { + z-index: 1 +} + +.btn-toolbar { + display: flex; + flex-wrap: wrap; + justify-content: flex-start +} + +.btn-toolbar .input-group { + width: auto +} + +.btn-group > .btn-group:not(:first-child), .btn-group > .btn:not(:first-child) { + margin-left: -1px +} + +.btn-group > .btn-group:not(:last-child) > .btn, .btn-group > .btn:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0 +} + +.btn-group > .btn-group:not(:first-child) > .btn, .btn-group > .btn:nth-child(n+3), .btn-group > :not(.btn-check) + .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0 +} + +.dropdown-toggle-split { + padding-right: .5625rem; + padding-left: .5625rem +} + +.dropdown-toggle-split::after, .dropend .dropdown-toggle-split::after, .dropup .dropdown-toggle-split::after { + margin-left: 0 +} + +.dropstart .dropdown-toggle-split::before { + margin-right: 0 +} + +.btn-group-sm > .btn + .dropdown-toggle-split, .btn-sm + .dropdown-toggle-split { + padding-right: .375rem; + padding-left: .375rem +} + +.btn-group-lg > .btn + .dropdown-toggle-split, .btn-lg + .dropdown-toggle-split { + padding-right: .75rem; + padding-left: .75rem +} + +.btn-group-vertical { + flex-direction: column; + align-items: flex-start; + justify-content: center +} + +.btn-group-vertical > .btn, .btn-group-vertical > .btn-group { + width: 100% +} + +.btn-group-vertical > .btn-group:not(:first-child), .btn-group-vertical > .btn:not(:first-child) { + margin-top: -1px +} + +.btn-group-vertical > .btn-group:not(:last-child) > .btn, .btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle) { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0 +} + +.btn-group-vertical > .btn-group:not(:first-child) > .btn, .btn-group-vertical > .btn ~ .btn { + border-top-left-radius: 0; + border-top-right-radius: 0 +} + +.nav { + display: flex; + flex-wrap: wrap; + padding-left: 0; + margin-bottom: 0; + list-style: none +} + +.nav-link { + display: block; + padding: .5rem 1rem; + color: #0d6efd; + text-decoration: none; + transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out +} + +@media (prefers-reduced-motion: reduce) { + .nav-link { + transition: none + } +} + +.nav-link:focus, .nav-link:hover { + color: #0a58ca +} + +.nav-link.disabled { + color: #6c757d; + pointer-events: none; + cursor: default +} + +.nav-tabs { + border-bottom: 1px solid #dee2e6 +} + +.nav-tabs .nav-link { + margin-bottom: -1px; + background: 0 0; + border: 1px solid transparent; + border-top-left-radius: .25rem; + border-top-right-radius: .25rem +} + +.nav-tabs .nav-link:focus, .nav-tabs .nav-link:hover { + border-color: #e9ecef #e9ecef #dee2e6; + isolation: isolate +} + +.nav-tabs .nav-link.disabled { + color: #6c757d; + background-color: transparent; + border-color: transparent +} + +.nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link.active { + color: #495057; + background-color: #fff; + border-color: #dee2e6 #dee2e6 #fff +} + +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-left-radius: 0; + border-top-right-radius: 0 +} + +.nav-pills .nav-link { + background: 0 0; + border: 0; + border-radius: .25rem +} + +.nav-pills .nav-link.active, .nav-pills .show > .nav-link { + color: #fff; + background-color: #0d6efd +} + +.nav-fill .nav-item, .nav-fill > .nav-link { + flex: 1 1 auto; + text-align: center +} + +.nav-justified .nav-item, .nav-justified > .nav-link { + flex-basis: 0; + flex-grow: 1; + text-align: center +} + +.nav-fill .nav-item .nav-link, .nav-justified .nav-item .nav-link { + width: 100% +} + +.tab-content > .tab-pane { + display: none +} + +.tab-content > .active { + display: block +} + +.navbar { + position: relative; + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + padding-top: .5rem; + padding-bottom: .5rem +} + +.navbar > .container, .navbar > .container-fluid, .navbar > .container-lg, .navbar > .container-md, .navbar > .container-sm, .navbar > .container-xl, .navbar > .container-xxl { + display: flex; + flex-wrap: inherit; + align-items: center; + justify-content: space-between +} + +.navbar-brand { + padding-top: .3125rem; + padding-bottom: .3125rem; + margin-right: 1rem; + font-size: 1.25rem; + text-decoration: none; + white-space: nowrap +} + +.navbar-nav { + display: flex; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + list-style: none +} + +.navbar-nav .nav-link { + padding-right: 0; + padding-left: 0 +} + +.navbar-nav .dropdown-menu { + position: static +} + +.navbar-text { + padding-top: .5rem; + padding-bottom: .5rem +} + +.navbar-collapse { + flex-basis: 100%; + flex-grow: 1; + align-items: center +} + +.navbar-toggler { + padding: .25rem .75rem; + font-size: 1.25rem; + line-height: 1; + background-color: transparent; + border: 1px solid transparent; + border-radius: .25rem; + transition: box-shadow .15s ease-in-out +} + +@media (prefers-reduced-motion: reduce) { + .navbar-toggler { + transition: none + } +} + +.navbar-toggler:hover { + text-decoration: none +} + +.navbar-toggler:focus { + text-decoration: none; + outline: 0; + box-shadow: 0 0 0 .25rem +} + +.navbar-toggler-icon { + display: inline-block; + width: 1.5em; + height: 1.5em; + vertical-align: middle; + background-repeat: no-repeat; + background-position: center; + background-size: 100% +} + +.navbar-nav-scroll { + max-height: var(--bs-scroll-height, 75vh); + overflow-y: auto +} + +@media (min-width: 576px) { + .navbar-expand-sm { + flex-wrap: nowrap; + justify-content: flex-start + } + + .navbar-expand-sm .navbar-nav { + flex-direction: row + } + + .navbar-expand-sm .navbar-nav .dropdown-menu { + position: absolute + } + + .navbar-expand-sm .navbar-nav .nav-link { + padding-right: .5rem; + padding-left: .5rem + } + + .navbar-expand-sm .navbar-nav-scroll { + overflow: visible + } + + .navbar-expand-sm .navbar-collapse { + display: flex !important; + flex-basis: auto + } + + .navbar-expand-sm .navbar-toggler { + display: none + } +} + +@media (min-width: 768px) { + .navbar-expand-md { + flex-wrap: nowrap; + justify-content: flex-start + } + + .navbar-expand-md .navbar-nav { + flex-direction: row + } + + .navbar-expand-md .navbar-nav .dropdown-menu { + position: absolute + } + + .navbar-expand-md .navbar-nav .nav-link { + padding-right: .5rem; + padding-left: .5rem + } + + .navbar-expand-md .navbar-nav-scroll { + overflow: visible + } + + .navbar-expand-md .navbar-collapse { + display: flex !important; + flex-basis: auto + } + + .navbar-expand-md .navbar-toggler { + display: none + } +} + +@media (min-width: 992px) { + .navbar-expand-lg { + flex-wrap: nowrap; + justify-content: flex-start + } + + .navbar-expand-lg .navbar-nav { + flex-direction: row + } + + .navbar-expand-lg .navbar-nav .dropdown-menu { + position: absolute + } + + .navbar-expand-lg .navbar-nav .nav-link { + padding-right: .5rem; + padding-left: .5rem + } + + .navbar-expand-lg .navbar-nav-scroll { + overflow: visible + } + + .navbar-expand-lg .navbar-collapse { + display: flex !important; + flex-basis: auto + } + + .navbar-expand-lg .navbar-toggler { + display: none + } +} + +@media (min-width: 1200px) { + .navbar-expand-xl { + flex-wrap: nowrap; + justify-content: flex-start + } + + .navbar-expand-xl .navbar-nav { + flex-direction: row + } + + .navbar-expand-xl .navbar-nav .dropdown-menu { + position: absolute + } + + .navbar-expand-xl .navbar-nav .nav-link { + padding-right: .5rem; + padding-left: .5rem + } + + .navbar-expand-xl .navbar-nav-scroll { + overflow: visible + } + + .navbar-expand-xl .navbar-collapse { + display: flex !important; + flex-basis: auto + } + + .navbar-expand-xl .navbar-toggler { + display: none + } +} + +@media (min-width: 1400px) { + .navbar-expand-xxl { + flex-wrap: nowrap; + justify-content: flex-start + } + + .navbar-expand-xxl .navbar-nav { + flex-direction: row + } + + .navbar-expand-xxl .navbar-nav .dropdown-menu { + position: absolute + } + + .navbar-expand-xxl .navbar-nav .nav-link { + padding-right: .5rem; + padding-left: .5rem + } + + .navbar-expand-xxl .navbar-nav-scroll { + overflow: visible + } + + .navbar-expand-xxl .navbar-collapse { + display: flex !important; + flex-basis: auto + } + + .navbar-expand-xxl .navbar-toggler { + display: none + } +} + +.navbar-expand { + flex-wrap: nowrap; + justify-content: flex-start +} + +.navbar-expand .navbar-nav { + flex-direction: row +} + +.navbar-expand .navbar-nav .dropdown-menu { + position: absolute +} + +.navbar-expand .navbar-nav .nav-link { + padding-right: .5rem; + padding-left: .5rem +} + +.navbar-expand .navbar-nav-scroll { + overflow: visible +} + +.navbar-expand .navbar-collapse { + display: flex !important; + flex-basis: auto +} + +.navbar-expand .navbar-toggler { + display: none +} + +.navbar-light .navbar-brand { + color: rgba(0, 0, 0, .9) +} + +.navbar-light .navbar-brand:focus, .navbar-light .navbar-brand:hover { + color: rgba(0, 0, 0, .9) +} + +.navbar-light .navbar-nav .nav-link { + color: rgba(0, 0, 0, .55) +} + +.navbar-light .navbar-nav .nav-link:focus, .navbar-light .navbar-nav .nav-link:hover { + color: rgba(0, 0, 0, .7) +} + +.navbar-light .navbar-nav .nav-link.disabled { + color: rgba(0, 0, 0, .3) +} + +.navbar-light .navbar-nav .nav-link.active, .navbar-light .navbar-nav .show > .nav-link { + color: rgba(0, 0, 0, .9) +} + +.navbar-light .navbar-toggler { + color: rgba(0, 0, 0, .55); + border-color: rgba(0, 0, 0, .1) +} + +.navbar-light .navbar-toggler-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") +} + +.navbar-light .navbar-text { + color: rgba(0, 0, 0, .55) +} + +.navbar-light .navbar-text a, .navbar-light .navbar-text a:focus, .navbar-light .navbar-text a:hover { + color: rgba(0, 0, 0, .9) +} + +.navbar-dark .navbar-brand { + color: #fff +} + +.navbar-dark .navbar-brand:focus, .navbar-dark .navbar-brand:hover { + color: #fff +} + +.navbar-dark .navbar-nav .nav-link { + color: rgba(255, 255, 255, .55) +} + +.navbar-dark .navbar-nav .nav-link:focus, .navbar-dark .navbar-nav .nav-link:hover { + color: rgba(255, 255, 255, .75) +} + +.navbar-dark .navbar-nav .nav-link.disabled { + color: rgba(255, 255, 255, .25) +} + +.navbar-dark .navbar-nav .nav-link.active, .navbar-dark .navbar-nav .show > .nav-link { + color: #fff +} + +.navbar-dark .navbar-toggler { + color: rgba(255, 255, 255, .55); + border-color: rgba(255, 255, 255, .1) +} + +.navbar-dark .navbar-toggler-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") +} + +.navbar-dark .navbar-text { + color: rgba(255, 255, 255, .55) +} + +.navbar-dark .navbar-text a, .navbar-dark .navbar-text a:focus, .navbar-dark .navbar-text a:hover { + color: #fff +} + +.card { + position: relative; + display: flex; + flex-direction: column; + min-width: 0; + word-wrap: break-word; + background-color: #fff; + background-clip: border-box; + border: 1px solid rgba(0, 0, 0, .125); + border-radius: .25rem +} + +.card > hr { + margin-right: 0; + margin-left: 0 +} + +.card > .list-group { + border-top: inherit; + border-bottom: inherit +} + +.card > .list-group:first-child { + border-top-width: 0; + border-top-left-radius: calc(.25rem - 1px); + border-top-right-radius: calc(.25rem - 1px) +} + +.card > .list-group:last-child { + border-bottom-width: 0; + border-bottom-right-radius: calc(.25rem - 1px); + border-bottom-left-radius: calc(.25rem - 1px) +} + +.card > .card-header + .list-group, .card > .list-group + .card-footer { + border-top: 0 +} + +.card-body { + flex: 1 1 auto; + padding: 1rem 1rem +} + +.card-title { + margin-bottom: .5rem +} + +.card-subtitle { + margin-top: -.25rem; + margin-bottom: 0 +} + +.card-text:last-child { + margin-bottom: 0 +} + +.card-link:hover { + text-decoration: none +} + +.card-link + .card-link { + margin-left: 1rem +} + +.card-header { + padding: .5rem 1rem; + margin-bottom: 0; + background-color: rgba(0, 0, 0, .03); + border-bottom: 1px solid rgba(0, 0, 0, .125) +} + +.card-header:first-child { + border-radius: calc(.25rem - 1px) calc(.25rem - 1px) 0 0 +} + +.card-footer { + padding: .5rem 1rem; + background-color: rgba(0, 0, 0, .03); + border-top: 1px solid rgba(0, 0, 0, .125) +} + +.card-footer:last-child { + border-radius: 0 0 calc(.25rem - 1px) calc(.25rem - 1px) +} + +.card-header-tabs { + margin-right: -.5rem; + margin-bottom: -.5rem; + margin-left: -.5rem; + border-bottom: 0 +} + +.card-header-pills { + margin-right: -.5rem; + margin-left: -.5rem +} + +.card-img-overlay { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + padding: 1rem; + border-radius: calc(.25rem - 1px) +} + +.card-img, .card-img-bottom, .card-img-top { + width: 100% +} + +.card-img, .card-img-top { + border-top-left-radius: calc(.25rem - 1px); + border-top-right-radius: calc(.25rem - 1px) +} + +.card-img, .card-img-bottom { + border-bottom-right-radius: calc(.25rem - 1px); + border-bottom-left-radius: calc(.25rem - 1px) +} + +.card-group > .card { + margin-bottom: .75rem +} + +@media (min-width: 576px) { + .card-group { + display: flex; + flex-flow: row wrap + } + + .card-group > .card { + flex: 1 0 0%; + margin-bottom: 0 + } + + .card-group > .card + .card { + margin-left: 0; + border-left: 0 + } + + .card-group > .card:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0 + } + + .card-group > .card:not(:last-child) .card-header, .card-group > .card:not(:last-child) .card-img-top { + border-top-right-radius: 0 + } + + .card-group > .card:not(:last-child) .card-footer, .card-group > .card:not(:last-child) .card-img-bottom { + border-bottom-right-radius: 0 + } + + .card-group > .card:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0 + } + + .card-group > .card:not(:first-child) .card-header, .card-group > .card:not(:first-child) .card-img-top { + border-top-left-radius: 0 + } + + .card-group > .card:not(:first-child) .card-footer, .card-group > .card:not(:first-child) .card-img-bottom { + border-bottom-left-radius: 0 + } +} + +.accordion-button { + position: relative; + display: flex; + align-items: center; + width: 100%; + padding: 1rem 1.25rem; + font-size: 1rem; + color: #212529; + text-align: left; + background-color: #fff; + border: 0; + border-radius: 0; + overflow-anchor: none; + transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out, border-radius .15s ease +} + +@media (prefers-reduced-motion: reduce) { + .accordion-button { + transition: none + } +} + +.accordion-button:not(.collapsed) { + color: #0c63e4; + background-color: #e7f1ff; + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .125) +} + +.accordion-button:not(.collapsed)::after { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230c63e4'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); + transform: rotate(-180deg) +} + +.accordion-button::after { + flex-shrink: 0; + width: 1.25rem; + height: 1.25rem; + margin-left: auto; + content: ""; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-size: 1.25rem; + transition: transform .2s ease-in-out +} + +@media (prefers-reduced-motion: reduce) { + .accordion-button::after { + transition: none + } +} + +.accordion-button:hover { + z-index: 2 +} + +.accordion-button:focus { + z-index: 3; + border-color: #86b7fe; + outline: 0; + box-shadow: 0 0 0 .25rem rgba(13, 110, 253, .25) +} + +.accordion-header { + margin-bottom: 0 +} + +.accordion-item { + background-color: #fff; + border: 1px solid rgba(0, 0, 0, .125) +} + +.accordion-item:first-of-type { + border-top-left-radius: .25rem; + border-top-right-radius: .25rem +} + +.accordion-item:first-of-type .accordion-button { + border-top-left-radius: calc(.25rem - 1px); + border-top-right-radius: calc(.25rem - 1px) +} + +.accordion-item:not(:first-of-type) { + border-top: 0 +} + +.accordion-item:last-of-type { + border-bottom-right-radius: .25rem; + border-bottom-left-radius: .25rem +} + +.accordion-item:last-of-type .accordion-button.collapsed { + border-bottom-right-radius: calc(.25rem - 1px); + border-bottom-left-radius: calc(.25rem - 1px) +} + +.accordion-item:last-of-type .accordion-collapse { + border-bottom-right-radius: .25rem; + border-bottom-left-radius: .25rem +} + +.accordion-body { + padding: 1rem 1.25rem +} + +.accordion-flush .accordion-collapse { + border-width: 0 +} + +.accordion-flush .accordion-item { + border-right: 0; + border-left: 0; + border-radius: 0 +} + +.accordion-flush .accordion-item:first-child { + border-top: 0 +} + +.accordion-flush .accordion-item:last-child { + border-bottom: 0 +} + +.accordion-flush .accordion-item .accordion-button { + border-radius: 0 +} + +.breadcrumb { + display: flex; + flex-wrap: wrap; + padding: 0 0; + margin-bottom: 1rem; + list-style: none +} + +.breadcrumb-item + .breadcrumb-item { + padding-left: .5rem +} + +.breadcrumb-item + .breadcrumb-item::before { + float: left; + padding-right: .5rem; + color: #6c757d; + content: var(--bs-breadcrumb-divider, "/") +} + +.breadcrumb-item.active { + color: #6c757d +} + +.pagination { + display: flex; + padding-left: 0; + list-style: none +} + +.page-link { + position: relative; + display: block; + color: #0d6efd; + text-decoration: none; + background-color: #fff; + border: 1px solid #dee2e6; + transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out +} + +@media (prefers-reduced-motion: reduce) { + .page-link { + transition: none + } +} + +.page-link:hover { + z-index: 2; + color: #0a58ca; + background-color: #e9ecef; + border-color: #dee2e6 +} + +.page-link:focus { + z-index: 3; + color: #0a58ca; + background-color: #e9ecef; + outline: 0; + box-shadow: 0 0 0 .25rem rgba(13, 110, 253, .25) +} + +.page-item:not(:first-child) .page-link { + margin-left: -1px +} + +.page-item.active .page-link { + z-index: 3; + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd +} + +.page-item.disabled .page-link { + color: #6c757d; + pointer-events: none; + background-color: #fff; + border-color: #dee2e6 +} + +.page-link { + padding: .375rem .75rem +} + +.page-item:first-child .page-link { + border-top-left-radius: .25rem; + border-bottom-left-radius: .25rem +} + +.page-item:last-child .page-link { + border-top-right-radius: .25rem; + border-bottom-right-radius: .25rem +} + +.pagination-lg .page-link { + padding: .75rem 1.5rem; + font-size: 1.25rem +} + +.pagination-lg .page-item:first-child .page-link { + border-top-left-radius: .3rem; + border-bottom-left-radius: .3rem +} + +.pagination-lg .page-item:last-child .page-link { + border-top-right-radius: .3rem; + border-bottom-right-radius: .3rem +} + +.pagination-sm .page-link { + padding: .25rem .5rem; + font-size: .875rem +} + +.pagination-sm .page-item:first-child .page-link { + border-top-left-radius: .2rem; + border-bottom-left-radius: .2rem +} + +.pagination-sm .page-item:last-child .page-link { + border-top-right-radius: .2rem; + border-bottom-right-radius: .2rem +} + +.badge { + display: inline-block; + padding: .35em .65em; + font-size: .75em; + font-weight: 700; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25rem +} + +.badge:empty { + display: none +} + +.btn .badge { + position: relative; + top: -1px +} + +.alert { + position: relative; + padding: 1rem 1rem; + margin-bottom: 1rem; + border: 1px solid transparent; + border-radius: .25rem +} + +.alert-heading { + color: inherit +} + +.alert-link { + font-weight: 700 +} + +.alert-dismissible { + padding-right: 3rem +} + +.alert-dismissible .btn-close { + position: absolute; + top: 0; + right: 0; + z-index: 2; + padding: 1.25rem 1rem +} + +.alert-primary { + color: #084298; + background-color: #cfe2ff; + border-color: #b6d4fe +} + +.alert-primary .alert-link { + color: #06357a +} + +.alert-secondary { + color: #41464b; + background-color: #e2e3e5; + border-color: #d3d6d8 +} + +.alert-secondary .alert-link { + color: #34383c +} + +.alert-success { + color: #0f5132; + background-color: #d1e7dd; + border-color: #badbcc +} + +.alert-success .alert-link { + color: #0c4128 +} + +.alert-info { + color: #055160; + background-color: #cff4fc; + border-color: #b6effb +} + +.alert-info .alert-link { + color: #04414d +} + +.alert-warning { + color: #664d03; + background-color: #fff3cd; + border-color: #ffecb5 +} + +.alert-warning .alert-link { + color: #523e02 +} + +.alert-danger { + color: #842029; + background-color: #f8d7da; + border-color: #f5c2c7 +} + +.alert-danger .alert-link { + color: #6a1a21 +} + +.alert-light { + color: #636464; + background-color: #fefefe; + border-color: #fdfdfe +} + +.alert-light .alert-link { + color: #4f5050 +} + +.alert-dark { + color: #141619; + background-color: #d3d3d4; + border-color: #bcbebf +} + +.alert-dark .alert-link { + color: #101214 +} + +@-webkit-keyframes progress-bar-stripes { + 0% { + background-position-x: 1rem + } +} + +@keyframes progress-bar-stripes { + 0% { + background-position-x: 1rem + } +} + +.progress { + display: flex; + height: 1rem; + overflow: hidden; + font-size: .75rem; + background-color: #e9ecef; + border-radius: .25rem +} + +.progress-bar { + display: flex; + flex-direction: column; + justify-content: center; + overflow: hidden; + color: #fff; + text-align: center; + white-space: nowrap; + background-color: #0d6efd; + transition: width .6s ease +} + +@media (prefers-reduced-motion: reduce) { + .progress-bar { + transition: none + } +} + +.progress-bar-striped { + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-size: 1rem 1rem +} + +.progress-bar-animated { + -webkit-animation: 1s linear infinite progress-bar-stripes; + animation: 1s linear infinite progress-bar-stripes +} + +@media (prefers-reduced-motion: reduce) { + .progress-bar-animated { + -webkit-animation: none; + animation: none + } +} + +.list-group { + display: flex; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + border-radius: .25rem +} + +.list-group-numbered { + list-style-type: none; + counter-reset: section +} + +.list-group-numbered > li::before { + content: counters(section, ".") ". "; + counter-increment: section +} + +.list-group-item-action { + width: 100%; + color: #495057; + text-align: inherit +} + +.list-group-item-action:focus, .list-group-item-action:hover { + z-index: 1; + color: #495057; + text-decoration: none; + background-color: #f8f9fa +} + +.list-group-item-action:active { + color: #212529; + background-color: #e9ecef +} + +.list-group-item { + position: relative; + display: block; + padding: .5rem 1rem; + color: #212529; + text-decoration: none; + background-color: #fff; + border: 1px solid rgba(0, 0, 0, .125) +} + +.list-group-item:first-child { + border-top-left-radius: inherit; + border-top-right-radius: inherit +} + +.list-group-item:last-child { + border-bottom-right-radius: inherit; + border-bottom-left-radius: inherit +} + +.list-group-item.disabled, .list-group-item:disabled { + color: #6c757d; + pointer-events: none; + background-color: #fff +} + +.list-group-item.active { + z-index: 2; + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd +} + +.list-group-item + .list-group-item { + border-top-width: 0 +} + +.list-group-item + .list-group-item.active { + margin-top: -1px; + border-top-width: 1px +} + +.list-group-horizontal { + flex-direction: row +} + +.list-group-horizontal > .list-group-item:first-child { + border-bottom-left-radius: .25rem; + border-top-right-radius: 0 +} + +.list-group-horizontal > .list-group-item:last-child { + border-top-right-radius: .25rem; + border-bottom-left-radius: 0 +} + +.list-group-horizontal > .list-group-item.active { + margin-top: 0 +} + +.list-group-horizontal > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0 +} + +.list-group-horizontal > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px +} + +@media (min-width: 576px) { + .list-group-horizontal-sm { + flex-direction: row + } + + .list-group-horizontal-sm > .list-group-item:first-child { + border-bottom-left-radius: .25rem; + border-top-right-radius: 0 + } + + .list-group-horizontal-sm > .list-group-item:last-child { + border-top-right-radius: .25rem; + border-bottom-left-radius: 0 + } + + .list-group-horizontal-sm > .list-group-item.active { + margin-top: 0 + } + + .list-group-horizontal-sm > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0 + } + + .list-group-horizontal-sm > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px + } +} + +@media (min-width: 768px) { + .list-group-horizontal-md { + flex-direction: row + } + + .list-group-horizontal-md > .list-group-item:first-child { + border-bottom-left-radius: .25rem; + border-top-right-radius: 0 + } + + .list-group-horizontal-md > .list-group-item:last-child { + border-top-right-radius: .25rem; + border-bottom-left-radius: 0 + } + + .list-group-horizontal-md > .list-group-item.active { + margin-top: 0 + } + + .list-group-horizontal-md > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0 + } + + .list-group-horizontal-md > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px + } +} + +@media (min-width: 992px) { + .list-group-horizontal-lg { + flex-direction: row + } + + .list-group-horizontal-lg > .list-group-item:first-child { + border-bottom-left-radius: .25rem; + border-top-right-radius: 0 + } + + .list-group-horizontal-lg > .list-group-item:last-child { + border-top-right-radius: .25rem; + border-bottom-left-radius: 0 + } + + .list-group-horizontal-lg > .list-group-item.active { + margin-top: 0 + } + + .list-group-horizontal-lg > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0 + } + + .list-group-horizontal-lg > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px + } +} + +@media (min-width: 1200px) { + .list-group-horizontal-xl { + flex-direction: row + } + + .list-group-horizontal-xl > .list-group-item:first-child { + border-bottom-left-radius: .25rem; + border-top-right-radius: 0 + } + + .list-group-horizontal-xl > .list-group-item:last-child { + border-top-right-radius: .25rem; + border-bottom-left-radius: 0 + } + + .list-group-horizontal-xl > .list-group-item.active { + margin-top: 0 + } + + .list-group-horizontal-xl > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0 + } + + .list-group-horizontal-xl > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px + } +} + +@media (min-width: 1400px) { + .list-group-horizontal-xxl { + flex-direction: row + } + + .list-group-horizontal-xxl > .list-group-item:first-child { + border-bottom-left-radius: .25rem; + border-top-right-radius: 0 + } + + .list-group-horizontal-xxl > .list-group-item:last-child { + border-top-right-radius: .25rem; + border-bottom-left-radius: 0 + } + + .list-group-horizontal-xxl > .list-group-item.active { + margin-top: 0 + } + + .list-group-horizontal-xxl > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0 + } + + .list-group-horizontal-xxl > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px + } +} + +.list-group-flush { + border-radius: 0 +} + +.list-group-flush > .list-group-item { + border-width: 0 0 1px +} + +.list-group-flush > .list-group-item:last-child { + border-bottom-width: 0 +} + +.list-group-item-primary { + color: #084298; + background-color: #cfe2ff +} + +.list-group-item-primary.list-group-item-action:focus, .list-group-item-primary.list-group-item-action:hover { + color: #084298; + background-color: #bacbe6 +} + +.list-group-item-primary.list-group-item-action.active { + color: #fff; + background-color: #084298; + border-color: #084298 +} + +.list-group-item-secondary { + color: #41464b; + background-color: #e2e3e5 +} + +.list-group-item-secondary.list-group-item-action:focus, .list-group-item-secondary.list-group-item-action:hover { + color: #41464b; + background-color: #cbccce +} + +.list-group-item-secondary.list-group-item-action.active { + color: #fff; + background-color: #41464b; + border-color: #41464b +} + +.list-group-item-success { + color: #0f5132; + background-color: #d1e7dd +} + +.list-group-item-success.list-group-item-action:focus, .list-group-item-success.list-group-item-action:hover { + color: #0f5132; + background-color: #bcd0c7 +} + +.list-group-item-success.list-group-item-action.active { + color: #fff; + background-color: #0f5132; + border-color: #0f5132 +} + +.list-group-item-info { + color: #055160; + background-color: #cff4fc +} + +.list-group-item-info.list-group-item-action:focus, .list-group-item-info.list-group-item-action:hover { + color: #055160; + background-color: #badce3 +} + +.list-group-item-info.list-group-item-action.active { + color: #fff; + background-color: #055160; + border-color: #055160 +} + +.list-group-item-warning { + color: #664d03; + background-color: #fff3cd +} + +.list-group-item-warning.list-group-item-action:focus, .list-group-item-warning.list-group-item-action:hover { + color: #664d03; + background-color: #e6dbb9 +} + +.list-group-item-warning.list-group-item-action.active { + color: #fff; + background-color: #664d03; + border-color: #664d03 +} + +.list-group-item-danger { + color: #842029; + background-color: #f8d7da +} + +.list-group-item-danger.list-group-item-action:focus, .list-group-item-danger.list-group-item-action:hover { + color: #842029; + background-color: #dfc2c4 +} + +.list-group-item-danger.list-group-item-action.active { + color: #fff; + background-color: #842029; + border-color: #842029 +} + +.list-group-item-light { + color: #636464; + background-color: #fefefe +} + +.list-group-item-light.list-group-item-action:focus, .list-group-item-light.list-group-item-action:hover { + color: #636464; + background-color: #e5e5e5 +} + +.list-group-item-light.list-group-item-action.active { + color: #fff; + background-color: #636464; + border-color: #636464 +} + +.list-group-item-dark { + color: #141619; + background-color: #d3d3d4 +} + +.list-group-item-dark.list-group-item-action:focus, .list-group-item-dark.list-group-item-action:hover { + color: #141619; + background-color: #bebebf +} + +.list-group-item-dark.list-group-item-action.active { + color: #fff; + background-color: #141619; + border-color: #141619 +} + +.btn-close { + box-sizing: content-box; + width: 1em; + height: 1em; + padding: .25em .25em; + color: #000; + background: transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat; + border: 0; + border-radius: .25rem; + opacity: .5 +} + +.btn-close:hover { + color: #000; + text-decoration: none; + opacity: .75 +} + +.btn-close:focus { + outline: 0; + box-shadow: 0 0 0 .25rem rgba(13, 110, 253, .25); + opacity: 1 +} + +.btn-close.disabled, .btn-close:disabled { + pointer-events: none; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + opacity: .25 +} + +.btn-close-white { + filter: invert(1) grayscale(100%) brightness(200%) +} + +.toast { + width: 350px; + max-width: 100%; + font-size: .875rem; + pointer-events: auto; + background-color: rgba(255, 255, 255, .85); + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, .1); + box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .15); + border-radius: .25rem +} + +.toast:not(.showing):not(.show) { + opacity: 0 +} + +.toast.hide { + display: none +} + +.toast-container { + width: -webkit-max-content; + width: -moz-max-content; + width: max-content; + max-width: 100%; + pointer-events: none +} + +.toast-container > :not(:last-child) { + margin-bottom: .75rem +} + +.toast-header { + display: flex; + align-items: center; + padding: .5rem .75rem; + color: #6c757d; + background-color: rgba(255, 255, 255, .85); + background-clip: padding-box; + border-bottom: 1px solid rgba(0, 0, 0, .05); + border-top-left-radius: calc(.25rem - 1px); + border-top-right-radius: calc(.25rem - 1px) +} + +.toast-header .btn-close { + margin-right: -.375rem; + margin-left: .75rem +} + +.toast-body { + padding: .75rem; + word-wrap: break-word +} + +.modal { + position: fixed; + top: 0; + left: 0; + z-index: 1060; + display: none; + width: 100%; + height: 100%; + overflow-x: hidden; + overflow-y: auto; + outline: 0 +} + +.modal-dialog { + position: relative; + width: auto; + margin: .5rem; + pointer-events: none +} + +.modal.fade .modal-dialog { + transition: transform .3s ease-out; + transform: translate(0, -50px) +} + +@media (prefers-reduced-motion: reduce) { + .modal.fade .modal-dialog { + transition: none + } +} + +.modal.show .modal-dialog { + transform: none +} + +.modal.modal-static .modal-dialog { + transform: scale(1.02) +} + +.modal-dialog-scrollable { + height: calc(100% - 1rem) +} + +.modal-dialog-scrollable .modal-content { + max-height: 100%; + overflow: hidden +} + +.modal-dialog-scrollable .modal-body { + overflow-y: auto +} + +.modal-dialog-centered { + display: flex; + align-items: center; + min-height: calc(100% - 1rem) +} + +.modal-content { + position: relative; + display: flex; + flex-direction: column; + width: 100%; + pointer-events: auto; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: .3rem; + outline: 0 +} + +.modal-backdrop { + position: fixed; + top: 0; + left: 0; + z-index: 1040; + width: 100vw; + height: 100vh; + background-color: #000 +} + +.modal-backdrop.fade { + opacity: 0 +} + +.modal-backdrop.show { + opacity: .5 +} + +.modal-header { + display: flex; + flex-shrink: 0; + align-items: center; + justify-content: space-between; + padding: 1rem 1rem; + border-bottom: 1px solid #dee2e6; + border-top-left-radius: calc(.3rem - 1px); + border-top-right-radius: calc(.3rem - 1px) +} + +.modal-header .btn-close { + padding: .5rem .5rem; + margin: -.5rem -.5rem -.5rem auto +} + +.modal-title { + margin-bottom: 0; + line-height: 1.5 +} + +.modal-body { + position: relative; + flex: 1 1 auto; + padding: 1rem +} + +.modal-footer { + display: flex; + flex-wrap: wrap; + flex-shrink: 0; + align-items: center; + justify-content: flex-end; + padding: .75rem; + border-top: 1px solid #dee2e6; + border-bottom-right-radius: calc(.3rem - 1px); + border-bottom-left-radius: calc(.3rem - 1px) +} + +.modal-footer > * { + margin: .25rem +} + +@media (min-width: 576px) { + .modal-dialog { + max-width: 500px; + margin: 1.75rem auto + } + + .modal-dialog-scrollable { + height: calc(100% - 3.5rem) + } + + .modal-dialog-centered { + min-height: calc(100% - 3.5rem) + } + + .modal-sm { + max-width: 300px + } +} + +@media (min-width: 992px) { + .modal-lg, .modal-xl { + max-width: 800px + } +} + +@media (min-width: 1200px) { + .modal-xl { + max-width: 1140px + } +} + +.modal-fullscreen { + width: 100vw; + max-width: none; + height: 100%; + margin: 0 +} + +.modal-fullscreen .modal-content { + height: 100%; + border: 0; + border-radius: 0 +} + +.modal-fullscreen .modal-header { + border-radius: 0 +} + +.modal-fullscreen .modal-body { + overflow-y: auto +} + +.modal-fullscreen .modal-footer { + border-radius: 0 +} + +@media (max-width: 575.98px) { + .modal-fullscreen-sm-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0 + } + + .modal-fullscreen-sm-down .modal-content { + height: 100%; + border: 0; + border-radius: 0 + } + + .modal-fullscreen-sm-down .modal-header { + border-radius: 0 + } + + .modal-fullscreen-sm-down .modal-body { + overflow-y: auto + } + + .modal-fullscreen-sm-down .modal-footer { + border-radius: 0 + } +} + +@media (max-width: 767.98px) { + .modal-fullscreen-md-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0 + } + + .modal-fullscreen-md-down .modal-content { + height: 100%; + border: 0; + border-radius: 0 + } + + .modal-fullscreen-md-down .modal-header { + border-radius: 0 + } + + .modal-fullscreen-md-down .modal-body { + overflow-y: auto + } + + .modal-fullscreen-md-down .modal-footer { + border-radius: 0 + } +} + +@media (max-width: 991.98px) { + .modal-fullscreen-lg-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0 + } + + .modal-fullscreen-lg-down .modal-content { + height: 100%; + border: 0; + border-radius: 0 + } + + .modal-fullscreen-lg-down .modal-header { + border-radius: 0 + } + + .modal-fullscreen-lg-down .modal-body { + overflow-y: auto + } + + .modal-fullscreen-lg-down .modal-footer { + border-radius: 0 + } +} + +@media (max-width: 1199.98px) { + .modal-fullscreen-xl-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0 + } + + .modal-fullscreen-xl-down .modal-content { + height: 100%; + border: 0; + border-radius: 0 + } + + .modal-fullscreen-xl-down .modal-header { + border-radius: 0 + } + + .modal-fullscreen-xl-down .modal-body { + overflow-y: auto + } + + .modal-fullscreen-xl-down .modal-footer { + border-radius: 0 + } +} + +@media (max-width: 1399.98px) { + .modal-fullscreen-xxl-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0 + } + + .modal-fullscreen-xxl-down .modal-content { + height: 100%; + border: 0; + border-radius: 0 + } + + .modal-fullscreen-xxl-down .modal-header { + border-radius: 0 + } + + .modal-fullscreen-xxl-down .modal-body { + overflow-y: auto + } + + .modal-fullscreen-xxl-down .modal-footer { + border-radius: 0 + } +} + +.tooltip { + position: absolute; + z-index: 1080; + display: block; + margin: 0; + font-family: var(--bs-font-sans-serif); + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + white-space: normal; + line-break: auto; + font-size: .875rem; + word-wrap: break-word; + opacity: 0 +} + +.tooltip.show { + opacity: .9 +} + +.tooltip .tooltip-arrow { + position: absolute; + display: block; + width: .8rem; + height: .4rem +} + +.tooltip .tooltip-arrow::before { + position: absolute; + content: ""; + border-color: transparent; + border-style: solid +} + +.bs-tooltip-auto[data-popper-placement^=top], .bs-tooltip-top { + padding: .4rem 0 +} + +.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow, .bs-tooltip-top .tooltip-arrow { + bottom: 0 +} + +.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before, .bs-tooltip-top .tooltip-arrow::before { + top: -1px; + border-width: .4rem .4rem 0; + border-top-color: #000 +} + +.bs-tooltip-auto[data-popper-placement^=right], .bs-tooltip-end { + padding: 0 .4rem +} + +.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow, .bs-tooltip-end .tooltip-arrow { + left: 0; + width: .4rem; + height: .8rem +} + +.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before, .bs-tooltip-end .tooltip-arrow::before { + right: -1px; + border-width: .4rem .4rem .4rem 0; + border-right-color: #000 +} + +.bs-tooltip-auto[data-popper-placement^=bottom], .bs-tooltip-bottom { + padding: .4rem 0 +} + +.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow, .bs-tooltip-bottom .tooltip-arrow { + top: 0 +} + +.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before, .bs-tooltip-bottom .tooltip-arrow::before { + bottom: -1px; + border-width: 0 .4rem .4rem; + border-bottom-color: #000 +} + +.bs-tooltip-auto[data-popper-placement^=left], .bs-tooltip-start { + padding: 0 .4rem +} + +.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow, .bs-tooltip-start .tooltip-arrow { + right: 0; + width: .4rem; + height: .8rem +} + +.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before, .bs-tooltip-start .tooltip-arrow::before { + left: -1px; + border-width: .4rem 0 .4rem .4rem; + border-left-color: #000 +} + +.tooltip-inner { + max-width: 200px; + padding: .25rem .5rem; + color: #fff; + text-align: center; + background-color: #000; + border-radius: .25rem +} + +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1070; + display: block; + max-width: 276px; + font-family: var(--bs-font-sans-serif); + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + white-space: normal; + line-break: auto; + font-size: .875rem; + word-wrap: break-word; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: .3rem +} + +.popover .popover-arrow { + position: absolute; + display: block; + width: 1rem; + height: .5rem +} + +.popover .popover-arrow::after, .popover .popover-arrow::before { + position: absolute; + display: block; + content: ""; + border-color: transparent; + border-style: solid +} + +.bs-popover-auto[data-popper-placement^=top] > .popover-arrow, .bs-popover-top > .popover-arrow { + bottom: calc(-.5rem - 1px) +} + +.bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before, .bs-popover-top > .popover-arrow::before { + bottom: 0; + border-width: .5rem .5rem 0; + border-top-color: rgba(0, 0, 0, .25) +} + +.bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after, .bs-popover-top > .popover-arrow::after { + bottom: 1px; + border-width: .5rem .5rem 0; + border-top-color: #fff +} + +.bs-popover-auto[data-popper-placement^=right] > .popover-arrow, .bs-popover-end > .popover-arrow { + left: calc(-.5rem - 1px); + width: .5rem; + height: 1rem +} + +.bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before, .bs-popover-end > .popover-arrow::before { + left: 0; + border-width: .5rem .5rem .5rem 0; + border-right-color: rgba(0, 0, 0, .25) +} + +.bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after, .bs-popover-end > .popover-arrow::after { + left: 1px; + border-width: .5rem .5rem .5rem 0; + border-right-color: #fff +} + +.bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow, .bs-popover-bottom > .popover-arrow { + top: calc(-.5rem - 1px) +} + +.bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before, .bs-popover-bottom > .popover-arrow::before { + top: 0; + border-width: 0 .5rem .5rem .5rem; + border-bottom-color: rgba(0, 0, 0, .25) +} + +.bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after, .bs-popover-bottom > .popover-arrow::after { + top: 1px; + border-width: 0 .5rem .5rem .5rem; + border-bottom-color: #fff +} + +.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before, .bs-popover-bottom .popover-header::before { + position: absolute; + top: 0; + left: 50%; + display: block; + width: 1rem; + margin-left: -.5rem; + content: ""; + border-bottom: 1px solid #f0f0f0 +} + +.bs-popover-auto[data-popper-placement^=left] > .popover-arrow, .bs-popover-start > .popover-arrow { + right: calc(-.5rem - 1px); + width: .5rem; + height: 1rem +} + +.bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before, .bs-popover-start > .popover-arrow::before { + right: 0; + border-width: .5rem 0 .5rem .5rem; + border-left-color: rgba(0, 0, 0, .25) +} + +.bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after, .bs-popover-start > .popover-arrow::after { + right: 1px; + border-width: .5rem 0 .5rem .5rem; + border-left-color: #fff +} + +.popover-header { + padding: .5rem 1rem; + margin-bottom: 0; + font-size: 1rem; + background-color: #f0f0f0; + border-bottom: 1px solid rgba(0, 0, 0, .2); + border-top-left-radius: calc(.3rem - 1px); + border-top-right-radius: calc(.3rem - 1px) +} + +.popover-header:empty { + display: none +} + +.popover-body { + padding: 1rem 1rem; + color: #212529 +} + +.carousel { + position: relative +} + +.carousel.pointer-event { + touch-action: pan-y +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden +} + +.carousel-inner::after { + display: block; + clear: both; + content: "" +} + +.carousel-item { + position: relative; + display: none; + float: left; + width: 100%; + margin-right: -100%; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + transition: transform .6s ease-in-out +} + +@media (prefers-reduced-motion: reduce) { + .carousel-item { + transition: none + } +} + +.carousel-item-next, .carousel-item-prev, .carousel-item.active { + display: block +} + +.active.carousel-item-end, .carousel-item-next:not(.carousel-item-start) { + transform: translateX(100%) +} + +.active.carousel-item-start, .carousel-item-prev:not(.carousel-item-end) { + transform: translateX(-100%) +} + +.carousel-fade .carousel-item { + opacity: 0; + transition-property: opacity; + transform: none +} + +.carousel-fade .carousel-item-next.carousel-item-start, .carousel-fade .carousel-item-prev.carousel-item-end, .carousel-fade .carousel-item.active { + z-index: 1; + opacity: 1 +} + +.carousel-fade .active.carousel-item-end, .carousel-fade .active.carousel-item-start { + z-index: 0; + opacity: 0; + transition: opacity 0s .6s +} + +@media (prefers-reduced-motion: reduce) { + .carousel-fade .active.carousel-item-end, .carousel-fade .active.carousel-item-start { + transition: none + } +} + +.carousel-control-next, .carousel-control-prev { + position: absolute; + top: 0; + bottom: 0; + z-index: 1; + display: flex; + align-items: center; + justify-content: center; + width: 15%; + padding: 0; + color: #fff; + text-align: center; + background: 0 0; + border: 0; + opacity: .5; + transition: opacity .15s ease +} + +@media (prefers-reduced-motion: reduce) { + .carousel-control-next, .carousel-control-prev { + transition: none + } +} + +.carousel-control-next:focus, .carousel-control-next:hover, .carousel-control-prev:focus, .carousel-control-prev:hover { + color: #fff; + text-decoration: none; + outline: 0; + opacity: .9 +} + +.carousel-control-prev { + left: 0 +} + +.carousel-control-next { + right: 0 +} + +.carousel-control-next-icon, .carousel-control-prev-icon { + display: inline-block; + width: 2rem; + height: 2rem; + background-repeat: no-repeat; + background-position: 50%; + background-size: 100% 100% +} + +.carousel-control-prev-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e") +} + +.carousel-control-next-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e") +} + +.carousel-indicators { + position: absolute; + right: 0; + bottom: 0; + left: 0; + z-index: 2; + display: flex; + justify-content: center; + padding: 0; + margin-right: 15%; + margin-bottom: 1rem; + margin-left: 15%; + list-style: none +} + +.carousel-indicators [data-bs-target] { + box-sizing: content-box; + flex: 0 1 auto; + width: 30px; + height: 3px; + padding: 0; + margin-right: 3px; + margin-left: 3px; + text-indent: -999px; + cursor: pointer; + background-color: #fff; + background-clip: padding-box; + border: 0; + border-top: 10px solid transparent; + border-bottom: 10px solid transparent; + opacity: .5; + transition: opacity .6s ease +} + +@media (prefers-reduced-motion: reduce) { + .carousel-indicators [data-bs-target] { + transition: none + } +} + +.carousel-indicators .active { + opacity: 1 +} + +.carousel-caption { + position: absolute; + right: 15%; + bottom: 1.25rem; + left: 15%; + padding-top: 1.25rem; + padding-bottom: 1.25rem; + color: #fff; + text-align: center +} + +.carousel-dark .carousel-control-next-icon, .carousel-dark .carousel-control-prev-icon { + filter: invert(1) grayscale(100) +} + +.carousel-dark .carousel-indicators [data-bs-target] { + background-color: #000 +} + +.carousel-dark .carousel-caption { + color: #000 +} + +@-webkit-keyframes spinner-border { + to { + transform: rotate(360deg) + } +} + +@keyframes spinner-border { + to { + transform: rotate(360deg) + } +} + +.spinner-border { + display: inline-block; + width: 2rem; + height: 2rem; + vertical-align: -.125em; + border: .25em solid currentColor; + border-right-color: transparent; + border-radius: 50%; + -webkit-animation: .75s linear infinite spinner-border; + animation: .75s linear infinite spinner-border +} + +.spinner-border-sm { + width: 1rem; + height: 1rem; + border-width: .2em +} + +@-webkit-keyframes spinner-grow { + 0% { + transform: scale(0) + } + 50% { + opacity: 1; + transform: none + } +} + +@keyframes spinner-grow { + 0% { + transform: scale(0) + } + 50% { + opacity: 1; + transform: none + } +} + +.spinner-grow { + display: inline-block; + width: 2rem; + height: 2rem; + vertical-align: -.125em; + background-color: currentColor; + border-radius: 50%; + opacity: 0; + -webkit-animation: .75s linear infinite spinner-grow; + animation: .75s linear infinite spinner-grow +} + +.spinner-grow-sm { + width: 1rem; + height: 1rem +} + +@media (prefers-reduced-motion: reduce) { + .spinner-border, .spinner-grow { + -webkit-animation-duration: 1.5s; + animation-duration: 1.5s + } +} + +.offcanvas { + position: fixed; + bottom: 0; + z-index: 1050; + display: flex; + flex-direction: column; + max-width: 100%; + visibility: hidden; + background-color: #fff; + background-clip: padding-box; + outline: 0; + transition: transform .3s ease-in-out +} + +@media (prefers-reduced-motion: reduce) { + .offcanvas { + transition: none + } +} + +.offcanvas-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 1rem 1rem +} + +.offcanvas-header .btn-close { + padding: .5rem .5rem; + margin-top: -.5rem; + margin-right: -.5rem; + margin-bottom: -.5rem +} + +.offcanvas-title { + margin-bottom: 0; + line-height: 1.5 +} + +.offcanvas-body { + flex-grow: 1; + padding: 1rem 1rem; + overflow-y: auto +} + +.offcanvas-start { + top: 0; + left: 0; + width: 400px; + border-right: 1px solid rgba(0, 0, 0, .2); + transform: translateX(-100%) +} + +.offcanvas-end { + top: 0; + right: 0; + width: 400px; + border-left: 1px solid rgba(0, 0, 0, .2); + transform: translateX(100%) +} + +.offcanvas-top { + top: 0; + right: 0; + left: 0; + height: 30vh; + max-height: 100%; + border-bottom: 1px solid rgba(0, 0, 0, .2); + transform: translateY(-100%) +} + +.offcanvas-bottom { + right: 0; + left: 0; + height: 30vh; + max-height: 100%; + border-top: 1px solid rgba(0, 0, 0, .2); + transform: translateY(100%) +} + +.offcanvas.show { + transform: none +} + +.clearfix::after { + display: block; + clear: both; + content: "" +} + +.link-primary { + color: #0d6efd +} + +.link-primary:focus, .link-primary:hover { + color: #0a58ca +} + +.link-secondary { + color: #6c757d +} + +.link-secondary:focus, .link-secondary:hover { + color: #565e64 +} + +.link-success { + color: #198754 +} + +.link-success:focus, .link-success:hover { + color: #146c43 +} + +.link-info { + color: #0dcaf0 +} + +.link-info:focus, .link-info:hover { + color: #3dd5f3 +} + +.link-warning { + color: #ffc107 +} + +.link-warning:focus, .link-warning:hover { + color: #ffcd39 +} + +.link-danger { + color: #dc3545 +} + +.link-danger:focus, .link-danger:hover { + color: #b02a37 +} + +.link-light { + color: #f8f9fa +} + +.link-light:focus, .link-light:hover { + color: #f9fafb +} + +.link-dark { + color: #212529 +} + +.link-dark:focus, .link-dark:hover { + color: #1a1e21 +} + +.ratio { + position: relative; + width: 100% +} + +.ratio::before { + display: block; + padding-top: var(--bs-aspect-ratio); + content: "" +} + +.ratio > * { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100% +} + +.ratio-1x1 { + --bs-aspect-ratio: 100% +} + +.ratio-4x3 { + --bs-aspect-ratio: calc(3 / 4 * 100%) +} + +.ratio-16x9 { + --bs-aspect-ratio: calc(9 / 16 * 100%) +} + +.ratio-21x9 { + --bs-aspect-ratio: calc(9 / 21 * 100%) +} + +.fixed-top { + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 1030 +} + +.fixed-bottom { + position: fixed; + right: 0; + bottom: 0; + left: 0; + z-index: 1030 +} + +.sticky-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020 +} + +@media (min-width: 576px) { + .sticky-sm-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020 + } +} + +@media (min-width: 768px) { + .sticky-md-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020 + } +} + +@media (min-width: 992px) { + .sticky-lg-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020 + } +} + +@media (min-width: 1200px) { + .sticky-xl-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020 + } +} + +@media (min-width: 1400px) { + .sticky-xxl-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020 + } +} + +.visually-hidden, .visually-hidden-focusable:not(:focus):not(:focus-within) { + position: absolute !important; + width: 1px !important; + height: 1px !important; + padding: 0 !important; + margin: -1px !important; + overflow: hidden !important; + clip: rect(0, 0, 0, 0) !important; + white-space: nowrap !important; + border: 0 !important +} + +.stretched-link::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1; + content: "" +} + +.text-truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap +} + +.align-baseline { + vertical-align: baseline !important +} + +.align-top { + vertical-align: top !important +} + +.align-middle { + vertical-align: middle !important +} + +.align-bottom { + vertical-align: bottom !important +} + +.align-text-bottom { + vertical-align: text-bottom !important +} + +.align-text-top { + vertical-align: text-top !important +} + +.float-start { + float: left !important +} + +.float-end { + float: right !important +} + +.float-none { + float: none !important +} + +.overflow-auto { + overflow: auto !important +} + +.overflow-hidden { + overflow: hidden !important +} + +.overflow-visible { + overflow: visible !important +} + +.overflow-scroll { + overflow: scroll !important +} + +.d-inline { + display: inline !important +} + +.d-inline-block { + display: inline-block !important +} + +.d-block { + display: block !important +} + +.d-grid { + display: grid !important +} + +.d-table { + display: table !important +} + +.d-table-row { + display: table-row !important +} + +.d-table-cell { + display: table-cell !important +} + +.d-flex { + display: flex !important +} + +.d-inline-flex { + display: inline-flex !important +} + +.d-none { + display: none !important +} + +.shadow { + box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .15) !important +} + +.shadow-sm { + box-shadow: 0 .125rem .25rem rgba(0, 0, 0, .075) !important +} + +.shadow-lg { + box-shadow: 0 1rem 3rem rgba(0, 0, 0, .175) !important +} + +.shadow-none { + box-shadow: none !important +} + +.position-static { + position: static !important +} + +.position-relative { + position: relative !important +} + +.position-absolute { + position: absolute !important +} + +.position-fixed { + position: fixed !important +} + +.position-sticky { + position: -webkit-sticky !important; + position: sticky !important +} + +.top-0 { + top: 0 !important +} + +.top-50 { + top: 50% !important +} + +.top-100 { + top: 100% !important +} + +.bottom-0 { + bottom: 0 !important +} + +.bottom-50 { + bottom: 50% !important +} + +.bottom-100 { + bottom: 100% !important +} + +.start-0 { + left: 0 !important +} + +.start-50 { + left: 50% !important +} + +.start-100 { + left: 100% !important +} + +.end-0 { + right: 0 !important +} + +.end-50 { + right: 50% !important +} + +.end-100 { + right: 100% !important +} + +.translate-middle { + transform: translate(-50%, -50%) !important +} + +.translate-middle-x { + transform: translateX(-50%) !important +} + +.translate-middle-y { + transform: translateY(-50%) !important +} + +.border { + border: 1px solid #dee2e6 !important +} + +.border-0 { + border: 0 !important +} + +.border-top { + border-top: 1px solid #dee2e6 !important +} + +.border-top-0 { + border-top: 0 !important +} + +.border-end { + border-right: 1px solid #dee2e6 !important +} + +.border-end-0 { + border-right: 0 !important +} + +.border-bottom { + border-bottom: 1px solid #dee2e6 !important +} + +.border-bottom-0 { + border-bottom: 0 !important +} + +.border-start { + border-left: 1px solid #dee2e6 !important +} + +.border-start-0 { + border-left: 0 !important +} + +.border-primary { + border-color: #0d6efd !important +} + +.border-secondary { + border-color: #6c757d !important +} + +.border-success { + border-color: #198754 !important +} + +.border-info { + border-color: #0dcaf0 !important +} + +.border-warning { + border-color: #ffc107 !important +} + +.border-danger { + border-color: #dc3545 !important +} + +.border-light { + border-color: #f8f9fa !important +} + +.border-dark { + border-color: #212529 !important +} + +.border-white { + border-color: #fff !important +} + +.border-1 { + border-width: 1px !important +} + +.border-2 { + border-width: 2px !important +} + +.border-3 { + border-width: 3px !important +} + +.border-4 { + border-width: 4px !important +} + +.border-5 { + border-width: 5px !important +} + +.w-25 { + width: 25% !important +} + +.w-50 { + width: 50% !important +} + +.w-75 { + width: 75% !important +} + +.w-100 { + width: 100% !important +} + +.w-auto { + width: auto !important +} + +.mw-100 { + max-width: 100% !important +} + +.vw-100 { + width: 100vw !important +} + +.min-vw-100 { + min-width: 100vw !important +} + +.h-25 { + height: 25% !important +} + +.h-50 { + height: 50% !important +} + +.h-75 { + height: 75% !important +} + +.h-100 { + height: 100% !important +} + +.h-auto { + height: auto !important +} + +.mh-100 { + max-height: 100% !important +} + +.vh-100 { + height: 100vh !important +} + +.min-vh-100 { + min-height: 100vh !important +} + +.flex-fill { + flex: 1 1 auto !important +} + +.flex-row { + flex-direction: row !important +} + +.flex-column { + flex-direction: column !important +} + +.flex-row-reverse { + flex-direction: row-reverse !important +} + +.flex-column-reverse { + flex-direction: column-reverse !important +} + +.flex-grow-0 { + flex-grow: 0 !important +} + +.flex-grow-1 { + flex-grow: 1 !important +} + +.flex-shrink-0 { + flex-shrink: 0 !important +} + +.flex-shrink-1 { + flex-shrink: 1 !important +} + +.flex-wrap { + flex-wrap: wrap !important +} + +.flex-nowrap { + flex-wrap: nowrap !important +} + +.flex-wrap-reverse { + flex-wrap: wrap-reverse !important +} + +.gap-0 { + gap: 0 !important +} + +.gap-1 { + gap: .25rem !important +} + +.gap-2 { + gap: .5rem !important +} + +.gap-3 { + gap: 1rem !important +} + +.gap-4 { + gap: 1.5rem !important +} + +.gap-5 { + gap: 3rem !important +} + +.justify-content-start { + justify-content: flex-start !important +} + +.justify-content-end { + justify-content: flex-end !important +} + +.justify-content-center { + justify-content: center !important +} + +.justify-content-between { + justify-content: space-between !important +} + +.justify-content-around { + justify-content: space-around !important +} + +.justify-content-evenly { + justify-content: space-evenly !important +} + +.align-items-start { + align-items: flex-start !important +} + +.align-items-end { + align-items: flex-end !important +} + +.align-items-center { + align-items: center !important +} + +.align-items-baseline { + align-items: baseline !important +} + +.align-items-stretch { + align-items: stretch !important +} + +.align-content-start { + align-content: flex-start !important +} + +.align-content-end { + align-content: flex-end !important +} + +.align-content-center { + align-content: center !important +} + +.align-content-between { + align-content: space-between !important +} + +.align-content-around { + align-content: space-around !important +} + +.align-content-stretch { + align-content: stretch !important +} + +.align-self-auto { + align-self: auto !important +} + +.align-self-start { + align-self: flex-start !important +} + +.align-self-end { + align-self: flex-end !important +} + +.align-self-center { + align-self: center !important +} + +.align-self-baseline { + align-self: baseline !important +} + +.align-self-stretch { + align-self: stretch !important +} + +.order-first { + order: -1 !important +} + +.order-0 { + order: 0 !important +} + +.order-1 { + order: 1 !important +} + +.order-2 { + order: 2 !important +} + +.order-3 { + order: 3 !important +} + +.order-4 { + order: 4 !important +} + +.order-5 { + order: 5 !important +} + +.order-last { + order: 6 !important +} + +.m-0 { + margin: 0 !important +} + +.m-1 { + margin: .25rem !important +} + +.m-2 { + margin: .5rem !important +} + +.m-3 { + margin: 1rem !important +} + +.m-4 { + margin: 1.5rem !important +} + +.m-5 { + margin: 3rem !important +} + +.m-auto { + margin: auto !important +} + +.mx-0 { + margin-right: 0 !important; + margin-left: 0 !important +} + +.mx-1 { + margin-right: .25rem !important; + margin-left: .25rem !important +} + +.mx-2 { + margin-right: .5rem !important; + margin-left: .5rem !important +} + +.mx-3 { + margin-right: 1rem !important; + margin-left: 1rem !important +} + +.mx-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important +} + +.mx-5 { + margin-right: 3rem !important; + margin-left: 3rem !important +} + +.mx-auto { + margin-right: auto !important; + margin-left: auto !important +} + +.my-0 { + margin-top: 0 !important; + margin-bottom: 0 !important +} + +.my-1 { + margin-top: .25rem !important; + margin-bottom: .25rem !important +} + +.my-2 { + margin-top: .5rem !important; + margin-bottom: .5rem !important +} + +.my-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important +} + +.my-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important +} + +.my-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important +} + +.my-auto { + margin-top: auto !important; + margin-bottom: auto !important +} + +.mt-0 { + margin-top: 0 !important +} + +.mt-1 { + margin-top: .25rem !important +} + +.mt-2 { + margin-top: .5rem !important +} + +.mt-3 { + margin-top: 1rem !important +} + +.mt-4 { + margin-top: 1.5rem !important +} + +.mt-5 { + margin-top: 3rem !important +} + +.mt-auto { + margin-top: auto !important +} + +.me-0 { + margin-right: 0 !important +} + +.me-1 { + margin-right: .25rem !important +} + +.me-2 { + margin-right: .5rem !important +} + +.me-3 { + margin-right: 1rem !important +} + +.me-4 { + margin-right: 1.5rem !important +} + +.me-5 { + margin-right: 3rem !important +} + +.me-auto { + margin-right: auto !important +} + +.mb-0 { + margin-bottom: 0 !important +} + +.mb-1 { + margin-bottom: .25rem !important +} + +.mb-2 { + margin-bottom: .5rem !important +} + +.mb-3 { + margin-bottom: 1rem !important +} + +.mb-4 { + margin-bottom: 1.5rem !important +} + +.mb-5 { + margin-bottom: 3rem !important +} + +.mb-auto { + margin-bottom: auto !important +} + +.ms-0 { + margin-left: 0 !important +} + +.ms-1 { + margin-left: .25rem !important +} + +.ms-2 { + margin-left: .5rem !important +} + +.ms-3 { + margin-left: 1rem !important +} + +.ms-4 { + margin-left: 1.5rem !important +} + +.ms-5 { + margin-left: 3rem !important +} + +.ms-auto { + margin-left: auto !important +} + +.p-0 { + padding: 0 !important +} + +.p-1 { + padding: .25rem !important +} + +.p-2 { + padding: .5rem !important +} + +.p-3 { + padding: 1rem !important +} + +.p-4 { + padding: 1.5rem !important +} + +.p-5 { + padding: 3rem !important +} + +.px-0 { + padding-right: 0 !important; + padding-left: 0 !important +} + +.px-1 { + padding-right: .25rem !important; + padding-left: .25rem !important +} + +.px-2 { + padding-right: .5rem !important; + padding-left: .5rem !important +} + +.px-3 { + padding-right: 1rem !important; + padding-left: 1rem !important +} + +.px-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important +} + +.px-5 { + padding-right: 3rem !important; + padding-left: 3rem !important +} + +.py-0 { + padding-top: 0 !important; + padding-bottom: 0 !important +} + +.py-1 { + padding-top: .25rem !important; + padding-bottom: .25rem !important +} + +.py-2 { + padding-top: .5rem !important; + padding-bottom: .5rem !important +} + +.py-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important +} + +.py-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important +} + +.py-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important +} + +.pt-0 { + padding-top: 0 !important +} + +.pt-1 { + padding-top: .25rem !important +} + +.pt-2 { + padding-top: .5rem !important +} + +.pt-3 { + padding-top: 1rem !important +} + +.pt-4 { + padding-top: 1.5rem !important +} + +.pt-5 { + padding-top: 3rem !important +} + +.pe-0 { + padding-right: 0 !important +} + +.pe-1 { + padding-right: .25rem !important +} + +.pe-2 { + padding-right: .5rem !important +} + +.pe-3 { + padding-right: 1rem !important +} + +.pe-4 { + padding-right: 1.5rem !important +} + +.pe-5 { + padding-right: 3rem !important +} + +.pb-0 { + padding-bottom: 0 !important +} + +.pb-1 { + padding-bottom: .25rem !important +} + +.pb-2 { + padding-bottom: .5rem !important +} + +.pb-3 { + padding-bottom: 1rem !important +} + +.pb-4 { + padding-bottom: 1.5rem !important +} + +.pb-5 { + padding-bottom: 3rem !important +} + +.ps-0 { + padding-left: 0 !important +} + +.ps-1 { + padding-left: .25rem !important +} + +.ps-2 { + padding-left: .5rem !important +} + +.ps-3 { + padding-left: 1rem !important +} + +.ps-4 { + padding-left: 1.5rem !important +} + +.ps-5 { + padding-left: 3rem !important +} + +.font-monospace { + font-family: var(--bs-font-monospace) !important +} + +.fs-1 { + font-size: calc(1.375rem + 1.5vw) !important +} + +.fs-2 { + font-size: calc(1.325rem + .9vw) !important +} + +.fs-3 { + font-size: calc(1.3rem + .6vw) !important +} + +.fs-4 { + font-size: calc(1.275rem + .3vw) !important +} + +.fs-5 { + font-size: 1.25rem !important +} + +.fs-6 { + font-size: 1rem !important +} + +.fst-italic { + font-style: italic !important +} + +.fst-normal { + font-style: normal !important +} + +.fw-light { + font-weight: 300 !important +} + +.fw-lighter { + font-weight: lighter !important +} + +.fw-normal { + font-weight: 400 !important +} + +.fw-bold { + font-weight: 700 !important +} + +.fw-bolder { + font-weight: bolder !important +} + +.lh-1 { + line-height: 1 !important +} + +.lh-sm { + line-height: 1.25 !important +} + +.lh-base { + line-height: 1.5 !important +} + +.lh-lg { + line-height: 2 !important +} + +.text-start { + text-align: left !important +} + +.text-end { + text-align: right !important +} + +.text-center { + text-align: center !important +} + +.text-decoration-none { + text-decoration: none !important +} + +.text-decoration-underline { + text-decoration: underline !important +} + +.text-decoration-line-through { + text-decoration: line-through !important +} + +.text-lowercase { + text-transform: lowercase !important +} + +.text-uppercase { + text-transform: uppercase !important +} + +.text-capitalize { + text-transform: capitalize !important +} + +.text-wrap { + white-space: normal !important +} + +.text-nowrap { + white-space: nowrap !important +} + +.text-break { + word-wrap: break-word !important; + word-break: break-word !important +} + +.text-primary { + color: #0d6efd !important +} + +.text-secondary { + color: #6c757d !important +} + +.text-success { + color: #198754 !important +} + +.text-info { + color: #0dcaf0 !important +} + +.text-warning { + color: #ffc107 !important +} + +.text-danger { + color: #dc3545 !important +} + +.text-light { + color: #f8f9fa !important +} + +.text-dark { + color: #212529 !important +} + +.text-white { + color: #fff !important +} + +.text-body { + color: #212529 !important +} + +.text-muted { + color: #6c757d !important +} + +.text-black-50 { + color: rgba(0, 0, 0, .5) !important +} + +.text-white-50 { + color: rgba(255, 255, 255, .5) !important +} + +.text-reset { + color: inherit !important +} + +.bg-primary { + background-color: #0d6efd !important +} + +.bg-secondary { + background-color: #6c757d !important +} + +.bg-success { + background-color: #198754 !important +} + +.bg-info { + background-color: #0dcaf0 !important +} + +.bg-warning { + background-color: #ffc107 !important +} + +.bg-danger { + background-color: #dc3545 !important +} + +.bg-light { + background-color: #f8f9fa !important +} + +.bg-dark { + background-color: #212529 !important +} + +.bg-body { + background-color: #fff !important +} + +.bg-white { + background-color: #fff !important +} + +.bg-transparent { + background-color: transparent !important +} + +.bg-gradient { + background-image: var(--bs-gradient) !important +} + +.user-select-all { + -webkit-user-select: all !important; + -moz-user-select: all !important; + user-select: all !important +} + +.user-select-auto { + -webkit-user-select: auto !important; + -moz-user-select: auto !important; + user-select: auto !important +} + +.user-select-none { + -webkit-user-select: none !important; + -moz-user-select: none !important; + user-select: none !important +} + +.pe-none { + pointer-events: none !important +} + +.pe-auto { + pointer-events: auto !important +} + +.rounded { + border-radius: .25rem !important +} + +.rounded-0 { + border-radius: 0 !important +} + +.rounded-1 { + border-radius: .2rem !important +} + +.rounded-2 { + border-radius: .25rem !important +} + +.rounded-3 { + border-radius: .3rem !important +} + +.rounded-circle { + border-radius: 50% !important +} + +.rounded-pill { + border-radius: 50rem !important +} + +.rounded-top { + border-top-left-radius: .25rem !important; + border-top-right-radius: .25rem !important +} + +.rounded-end { + border-top-right-radius: .25rem !important; + border-bottom-right-radius: .25rem !important +} + +.rounded-bottom { + border-bottom-right-radius: .25rem !important; + border-bottom-left-radius: .25rem !important +} + +.rounded-start { + border-bottom-left-radius: .25rem !important; + border-top-left-radius: .25rem !important +} + +.visible { + visibility: visible !important +} + +.invisible { + visibility: hidden !important +} + +@media (min-width: 576px) { + .float-sm-start { + float: left !important + } + + .float-sm-end { + float: right !important + } + + .float-sm-none { + float: none !important + } + + .d-sm-inline { + display: inline !important + } + + .d-sm-inline-block { + display: inline-block !important + } + + .d-sm-block { + display: block !important + } + + .d-sm-grid { + display: grid !important + } + + .d-sm-table { + display: table !important + } + + .d-sm-table-row { + display: table-row !important + } + + .d-sm-table-cell { + display: table-cell !important + } + + .d-sm-flex { + display: flex !important + } + + .d-sm-inline-flex { + display: inline-flex !important + } + + .d-sm-none { + display: none !important + } + + .flex-sm-fill { + flex: 1 1 auto !important + } + + .flex-sm-row { + flex-direction: row !important + } + + .flex-sm-column { + flex-direction: column !important + } + + .flex-sm-row-reverse { + flex-direction: row-reverse !important + } + + .flex-sm-column-reverse { + flex-direction: column-reverse !important + } + + .flex-sm-grow-0 { + flex-grow: 0 !important + } + + .flex-sm-grow-1 { + flex-grow: 1 !important + } + + .flex-sm-shrink-0 { + flex-shrink: 0 !important + } + + .flex-sm-shrink-1 { + flex-shrink: 1 !important + } + + .flex-sm-wrap { + flex-wrap: wrap !important + } + + .flex-sm-nowrap { + flex-wrap: nowrap !important + } + + .flex-sm-wrap-reverse { + flex-wrap: wrap-reverse !important + } + + .gap-sm-0 { + gap: 0 !important + } + + .gap-sm-1 { + gap: .25rem !important + } + + .gap-sm-2 { + gap: .5rem !important + } + + .gap-sm-3 { + gap: 1rem !important + } + + .gap-sm-4 { + gap: 1.5rem !important + } + + .gap-sm-5 { + gap: 3rem !important + } + + .justify-content-sm-start { + justify-content: flex-start !important + } + + .justify-content-sm-end { + justify-content: flex-end !important + } + + .justify-content-sm-center { + justify-content: center !important + } + + .justify-content-sm-between { + justify-content: space-between !important + } + + .justify-content-sm-around { + justify-content: space-around !important + } + + .justify-content-sm-evenly { + justify-content: space-evenly !important + } + + .align-items-sm-start { + align-items: flex-start !important + } + + .align-items-sm-end { + align-items: flex-end !important + } + + .align-items-sm-center { + align-items: center !important + } + + .align-items-sm-baseline { + align-items: baseline !important + } + + .align-items-sm-stretch { + align-items: stretch !important + } + + .align-content-sm-start { + align-content: flex-start !important + } + + .align-content-sm-end { + align-content: flex-end !important + } + + .align-content-sm-center { + align-content: center !important + } + + .align-content-sm-between { + align-content: space-between !important + } + + .align-content-sm-around { + align-content: space-around !important + } + + .align-content-sm-stretch { + align-content: stretch !important + } + + .align-self-sm-auto { + align-self: auto !important + } + + .align-self-sm-start { + align-self: flex-start !important + } + + .align-self-sm-end { + align-self: flex-end !important + } + + .align-self-sm-center { + align-self: center !important + } + + .align-self-sm-baseline { + align-self: baseline !important + } + + .align-self-sm-stretch { + align-self: stretch !important + } + + .order-sm-first { + order: -1 !important + } + + .order-sm-0 { + order: 0 !important + } + + .order-sm-1 { + order: 1 !important + } + + .order-sm-2 { + order: 2 !important + } + + .order-sm-3 { + order: 3 !important + } + + .order-sm-4 { + order: 4 !important + } + + .order-sm-5 { + order: 5 !important + } + + .order-sm-last { + order: 6 !important + } + + .m-sm-0 { + margin: 0 !important + } + + .m-sm-1 { + margin: .25rem !important + } + + .m-sm-2 { + margin: .5rem !important + } + + .m-sm-3 { + margin: 1rem !important + } + + .m-sm-4 { + margin: 1.5rem !important + } + + .m-sm-5 { + margin: 3rem !important + } + + .m-sm-auto { + margin: auto !important + } + + .mx-sm-0 { + margin-right: 0 !important; + margin-left: 0 !important + } + + .mx-sm-1 { + margin-right: .25rem !important; + margin-left: .25rem !important + } + + .mx-sm-2 { + margin-right: .5rem !important; + margin-left: .5rem !important + } + + .mx-sm-3 { + margin-right: 1rem !important; + margin-left: 1rem !important + } + + .mx-sm-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important + } + + .mx-sm-5 { + margin-right: 3rem !important; + margin-left: 3rem !important + } + + .mx-sm-auto { + margin-right: auto !important; + margin-left: auto !important + } + + .my-sm-0 { + margin-top: 0 !important; + margin-bottom: 0 !important + } + + .my-sm-1 { + margin-top: .25rem !important; + margin-bottom: .25rem !important + } + + .my-sm-2 { + margin-top: .5rem !important; + margin-bottom: .5rem !important + } + + .my-sm-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important + } + + .my-sm-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important + } + + .my-sm-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important + } + + .my-sm-auto { + margin-top: auto !important; + margin-bottom: auto !important + } + + .mt-sm-0 { + margin-top: 0 !important + } + + .mt-sm-1 { + margin-top: .25rem !important + } + + .mt-sm-2 { + margin-top: .5rem !important + } + + .mt-sm-3 { + margin-top: 1rem !important + } + + .mt-sm-4 { + margin-top: 1.5rem !important + } + + .mt-sm-5 { + margin-top: 3rem !important + } + + .mt-sm-auto { + margin-top: auto !important + } + + .me-sm-0 { + margin-right: 0 !important + } + + .me-sm-1 { + margin-right: .25rem !important + } + + .me-sm-2 { + margin-right: .5rem !important + } + + .me-sm-3 { + margin-right: 1rem !important + } + + .me-sm-4 { + margin-right: 1.5rem !important + } + + .me-sm-5 { + margin-right: 3rem !important + } + + .me-sm-auto { + margin-right: auto !important + } + + .mb-sm-0 { + margin-bottom: 0 !important + } + + .mb-sm-1 { + margin-bottom: .25rem !important + } + + .mb-sm-2 { + margin-bottom: .5rem !important + } + + .mb-sm-3 { + margin-bottom: 1rem !important + } + + .mb-sm-4 { + margin-bottom: 1.5rem !important + } + + .mb-sm-5 { + margin-bottom: 3rem !important + } + + .mb-sm-auto { + margin-bottom: auto !important + } + + .ms-sm-0 { + margin-left: 0 !important + } + + .ms-sm-1 { + margin-left: .25rem !important + } + + .ms-sm-2 { + margin-left: .5rem !important + } + + .ms-sm-3 { + margin-left: 1rem !important + } + + .ms-sm-4 { + margin-left: 1.5rem !important + } + + .ms-sm-5 { + margin-left: 3rem !important + } + + .ms-sm-auto { + margin-left: auto !important + } + + .p-sm-0 { + padding: 0 !important + } + + .p-sm-1 { + padding: .25rem !important + } + + .p-sm-2 { + padding: .5rem !important + } + + .p-sm-3 { + padding: 1rem !important + } + + .p-sm-4 { + padding: 1.5rem !important + } + + .p-sm-5 { + padding: 3rem !important + } + + .px-sm-0 { + padding-right: 0 !important; + padding-left: 0 !important + } + + .px-sm-1 { + padding-right: .25rem !important; + padding-left: .25rem !important + } + + .px-sm-2 { + padding-right: .5rem !important; + padding-left: .5rem !important + } + + .px-sm-3 { + padding-right: 1rem !important; + padding-left: 1rem !important + } + + .px-sm-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important + } + + .px-sm-5 { + padding-right: 3rem !important; + padding-left: 3rem !important + } + + .py-sm-0 { + padding-top: 0 !important; + padding-bottom: 0 !important + } + + .py-sm-1 { + padding-top: .25rem !important; + padding-bottom: .25rem !important + } + + .py-sm-2 { + padding-top: .5rem !important; + padding-bottom: .5rem !important + } + + .py-sm-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important + } + + .py-sm-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important + } + + .py-sm-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important + } + + .pt-sm-0 { + padding-top: 0 !important + } + + .pt-sm-1 { + padding-top: .25rem !important + } + + .pt-sm-2 { + padding-top: .5rem !important + } + + .pt-sm-3 { + padding-top: 1rem !important + } + + .pt-sm-4 { + padding-top: 1.5rem !important + } + + .pt-sm-5 { + padding-top: 3rem !important + } + + .pe-sm-0 { + padding-right: 0 !important + } + + .pe-sm-1 { + padding-right: .25rem !important + } + + .pe-sm-2 { + padding-right: .5rem !important + } + + .pe-sm-3 { + padding-right: 1rem !important + } + + .pe-sm-4 { + padding-right: 1.5rem !important + } + + .pe-sm-5 { + padding-right: 3rem !important + } + + .pb-sm-0 { + padding-bottom: 0 !important + } + + .pb-sm-1 { + padding-bottom: .25rem !important + } + + .pb-sm-2 { + padding-bottom: .5rem !important + } + + .pb-sm-3 { + padding-bottom: 1rem !important + } + + .pb-sm-4 { + padding-bottom: 1.5rem !important + } + + .pb-sm-5 { + padding-bottom: 3rem !important + } + + .ps-sm-0 { + padding-left: 0 !important + } + + .ps-sm-1 { + padding-left: .25rem !important + } + + .ps-sm-2 { + padding-left: .5rem !important + } + + .ps-sm-3 { + padding-left: 1rem !important + } + + .ps-sm-4 { + padding-left: 1.5rem !important + } + + .ps-sm-5 { + padding-left: 3rem !important + } + + .text-sm-start { + text-align: left !important + } + + .text-sm-end { + text-align: right !important + } + + .text-sm-center { + text-align: center !important + } +} + +@media (min-width: 768px) { + .float-md-start { + float: left !important + } + + .float-md-end { + float: right !important + } + + .float-md-none { + float: none !important + } + + .d-md-inline { + display: inline !important + } + + .d-md-inline-block { + display: inline-block !important + } + + .d-md-block { + display: block !important + } + + .d-md-grid { + display: grid !important + } + + .d-md-table { + display: table !important + } + + .d-md-table-row { + display: table-row !important + } + + .d-md-table-cell { + display: table-cell !important + } + + .d-md-flex { + display: flex !important + } + + .d-md-inline-flex { + display: inline-flex !important + } + + .d-md-none { + display: none !important + } + + .flex-md-fill { + flex: 1 1 auto !important + } + + .flex-md-row { + flex-direction: row !important + } + + .flex-md-column { + flex-direction: column !important + } + + .flex-md-row-reverse { + flex-direction: row-reverse !important + } + + .flex-md-column-reverse { + flex-direction: column-reverse !important + } + + .flex-md-grow-0 { + flex-grow: 0 !important + } + + .flex-md-grow-1 { + flex-grow: 1 !important + } + + .flex-md-shrink-0 { + flex-shrink: 0 !important + } + + .flex-md-shrink-1 { + flex-shrink: 1 !important + } + + .flex-md-wrap { + flex-wrap: wrap !important + } + + .flex-md-nowrap { + flex-wrap: nowrap !important + } + + .flex-md-wrap-reverse { + flex-wrap: wrap-reverse !important + } + + .gap-md-0 { + gap: 0 !important + } + + .gap-md-1 { + gap: .25rem !important + } + + .gap-md-2 { + gap: .5rem !important + } + + .gap-md-3 { + gap: 1rem !important + } + + .gap-md-4 { + gap: 1.5rem !important + } + + .gap-md-5 { + gap: 3rem !important + } + + .justify-content-md-start { + justify-content: flex-start !important + } + + .justify-content-md-end { + justify-content: flex-end !important + } + + .justify-content-md-center { + justify-content: center !important + } + + .justify-content-md-between { + justify-content: space-between !important + } + + .justify-content-md-around { + justify-content: space-around !important + } + + .justify-content-md-evenly { + justify-content: space-evenly !important + } + + .align-items-md-start { + align-items: flex-start !important + } + + .align-items-md-end { + align-items: flex-end !important + } + + .align-items-md-center { + align-items: center !important + } + + .align-items-md-baseline { + align-items: baseline !important + } + + .align-items-md-stretch { + align-items: stretch !important + } + + .align-content-md-start { + align-content: flex-start !important + } + + .align-content-md-end { + align-content: flex-end !important + } + + .align-content-md-center { + align-content: center !important + } + + .align-content-md-between { + align-content: space-between !important + } + + .align-content-md-around { + align-content: space-around !important + } + + .align-content-md-stretch { + align-content: stretch !important + } + + .align-self-md-auto { + align-self: auto !important + } + + .align-self-md-start { + align-self: flex-start !important + } + + .align-self-md-end { + align-self: flex-end !important + } + + .align-self-md-center { + align-self: center !important + } + + .align-self-md-baseline { + align-self: baseline !important + } + + .align-self-md-stretch { + align-self: stretch !important + } + + .order-md-first { + order: -1 !important + } + + .order-md-0 { + order: 0 !important + } + + .order-md-1 { + order: 1 !important + } + + .order-md-2 { + order: 2 !important + } + + .order-md-3 { + order: 3 !important + } + + .order-md-4 { + order: 4 !important + } + + .order-md-5 { + order: 5 !important + } + + .order-md-last { + order: 6 !important + } + + .m-md-0 { + margin: 0 !important + } + + .m-md-1 { + margin: .25rem !important + } + + .m-md-2 { + margin: .5rem !important + } + + .m-md-3 { + margin: 1rem !important + } + + .m-md-4 { + margin: 1.5rem !important + } + + .m-md-5 { + margin: 3rem !important + } + + .m-md-auto { + margin: auto !important + } + + .mx-md-0 { + margin-right: 0 !important; + margin-left: 0 !important + } + + .mx-md-1 { + margin-right: .25rem !important; + margin-left: .25rem !important + } + + .mx-md-2 { + margin-right: .5rem !important; + margin-left: .5rem !important + } + + .mx-md-3 { + margin-right: 1rem !important; + margin-left: 1rem !important + } + + .mx-md-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important + } + + .mx-md-5 { + margin-right: 3rem !important; + margin-left: 3rem !important + } + + .mx-md-auto { + margin-right: auto !important; + margin-left: auto !important + } + + .my-md-0 { + margin-top: 0 !important; + margin-bottom: 0 !important + } + + .my-md-1 { + margin-top: .25rem !important; + margin-bottom: .25rem !important + } + + .my-md-2 { + margin-top: .5rem !important; + margin-bottom: .5rem !important + } + + .my-md-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important + } + + .my-md-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important + } + + .my-md-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important + } + + .my-md-auto { + margin-top: auto !important; + margin-bottom: auto !important + } + + .mt-md-0 { + margin-top: 0 !important + } + + .mt-md-1 { + margin-top: .25rem !important + } + + .mt-md-2 { + margin-top: .5rem !important + } + + .mt-md-3 { + margin-top: 1rem !important + } + + .mt-md-4 { + margin-top: 1.5rem !important + } + + .mt-md-5 { + margin-top: 3rem !important + } + + .mt-md-auto { + margin-top: auto !important + } + + .me-md-0 { + margin-right: 0 !important + } + + .me-md-1 { + margin-right: .25rem !important + } + + .me-md-2 { + margin-right: .5rem !important + } + + .me-md-3 { + margin-right: 1rem !important + } + + .me-md-4 { + margin-right: 1.5rem !important + } + + .me-md-5 { + margin-right: 3rem !important + } + + .me-md-auto { + margin-right: auto !important + } + + .mb-md-0 { + margin-bottom: 0 !important + } + + .mb-md-1 { + margin-bottom: .25rem !important + } + + .mb-md-2 { + margin-bottom: .5rem !important + } + + .mb-md-3 { + margin-bottom: 1rem !important + } + + .mb-md-4 { + margin-bottom: 1.5rem !important + } + + .mb-md-5 { + margin-bottom: 3rem !important + } + + .mb-md-auto { + margin-bottom: auto !important + } + + .ms-md-0 { + margin-left: 0 !important + } + + .ms-md-1 { + margin-left: .25rem !important + } + + .ms-md-2 { + margin-left: .5rem !important + } + + .ms-md-3 { + margin-left: 1rem !important + } + + .ms-md-4 { + margin-left: 1.5rem !important + } + + .ms-md-5 { + margin-left: 3rem !important + } + + .ms-md-auto { + margin-left: auto !important + } + + .p-md-0 { + padding: 0 !important + } + + .p-md-1 { + padding: .25rem !important + } + + .p-md-2 { + padding: .5rem !important + } + + .p-md-3 { + padding: 1rem !important + } + + .p-md-4 { + padding: 1.5rem !important + } + + .p-md-5 { + padding: 3rem !important + } + + .px-md-0 { + padding-right: 0 !important; + padding-left: 0 !important + } + + .px-md-1 { + padding-right: .25rem !important; + padding-left: .25rem !important + } + + .px-md-2 { + padding-right: .5rem !important; + padding-left: .5rem !important + } + + .px-md-3 { + padding-right: 1rem !important; + padding-left: 1rem !important + } + + .px-md-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important + } + + .px-md-5 { + padding-right: 3rem !important; + padding-left: 3rem !important + } + + .py-md-0 { + padding-top: 0 !important; + padding-bottom: 0 !important + } + + .py-md-1 { + padding-top: .25rem !important; + padding-bottom: .25rem !important + } + + .py-md-2 { + padding-top: .5rem !important; + padding-bottom: .5rem !important + } + + .py-md-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important + } + + .py-md-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important + } + + .py-md-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important + } + + .pt-md-0 { + padding-top: 0 !important + } + + .pt-md-1 { + padding-top: .25rem !important + } + + .pt-md-2 { + padding-top: .5rem !important + } + + .pt-md-3 { + padding-top: 1rem !important + } + + .pt-md-4 { + padding-top: 1.5rem !important + } + + .pt-md-5 { + padding-top: 3rem !important + } + + .pe-md-0 { + padding-right: 0 !important + } + + .pe-md-1 { + padding-right: .25rem !important + } + + .pe-md-2 { + padding-right: .5rem !important + } + + .pe-md-3 { + padding-right: 1rem !important + } + + .pe-md-4 { + padding-right: 1.5rem !important + } + + .pe-md-5 { + padding-right: 3rem !important + } + + .pb-md-0 { + padding-bottom: 0 !important + } + + .pb-md-1 { + padding-bottom: .25rem !important + } + + .pb-md-2 { + padding-bottom: .5rem !important + } + + .pb-md-3 { + padding-bottom: 1rem !important + } + + .pb-md-4 { + padding-bottom: 1.5rem !important + } + + .pb-md-5 { + padding-bottom: 3rem !important + } + + .ps-md-0 { + padding-left: 0 !important + } + + .ps-md-1 { + padding-left: .25rem !important + } + + .ps-md-2 { + padding-left: .5rem !important + } + + .ps-md-3 { + padding-left: 1rem !important + } + + .ps-md-4 { + padding-left: 1.5rem !important + } + + .ps-md-5 { + padding-left: 3rem !important + } + + .text-md-start { + text-align: left !important + } + + .text-md-end { + text-align: right !important + } + + .text-md-center { + text-align: center !important + } +} + +@media (min-width: 992px) { + .float-lg-start { + float: left !important + } + + .float-lg-end { + float: right !important + } + + .float-lg-none { + float: none !important + } + + .d-lg-inline { + display: inline !important + } + + .d-lg-inline-block { + display: inline-block !important + } + + .d-lg-block { + display: block !important + } + + .d-lg-grid { + display: grid !important + } + + .d-lg-table { + display: table !important + } + + .d-lg-table-row { + display: table-row !important + } + + .d-lg-table-cell { + display: table-cell !important + } + + .d-lg-flex { + display: flex !important + } + + .d-lg-inline-flex { + display: inline-flex !important + } + + .d-lg-none { + display: none !important + } + + .flex-lg-fill { + flex: 1 1 auto !important + } + + .flex-lg-row { + flex-direction: row !important + } + + .flex-lg-column { + flex-direction: column !important + } + + .flex-lg-row-reverse { + flex-direction: row-reverse !important + } + + .flex-lg-column-reverse { + flex-direction: column-reverse !important + } + + .flex-lg-grow-0 { + flex-grow: 0 !important + } + + .flex-lg-grow-1 { + flex-grow: 1 !important + } + + .flex-lg-shrink-0 { + flex-shrink: 0 !important + } + + .flex-lg-shrink-1 { + flex-shrink: 1 !important + } + + .flex-lg-wrap { + flex-wrap: wrap !important + } + + .flex-lg-nowrap { + flex-wrap: nowrap !important + } + + .flex-lg-wrap-reverse { + flex-wrap: wrap-reverse !important + } + + .gap-lg-0 { + gap: 0 !important + } + + .gap-lg-1 { + gap: .25rem !important + } + + .gap-lg-2 { + gap: .5rem !important + } + + .gap-lg-3 { + gap: 1rem !important + } + + .gap-lg-4 { + gap: 1.5rem !important + } + + .gap-lg-5 { + gap: 3rem !important + } + + .justify-content-lg-start { + justify-content: flex-start !important + } + + .justify-content-lg-end { + justify-content: flex-end !important + } + + .justify-content-lg-center { + justify-content: center !important + } + + .justify-content-lg-between { + justify-content: space-between !important + } + + .justify-content-lg-around { + justify-content: space-around !important + } + + .justify-content-lg-evenly { + justify-content: space-evenly !important + } + + .align-items-lg-start { + align-items: flex-start !important + } + + .align-items-lg-end { + align-items: flex-end !important + } + + .align-items-lg-center { + align-items: center !important + } + + .align-items-lg-baseline { + align-items: baseline !important + } + + .align-items-lg-stretch { + align-items: stretch !important + } + + .align-content-lg-start { + align-content: flex-start !important + } + + .align-content-lg-end { + align-content: flex-end !important + } + + .align-content-lg-center { + align-content: center !important + } + + .align-content-lg-between { + align-content: space-between !important + } + + .align-content-lg-around { + align-content: space-around !important + } + + .align-content-lg-stretch { + align-content: stretch !important + } + + .align-self-lg-auto { + align-self: auto !important + } + + .align-self-lg-start { + align-self: flex-start !important + } + + .align-self-lg-end { + align-self: flex-end !important + } + + .align-self-lg-center { + align-self: center !important + } + + .align-self-lg-baseline { + align-self: baseline !important + } + + .align-self-lg-stretch { + align-self: stretch !important + } + + .order-lg-first { + order: -1 !important + } + + .order-lg-0 { + order: 0 !important + } + + .order-lg-1 { + order: 1 !important + } + + .order-lg-2 { + order: 2 !important + } + + .order-lg-3 { + order: 3 !important + } + + .order-lg-4 { + order: 4 !important + } + + .order-lg-5 { + order: 5 !important + } + + .order-lg-last { + order: 6 !important + } + + .m-lg-0 { + margin: 0 !important + } + + .m-lg-1 { + margin: .25rem !important + } + + .m-lg-2 { + margin: .5rem !important + } + + .m-lg-3 { + margin: 1rem !important + } + + .m-lg-4 { + margin: 1.5rem !important + } + + .m-lg-5 { + margin: 3rem !important + } + + .m-lg-auto { + margin: auto !important + } + + .mx-lg-0 { + margin-right: 0 !important; + margin-left: 0 !important + } + + .mx-lg-1 { + margin-right: .25rem !important; + margin-left: .25rem !important + } + + .mx-lg-2 { + margin-right: .5rem !important; + margin-left: .5rem !important + } + + .mx-lg-3 { + margin-right: 1rem !important; + margin-left: 1rem !important + } + + .mx-lg-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important + } + + .mx-lg-5 { + margin-right: 3rem !important; + margin-left: 3rem !important + } + + .mx-lg-auto { + margin-right: auto !important; + margin-left: auto !important + } + + .my-lg-0 { + margin-top: 0 !important; + margin-bottom: 0 !important + } + + .my-lg-1 { + margin-top: .25rem !important; + margin-bottom: .25rem !important + } + + .my-lg-2 { + margin-top: .5rem !important; + margin-bottom: .5rem !important + } + + .my-lg-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important + } + + .my-lg-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important + } + + .my-lg-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important + } + + .my-lg-auto { + margin-top: auto !important; + margin-bottom: auto !important + } + + .mt-lg-0 { + margin-top: 0 !important + } + + .mt-lg-1 { + margin-top: .25rem !important + } + + .mt-lg-2 { + margin-top: .5rem !important + } + + .mt-lg-3 { + margin-top: 1rem !important + } + + .mt-lg-4 { + margin-top: 1.5rem !important + } + + .mt-lg-5 { + margin-top: 3rem !important + } + + .mt-lg-auto { + margin-top: auto !important + } + + .me-lg-0 { + margin-right: 0 !important + } + + .me-lg-1 { + margin-right: .25rem !important + } + + .me-lg-2 { + margin-right: .5rem !important + } + + .me-lg-3 { + margin-right: 1rem !important + } + + .me-lg-4 { + margin-right: 1.5rem !important + } + + .me-lg-5 { + margin-right: 3rem !important + } + + .me-lg-auto { + margin-right: auto !important + } + + .mb-lg-0 { + margin-bottom: 0 !important + } + + .mb-lg-1 { + margin-bottom: .25rem !important + } + + .mb-lg-2 { + margin-bottom: .5rem !important + } + + .mb-lg-3 { + margin-bottom: 1rem !important + } + + .mb-lg-4 { + margin-bottom: 1.5rem !important + } + + .mb-lg-5 { + margin-bottom: 3rem !important + } + + .mb-lg-auto { + margin-bottom: auto !important + } + + .ms-lg-0 { + margin-left: 0 !important + } + + .ms-lg-1 { + margin-left: .25rem !important + } + + .ms-lg-2 { + margin-left: .5rem !important + } + + .ms-lg-3 { + margin-left: 1rem !important + } + + .ms-lg-4 { + margin-left: 1.5rem !important + } + + .ms-lg-5 { + margin-left: 3rem !important + } + + .ms-lg-auto { + margin-left: auto !important + } + + .p-lg-0 { + padding: 0 !important + } + + .p-lg-1 { + padding: .25rem !important + } + + .p-lg-2 { + padding: .5rem !important + } + + .p-lg-3 { + padding: 1rem !important + } + + .p-lg-4 { + padding: 1.5rem !important + } + + .p-lg-5 { + padding: 3rem !important + } + + .px-lg-0 { + padding-right: 0 !important; + padding-left: 0 !important + } + + .px-lg-1 { + padding-right: .25rem !important; + padding-left: .25rem !important + } + + .px-lg-2 { + padding-right: .5rem !important; + padding-left: .5rem !important + } + + .px-lg-3 { + padding-right: 1rem !important; + padding-left: 1rem !important + } + + .px-lg-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important + } + + .px-lg-5 { + padding-right: 3rem !important; + padding-left: 3rem !important + } + + .py-lg-0 { + padding-top: 0 !important; + padding-bottom: 0 !important + } + + .py-lg-1 { + padding-top: .25rem !important; + padding-bottom: .25rem !important + } + + .py-lg-2 { + padding-top: .5rem !important; + padding-bottom: .5rem !important + } + + .py-lg-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important + } + + .py-lg-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important + } + + .py-lg-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important + } + + .pt-lg-0 { + padding-top: 0 !important + } + + .pt-lg-1 { + padding-top: .25rem !important + } + + .pt-lg-2 { + padding-top: .5rem !important + } + + .pt-lg-3 { + padding-top: 1rem !important + } + + .pt-lg-4 { + padding-top: 1.5rem !important + } + + .pt-lg-5 { + padding-top: 3rem !important + } + + .pe-lg-0 { + padding-right: 0 !important + } + + .pe-lg-1 { + padding-right: .25rem !important + } + + .pe-lg-2 { + padding-right: .5rem !important + } + + .pe-lg-3 { + padding-right: 1rem !important + } + + .pe-lg-4 { + padding-right: 1.5rem !important + } + + .pe-lg-5 { + padding-right: 3rem !important + } + + .pb-lg-0 { + padding-bottom: 0 !important + } + + .pb-lg-1 { + padding-bottom: .25rem !important + } + + .pb-lg-2 { + padding-bottom: .5rem !important + } + + .pb-lg-3 { + padding-bottom: 1rem !important + } + + .pb-lg-4 { + padding-bottom: 1.5rem !important + } + + .pb-lg-5 { + padding-bottom: 3rem !important + } + + .ps-lg-0 { + padding-left: 0 !important + } + + .ps-lg-1 { + padding-left: .25rem !important + } + + .ps-lg-2 { + padding-left: .5rem !important + } + + .ps-lg-3 { + padding-left: 1rem !important + } + + .ps-lg-4 { + padding-left: 1.5rem !important + } + + .ps-lg-5 { + padding-left: 3rem !important + } + + .text-lg-start { + text-align: left !important + } + + .text-lg-end { + text-align: right !important + } + + .text-lg-center { + text-align: center !important + } +} + +@media (min-width: 1200px) { + .float-xl-start { + float: left !important + } + + .float-xl-end { + float: right !important + } + + .float-xl-none { + float: none !important + } + + .d-xl-inline { + display: inline !important + } + + .d-xl-inline-block { + display: inline-block !important + } + + .d-xl-block { + display: block !important + } + + .d-xl-grid { + display: grid !important + } + + .d-xl-table { + display: table !important + } + + .d-xl-table-row { + display: table-row !important + } + + .d-xl-table-cell { + display: table-cell !important + } + + .d-xl-flex { + display: flex !important + } + + .d-xl-inline-flex { + display: inline-flex !important + } + + .d-xl-none { + display: none !important + } + + .flex-xl-fill { + flex: 1 1 auto !important + } + + .flex-xl-row { + flex-direction: row !important + } + + .flex-xl-column { + flex-direction: column !important + } + + .flex-xl-row-reverse { + flex-direction: row-reverse !important + } + + .flex-xl-column-reverse { + flex-direction: column-reverse !important + } + + .flex-xl-grow-0 { + flex-grow: 0 !important + } + + .flex-xl-grow-1 { + flex-grow: 1 !important + } + + .flex-xl-shrink-0 { + flex-shrink: 0 !important + } + + .flex-xl-shrink-1 { + flex-shrink: 1 !important + } + + .flex-xl-wrap { + flex-wrap: wrap !important + } + + .flex-xl-nowrap { + flex-wrap: nowrap !important + } + + .flex-xl-wrap-reverse { + flex-wrap: wrap-reverse !important + } + + .gap-xl-0 { + gap: 0 !important + } + + .gap-xl-1 { + gap: .25rem !important + } + + .gap-xl-2 { + gap: .5rem !important + } + + .gap-xl-3 { + gap: 1rem !important + } + + .gap-xl-4 { + gap: 1.5rem !important + } + + .gap-xl-5 { + gap: 3rem !important + } + + .justify-content-xl-start { + justify-content: flex-start !important + } + + .justify-content-xl-end { + justify-content: flex-end !important + } + + .justify-content-xl-center { + justify-content: center !important + } + + .justify-content-xl-between { + justify-content: space-between !important + } + + .justify-content-xl-around { + justify-content: space-around !important + } + + .justify-content-xl-evenly { + justify-content: space-evenly !important + } + + .align-items-xl-start { + align-items: flex-start !important + } + + .align-items-xl-end { + align-items: flex-end !important + } + + .align-items-xl-center { + align-items: center !important + } + + .align-items-xl-baseline { + align-items: baseline !important + } + + .align-items-xl-stretch { + align-items: stretch !important + } + + .align-content-xl-start { + align-content: flex-start !important + } + + .align-content-xl-end { + align-content: flex-end !important + } + + .align-content-xl-center { + align-content: center !important + } + + .align-content-xl-between { + align-content: space-between !important + } + + .align-content-xl-around { + align-content: space-around !important + } + + .align-content-xl-stretch { + align-content: stretch !important + } + + .align-self-xl-auto { + align-self: auto !important + } + + .align-self-xl-start { + align-self: flex-start !important + } + + .align-self-xl-end { + align-self: flex-end !important + } + + .align-self-xl-center { + align-self: center !important + } + + .align-self-xl-baseline { + align-self: baseline !important + } + + .align-self-xl-stretch { + align-self: stretch !important + } + + .order-xl-first { + order: -1 !important + } + + .order-xl-0 { + order: 0 !important + } + + .order-xl-1 { + order: 1 !important + } + + .order-xl-2 { + order: 2 !important + } + + .order-xl-3 { + order: 3 !important + } + + .order-xl-4 { + order: 4 !important + } + + .order-xl-5 { + order: 5 !important + } + + .order-xl-last { + order: 6 !important + } + + .m-xl-0 { + margin: 0 !important + } + + .m-xl-1 { + margin: .25rem !important + } + + .m-xl-2 { + margin: .5rem !important + } + + .m-xl-3 { + margin: 1rem !important + } + + .m-xl-4 { + margin: 1.5rem !important + } + + .m-xl-5 { + margin: 3rem !important + } + + .m-xl-auto { + margin: auto !important + } + + .mx-xl-0 { + margin-right: 0 !important; + margin-left: 0 !important + } + + .mx-xl-1 { + margin-right: .25rem !important; + margin-left: .25rem !important + } + + .mx-xl-2 { + margin-right: .5rem !important; + margin-left: .5rem !important + } + + .mx-xl-3 { + margin-right: 1rem !important; + margin-left: 1rem !important + } + + .mx-xl-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important + } + + .mx-xl-5 { + margin-right: 3rem !important; + margin-left: 3rem !important + } + + .mx-xl-auto { + margin-right: auto !important; + margin-left: auto !important + } + + .my-xl-0 { + margin-top: 0 !important; + margin-bottom: 0 !important + } + + .my-xl-1 { + margin-top: .25rem !important; + margin-bottom: .25rem !important + } + + .my-xl-2 { + margin-top: .5rem !important; + margin-bottom: .5rem !important + } + + .my-xl-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important + } + + .my-xl-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important + } + + .my-xl-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important + } + + .my-xl-auto { + margin-top: auto !important; + margin-bottom: auto !important + } + + .mt-xl-0 { + margin-top: 0 !important + } + + .mt-xl-1 { + margin-top: .25rem !important + } + + .mt-xl-2 { + margin-top: .5rem !important + } + + .mt-xl-3 { + margin-top: 1rem !important + } + + .mt-xl-4 { + margin-top: 1.5rem !important + } + + .mt-xl-5 { + margin-top: 3rem !important + } + + .mt-xl-auto { + margin-top: auto !important + } + + .me-xl-0 { + margin-right: 0 !important + } + + .me-xl-1 { + margin-right: .25rem !important + } + + .me-xl-2 { + margin-right: .5rem !important + } + + .me-xl-3 { + margin-right: 1rem !important + } + + .me-xl-4 { + margin-right: 1.5rem !important + } + + .me-xl-5 { + margin-right: 3rem !important + } + + .me-xl-auto { + margin-right: auto !important + } + + .mb-xl-0 { + margin-bottom: 0 !important + } + + .mb-xl-1 { + margin-bottom: .25rem !important + } + + .mb-xl-2 { + margin-bottom: .5rem !important + } + + .mb-xl-3 { + margin-bottom: 1rem !important + } + + .mb-xl-4 { + margin-bottom: 1.5rem !important + } + + .mb-xl-5 { + margin-bottom: 3rem !important + } + + .mb-xl-auto { + margin-bottom: auto !important + } + + .ms-xl-0 { + margin-left: 0 !important + } + + .ms-xl-1 { + margin-left: .25rem !important + } + + .ms-xl-2 { + margin-left: .5rem !important + } + + .ms-xl-3 { + margin-left: 1rem !important + } + + .ms-xl-4 { + margin-left: 1.5rem !important + } + + .ms-xl-5 { + margin-left: 3rem !important + } + + .ms-xl-auto { + margin-left: auto !important + } + + .p-xl-0 { + padding: 0 !important + } + + .p-xl-1 { + padding: .25rem !important + } + + .p-xl-2 { + padding: .5rem !important + } + + .p-xl-3 { + padding: 1rem !important + } + + .p-xl-4 { + padding: 1.5rem !important + } + + .p-xl-5 { + padding: 3rem !important + } + + .px-xl-0 { + padding-right: 0 !important; + padding-left: 0 !important + } + + .px-xl-1 { + padding-right: .25rem !important; + padding-left: .25rem !important + } + + .px-xl-2 { + padding-right: .5rem !important; + padding-left: .5rem !important + } + + .px-xl-3 { + padding-right: 1rem !important; + padding-left: 1rem !important + } + + .px-xl-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important + } + + .px-xl-5 { + padding-right: 3rem !important; + padding-left: 3rem !important + } + + .py-xl-0 { + padding-top: 0 !important; + padding-bottom: 0 !important + } + + .py-xl-1 { + padding-top: .25rem !important; + padding-bottom: .25rem !important + } + + .py-xl-2 { + padding-top: .5rem !important; + padding-bottom: .5rem !important + } + + .py-xl-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important + } + + .py-xl-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important + } + + .py-xl-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important + } + + .pt-xl-0 { + padding-top: 0 !important + } + + .pt-xl-1 { + padding-top: .25rem !important + } + + .pt-xl-2 { + padding-top: .5rem !important + } + + .pt-xl-3 { + padding-top: 1rem !important + } + + .pt-xl-4 { + padding-top: 1.5rem !important + } + + .pt-xl-5 { + padding-top: 3rem !important + } + + .pe-xl-0 { + padding-right: 0 !important + } + + .pe-xl-1 { + padding-right: .25rem !important + } + + .pe-xl-2 { + padding-right: .5rem !important + } + + .pe-xl-3 { + padding-right: 1rem !important + } + + .pe-xl-4 { + padding-right: 1.5rem !important + } + + .pe-xl-5 { + padding-right: 3rem !important + } + + .pb-xl-0 { + padding-bottom: 0 !important + } + + .pb-xl-1 { + padding-bottom: .25rem !important + } + + .pb-xl-2 { + padding-bottom: .5rem !important + } + + .pb-xl-3 { + padding-bottom: 1rem !important + } + + .pb-xl-4 { + padding-bottom: 1.5rem !important + } + + .pb-xl-5 { + padding-bottom: 3rem !important + } + + .ps-xl-0 { + padding-left: 0 !important + } + + .ps-xl-1 { + padding-left: .25rem !important + } + + .ps-xl-2 { + padding-left: .5rem !important + } + + .ps-xl-3 { + padding-left: 1rem !important + } + + .ps-xl-4 { + padding-left: 1.5rem !important + } + + .ps-xl-5 { + padding-left: 3rem !important + } + + .text-xl-start { + text-align: left !important + } + + .text-xl-end { + text-align: right !important + } + + .text-xl-center { + text-align: center !important + } +} + +@media (min-width: 1400px) { + .float-xxl-start { + float: left !important + } + + .float-xxl-end { + float: right !important + } + + .float-xxl-none { + float: none !important + } + + .d-xxl-inline { + display: inline !important + } + + .d-xxl-inline-block { + display: inline-block !important + } + + .d-xxl-block { + display: block !important + } + + .d-xxl-grid { + display: grid !important + } + + .d-xxl-table { + display: table !important + } + + .d-xxl-table-row { + display: table-row !important + } + + .d-xxl-table-cell { + display: table-cell !important + } + + .d-xxl-flex { + display: flex !important + } + + .d-xxl-inline-flex { + display: inline-flex !important + } + + .d-xxl-none { + display: none !important + } + + .flex-xxl-fill { + flex: 1 1 auto !important + } + + .flex-xxl-row { + flex-direction: row !important + } + + .flex-xxl-column { + flex-direction: column !important + } + + .flex-xxl-row-reverse { + flex-direction: row-reverse !important + } + + .flex-xxl-column-reverse { + flex-direction: column-reverse !important + } + + .flex-xxl-grow-0 { + flex-grow: 0 !important + } + + .flex-xxl-grow-1 { + flex-grow: 1 !important + } + + .flex-xxl-shrink-0 { + flex-shrink: 0 !important + } + + .flex-xxl-shrink-1 { + flex-shrink: 1 !important + } + + .flex-xxl-wrap { + flex-wrap: wrap !important + } + + .flex-xxl-nowrap { + flex-wrap: nowrap !important + } + + .flex-xxl-wrap-reverse { + flex-wrap: wrap-reverse !important + } + + .gap-xxl-0 { + gap: 0 !important + } + + .gap-xxl-1 { + gap: .25rem !important + } + + .gap-xxl-2 { + gap: .5rem !important + } + + .gap-xxl-3 { + gap: 1rem !important + } + + .gap-xxl-4 { + gap: 1.5rem !important + } + + .gap-xxl-5 { + gap: 3rem !important + } + + .justify-content-xxl-start { + justify-content: flex-start !important + } + + .justify-content-xxl-end { + justify-content: flex-end !important + } + + .justify-content-xxl-center { + justify-content: center !important + } + + .justify-content-xxl-between { + justify-content: space-between !important + } + + .justify-content-xxl-around { + justify-content: space-around !important + } + + .justify-content-xxl-evenly { + justify-content: space-evenly !important + } + + .align-items-xxl-start { + align-items: flex-start !important + } + + .align-items-xxl-end { + align-items: flex-end !important + } + + .align-items-xxl-center { + align-items: center !important + } + + .align-items-xxl-baseline { + align-items: baseline !important + } + + .align-items-xxl-stretch { + align-items: stretch !important + } + + .align-content-xxl-start { + align-content: flex-start !important + } + + .align-content-xxl-end { + align-content: flex-end !important + } + + .align-content-xxl-center { + align-content: center !important + } + + .align-content-xxl-between { + align-content: space-between !important + } + + .align-content-xxl-around { + align-content: space-around !important + } + + .align-content-xxl-stretch { + align-content: stretch !important + } + + .align-self-xxl-auto { + align-self: auto !important + } + + .align-self-xxl-start { + align-self: flex-start !important + } + + .align-self-xxl-end { + align-self: flex-end !important + } + + .align-self-xxl-center { + align-self: center !important + } + + .align-self-xxl-baseline { + align-self: baseline !important + } + + .align-self-xxl-stretch { + align-self: stretch !important + } + + .order-xxl-first { + order: -1 !important + } + + .order-xxl-0 { + order: 0 !important + } + + .order-xxl-1 { + order: 1 !important + } + + .order-xxl-2 { + order: 2 !important + } + + .order-xxl-3 { + order: 3 !important + } + + .order-xxl-4 { + order: 4 !important + } + + .order-xxl-5 { + order: 5 !important + } + + .order-xxl-last { + order: 6 !important + } + + .m-xxl-0 { + margin: 0 !important + } + + .m-xxl-1 { + margin: .25rem !important + } + + .m-xxl-2 { + margin: .5rem !important + } + + .m-xxl-3 { + margin: 1rem !important + } + + .m-xxl-4 { + margin: 1.5rem !important + } + + .m-xxl-5 { + margin: 3rem !important + } + + .m-xxl-auto { + margin: auto !important + } + + .mx-xxl-0 { + margin-right: 0 !important; + margin-left: 0 !important + } + + .mx-xxl-1 { + margin-right: .25rem !important; + margin-left: .25rem !important + } + + .mx-xxl-2 { + margin-right: .5rem !important; + margin-left: .5rem !important + } + + .mx-xxl-3 { + margin-right: 1rem !important; + margin-left: 1rem !important + } + + .mx-xxl-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important + } + + .mx-xxl-5 { + margin-right: 3rem !important; + margin-left: 3rem !important + } + + .mx-xxl-auto { + margin-right: auto !important; + margin-left: auto !important + } + + .my-xxl-0 { + margin-top: 0 !important; + margin-bottom: 0 !important + } + + .my-xxl-1 { + margin-top: .25rem !important; + margin-bottom: .25rem !important + } + + .my-xxl-2 { + margin-top: .5rem !important; + margin-bottom: .5rem !important + } + + .my-xxl-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important + } + + .my-xxl-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important + } + + .my-xxl-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important + } + + .my-xxl-auto { + margin-top: auto !important; + margin-bottom: auto !important + } + + .mt-xxl-0 { + margin-top: 0 !important + } + + .mt-xxl-1 { + margin-top: .25rem !important + } + + .mt-xxl-2 { + margin-top: .5rem !important + } + + .mt-xxl-3 { + margin-top: 1rem !important + } + + .mt-xxl-4 { + margin-top: 1.5rem !important + } + + .mt-xxl-5 { + margin-top: 3rem !important + } + + .mt-xxl-auto { + margin-top: auto !important + } + + .me-xxl-0 { + margin-right: 0 !important + } + + .me-xxl-1 { + margin-right: .25rem !important + } + + .me-xxl-2 { + margin-right: .5rem !important + } + + .me-xxl-3 { + margin-right: 1rem !important + } + + .me-xxl-4 { + margin-right: 1.5rem !important + } + + .me-xxl-5 { + margin-right: 3rem !important + } + + .me-xxl-auto { + margin-right: auto !important + } + + .mb-xxl-0 { + margin-bottom: 0 !important + } + + .mb-xxl-1 { + margin-bottom: .25rem !important + } + + .mb-xxl-2 { + margin-bottom: .5rem !important + } + + .mb-xxl-3 { + margin-bottom: 1rem !important + } + + .mb-xxl-4 { + margin-bottom: 1.5rem !important + } + + .mb-xxl-5 { + margin-bottom: 3rem !important + } + + .mb-xxl-auto { + margin-bottom: auto !important + } + + .ms-xxl-0 { + margin-left: 0 !important + } + + .ms-xxl-1 { + margin-left: .25rem !important + } + + .ms-xxl-2 { + margin-left: .5rem !important + } + + .ms-xxl-3 { + margin-left: 1rem !important + } + + .ms-xxl-4 { + margin-left: 1.5rem !important + } + + .ms-xxl-5 { + margin-left: 3rem !important + } + + .ms-xxl-auto { + margin-left: auto !important + } + + .p-xxl-0 { + padding: 0 !important + } + + .p-xxl-1 { + padding: .25rem !important + } + + .p-xxl-2 { + padding: .5rem !important + } + + .p-xxl-3 { + padding: 1rem !important + } + + .p-xxl-4 { + padding: 1.5rem !important + } + + .p-xxl-5 { + padding: 3rem !important + } + + .px-xxl-0 { + padding-right: 0 !important; + padding-left: 0 !important + } + + .px-xxl-1 { + padding-right: .25rem !important; + padding-left: .25rem !important + } + + .px-xxl-2 { + padding-right: .5rem !important; + padding-left: .5rem !important + } + + .px-xxl-3 { + padding-right: 1rem !important; + padding-left: 1rem !important + } + + .px-xxl-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important + } + + .px-xxl-5 { + padding-right: 3rem !important; + padding-left: 3rem !important + } + + .py-xxl-0 { + padding-top: 0 !important; + padding-bottom: 0 !important + } + + .py-xxl-1 { + padding-top: .25rem !important; + padding-bottom: .25rem !important + } + + .py-xxl-2 { + padding-top: .5rem !important; + padding-bottom: .5rem !important + } + + .py-xxl-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important + } + + .py-xxl-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important + } + + .py-xxl-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important + } + + .pt-xxl-0 { + padding-top: 0 !important + } + + .pt-xxl-1 { + padding-top: .25rem !important + } + + .pt-xxl-2 { + padding-top: .5rem !important + } + + .pt-xxl-3 { + padding-top: 1rem !important + } + + .pt-xxl-4 { + padding-top: 1.5rem !important + } + + .pt-xxl-5 { + padding-top: 3rem !important + } + + .pe-xxl-0 { + padding-right: 0 !important + } + + .pe-xxl-1 { + padding-right: .25rem !important + } + + .pe-xxl-2 { + padding-right: .5rem !important + } + + .pe-xxl-3 { + padding-right: 1rem !important + } + + .pe-xxl-4 { + padding-right: 1.5rem !important + } + + .pe-xxl-5 { + padding-right: 3rem !important + } + + .pb-xxl-0 { + padding-bottom: 0 !important + } + + .pb-xxl-1 { + padding-bottom: .25rem !important + } + + .pb-xxl-2 { + padding-bottom: .5rem !important + } + + .pb-xxl-3 { + padding-bottom: 1rem !important + } + + .pb-xxl-4 { + padding-bottom: 1.5rem !important + } + + .pb-xxl-5 { + padding-bottom: 3rem !important + } + + .ps-xxl-0 { + padding-left: 0 !important + } + + .ps-xxl-1 { + padding-left: .25rem !important + } + + .ps-xxl-2 { + padding-left: .5rem !important + } + + .ps-xxl-3 { + padding-left: 1rem !important + } + + .ps-xxl-4 { + padding-left: 1.5rem !important + } + + .ps-xxl-5 { + padding-left: 3rem !important + } + + .text-xxl-start { + text-align: left !important + } + + .text-xxl-end { + text-align: right !important + } + + .text-xxl-center { + text-align: center !important + } +} + +@media (min-width: 1200px) { + .fs-1 { + font-size: 2.5rem !important + } + + .fs-2 { + font-size: 2rem !important + } + + .fs-3 { + font-size: 1.75rem !important + } + + .fs-4 { + font-size: 1.5rem !important + } +} + +@media print { + .d-print-inline { + display: inline !important + } + + .d-print-inline-block { + display: inline-block !important + } + + .d-print-block { + display: block !important + } + + .d-print-grid { + display: grid !important + } + + .d-print-table { + display: table !important + } + + .d-print-table-row { + display: table-row !important + } + + .d-print-table-cell { + display: table-cell !important + } + + .d-print-flex { + display: flex !important + } + + .d-print-inline-flex { + display: inline-flex !important + } + + .d-print-none { + display: none !important + } +} diff --git a/app/static/js/fillword.js b/app/static/js/fillword.js new file mode 100644 index 0000000..3e3fbd9 --- /dev/null +++ b/app/static/js/fillword.js @@ -0,0 +1,29 @@ +isRead = true; +isChoose = true; +var reader = window.speechSynthesis; // 全局定义朗读者,以便朗读和暂停 + +function getWord(){ + var word = window.getSelection?window.getSelection():document.selection.createRange().text; + return word; +} +function fillinWord(){ + var word = getWord(); + if (isRead) read(word); + if (!isChoose) return; + var element = document.getElementById("selected-words"); + element.value = element.value + " " + word; +} +document.getElementById("text-content").addEventListener("click", fillinWord, false); +function read(s){ + var msg = new SpeechSynthesisUtterance(s); + reader.speak(msg); +} +function onReadClick(){ + isRead = !isRead; + if(!isRead){ + reader.cancel(); + } +} +function onChooseClick(){ + isChoose = !isChoose; +} \ No newline at end of file diff --git a/app/static/js/highlight.js b/app/static/js/highlight.js new file mode 100644 index 0000000..2e0d84a --- /dev/null +++ b/app/static/js/highlight.js @@ -0,0 +1,95 @@ +var isHighlight = true; + +function cancelBtnHandler() { + cancel_highLight(); + document.getElementById("text-content").removeEventListener("click", fillinWord, false); + document.getElementById("text-content").removeEventListener("touchstart", fillinWord, false); + document.getElementById("text-content").addEventListener("click", fillinWord2, false); + document.getElementById("text-content").addEventListener("touchstart", fillinWord2, false); +} + +function showBtnHandler() { + document.getElementById("text-content").removeEventListener("click", fillinWord2, false); + document.getElementById("text-content").removeEventListener("touchstart", fillinWord2, false); + document.getElementById("text-content").addEventListener("click", fillinWord, false); + document.getElementById("text-content").addEventListener("touchstart", fillinWord, false); + highLight(); +} + +function getWord() { + var word = window.getSelection ? window.getSelection() : document.selection.createRange().text; + return word; +} + +function highLight() { + if(!isHighlight) return; + var txt = document.getElementById("article").innerText; + var sel_word1 = document.getElementById("selected-words"); + var sel_word2 = document.getElementById("selected-words2"); + if (sel_word1 != null) { + var list = sel_word1.value.split(" "); + for (var i = 0; i < list.length; ++i) { + list[i] = list[i].replace(/(^\s*)|(\s*$)/g, ""); + if (list[i] != "" && "".indexOf(list[i]) == -1 && "".indexOf(list[i]) == -1) { + txt = txt.replace(new RegExp(list[i], "g"), "" + list[i] + ""); + } + } + } + if (sel_word2 != null) { + var list2 = sel_word2.value.split(" "); + for (var i = 0; i < list2.length; ++i) { + list2[i] = list2[i].replace(/(^\s*)|(\s*$)/g, ""); + if (list2[i] != "" && "".indexOf(list2[i]) == -1 && "".indexOf(list2[i]) == -1) { + txt = txt.replace(new RegExp(list2[i], "g"), "" + list2[i] + ""); + } + } + } + document.getElementById("article").innerHTML = txt; +} + +function cancel_highLight() { + var txt = document.getElementById("article").innerText; + var sel_word1 = document.getElementById("selected-words"); + var sel_word2 = document.getElementById("selected-words2"); + if (sel_word1 != null) { + var list = sel_word1.value.split(" "); + for (var i = 0; i < list.length; ++i) { + list[i] = list[i].replace(/(^\s*)|(\s*$)/g, ""); + if (list[i] != "") { + txt = txt.replace("" + list[i] + "", "list[i]"); + } + } + } + if (sel_word2 != null) { + var list2 = sel_word1.value.split(" "); + for (var i = 0; i < list2.length; ++i) { + var list2 = sel_word2.value.split(" "); + list2[i] = list2[i].replace(/(^\s*)|(\s*$)/g, ""); + if (list2[i] != "") { + txt = txt.replace("" + list[i] + "", "list[i]"); + } + } + } + document.getElementById("article").innerHTML = txt; +} + +function fillinWord() { + highLight(); +} + +function fillinWord2() { + cancel_highLight(); +} + +function ChangeHighlight() { + if (isHighlight) { + isHighlight = false; + cancel_highLight(); + } else { + isHighlight = true; + highLight(); + + } +} + +showBtnHandler(); diff --git a/app/static/usr/instructions.html b/app/static/usr/instructions.html index 38126d7..d352523 100644 --- a/app/static/usr/instructions.html +++ b/app/static/usr/instructions.html @@ -1,86 +1,86 @@ - - - - - - 怎么用English Pal - - - - - -

本软件的宗旨是:珍惜你的时间, 提高你的获取英文信息的速度与准确度。 不管你是英语爱好者,备考的学生,还是英语老师,都能从 English Pal 中发现用处。

- -

如果你教英语,English Pal 可以帮你掌握题目词汇规律, 提高教学质量。

- -

如果你学英语,English Pal 可以帮你迅速提高词汇, 轻松应对各种考试。

- -

1秒内闪电查词,告别字典。 私人定制的单词簿,永久相伴,记录奋斗岁月。

- -

现在就试试看吧。 English Pal 期待你的捷报, English Pal 期待你的远航

- -

使用方法

- -

在EnglishPal主页点击成为会员链接。支付会员费后即可开始使用。

- -

活跃会员还有机会获得英文阅读10分钟一对一指导。

- - - - - - - - - - - - - - - - - - - - - - - - - -
截图说明
精选短文,让你窥见世界。 统计词频,让你掌握规律。
时间无价,个性化的生词簿,为你节省记背单词时间。
考试人人都怕,单词的考试分类,让你目的明确。
- - - - - + + + + + + 怎么用English Pal + + + + + +

本软件的宗旨是:珍惜你的时间, 提高你的获取英文信息的速度与准确度。 不管你是英语爱好者,备考的学生,还是英语老师,都能从 English Pal 中发现用处。

+ +

如果你教英语,English Pal 可以帮你掌握题目词汇规律, 提高教学质量。

+ +

如果你学英语,English Pal 可以帮你迅速提高词汇, 轻松应对各种考试。

+ +

1秒内闪电查词,告别字典。 私人定制的单词簿,永久相伴,记录奋斗岁月。

+ +

现在就试试看吧。 English Pal 期待你的捷报, English Pal 期待你的远航

+ +

使用方法

+ +

在EnglishPal主页点击成为会员链接。支付会员费后即可开始使用。

+ +

活跃会员还有机会获得英文阅读10分钟一对一指导。

+ + + + + + + + + + + + + + + + + + + + + + + + + +
截图说明
精选短文,让你窥见世界。 统计词频,让你掌握规律。
时间无价,个性化的生词簿,为你节省记背单词时间。
考试人人都怕,单词的考试分类,让你目的明确。
+ + + + + diff --git a/app/templates/expiry.html b/app/templates/expiry.html new file mode 100644 index 0000000..64e59f7 --- /dev/null +++ b/app/templates/expiry.html @@ -0,0 +1,16 @@ + + + + + 账号过期 + + +

您的账号{{ username }}过期。

+

为了提高服务质量,English Pal 收取会员费用, 每天1元。

+

请决定你要试用的时间长度,扫描下面支付宝二维码支付。 支付时请注明English Pal Membership Fee。 我们会于12小时内激活账号。

+

支付宝二维码

+

如果有问题,请联系开发者 dev@qq.com。

+

登出

+ + + diff --git a/app/templates/login.html b/app/templates/login.html index ff11c74..e56b678 100644 --- a/app/templates/login.html +++ b/app/templates/login.html @@ -1,15 +1,21 @@ -{% block body %} -{% if session['logged_in'] %} - -You're logged in already! - -{% else %} - -
-

-

-

-
-{% endif %} -{% endblock %} - +{% block body %} +{% if session['logged_in'] %} + +You're logged in already! + +{% else %} + +
+

+ +

+

+ +

+

+ +

+
+{% endif %} +{% endblock %} + diff --git a/app/templates/mainpage_get.html b/app/templates/mainpage_get.html new file mode 100644 index 0000000..6e1d9b4 --- /dev/null +++ b/app/templates/mainpage_get.html @@ -0,0 +1,53 @@ + + + + + + + {{ yml['header'] | safe }} + {% if yml['css']['item'] %} + {% for css in yml['css']['item'] %} + + {% endfor %} + {% endif %} + {% if yml['js']['head'] %} + {% for js in yml['js']['head'] %} + + {% endfor %} + {% endif %} + + EnglishPal 英文单词高效记 + + + +
+

English Pal - Learn English smartly!

+ {% if session['logged_in'] %} + {{session['username']}}

+ {% else %} +

登录 成为会员 使用说明

+

{{random_ads|safe}}

+ {% endif %} + +

粘帖1篇文章 (English only)

+
+
+ + +
+ {% if d_len > 0 %} +

最常见的词

+ {% for x in lst if x[1]>99 %} + {{x[0]}} {{x[1]}} + {% endfor %} + {% endif %} + +
+ {{ yml['footer'] | safe }} +{% if yml['js']['bottom'] %} + {% for js in yml['js']['bottom'] %} + + {% endfor %} + {% endif %} + + \ No newline at end of file diff --git a/app/templates/mainpage_post.html b/app/templates/mainpage_post.html new file mode 100644 index 0000000..7357457 --- /dev/null +++ b/app/templates/mainpage_post.html @@ -0,0 +1,40 @@ + + + + + Title + + {{ yml['header'] | safe }} + {% if yml['css']['item'] %} + {% for css in yml['css']['item'] %} + + {% endfor %} + {% endif %} + {% if yml['js']['head'] %} + {% for js in yml['js']['head'] %} + + {% endfor %} + {% endif %} + + + +
+ {% for x in lst %} +

+ {{loop.index}} + : + {{x[0]}} + ({{x[1]}}) + +

+ {% endfor %} + +
+ {{ yml['footer'] | safe }} +{% if yml['js']['bottom'] %} + {% for js in yml['js']['bottom'] %} + + {% endfor %} + {% endif %} + + \ No newline at end of file diff --git a/app/templates/not_login.html b/app/templates/not_login.html new file mode 100644 index 0000000..b268be0 --- /dev/null +++ b/app/templates/not_login.html @@ -0,0 +1,5 @@ +{% block body %} +{% if not session['logged_in'] %} +

请先登录

+{% endif %} +{% endblock %} diff --git a/app/templates/reset.html b/app/templates/reset.html new file mode 100644 index 0000000..e510d3d --- /dev/null +++ b/app/templates/reset.html @@ -0,0 +1,14 @@ + + +
+ 旧密码: + +
+ 新密码: + +
+ + +
+ + \ No newline at end of file diff --git a/app/templates/signup.html b/app/templates/signup.html index 472fdaf..421def2 100644 --- a/app/templates/signup.html +++ b/app/templates/signup.html @@ -1,19 +1,19 @@ -{% block body %} -{% if session['logged_in'] %} - -You're logged in already! Logout. - -{% else %} - -

{{ get_flashed_messages()[0] | safe }}

- -

Sign up here.

- -
-

-

-

-
-{% endif %} -{% endblock %} - +{% block body %} +{% if session['logged_in'] %} + +You're logged in already! Logout. + +{% else %} + +

{{ get_flashed_messages()[0] | safe }}

+ +

Sign up here.

+ +
+

+

+

+
+{% endif %} +{% endblock %} + diff --git a/app/templates/userpage_get.html b/app/templates/userpage_get.html new file mode 100644 index 0000000..aafc1f6 --- /dev/null +++ b/app/templates/userpage_get.html @@ -0,0 +1,109 @@ + + + + + + + + {{ yml['header'] | safe }} + {% if yml['css']['item'] %} + {% for css in yml['css']['item'] %} + + {% endfor %} + {% endif %} + {% if yml['js']['head'] %} + {% for js in yml['js']['head'] %} + + {% endfor %} + {% endif %} + + EnglishPal Study Room for {{ username }} + + +
+

English Pal for {{ username }} + 登出 + 重设密码 +

+ {{ flashed_messages|safe }} + +

下一篇 Next Article

+

阅读文章并回答问题

+
{{ today_article|safe }}
+ + 生词高亮 + 大声朗读 + 划词入库 + +

收集生词吧 (可以在正文中划词,也可以复制黏贴)

+
+
+ + +
+ {% if session.get['thisWord'] %} + + {% endif %} + + {% if d_len > 0 %} +

我的生词簿

+ {% for x in lst3 %} + {% set word = x[0] %} + + {% set freq = x[1] %} + {% if session.get('thisWord') == x[0] and session.get('time') == 1 %} + + {% endif %} + {% if freq > 1 %} +

+ {{ word }} + ( + {{ freq }} + ) + + 熟悉 + 不熟悉 + 删除 +

+ {% else %} +

+ {{ word }} + ( + {{ freq }} + ) + 熟悉 + 不熟悉 + 删除 +

+ {% endif %} + {% else %} + {{ word }}{{ freq }} + {% endfor %} + + {% endif %} +
+{{ yml['footer'] | safe }} +{% if yml['js']['bottom'] %} + {% for js in yml['js']['bottom'] %} + + {% endfor %} +{% endif %} + + + + \ No newline at end of file diff --git a/app/templates/userpage_post.html b/app/templates/userpage_post.html new file mode 100644 index 0000000..ba3b38d --- /dev/null +++ b/app/templates/userpage_post.html @@ -0,0 +1,45 @@ + + + + + + + + {{ yml['header'] | safe }} + {% if yml['css']['item'] %} + {% for css in yml['css']['item'] %} + + {% endfor %} + {% endif %} + {% if yml['js']['head'] %} + {% for js in yml['js']['head'] %} + + {% endfor %} + {% endif %} + + EnglishPal Study Room for {{username}} + + +

勾选不认识的单词

+
+ + {% for x in lst %} + {% set word = x[0]%} +

+ {{loop.index}} + : + {{word}} + ({{x[1]}}) + +

+ + {% endfor %} +
+ {{ yml['footer'] | safe }} + {% if yml['js']['bottom'] %} + {% for js in yml['js']['bottom'] %} + + {% endfor %} + {% endif %} + + \ No newline at end of file diff --git a/app/test/test_add_word.py b/app/test/test_add_word.py index ffac643..a08c376 100644 --- a/app/test/test_add_word.py +++ b/app/test/test_add_word.py @@ -6,18 +6,19 @@ from selenium.webdriver.common.desired_capabilities import DesiredCapabilities import random, time import string -import pytest -#driver = webdriver.Remote('http://localhost:4444/wd/hub', DesiredCapabilities.FIREFOX) -#driver.implicitly_wait(10) +driver = webdriver.Remote('http://localhost:4444/wd/hub', DesiredCapabilities.FIREFOX) +driver.implicitly_wait(10) + +HOME_PAGE = 'http://121.4.94.30:91/' + def has_punctuation(s): return [c for c in s if c in string.punctuation] != [] - -@pytest.mark.usefixtures -def test_add_word(URL, driver): + +def test_add_word(): try: - driver.get(URL) + driver.get(HOME_PAGE) assert 'English Pal -' in driver.page_source # login diff --git a/app/test/test_add_word_and_essay_does_not_change.py b/app/test/test_add_word_and_essay_does_not_change.py index 8ee81d0..2746657 100644 --- a/app/test/test_add_word_and_essay_does_not_change.py +++ b/app/test/test_add_word_and_essay_does_not_change.py @@ -3,21 +3,22 @@ # docker run -d -p 4444:4444 selenium/standalone-chrome from selenium import webdriver from selenium.webdriver.common.desired_capabilities import DesiredCapabilities -import pytest + import random, time import string -#driver = webdriver.Remote('http://localhost:4444/wd/hub', DesiredCapabilities.FIREFOX) -#driver.implicitly_wait(10) +driver = webdriver.Remote('http://localhost:4444/wd/hub', DesiredCapabilities.FIREFOX) +driver.implicitly_wait(10) + +HOME_PAGE = 'http://121.4.94.30:91/' def has_punctuation(s): return [c for c in s if c in string.punctuation] != [] - -@pytest.mark.usefixtures -def test_add_word_and_essay_does_not_change(URL, driver): + +def test_add_word_and_essay_does_not_change(): try: - driver.get(URL) + driver.get(HOME_PAGE) assert 'English Pal -' in driver.page_source # login diff --git a/app/test/test_delete_word.py b/app/test/test_delete_word.py index 59128a7..5e2f31a 100644 --- a/app/test/test_delete_word.py +++ b/app/test/test_delete_word.py @@ -1,57 +1,61 @@ -# -*- coding: utf-8 -*- -# Run the docker image using the following command: -# docker run -d -p 4444:4444 selenium/standalone-chrome -from selenium import webdriver -from selenium.webdriver.common.desired_capabilities import DesiredCapabilities -import pytest -import random, time -import string - -# 调用本地chromedriver -# driver = webdriver.Chrome(executable_path="D:\ChromeDriver\chromedriver.exe") -# driver.get("http://127.0.0.1:5000/") -#driver = webdriver.Remote('http://localhost:4444/wd/hub', DesiredCapabilities.FIREFOX) -#driver.implicitly_wait(10) -# driver.maximize_window() -# HOME_PAGE = "http://127.0.0.1:5000/" - -@pytest.mark.usefixtures -def test_delete_word(): - try: - driver.get(URL) - assert 'English Pal -' in driver.page_source - # login - elem = driver.find_element_by_link_text('登录') - elem.click() - - uname = 'lanhui' - password = 'l0ve1t' - elem = driver.find_element_by_name('username') - elem.send_keys(uname) - - elem = driver.find_element_by_name('password') - elem.send_keys(password) - - elem = driver.find_element_by_xpath('//form[1]/p[3]/input[1]') # 找到登录按钮 - elem.click() - - assert 'EnglishPal Study Room for ' + uname in driver.title - - # delete - elems = driver.find_element_by_class_name('new-word') - # 移动到元素elems对象的“顶端”与当前窗口的“顶部”对齐 - driver.execute_script("arguments[0].scrollIntoView();", elems) - driver.save_screenshot('test_delete_pic1.png') - current_2 = elems.text - elem = driver.find_element_by_link_text("删除") - elem.click() - elems = driver.find_element_by_class_name('new-word') - driver.execute_script("arguments[0].scrollIntoView();", elems) - driver.save_screenshot('test_delete_pic2.png') - now_2 = elems.text - - assert current_2 != now_2 - - finally: - driver.quit() - +# -*- coding: utf-8 -*- +# Run the docker image using the following command: +# docker run -d -p 4444:4444 selenium/standalone-chrome +from selenium import webdriver +from selenium.webdriver.common.desired_capabilities import DesiredCapabilities + +import random, time +import string + +# 调用本地chromedriver +# driver = webdriver.Chrome(executable_path="D:\ChromeDriver\chromedriver.exe") +# driver.get("http://127.0.0.1:5000/") +driver = webdriver.Remote('http://localhost:4444/wd/hub', DesiredCapabilities.FIREFOX) +driver.implicitly_wait(10) +# driver.maximize_window() +# HOME_PAGE = "http://127.0.0.1:5000/" + + +HOME_PAGE = 'http://121.4.94.30:91/' + + +def test_delete_word(): + try: + driver.get(HOME_PAGE) + assert 'English Pal -' in driver.page_source + # login + elem = driver.find_element_by_link_text('登录') + elem.click() + + uname = 'lanhui' + password = 'l0ve1t' + elem = driver.find_element_by_name('username') + elem.send_keys(uname) + + elem = driver.find_element_by_name('password') + elem.send_keys(password) + + elem = driver.find_element_by_xpath('//form[1]/p[3]/input[1]') # 找到登录按钮 + elem.click() + + assert 'EnglishPal Study Room for ' + uname in driver.title + + # delete + elems = driver.find_element_by_class_name('new-word') + # 移动到元素elems对象的“顶端”与当前窗口的“顶部”对齐 + driver.execute_script("arguments[0].scrollIntoView();", elems) + driver.save_screenshot('test_delete_pic1.png') + current_2 = elems.text + elem = driver.find_element_by_link_text("删除") + elem.click() + elems = driver.find_element_by_class_name('new-word') + driver.execute_script("arguments[0].scrollIntoView();", elems) + driver.save_screenshot('test_delete_pic2.png') + now_2 = elems.text + + assert current_2 != now_2 + + finally: + driver.quit() + +# test_delete_word() diff --git a/app/test/test_login.py b/app/test/test_login.py index d711cb0..bb4df51 100644 --- a/app/test/test_login.py +++ b/app/test/test_login.py @@ -3,17 +3,19 @@ # docker run -d -p 4444:4444 selenium/standalone-chrome from selenium import webdriver from selenium.webdriver.common.desired_capabilities import DesiredCapabilities -import pytest + import random, string -#driver = webdriver.Remote('http://localhost:4444/wd/hub', DesiredCapabilities.FIREFOX) -#driver.implicitly_wait(10) +driver = webdriver.Remote('http://localhost:4444/wd/hub', DesiredCapabilities.FIREFOX) +driver.implicitly_wait(10) + +HOME_PAGE = 'http://121.4.94.30:91/' -@pytest.mark.usefixtures -def test_login(URL, driver): + +def test_login(): try: - driver.get(URL) + driver.get(HOME_PAGE) driver.save_screenshot('./app/test/test_login_pic0.png') assert 'English Pal -' in driver.page_source @@ -39,7 +41,7 @@ def test_login(URL, driver): assert uname in driver.page_source # logout - driver.get(URL + 'logout') + driver.get(HOME_PAGE + 'logout') driver.save_screenshot('./app/test/test_login_pic3.png') # login diff --git a/app/test/test_login_security_fix.py b/app/test/test_login_security_fix.py index f17122a..461aaba 100644 --- a/app/test/test_login_security_fix.py +++ b/app/test/test_login_security_fix.py @@ -3,16 +3,17 @@ # docker run -d -p 4444:4444 selenium/standalone-chrome from selenium import webdriver from selenium.webdriver.common.desired_capabilities import DesiredCapabilities -import pytest + import random, string -#driver = webdriver.Remote('http://localhost:4444/wd/hub', DesiredCapabilities.FIREFOX) -#driver.implicitly_wait(10) +driver = webdriver.Remote('http://localhost:4444/wd/hub', DesiredCapabilities.FIREFOX) +driver.implicitly_wait(10) + +HOME_PAGE = 'http://121.4.94.30:91/' -@pytest.mark.usefixtures def test_login_security_fix(): try: - driver.get(URL) + driver.get(HOME_PAGE) elem = driver.find_element_by_link_text('登录') elem.click() diff --git a/app/test/test_next_essay.py b/app/test/test_next_essay.py index fb242d9..9814e58 100644 --- a/app/test/test_next_essay.py +++ b/app/test/test_next_essay.py @@ -3,16 +3,19 @@ # docker run -d -p 4444:4444 selenium/standalone-chrome from selenium import webdriver from selenium.webdriver.common.desired_capabilities import DesiredCapabilities -import pytest + import random, string, time -#driver = webdriver.Remote('http://localhost:4444/wd/hub', DesiredCapabilities.FIREFOX) -#driver.implicitly_wait(10) +driver = webdriver.Remote('http://localhost:4444/wd/hub', DesiredCapabilities.FIREFOX) +driver.implicitly_wait(10) -@pytest.mark.usefixtures -def test_next(URL, driver): +HOME_PAGE = 'http://121.4.94.30:91/' + + + +def test_next(): try: - driver.get(URL) + driver.get(HOME_PAGE) assert 'English Pal -' in driver.page_source # login diff --git a/app/test/test_page_position.py b/app/test/test_page_position.py index 4eb8ef9..be6ece3 100644 --- a/app/test/test_page_position.py +++ b/app/test/test_page_position.py @@ -6,10 +6,15 @@ Click the Familiar or Unfamiliar button (current word frequency is 1), and the p from random import randint from selenium import webdriver -import pytest from selenium.common.exceptions import NoSuchElementException from selenium.webdriver.common.desired_capabilities import DesiredCapabilities +driver = webdriver.Remote('http://localhost:4444/wd/hub', DesiredCapabilities.FIREFOX) +driver.implicitly_wait(10) + +HOME_PAGE = 'http://121.4.94.30:91/' + + def click_by_random(text): elements = driver.find_elements_by_link_text(text) # 点击单词表中的第一个单词的熟悉按钮 elements[randint(0, len(elements) - 1)].click() @@ -28,10 +33,10 @@ def get_scrollTop(): roll_height = driver.execute_script(js) return roll_height -@pytest.mark.usefixtures -def test_page_position(URL, driver): + +def test_page_position(): try: - driver.get(URL) + driver.get(HOME_PAGE) # login driver.find_element_by_link_text('登录').click() diff --git a/app/test/test_signup.py b/app/test/test_signup.py index d034107..a2664c5 100644 --- a/app/test/test_signup.py +++ b/app/test/test_signup.py @@ -3,19 +3,19 @@ # docker run -d -p 4444:4444 selenium/standalone-chrome from selenium import webdriver from selenium.webdriver.common.desired_capabilities import DesiredCapabilities -import pytest + import random, string -#driver = webdriver.Remote('http://localhost:4444/wd/hub', DesiredCapabilities.FIREFOX) -#driver.implicitly_wait(10) +driver = webdriver.Remote('http://localhost:4444/wd/hub', DesiredCapabilities.FIREFOX) +driver.implicitly_wait(10) + +HOME_PAGE = 'http://121.4.94.30:91/' - -@pytest.mark.usefixtures -def test_signup(URL, driver): +def test_signup(): try: - driver.get(URL) + driver.get(HOME_PAGE) driver.save_screenshot('test_signup_pic0.png') assert 'English Pal -' in driver.page_source diff --git a/app/user_service.py b/app/user_service.py new file mode 100644 index 0000000..139c140 --- /dev/null +++ b/app/user_service.py @@ -0,0 +1,174 @@ +from datetime import datetime + +from flask import * + +# from app import Yaml +# from app.Article import get_today_article, load_freq_history +# from app.WordFreq import WordFreq +# from app.wordfreqCMD import sort_in_descending_order + +import Yaml +from Article import get_today_article, load_freq_history +from WordFreq import WordFreq +from wordfreqCMD import sort_in_descending_order + +import pickle_idea +import pickle_idea2 + +# 初始化蓝图 +userService = Blueprint("user_bp", __name__) + +path_prefix = '/var/www/wordfreq/wordfreq/' +path_prefix = './' # comment this line in deployment + + +@userService.route("//reset", methods=['GET', 'POST']) +def user_reset(username): + ''' + 用户界面 + :param username: 用户名 + :return: 返回页面内容 + ''' + if request.method == 'GET': + session['articleID'] = None + return redirect(url_for('user_bp.userpage', username=username)) + else: + return 'Under construction' + + +@userService.route("///unfamiliar", methods=['GET', 'POST']) +def unfamiliar(username, word): + ''' + + :param username: + :param word: + :return: + ''' + user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username) + pickle_idea.unfamiliar(user_freq_record, word) + session['thisWord'] = word # 1. put a word into session + session['time'] = 1 + return redirect(url_for('user_bp.userpage', username=username)) + + +@userService.route("///familiar", methods=['GET', 'POST']) +def familiar(username, word): + ''' + + :param username: + :param word: + :return: + ''' + user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username) + pickle_idea.familiar(user_freq_record, word) + session['thisWord'] = word # 1. put a word into session + session['time'] = 1 + return redirect(url_for('user_bp.userpage', username=username)) + + +@userService.route("///del", methods=['GET', 'POST']) +def deleteword(username, word): + ''' + 删除单词 + :param username: 用户名 + :param word: 单词 + :return: 重定位到用户界面 + ''' + user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username) + pickle_idea2.deleteRecord(user_freq_record, word) + flash(f'{word} is no longer in your word list.') + return redirect(url_for('user_bp.userpage', username=username)) + + +@userService.route("/", methods=['GET', 'POST']) +def userpage(username): + ''' + 用户界面 + :param username: 用户名 + :return: 返回用户界面 + ''' + # 未登录,跳转到未登录界面 + if not session.get('logged_in'): + return render_template('not_login.html') + + # 用户过期 + user_expiry_date = session.get('expiry_date') + if datetime.now().strftime('%Y%m%d') > user_expiry_date: + return render_template('expiry.html') + + # 获取session里的用户名 + username = session.get('username') + + user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username) + + if request.method == 'POST': # when we submit a form + content = request.form['content'] + f = WordFreq(content) + lst = f.get_freq() + return render_template('userpage_post.html',username=username,lst = lst, yml=Yaml.yml) + + elif request.method == 'GET': # when we load a html page + d = load_freq_history(user_freq_record) + lst = pickle_idea2.dict2lst(d) + lst2 = [] + for t in lst: + lst2.append((t[0], len(t[1]))) + lst3 = sort_in_descending_order(lst2) + words = '' + for x in lst3: + words += x[0] + ' ' + return render_template('userpage_get.html', + username=username, + session=session, + flashed_messages=get_flashed_messages_if_any(), + today_article=get_today_article(user_freq_record, session['articleID']), + d_len=len(d), + lst3=lst3, + yml=Yaml.yml, + words=words) + + + + + +@userService.route("//mark", methods=['GET', 'POST']) +def user_mark_word(username): + ''' + 标记单词 + :param username: 用户名 + :return: 重定位到用户界面 + ''' + username = session[username] + user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username) + if request.method == 'POST': + # 提交标记的单词 + d = load_freq_history(user_freq_record) + lst_history = pickle_idea2.dict2lst(d) + lst = [] + for word in request.form.getlist('marked'): + lst.append((word, [get_time()])) + d = pickle_idea2.merge_frequency(lst, lst_history) + pickle_idea2.save_frequency_to_pickle(d, user_freq_record) + return redirect(url_for('user_bp.userpage', username=username)) + else: + return 'Under construction' + +def get_time(): + ''' + 获取当前时间 + :return: 当前时间 + ''' + return datetime.now().strftime('%Y%m%d%H%M') # upper to minutes + +def get_flashed_messages_if_any(): + ''' + 在用户界面显示黄色提示信息 + :return: 包含HTML标签的提示信息 + ''' + messages = get_flashed_messages() + s = '' + for message in messages: + s += '' + return s diff --git a/requirements.txt b/requirements.txt index d42ebf8..2746a3b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ Flask==1.1.2 selenium==3.141.0 +PyYAML~=6.0