From 4d2dd2b68e059b7e01c6edf464383f6d45b02950 Mon Sep 17 00:00:00 2001 From: Lan Hui <1348141770@qq.com> Date: Wed, 26 Jan 2022 21:10:09 +0800 Subject: [PATCH] =?UTF-8?q?Repalce=20old=20app=20folder=20with=20SoftArch?= =?UTF-8?q?=E7=8E=8B=E7=82=AB/english-pal-master/app/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Article.py | 137 + app/Login.py | 77 + app/UseSqlite.py | 174 +- app/Yaml.py | 27 + app/account_service.py | 129 + app/layout/partial/footer.html | 21 + app/layout/partial/header.html | 3 + app/main.py | 612 +- app/static/config.yml | 19 + app/static/css/aplayercss.css | 709 + app/static/css/bootstrap.css | 11192 ++++++++++++++++ app/static/css/custom.css | 4 + app/static/js/APlayer.js | 1348 ++ app/static/js/Meting.js | 84 + app/static/js/fillword.js | 29 + app/static/js/highlight.js | 95 + app/static/usr/instructions.html | 172 +- app/templates/login.html | 36 +- app/templates/mainpage_get.html | 53 + app/templates/mainpage_post.html | 40 + app/templates/not_login.html | 5 + app/templates/out_time.html | 16 + app/templates/reset.html | 14 + app/templates/signup.html | 38 +- app/templates/userpage_get.html | 106 + app/templates/userpage_post.html | 45 + app/test/test_add_word.py | 15 +- ...test_add_word_and_essay_does_not_change.py | 15 +- app/test/test_delete_word.py | 118 +- app/test/test_login.py | 16 +- app/test/test_login_security_fix.py | 11 +- app/test/test_next_essay.py | 15 +- app/test/test_page_position.py | 13 +- app/test/test_signup.py | 14 +- app/user_service.py | 174 + 35 files changed, 14771 insertions(+), 805 deletions(-) create mode 100644 app/Article.py create mode 100644 app/Login.py create mode 100644 app/Yaml.py create mode 100644 app/account_service.py create mode 100644 app/layout/partial/footer.html create mode 100644 app/layout/partial/header.html create mode 100644 app/static/config.yml create mode 100644 app/static/css/aplayercss.css create mode 100644 app/static/css/bootstrap.css create mode 100644 app/static/css/custom.css create mode 100644 app/static/js/APlayer.js create mode 100644 app/static/js/Meting.js create mode 100644 app/static/js/fillword.js create mode 100644 app/static/js/highlight.js create mode 100644 app/templates/mainpage_get.html create mode 100644 app/templates/mainpage_post.html create mode 100644 app/templates/not_login.html create mode 100644 app/templates/out_time.html create mode 100644 app/templates/reset.html create mode 100644 app/templates/userpage_get.html create mode 100644 app/templates/userpage_post.html create mode 100644 app/user_service.py 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..1192240 --- /dev/null +++ b/app/Login.py @@ -0,0 +1,77 @@ +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 = '20211230' + # 将用户名和密码一起加密,以免暴露不同用户的相同密码 + 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_psd, new_psd): + ''' + 修改密码 + :param username: 用户名 + :param old_psd: 旧的密码 + :param new_psd: 新密码 + :return: 修改成功:True 否则:False + ''' + if not verify_user(username, old_psd): # 旧密码错误 + return False + # 将用户名和密码一起加密,以免暴露不同用户的相同密码 + password = md5(username + new_psd) + 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(str): + ''' + MD5摘要 + :param str: 字符串 + :return: 经MD5以后的字符串 + ''' + # 当前MD5已被关闭,若要开启需删除下面两行 + print("MD5尚未开启") + return str + # 当前MD5已被关闭,若要开启需删除上面两行 + h = hashlib.md5(str.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..5b13341 --- /dev/null +++ b/app/static/config.yml @@ -0,0 +1,19 @@ +# 全局引入的css文件地址 +css: + item: + - static/css/bootstrap.css + # - static/css/aplayercss.css + # - static/css/custom.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/aplayercss.css b/app/static/css/aplayercss.css new file mode 100644 index 0000000..4ac994a --- /dev/null +++ b/app/static/css/aplayercss.css @@ -0,0 +1,709 @@ +.aplayer { + background: #fff; + font-family: Arial, Helvetica, sans-serif; + margin: 5px; + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .07), 0 1px 5px 0 rgba(0, 0, 0, .1); + border-radius: 2px; + overflow: hidden; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + line-height: normal; + position: relative +} + +.aplayer * { + box-sizing: content-box +} + +.aplayer svg { + width: 100%; + height: 100% +} + +.aplayer svg circle, .aplayer svg path { + fill: #fff +} + +.aplayer.aplayer-withlist .aplayer-info { + border-bottom: 1px solid #e9e9e9 +} + +.aplayer.aplayer-withlist .aplayer-list { + display: block +} + +.aplayer.aplayer-withlist .aplayer-icon-order, .aplayer.aplayer-withlist .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon.aplayer-icon-menu { + display: inline +} + +.aplayer.aplayer-withlrc .aplayer-pic { + height: 90px; + width: 90px +} + +.aplayer.aplayer-withlrc .aplayer-info { + margin-left: 90px; + height: 90px; + padding: 10px 7px 0 +} + +.aplayer.aplayer-withlrc .aplayer-lrc { + display: block +} + +.aplayer.aplayer-narrow { + width: 66px +} + +.aplayer.aplayer-narrow .aplayer-info, .aplayer.aplayer-narrow .aplayer-list { + display: none +} + +.aplayer.aplayer-narrow .aplayer-body, .aplayer.aplayer-narrow .aplayer-pic { + height: 66px; + width: 66px +} + +.aplayer.aplayer-fixed { + position: fixed; + bottom: 0; + left: 0; + right: 0; + margin: 0; + z-index: 99; + overflow: visible; + max-width: 400px; + box-shadow: none +} + +.aplayer.aplayer-fixed .aplayer-list { + margin-bottom: 65px; + border: 1px solid #eee; + border-bottom: none +} + +.aplayer.aplayer-fixed .aplayer-body { + position: fixed; + bottom: 0; + left: 0; + right: 0; + margin: 0; + z-index: 99; + background: #fff; + padding-right: 18px; + transition: all .3s ease; + max-width: 400px +} + +.aplayer.aplayer-fixed .aplayer-lrc { + display: block; + position: fixed; + bottom: 10px; + left: 0; + right: 0; + margin: 0; + z-index: 98; + pointer-events: none; + text-shadow: -1px -1px 0 #fff +} + +.aplayer.aplayer-fixed .aplayer-lrc:after, .aplayer.aplayer-fixed .aplayer-lrc:before { + display: none +} + +.aplayer.aplayer-fixed .aplayer-info { + -webkit-transform: scaleX(1); + transform: scaleX(1); + -webkit-transform-origin: 0 0; + transform-origin: 0 0; + transition: all .3s ease; + border-bottom: none; + border-top: 1px solid #e9e9e9 +} + +.aplayer.aplayer-fixed .aplayer-info .aplayer-music { + width: calc(100% - 105px) +} + +.aplayer.aplayer-fixed .aplayer-miniswitcher { + display: block +} + +.aplayer.aplayer-fixed.aplayer-narrow .aplayer-info { + display: block; + -webkit-transform: scaleX(0); + transform: scaleX(0) +} + +.aplayer.aplayer-fixed.aplayer-narrow .aplayer-body { + width: 66px !important +} + +.aplayer.aplayer-fixed.aplayer-narrow .aplayer-miniswitcher .aplayer-icon { + -webkit-transform: rotateY(0); + transform: rotateY(0) +} + +.aplayer.aplayer-fixed .aplayer-icon-back, .aplayer.aplayer-fixed .aplayer-icon-forward, .aplayer.aplayer-fixed .aplayer-icon-lrc, .aplayer.aplayer-fixed .aplayer-icon-play { + display: inline-block +} + +.aplayer.aplayer-fixed .aplayer-icon-back, .aplayer.aplayer-fixed .aplayer-icon-forward, .aplayer.aplayer-fixed .aplayer-icon-menu, .aplayer.aplayer-fixed .aplayer-icon-play { + position: absolute; + bottom: 27px; + width: 20px; + height: 20px +} + +.aplayer.aplayer-fixed .aplayer-icon-back { + right: 75px +} + +.aplayer.aplayer-fixed .aplayer-icon-play { + right: 50px +} + +.aplayer.aplayer-fixed .aplayer-icon-forward { + right: 25px +} + +.aplayer.aplayer-fixed .aplayer-icon-menu { + right: 0 +} + +.aplayer.aplayer-arrow .aplayer-icon-loop, .aplayer.aplayer-arrow .aplayer-icon-order, .aplayer.aplayer-mobile .aplayer-icon-volume-down { + display: none +} + +.aplayer.aplayer-loading .aplayer-info .aplayer-controller .aplayer-loading-icon { + display: block +} + +.aplayer.aplayer-loading .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-played .aplayer-thumb { + -webkit-transform: scale(1); + transform: scale(1) +} + +.aplayer .aplayer-body { + position: relative +} + +.aplayer .aplayer-icon { + width: 15px; + height: 15px; + border: none; + background-color: transparent; + outline: none; + cursor: pointer; + opacity: .8; + vertical-align: middle; + padding: 0; + font-size: 12px; + margin: 0; + display: inline-block +} + +.aplayer .aplayer-icon path { + transition: all .2s ease-in-out +} + +.aplayer .aplayer-icon-back, .aplayer .aplayer-icon-forward, .aplayer .aplayer-icon-lrc, .aplayer .aplayer-icon-order, .aplayer .aplayer-icon-play { + display: none +} + +.aplayer .aplayer-icon-lrc-inactivity svg { + opacity: .4 +} + +.aplayer .aplayer-icon-forward { + -webkit-transform: rotate(180deg); + transform: rotate(180deg) +} + +.aplayer .aplayer-lrc-content { + display: none +} + +.aplayer .aplayer-pic { + position: relative; + float: left; + height: 66px; + width: 66px; + background-size: cover; + background-position: 50%; + transition: all .3s ease; + cursor: pointer +} + +.aplayer .aplayer-pic:hover .aplayer-button { + opacity: 1 +} + +.aplayer .aplayer-pic .aplayer-button { + position: absolute; + border-radius: 50%; + opacity: .8; + text-shadow: 0 1px 1px rgba(0, 0, 0, .2); + box-shadow: 0 1px 1px rgba(0, 0, 0, .2); + background: rgba(0, 0, 0, .2); + transition: all .1s ease +} + +.aplayer .aplayer-pic .aplayer-button path { + fill: #fff +} + +.aplayer .aplayer-pic .aplayer-hide { + display: none +} + +.aplayer .aplayer-pic .aplayer-play { + width: 26px; + height: 26px; + border: 2px solid #fff; + bottom: 50%; + right: 50%; + margin: 0 -15px -15px 0 +} + +.aplayer .aplayer-pic .aplayer-play svg { + position: absolute; + top: 3px; + left: 4px; + height: 20px; + width: 20px +} + +.aplayer .aplayer-pic .aplayer-pause { + width: 16px; + height: 16px; + border: 2px solid #fff; + bottom: 4px; + right: 4px +} + +.aplayer .aplayer-pic .aplayer-pause svg { + position: absolute; + top: 2px; + left: 2px; + height: 12px; + width: 12px +} + +.aplayer .aplayer-info { + margin-left: 66px; + padding: 14px 7px 0 10px; + height: 66px; + box-sizing: border-box +} + +.aplayer .aplayer-info .aplayer-music { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + margin: 0 0 13px 5px; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + cursor: default; + padding-bottom: 2px; + height: 20px +} + +.aplayer .aplayer-info .aplayer-music .aplayer-title { + font-size: 14px +} + +.aplayer .aplayer-info .aplayer-music .aplayer-author { + font-size: 12px; + color: #666 +} + +.aplayer .aplayer-info .aplayer-controller { + position: relative; + display: flex +} + +.aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap { + margin: 0 0 0 5px; + padding: 4px 0; + cursor: pointer !important; + flex: 1 +} + +.aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap:hover .aplayer-bar .aplayer-played .aplayer-thumb { + -webkit-transform: scale(1); + transform: scale(1) +} + +.aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar { + position: relative; + height: 2px; + width: 100%; + background: #cdcdcd +} + +.aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-loaded { + position: absolute; + left: 0; + top: 0; + bottom: 0; + background: #aaa; + height: 2px; + transition: all .5s ease +} + +.aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-played { + position: absolute; + left: 0; + top: 0; + bottom: 0; + height: 2px +} + +.aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-played .aplayer-thumb { + position: absolute; + top: 0; + right: 5px; + margin-top: -4px; + margin-right: -10px; + height: 10px; + width: 10px; + border-radius: 50%; + cursor: pointer; + transition: all .3s ease-in-out; + -webkit-transform: scale(0); + transform: scale(0) +} + +.aplayer .aplayer-info .aplayer-controller .aplayer-time { + position: relative; + right: 0; + bottom: 4px; + height: 17px; + color: #999; + font-size: 11px; + padding-left: 7px +} + +.aplayer .aplayer-info .aplayer-controller .aplayer-time .aplayer-time-inner { + vertical-align: middle +} + +.aplayer .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon { + cursor: pointer; + transition: all .2s ease +} + +.aplayer .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon path { + fill: #666 +} + +.aplayer .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon.aplayer-icon-loop { + margin-right: 2px +} + +.aplayer .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon:hover path { + fill: #000 +} + +.aplayer .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon.aplayer-icon-menu, .aplayer .aplayer-info .aplayer-controller .aplayer-time.aplayer-time-narrow .aplayer-icon-menu, .aplayer .aplayer-info .aplayer-controller .aplayer-time.aplayer-time-narrow .aplayer-icon-mode { + display: none +} + +.aplayer .aplayer-info .aplayer-controller .aplayer-volume-wrap { + position: relative; + display: inline-block; + margin-left: 3px; + cursor: pointer !important +} + +.aplayer .aplayer-info .aplayer-controller .aplayer-volume-wrap:hover .aplayer-volume-bar-wrap { + height: 40px +} + +.aplayer .aplayer-info .aplayer-controller .aplayer-volume-wrap .aplayer-volume-bar-wrap { + position: absolute; + bottom: 15px; + right: -3px; + width: 25px; + height: 0; + z-index: 99; + overflow: hidden; + transition: all .2s ease-in-out +} + +.aplayer .aplayer-info .aplayer-controller .aplayer-volume-wrap .aplayer-volume-bar-wrap.aplayer-volume-bar-wrap-active { + height: 40px +} + +.aplayer .aplayer-info .aplayer-controller .aplayer-volume-wrap .aplayer-volume-bar-wrap .aplayer-volume-bar { + position: absolute; + bottom: 0; + right: 10px; + width: 5px; + height: 35px; + background: #aaa; + border-radius: 2.5px; + overflow: hidden +} + +.aplayer .aplayer-info .aplayer-controller .aplayer-volume-wrap .aplayer-volume-bar-wrap .aplayer-volume-bar .aplayer-volume { + position: absolute; + bottom: 0; + right: 0; + width: 5px; + transition: all .1s ease +} + +.aplayer .aplayer-info .aplayer-controller .aplayer-loading-icon { + display: none +} + +.aplayer .aplayer-info .aplayer-controller .aplayer-loading-icon svg { + position: absolute; + -webkit-animation: rotate 1s linear infinite; + animation: rotate 1s linear infinite +} + +.aplayer .aplayer-lrc { + display: none; + position: relative; + height: 30px; + text-align: center; + overflow: hidden; + margin: -10px 0 7px +} + +.aplayer .aplayer-lrc:before { + top: 0; + height: 10%; + background: linear-gradient(180deg, #fff 0, hsla(0, 0%, 100%, 0)); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#ffffff", endColorstr="#00ffffff", GradientType=0) +} + +.aplayer .aplayer-lrc:after, .aplayer .aplayer-lrc:before { + position: absolute; + z-index: 1; + display: block; + overflow: hidden; + width: 100%; + content: " " +} + +.aplayer .aplayer-lrc:after { + bottom: 0; + height: 33%; + background: linear-gradient(180deg, hsla(0, 0%, 100%, 0) 0, hsla(0, 0%, 100%, .8)); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#00ffffff", endColorstr="#ccffffff", GradientType=0) +} + +.aplayer .aplayer-lrc p { + font-size: 12px; + color: #666; + line-height: 16px !important; + height: 16px !important; + padding: 0 !important; + margin: 0 !important; + transition: all .5s ease-out; + opacity: .4; + overflow: hidden +} + +.aplayer .aplayer-lrc p.aplayer-lrc-current { + opacity: 1; + overflow: visible; + height: auto !important; + min-height: 16px +} + +.aplayer .aplayer-lrc.aplayer-lrc-hide { + display: none +} + +.aplayer .aplayer-lrc .aplayer-lrc-contents { + width: 100%; + transition: all .5s ease-out; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + cursor: default +} + +.aplayer .aplayer-list { + overflow: auto; + transition: all .5s ease; + will-change: height; + display: none; + overflow: hidden +} + +.aplayer .aplayer-list.aplayer-list-hide { + max-height: 0 !important +} + +.aplayer .aplayer-list ol { + list-style-type: none; + margin: 0; + padding: 0; + overflow-y: auto +} + +.aplayer .aplayer-list ol::-webkit-scrollbar { + width: 5px +} + +.aplayer .aplayer-list ol::-webkit-scrollbar-thumb { + border-radius: 3px; + background-color: #eee +} + +.aplayer .aplayer-list ol::-webkit-scrollbar-thumb:hover { + background-color: #ccc +} + +.aplayer .aplayer-list ol li { + position: relative; + height: 32px; + line-height: 32px; + padding: 0 15px; + font-size: 12px; + border-top: 1px solid #e9e9e9; + cursor: pointer; + transition: all .2s ease; + overflow: hidden; + margin: 0 +} + +.aplayer .aplayer-list ol li:first-child { + border-top: none +} + +.aplayer .aplayer-list ol li:hover { + background: #efefef +} + +.aplayer .aplayer-list ol li.aplayer-list-light { + background: #e9e9e9 +} + +.aplayer .aplayer-list ol li.aplayer-list-light .aplayer-list-cur { + display: inline-block +} + +.aplayer .aplayer-list ol li .aplayer-list-cur { + display: none; + width: 3px; + height: 22px; + position: absolute; + left: 0; + top: 5px; + cursor: pointer +} + +.aplayer .aplayer-list ol li .aplayer-list-index { + color: #666; + margin-right: 12px; + cursor: pointer +} + +.aplayer .aplayer-list ol li .aplayer-list-author { + color: #666; + float: right; + cursor: pointer +} + +.aplayer .aplayer-notice { + opacity: 0; + position: absolute; + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); + font-size: 12px; + border-radius: 4px; + padding: 5px 10px; + transition: all .3s ease-in-out; + overflow: hidden; + color: #fff; + pointer-events: none; + background-color: #f4f4f5; + color: #909399 +} + +.aplayer .aplayer-miniswitcher { + display: none; + position: absolute; + top: 0; + right: 0; + bottom: 0; + height: 100%; + background: #e6e6e6; + width: 18px; + border-radius: 0 2px 2px 0 +} + +.aplayer .aplayer-miniswitcher .aplayer-icon { + height: 100%; + width: 100%; + -webkit-transform: rotateY(180deg); + transform: rotateY(180deg); + transition: all .3s ease +} + +.aplayer .aplayer-miniswitcher .aplayer-icon path { + fill: #666 +} + +.aplayer .aplayer-miniswitcher .aplayer-icon:hover path { + fill: #000 +} + +@-webkit-keyframes aplayer-roll { + 0% { + left: 0 + } + to { + left: -100% + } +} + +@keyframes aplayer-roll { + 0% { + left: 0 + } + to { + left: -100% + } +} + +@-webkit-keyframes rotate { + 0% { + -webkit-transform: rotate(0); + transform: rotate(0) + } + to { + -webkit-transform: rotate(1turn); + transform: rotate(1turn) + } +} + +@keyframes rotate { + 0% { + -webkit-transform: rotate(0); + transform: rotate(0) + } + to { + -webkit-transform: rotate(1turn); + transform: rotate(1turn) + } +} + +.aplayer{ + width: 500px; + margin: auto; +} \ 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/css/custom.css b/app/static/css/custom.css new file mode 100644 index 0000000..89cc999 --- /dev/null +++ b/app/static/css/custom.css @@ -0,0 +1,4 @@ +mark { + color: #FFFF00; + background-color: rgba(0,0,0,0); +} diff --git a/app/static/js/APlayer.js b/app/static/js/APlayer.js new file mode 100644 index 0000000..094f5df --- /dev/null +++ b/app/static/js/APlayer.js @@ -0,0 +1,1348 @@ +!function (e, t) { + "object" == typeof exports && "object" == typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define("APlayer", [], t) : "object" == typeof exports ? exports.APlayer = t() : e.APlayer = t() +}(window, function () { + return function (e) { + var t = {}; + + function n(i) { + if (t[i]) return t[i].exports; + var a = t[i] = {i: i, l: !1, exports: {}}; + return e[i].call(a.exports, a, a.exports, n), a.l = !0, a.exports + } + + return n.m = e, n.c = t, n.d = function (e, t, i) { + n.o(e, t) || Object.defineProperty(e, t, {configurable: !1, enumerable: !0, get: i}) + }, n.r = function (e) { + Object.defineProperty(e, "__esModule", {value: !0}) + }, n.n = function (e) { + var t = e && e.__esModule ? function () { + return e.default + } : function () { + return e + }; + return n.d(t, "a", t), t + }, n.o = function (e, t) { + return Object.prototype.hasOwnProperty.call(e, t) + }, n.p = "/", n(n.s = 41) + }([function (e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", {value: !0}); + var i = /mobile/i.test(window.navigator.userAgent), a = { + secondToTime: function (e) { + var t = Math.floor(e / 3600), n = Math.floor((e - 3600 * t) / 60), + i = Math.floor(e - 3600 * t - 60 * n); + return (t > 0 ? [t, n, i] : [n, i]).map(function (e) { + return e < 10 ? "0" + e : "" + e + }).join(":") + }, + getElementViewLeft: function (e) { + var t = e.offsetLeft, n = e.offsetParent, + i = document.body.scrollLeft + document.documentElement.scrollLeft; + if (document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement) for (; null !== n && n !== e;) t += n.offsetLeft, n = n.offsetParent; else for (; null !== n;) t += n.offsetLeft, n = n.offsetParent; + return t - i + }, + getElementViewTop: function (e, t) { + for (var n, i = e.offsetTop, a = e.offsetParent; null !== a;) i += a.offsetTop, a = a.offsetParent; + return n = document.body.scrollTop + document.documentElement.scrollTop, t ? i : i - n + }, + isMobile: i, + storage: { + set: function (e, t) { + localStorage.setItem(e, t) + }, get: function (e) { + return localStorage.getItem(e) + } + }, + nameMap: { + dragStart: i ? "touchstart" : "mousedown", + dragMove: i ? "touchmove" : "mousemove", + dragEnd: i ? "touchend" : "mouseup" + }, + randomOrder: function (e) { + return function (e) { + for (var t = e.length - 1; t >= 0; t--) { + var n = Math.floor(Math.random() * (t + 1)), i = e[n]; + e[n] = e[t], e[t] = i + } + return e + }([].concat(function (e) { + if (Array.isArray(e)) { + for (var t = 0, n = Array(e.length); t < e.length; t++) n[t] = e[t]; + return n + } + return Array.from(e) + }(Array(e))).map(function (e, t) { + return t + })) + } + }; + t.default = a + }, function (e, t, n) { + var i = n(2); + e.exports = function (e) { + "use strict"; + e = e || {}; + var t = "", n = i.$each, a = e.audio, r = (e.$value, e.$index, i.$escape), o = e.theme, s = e.index; + return n(a, function (e, n) { + t += '\n

  • \n \n ', t += r(n + s), t += '\n ', t += r(e.name), t += '\n ', t += r(e.artist), t += "\n
  • \n" + }), t + } + }, function (e, t, n) { + "use strict"; + e.exports = n(15) + }, function (e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", {value: !0}); + var i = g(n(33)), a = g(n(32)), r = g(n(31)), o = g(n(30)), s = g(n(29)), l = g(n(28)), u = g(n(27)), + c = g(n(26)), p = g(n(25)), d = g(n(24)), h = g(n(23)), y = g(n(22)), f = g(n(21)), v = g(n(20)), + m = g(n(19)); + + function g(e) { + return e && e.__esModule ? e : {default: e} + } + + var w = { + play: i.default, + pause: a.default, + volumeUp: r.default, + volumeDown: o.default, + volumeOff: s.default, + orderRandom: l.default, + orderList: u.default, + menu: c.default, + loopAll: p.default, + loopOne: d.default, + loopNone: h.default, + loading: y.default, + right: f.default, + skip: v.default, + lrc: m.default + }; + t.default = w + }, function (e, t, n) { + "use strict"; + var i, a = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (e) { + return typeof e + } : function (e) { + return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e + }; + i = function () { + return this + }(); + try { + i = i || Function("return this")() || (0, eval)("this") + } catch (e) { + "object" === ("undefined" == typeof window ? "undefined" : a(window)) && (i = window) + } + e.exports = i + }, function (e, t, n) { + "use strict"; + var i, a, r = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (e) { + return typeof e + } : function (e) { + return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e + }; + void 0 === (a = "function" == typeof (i = function () { + if ("object" === ("undefined" == typeof window ? "undefined" : r(window)) && void 0 !== document.querySelectorAll && void 0 !== window.pageYOffset && void 0 !== history.pushState) { + var e = function (e, t, n, i) { + return n > i ? t : e + (t - e) * ((a = n / i) < .5 ? 4 * a * a * a : (a - 1) * (2 * a - 2) * (2 * a - 2) + 1); + var a + }, t = function (t, n, i, a) { + n = n || 500; + var r = (a = a || window).scrollTop || window.pageYOffset; + if ("number" == typeof t) var o = parseInt(t); else var o = function (e, t) { + return "HTML" === e.nodeName ? -t : e.getBoundingClientRect().top + t + }(t, r); + var s = Date.now(), + l = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || function (e) { + window.setTimeout(e, 15) + }; + !function u() { + var c = Date.now() - s; + a !== window ? a.scrollTop = e(r, o, c, n) : window.scroll(0, e(r, o, c, n)), c > n ? "function" == typeof i && i(t) : l(u) + }() + }, n = function (e) { + if (!e.defaultPrevented) { + e.preventDefault(), location.hash !== this.hash && window.history.pushState(null, null, this.hash); + var n = document.getElementById(this.hash.substring(1)); + if (!n) return; + t(n, 500, function (e) { + location.replace("#" + e.id) + }) + } + }; + return document.addEventListener("DOMContentLoaded", function () { + for (var e, t = document.querySelectorAll('a[href^="#"]:not([href="#"])'), i = t.length; e = t[--i];) e.addEventListener("click", n, !1) + }), t + } + }) ? i.call(t, n, t, e) : i) || (e.exports = a) + }, function (e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", {value: !0}); + var i = function () { + function e(e, t) { + for (var n = 0; n < t.length; n++) { + var i = t[n]; + i.enumerable = i.enumerable || !1, i.configurable = !0, "value" in i && (i.writable = !0), Object.defineProperty(e, i.key, i) + } + } + + return function (t, n, i) { + return n && e(t.prototype, n), i && e(t, i), t + } + }(), a = s(n(1)), r = s(n(0)), o = s(n(5)); + + function s(e) { + return e && e.__esModule ? e : {default: e} + } + + var l = function () { + function e(t) { + !function (e, t) { + if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function") + }(this, e), this.player = t, this.index = 0, this.audios = this.player.options.audio, this.bindEvents() + } + + return i(e, [{ + key: "bindEvents", value: function () { + var e = this; + this.player.template.list.addEventListener("click", function (t) { + var n = void 0; + n = "LI" === t.target.tagName.toUpperCase() ? t.target : t.target.parentElement; + var i = parseInt(n.getElementsByClassName("aplayer-list-index")[0].innerHTML) - 1; + i !== e.index ? (e.switch(i), e.player.play()) : e.player.toggle() + }) + } + }, { + key: "show", value: function () { + this.player.events.trigger("listshow"), this.player.template.list.classList.remove("aplayer-list-hide"), this.player.template.listOl.scrollTop = 33 * this.index + } + }, { + key: "hide", value: function () { + this.player.events.trigger("listhide"), this.player.template.list.classList.add("aplayer-list-hide") + } + }, { + key: "toggle", value: function () { + this.player.template.list.classList.contains("aplayer-list-hide") ? this.show() : this.hide() + } + }, { + key: "add", value: function (e) { + this.player.events.trigger("listadd", {audios: e}), "[object Array]" !== Object.prototype.toString.call(e) && (e = [e]), e.map(function (e) { + return e.name = e.name || e.title || "Audio name", e.artist = e.artist || e.author || "Audio artist", e.cover = e.cover || e.pic, e.type = e.type || "normal", e + }); + var t = !(this.audios.length > 1), n = 0 === this.audios.length; + this.player.template.listOl.innerHTML += (0, a.default)({ + theme: this.player.options.theme, + audio: e, + index: this.audios.length + 1 + }), this.audios = this.audios.concat(e), t && this.audios.length > 1 && this.player.container.classList.add("aplayer-withlist"), this.player.randomOrder = r.default.randomOrder(this.audios.length), this.player.template.listCurs = this.player.container.querySelectorAll(".aplayer-list-cur"), this.player.template.listCurs[this.audios.length - 1].style.backgroundColor = e.theme || this.player.options.theme, n && ("random" === this.player.options.order ? this.switch(this.player.randomOrder[0]) : this.switch(0)) + } + }, { + key: "remove", value: function (e) { + if (this.player.events.trigger("listremove", {index: e}), this.audios[e]) if (this.audios.length > 1) { + var t = this.player.container.querySelectorAll(".aplayer-list li"); + t[e].remove(), this.audios.splice(e, 1), this.player.lrc && this.player.lrc.remove(e), e === this.index && (this.audios[e] ? this.switch(e) : this.switch(e - 1)), this.index > e && this.index--; + for (var n = e; n < t.length; n++) t[n].getElementsByClassName("aplayer-list-index")[0].textContent = n; + 1 === this.audios.length && this.player.container.classList.remove("aplayer-withlist"), this.player.template.listCurs = this.player.container.querySelectorAll(".aplayer-list-cur") + } else this.clear() + } + }, { + key: "switch", value: function (e) { + if (this.player.events.trigger("listswitch", {index: e}), void 0 !== e && this.audios[e]) { + this.index = e; + var t = this.audios[this.index]; + this.player.template.pic.style.backgroundImage = t.cover ? "url('" + t.cover + "')" : "", this.player.theme(this.audios[this.index].theme || this.player.options.theme, this.index, !1), this.player.template.title.innerHTML = t.name, this.player.template.author.innerHTML = t.artist ? " - " + t.artist : ""; + var n = this.player.container.getElementsByClassName("aplayer-list-light")[0]; + n && n.classList.remove("aplayer-list-light"), this.player.container.querySelectorAll(".aplayer-list li")[this.index].classList.add("aplayer-list-light"), (0, o.default)(33 * this.index, 500, null, this.player.template.listOl), this.player.setAudio(t), this.player.lrc && this.player.lrc.switch(this.index), this.player.lrc && this.player.lrc.update(0), 1 !== this.player.duration && (this.player.template.dtime.innerHTML = r.default.secondToTime(this.player.duration)) + } + } + }, { + key: "clear", value: function () { + this.player.events.trigger("listclear"), this.index = 0, this.player.container.classList.remove("aplayer-withlist"), this.player.pause(), this.audios = [], this.player.lrc && this.player.lrc.clear(), this.player.audio.src = "", this.player.template.listOl.innerHTML = "", this.player.template.pic.style.backgroundImage = "", this.player.theme(this.player.options.theme, this.index, !1), this.player.template.title.innerHTML = "No audio", this.player.template.author.innerHTML = "", this.player.bar.set("loaded", 0, "width"), this.player.template.dtime.innerHTML = r.default.secondToTime(0) + } + }]), e + }(); + t.default = l + }, function (e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", {value: !0}); + var i = function () { + function e(e, t) { + for (var n = 0; n < t.length; n++) { + var i = t[n]; + i.enumerable = i.enumerable || !1, i.configurable = !0, "value" in i && (i.writable = !0), Object.defineProperty(e, i.key, i) + } + } + + return function (t, n, i) { + return n && e(t.prototype, n), i && e(t, i), t + } + }(); + var a = function () { + function e() { + !function (e, t) { + if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function") + }(this, e), this.events = {}, this.audioEvents = ["abort", "canplay", "canplaythrough", "durationchange", "emptied", "ended", "error", "loadeddata", "loadedmetadata", "loadstart", "mozaudioavailable", "pause", "play", "playing", "progress", "ratechange", "seeked", "seeking", "stalled", "suspend", "timeupdate", "volumechange", "waiting"], this.playerEvents = ["destroy", "listshow", "listhide", "listadd", "listremove", "listswitch", "listclear", "noticeshow", "noticehide", "lrcshow", "lrchide"] + } + + return i(e, [{ + key: "on", value: function (e, t) { + this.type(e) && "function" == typeof t && (this.events[e] || (this.events[e] = []), this.events[e].push(t)) + } + }, { + key: "trigger", value: function (e, t) { + if (this.events[e] && this.events[e].length) for (var n = 0; n < this.events[e].length; n++) this.events[e][n](t) + } + }, { + key: "type", value: function (e) { + return -1 !== this.playerEvents.indexOf(e) ? "player" : -1 !== this.audioEvents.indexOf(e) ? "audio" : (console.error("Unknown event name: " + e), null) + } + }]), e + }(); + t.default = a + }, function (e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", {value: !0}); + var i = function () { + function e(e, t) { + for (var n = 0; n < t.length; n++) { + var i = t[n]; + i.enumerable = i.enumerable || !1, i.configurable = !0, "value" in i && (i.writable = !0), Object.defineProperty(e, i.key, i) + } + } + + return function (t, n, i) { + return n && e(t.prototype, n), i && e(t, i), t + } + }(); + var a = function () { + function e(t) { + !function (e, t) { + if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function") + }(this, e), this.player = t, window.requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (e) { + window.setTimeout(e, 1e3 / 60) + }, this.types = ["loading"], this.init() + } + + return i(e, [{ + key: "init", value: function () { + var e = this; + this.types.forEach(function (t) { + e["init" + t + "Checker"]() + }) + } + }, { + key: "initloadingChecker", value: function () { + var e = this, t = 0, n = 0, i = !1; + this.loadingChecker = setInterval(function () { + e.enableloadingChecker && (n = e.player.audio.currentTime, i || n !== t || e.player.audio.paused || (e.player.container.classList.add("aplayer-loading"), i = !0), i && n > t && !e.player.audio.paused && (e.player.container.classList.remove("aplayer-loading"), i = !1), t = n) + }, 100) + } + }, { + key: "enable", value: function (e) { + this["enable" + e + "Checker"] = !0, "fps" === e && this.initfpsChecker() + } + }, { + key: "disable", value: function (e) { + this["enable" + e + "Checker"] = !1 + } + }, { + key: "destroy", value: function () { + var e = this; + this.types.forEach(function (t) { + e["enable" + t + "Checker"] = !1, e[t + "Checker"] && clearInterval(e[t + "Checker"]) + }) + } + }]), e + }(); + t.default = a + }, function (e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", {value: !0}); + var i = function () { + function e(e, t) { + for (var n = 0; n < t.length; n++) { + var i = t[n]; + i.enumerable = i.enumerable || !1, i.configurable = !0, "value" in i && (i.writable = !0), Object.defineProperty(e, i.key, i) + } + } + + return function (t, n, i) { + return n && e(t.prototype, n), i && e(t, i), t + } + }(), a = o(n(0)), r = o(n(3)); + + function o(e) { + return e && e.__esModule ? e : {default: e} + } + + var s = function () { + function e(t) { + !function (e, t) { + if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function") + }(this, e), this.player = t, this.initPlayButton(), this.initPlayBar(), this.initOrderButton(), this.initLoopButton(), this.initMenuButton(), a.default.isMobile || this.initVolumeButton(), this.initMiniSwitcher(), this.initSkipButton(), this.initLrcButton() + } + + return i(e, [{ + key: "initPlayButton", value: function () { + var e = this; + this.player.template.pic.addEventListener("click", function () { + e.player.toggle() + }) + } + }, { + key: "initPlayBar", value: function () { + var e = this, t = function (t) { + var n = ((t.clientX || t.changedTouches[0].clientX) - a.default.getElementViewLeft(e.player.template.barWrap)) / e.player.template.barWrap.clientWidth; + n = Math.max(n, 0), n = Math.min(n, 1), e.player.bar.set("played", n, "width"), e.player.lrc && e.player.lrc.update(n * e.player.duration), e.player.template.ptime.innerHTML = a.default.secondToTime(n * e.player.duration) + }, n = function n(i) { + document.removeEventListener(a.default.nameMap.dragEnd, n), document.removeEventListener(a.default.nameMap.dragMove, t); + var r = ((i.clientX || i.changedTouches[0].clientX) - a.default.getElementViewLeft(e.player.template.barWrap)) / e.player.template.barWrap.clientWidth; + r = Math.max(r, 0), r = Math.min(r, 1), e.player.bar.set("played", r, "width"), e.player.seek(e.player.bar.get("played", "width") * e.player.duration), e.player.disableTimeupdate = !1 + }; + this.player.template.barWrap.addEventListener(a.default.nameMap.dragStart, function () { + e.player.disableTimeupdate = !0, document.addEventListener(a.default.nameMap.dragMove, t), document.addEventListener(a.default.nameMap.dragEnd, n) + }) + } + }, { + key: "initVolumeButton", value: function () { + var e = this; + this.player.template.volumeButton.addEventListener("click", function () { + e.player.audio.muted ? (e.player.audio.muted = !1, e.player.switchVolumeIcon(), e.player.bar.set("volume", e.player.volume(), "height")) : (e.player.audio.muted = !0, e.player.switchVolumeIcon(), e.player.bar.set("volume", 0, "height")) + }); + var t = function (t) { + var n = 1 - ((t.clientY || t.changedTouches[0].clientY) - a.default.getElementViewTop(e.player.template.volumeBar, e.player.options.fixed)) / e.player.template.volumeBar.clientHeight; + n = Math.max(n, 0), n = Math.min(n, 1), e.player.volume(n) + }, n = function n(i) { + e.player.template.volumeBarWrap.classList.remove("aplayer-volume-bar-wrap-active"), document.removeEventListener(a.default.nameMap.dragEnd, n), document.removeEventListener(a.default.nameMap.dragMove, t); + var r = 1 - ((i.clientY || i.changedTouches[0].clientY) - a.default.getElementViewTop(e.player.template.volumeBar, e.player.options.fixed)) / e.player.template.volumeBar.clientHeight; + r = Math.max(r, 0), r = Math.min(r, 1), e.player.volume(r) + }; + this.player.template.volumeBarWrap.addEventListener(a.default.nameMap.dragStart, function () { + e.player.template.volumeBarWrap.classList.add("aplayer-volume-bar-wrap-active"), document.addEventListener(a.default.nameMap.dragMove, t), document.addEventListener(a.default.nameMap.dragEnd, n) + }) + } + }, { + key: "initOrderButton", value: function () { + var e = this; + this.player.template.order.addEventListener("click", function () { + "list" === e.player.options.order ? (e.player.options.order = "random", e.player.template.order.innerHTML = r.default.orderRandom) : "random" === e.player.options.order && (e.player.options.order = "list", e.player.template.order.innerHTML = r.default.orderList) + }) + } + }, { + key: "initLoopButton", value: function () { + var e = this; + this.player.template.loop.addEventListener("click", function () { + e.player.list.audios.length > 1 ? "one" === e.player.options.loop ? (e.player.options.loop = "none", e.player.template.loop.innerHTML = r.default.loopNone) : "none" === e.player.options.loop ? (e.player.options.loop = "all", e.player.template.loop.innerHTML = r.default.loopAll) : "all" === e.player.options.loop && (e.player.options.loop = "one", e.player.template.loop.innerHTML = r.default.loopOne) : "one" === e.player.options.loop || "all" === e.player.options.loop ? (e.player.options.loop = "none", e.player.template.loop.innerHTML = r.default.loopNone) : "none" === e.player.options.loop && (e.player.options.loop = "all", e.player.template.loop.innerHTML = r.default.loopAll) + }) + } + }, { + key: "initMenuButton", value: function () { + var e = this; + this.player.template.menu.addEventListener("click", function () { + e.player.list.toggle() + }) + } + }, { + key: "initMiniSwitcher", value: function () { + var e = this; + this.player.template.miniSwitcher.addEventListener("click", function () { + e.player.setMode("mini" === e.player.mode ? "normal" : "mini") + }) + } + }, { + key: "initSkipButton", value: function () { + var e = this; + this.player.template.skipBackButton.addEventListener("click", function () { + e.player.skipBack() + }), this.player.template.skipForwardButton.addEventListener("click", function () { + e.player.skipForward() + }), this.player.template.skipPlayButton.addEventListener("click", function () { + e.player.toggle() + }) + } + }, { + key: "initLrcButton", value: function () { + var e = this; + this.player.template.lrcButton.addEventListener("click", function () { + e.player.template.lrcButton.classList.contains("aplayer-icon-lrc-inactivity") ? (e.player.template.lrcButton.classList.remove("aplayer-icon-lrc-inactivity"), e.player.lrc && e.player.lrc.show()) : (e.player.template.lrcButton.classList.add("aplayer-icon-lrc-inactivity"), e.player.lrc && e.player.lrc.hide()) + }) + } + }]), e + }(); + t.default = s + }, function (e, t, n) { + var i = n(2); + e.exports = function (e) { + "use strict"; + e = e || {}; + var t = "", n = i.$each, a = e.lyrics, r = (e.$value, e.$index, i.$escape); + return n(a, function (e, n) { + t += "\n 0 && void 0 !== arguments[0] ? arguments[0] : this.player.audio.currentTime; + if (this.index > this.current.length - 1 || e < this.current[this.index][0] || !this.current[this.index + 1] || e >= this.current[this.index + 1][0]) for (var t = 0; t < this.current.length; t++) e >= this.current[t][0] && (!this.current[t + 1] || e < this.current[t + 1][0]) && (this.index = t, this.container.style.transform = "translateY(" + 16 * -this.index + "px)", this.container.style.webkitTransform = "translateY(" + 16 * -this.index + "px)", this.container.getElementsByClassName("aplayer-lrc-current")[0].classList.remove("aplayer-lrc-current"), this.container.getElementsByTagName("p")[t].classList.add("aplayer-lrc-current")) + } + }, { + key: "switch", value: function (e) { + var t = this; + if (!this.parsed[e]) if (this.async) { + this.parsed[e] = [["00:00", "Loading"]]; + var n = new XMLHttpRequest; + n.onreadystatechange = function () { + e === t.player.list.index && 4 === n.readyState && (n.status >= 200 && n.status < 300 || 304 === n.status ? t.parsed[e] = t.parse(n.responseText) : (t.player.notice("LRC file request fails: status " + n.status), t.parsed[e] = [["00:00", "Not available"]]), t.container.innerHTML = (0, o.default)({lyrics: t.parsed[e]}), t.update(0), t.current = t.parsed[e]) + }; + var i = this.player.list.audios[e].lrc; + n.open("get", i, !0), n.send(null) + } else this.player.list.audios[e].lrc ? this.parsed[e] = this.parse(this.player.list.audios[e].lrc) : this.parsed[e] = [["00:00", "Not available"]]; + this.container.innerHTML = (0, o.default)({lyrics: this.parsed[e]}), this.update(0), this.current = this.parsed[e] + } + }, { + key: "parse", value: function (e) { + if (e) { + for (var t = (e = e.replace(/([^\]^\n])\[/g, function (e, t) { + return t + "\n[" + })).split("\n"), n = [], i = t.length, a = 0; a < i; a++) { + var r = t[a].match(/\[(\d{2}):(\d{2})(\.(\d{2,3}))?]/g), + o = t[a].replace(/.*\[(\d{2}):(\d{2})(\.(\d{2,3}))?]/g, "").replace(/<(\d{2}):(\d{2})(\.(\d{2,3}))?>/g, "").replace(/^\s+|\s+$/g, ""); + if (r) for (var s = r.length, l = 0; l < s; l++) { + var u = /\[(\d{2}):(\d{2})(\.(\d{2,3}))?]/.exec(r[l]), + c = 60 * u[1] + parseInt(u[2]) + (u[4] ? parseInt(u[4]) / (2 === (u[4] + "").length ? 100 : 1e3) : 0); + n.push([c, o]) + } + } + return (n = n.filter(function (e) { + return e[1] + })).sort(function (e, t) { + return e[0] - t[0] + }), n + } + return [] + } + }, { + key: "remove", value: function (e) { + this.parsed.splice(e, 1) + } + }, { + key: "clear", value: function () { + this.parsed = [], this.container.innerHTML = "" + } + }]), e + }(); + t.default = s + }, function (e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", {value: !0}); + var i, a = function () { + function e(e, t) { + for (var n = 0; n < t.length; n++) { + var i = t[n]; + i.enumerable = i.enumerable || !1, i.configurable = !0, "value" in i && (i.writable = !0), Object.defineProperty(e, i.key, i) + } + } + + return function (t, n, i) { + return n && e(t.prototype, n), i && e(t, i), t + } + }(), r = n(0), o = (i = r) && i.__esModule ? i : {default: i}; + var s = function () { + function e(t) { + !function (e, t) { + if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function") + }(this, e), this.storageName = t.options.storageName, this.data = JSON.parse(o.default.storage.get(this.storageName)), this.data || (this.data = {}), this.data.volume = this.data.volume || t.options.volume + } + + return a(e, [{ + key: "get", value: function (e) { + return this.data[e] + } + }, { + key: "set", value: function (e, t) { + this.data[e] = t, o.default.storage.set(this.storageName, JSON.stringify(this.data)) + } + }]), e + }(); + t.default = s + }, function (e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", {value: !0}); + var i = function () { + function e(e, t) { + for (var n = 0; n < t.length; n++) { + var i = t[n]; + i.enumerable = i.enumerable || !1, i.configurable = !0, "value" in i && (i.writable = !0), Object.defineProperty(e, i.key, i) + } + } + + return function (t, n, i) { + return n && e(t.prototype, n), i && e(t, i), t + } + }(); + var a = function () { + function e(t) { + !function (e, t) { + if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function") + }(this, e), this.elements = {}, this.elements.volume = t.volume, this.elements.played = t.played, this.elements.loaded = t.loaded + } + + return i(e, [{ + key: "set", value: function (e, t, n) { + t = Math.max(t, 0), t = Math.min(t, 1), this.elements[e].style[n] = 100 * t + "%" + } + }, { + key: "get", value: function (e, t) { + return parseFloat(this.elements[e].style[t]) / 100 + } + }]), e + }(); + t.default = a + }, function (e, t, n) { + "use strict"; + (function (t) { + e.exports = !1; + try { + e.exports = "[object process]" === Object.prototype.toString.call(t.process) + } catch (e) { + } + }).call(this, n(4)) + }, function (e, t, n) { + "use strict"; + (function (t) { + var i = n(14), a = Object.create(i ? t : window), r = /["&'<>]/; + a.$escape = function (e) { + return function (e) { + var t = "" + e, n = r.exec(t); + if (!n) return e; + var i = "", a = void 0, o = void 0, s = void 0; + for (a = n.index, o = 0; a < t.length; a++) { + switch (t.charCodeAt(a)) { + case 34: + s = """; + break; + case 38: + s = "&"; + break; + case 39: + s = "'"; + break; + case 60: + s = "<"; + break; + case 62: + s = ">"; + break; + default: + continue + } + o !== a && (i += t.substring(o, a)), o = a + 1, i += s + } + return o !== a ? i + t.substring(o, a) : i + }(function e(t) { + "string" != typeof t && (t = void 0 === t || null === t ? "" : "function" == typeof t ? e(t.call(t)) : JSON.stringify(t)); + return t + }(e)) + }, a.$each = function (e, t) { + if (Array.isArray(e)) for (var n = 0, i = e.length; n < i; n++) t(e[n], n); else for (var a in e) t(e[a], a) + }, e.exports = a + }).call(this, n(4)) + }, function (e, t, n) { + var i = n(2); + e.exports = function (e) { + "use strict"; + var t = "", a = (e = e || {}).options, r = e.cover, o = i.$escape, s = e.icons, + l = (arguments[1], function (e) { + return t += e + }), u = e.getObject; + e.theme, e.audio, e.index; + return a.fixed ? (t += '\n
    1) for (var n = 1; n < arguments.length; n++) t[n - 1] = arguments[n]; + c.push(new f(e, t)), 1 !== c.length || p || l(y) + }, f.prototype.run = function () { + this.fun.apply(null, this.array) + }, r.title = "browser", r.browser = !0, r.env = {}, r.argv = [], r.version = "", r.versions = {}, r.on = v, r.addListener = v, r.once = v, r.off = v, r.removeListener = v, r.removeAllListeners = v, r.emit = v, r.prependListener = v, r.prependOnceListener = v, r.listeners = function (e) { + return [] + }, r.binding = function (e) { + throw new Error("process.binding is not supported") + }, r.cwd = function () { + return "/" + }, r.chdir = function (e) { + throw new Error("process.chdir is not supported") + }, r.umask = function () { + return 0 + } + }, function (e, t, n) { + "use strict"; + (function (e, t) { + !function (e, n) { + if (!e.setImmediate) { + var i, a, r, o, s, l = 1, u = {}, c = !1, p = e.document, + d = Object.getPrototypeOf && Object.getPrototypeOf(e); + d = d && d.setTimeout ? d : e, "[object process]" === {}.toString.call(e.process) ? i = function (e) { + t.nextTick(function () { + y(e) + }) + } : !function () { + if (e.postMessage && !e.importScripts) { + var t = !0, n = e.onmessage; + return e.onmessage = function () { + t = !1 + }, e.postMessage("", "*"), e.onmessage = n, t + } + }() ? e.MessageChannel ? ((r = new MessageChannel).port1.onmessage = function (e) { + y(e.data) + }, i = function (e) { + r.port2.postMessage(e) + }) : p && "onreadystatechange" in p.createElement("script") ? (a = p.documentElement, i = function (e) { + var t = p.createElement("script"); + t.onreadystatechange = function () { + y(e), t.onreadystatechange = null, a.removeChild(t), t = null + }, a.appendChild(t) + }) : i = function (e) { + setTimeout(y, 0, e) + } : (o = "setImmediate$" + Math.random() + "$", s = function (t) { + t.source === e && "string" == typeof t.data && 0 === t.data.indexOf(o) && y(+t.data.slice(o.length)) + }, e.addEventListener ? e.addEventListener("message", s, !1) : e.attachEvent("onmessage", s), i = function (t) { + e.postMessage(o + t, "*") + }), d.setImmediate = function (e) { + "function" != typeof e && (e = new Function("" + e)); + for (var t = new Array(arguments.length - 1), n = 0; n < t.length; n++) t[n] = arguments[n + 1]; + var a = {callback: e, args: t}; + return u[l] = a, i(l), l++ + }, d.clearImmediate = h + } + + function h(e) { + delete u[e] + } + + function y(e) { + if (c) setTimeout(y, 0, e); else { + var t = u[e]; + if (t) { + c = !0; + try { + !function (e) { + var t = e.callback, i = e.args; + switch (i.length) { + case 0: + t(); + break; + case 1: + t(i[0]); + break; + case 2: + t(i[0], i[1]); + break; + case 3: + t(i[0], i[1], i[2]); + break; + default: + t.apply(n, i) + } + }(t) + } finally { + h(e), c = !1 + } + } + } + } + }("undefined" == typeof self ? void 0 === e ? void 0 : e : self) + }).call(this, n(4), n(34)) + }, function (e, t, n) { + "use strict"; + var i = Function.prototype.apply; + + function a(e, t) { + this._id = e, this._clearFn = t + } + + t.setTimeout = function () { + return new a(i.call(setTimeout, window, arguments), clearTimeout) + }, t.setInterval = function () { + return new a(i.call(setInterval, window, arguments), clearInterval) + }, t.clearTimeout = t.clearInterval = function (e) { + e && e.close() + }, a.prototype.unref = a.prototype.ref = function () { + }, a.prototype.close = function () { + this._clearFn.call(window, this._id) + }, t.enroll = function (e, t) { + clearTimeout(e._idleTimeoutId), e._idleTimeout = t + }, t.unenroll = function (e) { + clearTimeout(e._idleTimeoutId), e._idleTimeout = -1 + }, t._unrefActive = t.active = function (e) { + clearTimeout(e._idleTimeoutId); + var t = e._idleTimeout; + t >= 0 && (e._idleTimeoutId = setTimeout(function () { + e._onTimeout && e._onTimeout() + }, t)) + }, n(35), t.setImmediate = setImmediate, t.clearImmediate = clearImmediate + }, function (e, t, n) { + "use strict"; + (function (t) { + var n = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (e) { + return typeof e + } : function (e) { + return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e + }, i = setTimeout; + + function a() { + } + + function r(e) { + if (!(this instanceof r)) throw new TypeError("Promises must be constructed via new"); + if ("function" != typeof e) throw new TypeError("not a function"); + this._state = 0, this._handled = !1, this._value = void 0, this._deferreds = [], c(e, this) + } + + function o(e, t) { + for (; 3 === e._state;) e = e._value; + 0 !== e._state ? (e._handled = !0, r._immediateFn(function () { + var n = 1 === e._state ? t.onFulfilled : t.onRejected; + if (null !== n) { + var i; + try { + i = n(e._value) + } catch (e) { + return void l(t.promise, e) + } + s(t.promise, i) + } else (1 === e._state ? s : l)(t.promise, e._value) + })) : e._deferreds.push(t) + } + + function s(e, t) { + try { + if (t === e) throw new TypeError("A promise cannot be resolved with itself."); + if (t && ("object" === (void 0 === t ? "undefined" : n(t)) || "function" == typeof t)) { + var i = t.then; + if (t instanceof r) return e._state = 3, e._value = t, void u(e); + if ("function" == typeof i) return void c((a = i, o = t, function () { + a.apply(o, arguments) + }), e) + } + e._state = 1, e._value = t, u(e) + } catch (t) { + l(e, t) + } + var a, o + } + + function l(e, t) { + e._state = 2, e._value = t, u(e) + } + + function u(e) { + 2 === e._state && 0 === e._deferreds.length && r._immediateFn(function () { + e._handled || r._unhandledRejectionFn(e._value) + }); + for (var t = 0, n = e._deferreds.length; t < n; t++) o(e, e._deferreds[t]); + e._deferreds = null + } + + function c(e, t) { + var n = !1; + try { + e(function (e) { + n || (n = !0, s(t, e)) + }, function (e) { + n || (n = !0, l(t, e)) + }) + } catch (e) { + if (n) return; + n = !0, l(t, e) + } + } + + r.prototype.catch = function (e) { + return this.then(null, e) + }, r.prototype.then = function (e, t) { + var n = new this.constructor(a); + return o(this, new function (e, t, n) { + this.onFulfilled = "function" == typeof e ? e : null, this.onRejected = "function" == typeof t ? t : null, this.promise = n + }(e, t, n)), n + }, r.prototype.finally = function (e) { + var t = this.constructor; + return this.then(function (n) { + return t.resolve(e()).then(function () { + return n + }) + }, function (n) { + return t.resolve(e()).then(function () { + return t.reject(n) + }) + }) + }, r.all = function (e) { + return new r(function (t, i) { + if (!e || void 0 === e.length) throw new TypeError("Promise.all accepts an array"); + var a = Array.prototype.slice.call(e); + if (0 === a.length) return t([]); + var r = a.length; + + function o(e, s) { + try { + if (s && ("object" === (void 0 === s ? "undefined" : n(s)) || "function" == typeof s)) { + var l = s.then; + if ("function" == typeof l) return void l.call(s, function (t) { + o(e, t) + }, i) + } + a[e] = s, 0 == --r && t(a) + } catch (e) { + i(e) + } + } + + for (var s = 0; s < a.length; s++) o(s, a[s]) + }) + }, r.resolve = function (e) { + return e && "object" === (void 0 === e ? "undefined" : n(e)) && e.constructor === r ? e : new r(function (t) { + t(e) + }) + }, r.reject = function (e) { + return new r(function (t, n) { + n(e) + }) + }, r.race = function (e) { + return new r(function (t, n) { + for (var i = 0, a = e.length; i < a; i++) e[i].then(t, n) + }) + }, r._immediateFn = "function" == typeof t && function (e) { + t(e) + } || function (e) { + i(e, 0) + }, r._unhandledRejectionFn = function (e) { + "undefined" != typeof console && console && console.warn("Possible Unhandled Promise Rejection:", e) + }, e.exports = r + }).call(this, n(36).setImmediate) + }, function (e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", {value: !0}); + var i = function () { + function e(e, t) { + for (var n = 0; n < t.length; n++) { + var i = t[n]; + i.enumerable = i.enumerable || !1, i.configurable = !0, "value" in i && (i.writable = !0), Object.defineProperty(e, i.key, i) + } + } + + return function (t, n, i) { + return n && e(t.prototype, n), i && e(t, i), t + } + }(), a = v(n(37)), r = v(n(0)), o = v(n(3)), s = v(n(18)), l = v(n(17)), u = v(n(13)), c = v(n(12)), + p = v(n(11)), d = v(n(9)), h = v(n(8)), y = v(n(7)), f = v(n(6)); + + function v(e) { + return e && e.__esModule ? e : {default: e} + } + + var m = [], g = function () { + function e(t) { + if (function (e, t) { + if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function") + }(this, e), this.options = (0, s.default)(t), this.container = this.options.container, this.paused = !0, this.playedPromise = a.default.resolve(), this.mode = "normal", this.randomOrder = r.default.randomOrder(this.options.audio.length), this.container.classList.add("aplayer"), this.options.lrcType && !this.options.fixed && this.container.classList.add("aplayer-withlrc"), this.options.audio.length > 1 && this.container.classList.add("aplayer-withlist"), r.default.isMobile && this.container.classList.add("aplayer-mobile"), this.arrow = this.container.offsetWidth <= 300, this.arrow && this.container.classList.add("aplayer-arrow"), this.container = this.options.container, 2 === this.options.lrcType || !0 === this.options.lrcType) for (var n = this.container.getElementsByClassName("aplayer-lrc-content"), i = 0; i < n.length; i++) this.options.audio[i] && (this.options.audio[i].lrc = n[i].innerHTML); + this.template = new l.default({ + container: this.container, + options: this.options, + randomOrder: this.randomOrder + }), this.options.fixed && (this.container.classList.add("aplayer-fixed"), this.template.body.style.width = this.template.body.offsetWidth - 18 + "px"), this.options.mini && (this.setMode("mini"), this.template.info.style.display = "block"), this.template.info.offsetWidth < 200 && this.template.time.classList.add("aplayer-time-narrow"), this.options.lrcType && (this.lrc = new p.default({ + container: this.template.lrc, + async: 3 === this.options.lrcType, + player: this + })), this.events = new y.default, this.storage = new c.default(this), this.bar = new u.default(this.template), this.controller = new d.default(this), this.timer = new h.default(this), this.list = new f.default(this), this.initAudio(), this.bindEvents(), "random" === this.options.order ? this.list.switch(this.randomOrder[0]) : this.list.switch(0), this.options.autoplay && this.play(), m.push(this) + } + + return i(e, [{ + key: "initAudio", value: function () { + var e = this; + this.audio = document.createElement("audio"), this.audio.preload = this.options.preload; + for (var t = function (t) { + e.audio.addEventListener(e.events.audioEvents[t], function (n) { + e.events.trigger(e.events.audioEvents[t], n) + }) + }, n = 0; n < this.events.audioEvents.length; n++) t(n); + this.volume(this.storage.get("volume"), !0) + } + }, { + key: "bindEvents", value: function () { + var e = this; + this.on("play", function () { + e.paused && e.setUIPlaying() + }), this.on("pause", function () { + e.paused || e.setUIPaused() + }), this.on("timeupdate", function () { + if (!e.disableTimeupdate) { + e.bar.set("played", e.audio.currentTime / e.duration, "width"), e.lrc && e.lrc.update(); + var t = r.default.secondToTime(e.audio.currentTime); + e.template.ptime.innerHTML !== t && (e.template.ptime.innerHTML = t) + } + }), this.on("durationchange", function () { + 1 !== e.duration && (e.template.dtime.innerHTML = r.default.secondToTime(e.duration)) + }), this.on("progress", function () { + var t = e.audio.buffered.length ? e.audio.buffered.end(e.audio.buffered.length - 1) / e.duration : 0; + e.bar.set("loaded", t, "width") + }); + var t = void 0; + this.on("error", function () { + e.list.audios.length > 1 ? (e.notice("An audio error has occurred, player will skip forward in 2 seconds."), t = setTimeout(function () { + e.skipForward(), e.paused || e.play() + }, 2e3)) : 1 === e.list.audios.length && e.notice("An audio error has occurred.") + }), this.events.on("listswitch", function () { + t && clearTimeout(t) + }), this.on("ended", function () { + "none" === e.options.loop ? "list" === e.options.order ? e.list.index < e.list.audios.length - 1 ? (e.list.switch((e.list.index + 1) % e.list.audios.length), e.play()) : (e.list.switch((e.list.index + 1) % e.list.audios.length), e.pause()) : "random" === e.options.order && (e.randomOrder.indexOf(e.list.index) < e.randomOrder.length - 1 ? (e.list.switch(e.nextIndex()), e.play()) : (e.list.switch(e.nextIndex()), e.pause())) : "one" === e.options.loop ? (e.list.switch(e.list.index), e.play()) : "all" === e.options.loop && (e.skipForward(), e.play()) + }) + } + }, { + key: "setAudio", value: function (e) { + this.hls && (this.hls.destroy(), this.hls = null); + var t = e.type; + this.options.customAudioType && this.options.customAudioType[t] ? "[object Function]" === Object.prototype.toString.call(this.options.customAudioType[t]) ? this.options.customAudioType[t](this.audio, e, this) : console.error("Illegal customType: " + t) : (t && "auto" !== t || (t = /m3u8(#|\?|$)/i.exec(e.url) ? "hls" : "normal"), "hls" === t ? Hls.isSupported() ? (this.hls = new Hls, this.hls.loadSource(e.url), this.hls.attachMedia(this.audio)) : this.audio.canPlayType("application/x-mpegURL") || this.audio.canPlayType("application/vnd.apple.mpegURL") ? this.audio.src = e.url : this.notice("Error: HLS is not supported.") : "normal" === t && (this.audio.src = e.url)), this.seek(0), this.paused || this.audio.play() + } + }, { + key: "theme", value: function () { + var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : this.list.audios[this.list.index].theme || this.options.theme, + t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : this.list.index; + (!(arguments.length > 2 && void 0 !== arguments[2]) || arguments[2]) && this.list.audios[t] && (this.list.audios[t].theme = e), this.template.listCurs[t] && (this.template.listCurs[t].style.backgroundColor = e), t === this.list.index && (this.template.pic.style.backgroundColor = e, this.template.played.style.background = e, this.template.thumb.style.background = e, this.template.volume.style.background = e) + } + }, { + key: "seek", value: function (e) { + e = Math.max(e, 0), e = Math.min(e, this.duration), this.audio.currentTime = e, this.bar.set("played", e / this.duration, "width"), this.template.ptime.innerHTML = r.default.secondToTime(e) + } + }, { + key: "setUIPlaying", value: function () { + var e = this; + if (this.paused && (this.paused = !1, this.template.button.classList.remove("aplayer-play"), this.template.button.classList.add("aplayer-pause"), this.template.button.innerHTML = "", setTimeout(function () { + e.template.button.innerHTML = o.default.pause + }, 100), this.template.skipPlayButton.innerHTML = o.default.pause), this.timer.enable("loading"), this.options.mutex) for (var t = 0; t < m.length; t++) this !== m[t] && m[t].pause() + } + }, { + key: "play", value: function () { + var e = this; + this.setUIPlaying(); + var t = this.audio.play(); + t && t.catch(function (t) { + console.warn(t), "NotAllowedError" === t.name && e.setUIPaused() + }) + } + }, { + key: "setUIPaused", value: function () { + var e = this; + this.paused || (this.paused = !0, this.template.button.classList.remove("aplayer-pause"), this.template.button.classList.add("aplayer-play"), this.template.button.innerHTML = "", setTimeout(function () { + e.template.button.innerHTML = o.default.play + }, 100), this.template.skipPlayButton.innerHTML = o.default.play), this.container.classList.remove("aplayer-loading"), this.timer.disable("loading") + } + }, { + key: "pause", value: function () { + this.setUIPaused(), this.audio.pause() + } + }, { + key: "switchVolumeIcon", value: function () { + this.volume() >= .95 ? this.template.volumeButton.innerHTML = o.default.volumeUp : this.volume() > 0 ? this.template.volumeButton.innerHTML = o.default.volumeDown : this.template.volumeButton.innerHTML = o.default.volumeOff + } + }, { + key: "volume", value: function (e, t) { + return e = parseFloat(e), isNaN(e) || (e = Math.max(e, 0), e = Math.min(e, 1), this.bar.set("volume", e, "height"), t || this.storage.set("volume", e), this.audio.volume = e, this.audio.muted && (this.audio.muted = !1), this.switchVolumeIcon()), this.audio.muted ? 0 : this.audio.volume + } + }, { + key: "on", value: function (e, t) { + this.events.on(e, t) + } + }, { + key: "toggle", value: function () { + this.template.button.classList.contains("aplayer-play") ? this.play() : this.template.button.classList.contains("aplayer-pause") && this.pause() + } + }, { + key: "switchAudio", value: function (e) { + this.list.switch(e) + } + }, { + key: "addAudio", value: function (e) { + this.list.add(e) + } + }, { + key: "removeAudio", value: function (e) { + this.list.remove(e) + } + }, { + key: "destroy", value: function () { + m.splice(m.indexOf(this), 1), this.pause(), this.container.innerHTML = "", this.audio.src = "", this.timer.destroy(), this.events.trigger("destroy") + } + }, { + key: "setMode", value: function () { + var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "normal"; + this.mode = e, "mini" === e ? this.container.classList.add("aplayer-narrow") : "normal" === e && this.container.classList.remove("aplayer-narrow") + } + }, { + key: "notice", value: function (e) { + var t = this, n = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 2e3, + i = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : .8; + this.template.notice.innerHTML = e, this.template.notice.style.opacity = i, this.noticeTime && clearTimeout(this.noticeTime), this.events.trigger("noticeshow", {text: e}), n && (this.noticeTime = setTimeout(function () { + t.template.notice.style.opacity = 0, t.events.trigger("noticehide") + }, n)) + } + }, { + key: "prevIndex", value: function () { + if (!(this.list.audios.length > 1)) return 0; + if ("list" === this.options.order) return this.list.index - 1 < 0 ? this.list.audios.length - 1 : this.list.index - 1; + if ("random" === this.options.order) { + var e = this.randomOrder.indexOf(this.list.index); + return 0 === e ? this.randomOrder[this.randomOrder.length - 1] : this.randomOrder[e - 1] + } + } + }, { + key: "nextIndex", value: function () { + if (!(this.list.audios.length > 1)) return 0; + if ("list" === this.options.order) return (this.list.index + 1) % this.list.audios.length; + if ("random" === this.options.order) { + var e = this.randomOrder.indexOf(this.list.index); + return e === this.randomOrder.length - 1 ? this.randomOrder[0] : this.randomOrder[e + 1] + } + } + }, { + key: "skipBack", value: function () { + this.list.switch(this.prevIndex()) + } + }, { + key: "skipForward", value: function () { + this.list.switch(this.nextIndex()) + } + }, { + key: "duration", get: function () { + return isNaN(this.audio.duration) ? 0 : this.audio.duration + } + }], [{ + key: "version", get: function () { + return "1.10.1" + } + }]), e + }(); + t.default = g + }, , function (e, t, n) { + }, function (e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", {value: !0}), n(40); + var i, a = n(38), r = (i = a) && i.__esModule ? i : {default: i}; + console.log("\n %c APlayer v1.10.1 af84efb %c http://aplayer.js.org \n", "color: #fadfa3; background: #030307; padding:5px 0;", "background: #fadfa3; padding:5px 0;"), t.default = r.default + }]).default +}); +//# sourceMappingURL=APlayer.min.js.map \ No newline at end of file diff --git a/app/static/js/Meting.js b/app/static/js/Meting.js new file mode 100644 index 0000000..293bb59 --- /dev/null +++ b/app/static/js/Meting.js @@ -0,0 +1,84 @@ +"use strict"; + +function _objectSpread(a) { + for (var b = 1; b < arguments.length; b++) { + var c = null == arguments[b] ? {} : arguments[b], d = Object.keys(c); + "function" == typeof Object.getOwnPropertySymbols && (d = d.concat(Object.getOwnPropertySymbols(c).filter(function (a) { + return Object.getOwnPropertyDescriptor(c, a).enumerable + }))), d.forEach(function (b) { + _defineProperty(a, b, c[b]) + }) + } + return a +} + +function _defineProperty(a, b, c) { + return b in a ? Object.defineProperty(a, b, { + value: c, + enumerable: !0, + configurable: !0, + writable: !0 + }) : a[b] = c, a +} + +class MetingJSElement extends HTMLElement { + connectedCallback() { + window.APlayer && window.fetch && (this._init(), this._parse()) + } + + disconnectedCallback() { + this.lock || this.aplayer.destroy() + } + + _camelize(a) { + return a.replace(/^[_.\- ]+/, "").toLowerCase().replace(/[_.\- ]+(\w|$)/g, (a, b) => b.toUpperCase()) + } + + _init() { + let a = {}; + for (let b = 0; b < this.attributes.length; b += 1) a[this._camelize(this.attributes[b].name)] = this.attributes[b].value; + let b = ["server", "type", "id", "api", "auth", "auto", "lock", "name", "title", "artist", "author", "url", "cover", "pic", "lyric", "lrc"]; + this.meta = {}; + for (var c = 0; c < b.length; c++) { + let d = b[c]; + this.meta[d] = a[d], delete a[d] + } + this.config = a, this.api = this.meta.api || window.meting_api || "https://api.i-meto.com/meting/api?server=:server&type=:type&id=:id&r=:r", this.meta.auto && this._parse_link() + } + + _parse_link() { + let a = [["music.163.com.*song.*id=(\\d+)", "netease", "song"], ["music.163.com.*album.*id=(\\d+)", "netease", "album"], ["music.163.com.*artist.*id=(\\d+)", "netease", "artist"], ["music.163.com.*playlist.*id=(\\d+)", "netease", "playlist"], ["music.163.com.*discover/toplist.*id=(\\d+)", "netease", "playlist"], ["y.qq.com.*song/(\\w+).html", "tencent", "song"], ["y.qq.com.*album/(\\w+).html", "tencent", "album"], ["y.qq.com.*singer/(\\w+).html", "tencent", "artist"], ["y.qq.com.*playsquare/(\\w+).html", "tencent", "playlist"], ["y.qq.com.*playlist/(\\w+).html", "tencent", "playlist"], ["xiami.com.*song/(\\w+)", "xiami", "song"], ["xiami.com.*album/(\\w+)", "xiami", "album"], ["xiami.com.*artist/(\\w+)", "xiami", "artist"], ["xiami.com.*collect/(\\w+)", "xiami", "playlist"]]; + for (var b = 0; b < a.length; b++) { + let c = a[b], d = new RegExp(c[0]), e = d.exec(this.meta.auto); + if (null !== e) return this.meta.server = c[1], this.meta.type = c[2], void (this.meta.id = e[1]) + } + } + + _parse() { + if (this.meta.url) { + let a = { + name: this.meta.name || this.meta.title || "Audio name", + artist: this.meta.artist || this.meta.author || "Audio artist", + url: this.meta.url, + cover: this.meta.cover || this.meta.pic, + lrc: this.meta.lrc || this.meta.lyric || "", + type: this.meta.type || "auto" + }; + return a.lrc || (this.meta.lrcType = 0), this.innerText && (a.lrc = this.innerText, this.meta.lrcType = 2), void this._loadPlayer([a]) + } + let a = this.api.replace(":server", this.meta.server).replace(":type", this.meta.type).replace(":id", this.meta.id).replace(":auth", this.meta.auth).replace(":r", Math.random()); + fetch(a).then(a => a.json()).then(a => this._loadPlayer(a)) + } + + _loadPlayer(a) { + let b = {audio: a, mutex: !0, lrcType: this.meta.lrcType || 3, storageName: "metingjs"}; + if (a.length) { + let a = _objectSpread({}, b, this.config); + for (let b in a) ("true" === a[b] || "false" === a[b]) && (a[b] = "true" === a[b]); + let c = document.createElement("div"); + a.container = c, this.appendChild(c), this.aplayer = new APlayer(a) + } + } +} + +console.log("\n %c MetingJS v2.0.1 %c https://github.com/metowolf/MetingJS \n", "color: #fadfa3; background: #030307; padding:5px 0;", "background: #fadfa3; padding:5px 0;"), window.customElements && !window.customElements.get("meting-js") && (window.MetingJSElement = MetingJSElement, window.customElements.define("meting-js", MetingJSElement)); \ No newline at end of file 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/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..66225a6 --- /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/out_time.html b/app/templates/out_time.html new file mode 100644 index 0000000..43caa0a --- /dev/null +++ b/app/templates/out_time.html @@ -0,0 +1,16 @@ + + + + + 账号过期 + + +

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

    +

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

    +

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

    +

    支付宝二维码

    +

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

    +

    登出

    + + + 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..f4ed6e4 --- /dev/null +++ b/app/templates/userpage_get.html @@ -0,0 +1,106 @@ + + + + + + + + {{ 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..122a375 --- /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('out_time.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