Compare commits

..

No commits in common. "master" and "main" have entirely different histories.
master ... main

303 changed files with 266 additions and 61348 deletions

255
.gitignore vendored Normal file
View File

@ -0,0 +1,255 @@
# ---> JetBrains
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
# ---> Python
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
# ---> VirtualEnv
# Virtualenv
# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/
.Python
[Bb]in
[Ii]nclude
[Ll]ib
[Ll]ib64
[Ll]ocal
[Ss]cripts
pyvenv.cfg
.venv
pip-selfcheck.json

8
.idea/.gitignore vendored
View File

@ -1,8 +0,0 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="Django default" uuid="8e7b6fc5-78c2-4dff-80a1-6bc5faa4393a">
<driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize>
<imported>true</imported>
<remarks>$PROJECT_DIR$/不夜城考试/settings.py</remarks>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:E:\实验台\python\不夜城考试\db.sqlite3</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>

View File

@ -1,21 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="PyPep8Inspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="ignoredErrors">
<list>
<option value="E262" />
<option value="W605" />
<option value="E127" />
</list>
</option>
</inspection_tool>
<inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredIdentifiers">
<list>
<option value="urllib.parse" />
</list>
</option>
</inspection_tool>
</profile>
</component>

View File

@ -1,6 +0,0 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.12 (CyberExam)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (CyberExam)" project-jdk-type="Python SDK" />
</project>

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/不夜城考试.iml" filepath="$PROJECT_DIR$/.idea/不夜城考试.iml" />
</modules>
</component>
</project>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SqlDialectMappings">
<file url="PROJECT" dialect="SQLite" />
</component>
</project>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="FacetManager">
<facet type="django" name="Django">
<configuration>
<option name="rootFolder" value="$MODULE_DIR$" />
<option name="settingsModule" value="不夜城考试/settings.py" />
<option name="manageScript" value="$MODULE_DIR$/manage.py" />
<option name="environment" value="&lt;map/&gt;" />
<option name="doNotUseTestRunner" value="false" />
<option name="trackFilePattern" value="migrations" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.venv" />
<excludeFolder url="file://$MODULE_DIR$/.venv-linux" />
</content>
<orderEntry type="jdk" jdkName="Python 3.12 (CyberExam)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

View File

@ -1,16 +0,0 @@
"""
ASGI config for 不夜城考试 project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'CyberExam.settings')
application = get_asgi_application()

View File

@ -1,137 +0,0 @@
"""
Django settings for CyberExam project.
Generated by 'django-admin startproject' using Django 5.0.7.
For more information on this file, see
https://docs.djangoproject.com/en/5.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.0/ref/settings/
"""
from pathlib import Path
import os
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-!78yd6se#zw2x9##j$x@$j9+q)cf!7%pham38azqz+p3j)chwe'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
ALLOWED_HOSTS = ['*']
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'exam',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'CyberExam.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates']
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'django.template.context_processors.media',
],
},
},
]
WSGI_APPLICATION = 'CyberExam.wsgi.application'
# Database
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/5.0/topics/i18n/
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.0/howto/static-files/
STATIC_URL = 'static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static/'),
os.path.join(BASE_DIR, 'media/'),
]
# Default primary key field type
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
MEDIA_URL = 'media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
AUTH_USER_MODEL = 'exam.CyberUser'

View File

@ -1,25 +0,0 @@
"""
URL configuration for 不夜城考试 project.
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/5.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the "include()" function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from . import settings
urlpatterns = [
path('admin/', admin.site.urls),
path('exam/', include(('exam.urls', 'exam'), namespace='exam')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

View File

@ -1,26 +0,0 @@
"""
WSGI config for 不夜城考试 project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
from os.path import join,dirname,abspath
PROJECT_DIR = dirname(dirname(abspath(__file__)))#3
import sys # 4
sys.path.insert(0,PROJECT_DIR) # 5
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'CyberExam.settings')
application = get_wsgi_application()

9
LICENSE Normal file
View File

@ -0,0 +1,9 @@
MIT License
Copyright (c) 2024 awinx
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

2
README.md Normal file
View File

@ -0,0 +1,2 @@
# CyberExam-django

Binary file not shown.

View File

@ -1 +0,0 @@
default_app_config = 'exam.apps.ExamConfig'

View File

@ -1,8 +0,0 @@
from django.contrib import admin
# Register your models here.
from .models import Question, Choice, CyberUser
admin.site.register(Question)
admin.site.register(Choice)
admin.site.register(CyberUser)

View File

@ -1,6 +0,0 @@
from django.apps import AppConfig
class ExamConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'exam'

View File

@ -1,129 +0,0 @@
from django.forms import Form, fields
from django.core.exceptions import ValidationError
class RegisterForm(Form):
username = fields.CharField(
required=True,
min_length=2,
max_length=20,
error_messages={
'required': '用户名不可以为空!',
'min_length': '用户名应大于2位',
'max_length': '用户名应小于20位',
},
)
nickname = fields.CharField(
required=True,
min_length=2,
max_length=20,
error_messages={
'required': '昵称不可以为空!',
'min_length': '昵称应大于2位',
'max_length': '昵称应小于20位',
},
)
password1 = fields.CharField(
required=True,
min_length=6,
max_length=20,
error_messages={
'required': '密码不可以位空!',
'min_length': '密码应大于6位',
'max_length': '密码应小于20位',
},
)
password2 = fields.CharField(
required=True,
error_messages={
'required': '请再次输入密码!',
},
)
email = fields.EmailField(
required=True,
error_messages={
'required': '请随便填个邮箱吧...',
},
)
def clean_password2(self):
if not self.errors.get("password1"):
if self.cleaned_data["password2"] != self.cleaned_data["password1"]:
raise ValidationError("您输入的密码不一致,请重新输入!")
return self.cleaned_data
class LoginForm(Form):
username = fields.CharField(
required=True,
error_messages={
'required': '请输入用户名',
},
)
password = fields.CharField(
required=True,
error_messages={
'required': '请输入密码',
},
)
class CreateForm(Form):
text = fields.CharField(
required=True,
max_length=300,
error_messages={
'required': '请输入题目',
'max_length': '不得超过300字'
}
)
image = fields.ImageField(required=False)
a = fields.CharField(
required=True,
max_length=300,
error_messages={
'required': '请输入选项',
'max_length': '不得超过300字'
}
)
b = fields.CharField(
required=True,
max_length=300,
error_messages={
'required': '请输入选项',
'max_length': '不得超过300字'
}
)
c = fields.CharField(
required=True,
max_length=300,
error_messages={
'required': '请输入选项',
'max_length': '不得超过300字'
}
)
d = fields.CharField(
required=True,
max_length=300,
error_messages={
'required': '请输入选项',
'max_length': '不得超过300字'
}
)
answer = fields.ChoiceField(choices=(('A', 'A'), ('B', 'B'), ('C', 'C'), ('D', 'D')))
class AnswerForm(Form):
questionID = fields.UUIDField()
answer = fields.ChoiceField(choices=(('A', 'A'), ('B', 'B'), ('C', 'C'), ('D', 'D')))

View File

@ -1,70 +0,0 @@
# Generated by Django 5.0.7 on 2024-07-12 10:42
import django.db.models.deletion
import uuid
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
]
operations = [
migrations.CreateModel(
name='Question',
fields=[
('uid', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False, unique=True)),
('question_text', models.CharField(max_length=300, unique=True, verbose_name='题目文本')),
('pub_date', models.DateTimeField(auto_now=True, verbose_name='发布日期')),
('image', models.ImageField(blank=True, null=True, upload_to='images/question_images/', verbose_name='图片')),
('choice_a', models.CharField(max_length=300)),
('choice_b', models.CharField(max_length=300)),
('choice_c', models.CharField(max_length=300)),
('choice_d', models.CharField(max_length=300)),
('answer', models.CharField(choices=[('A', 'A'), ('B', 'B'), ('C', 'C'), ('D', 'D')], max_length=10)),
],
options={
'verbose_name': '问题',
'verbose_name_plural': '问题',
},
),
migrations.CreateModel(
name='CyberUser',
fields=[
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
('uid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('username', models.CharField(max_length=15, unique=True, verbose_name='用户名')),
('nickname', models.CharField(blank=True, max_length=13, null=True, verbose_name='昵称')),
('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='邮箱')),
('picture', models.ImageField(blank=True, null=True, upload_to='images/avatars', verbose_name='用户头像')),
('date_joined', models.DateTimeField(auto_now_add=True)),
('score', models.IntegerField(default=0)),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
],
options={
'verbose_name': '用户',
'verbose_name_plural': '用户',
},
),
migrations.CreateModel(
name='Choice',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('choice', models.CharField(choices=[('A', 'A'), ('B', 'B'), ('C', 'C'), ('D', 'D')], max_length=10)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL)),
('question', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='exam.question')),
],
),
]

View File

@ -1,81 +0,0 @@
import uuid
from django.db import models
from django.contrib.auth.models import BaseUserManager, AbstractUser
from django.contrib.auth import get_user_model
# Create your models here.
class Question(models.Model):
uid = models.UUIDField(primary_key=True, default=uuid.uuid4, unique=True)
question_text = models.CharField(max_length=300, unique=True, verbose_name='题目文本')
pub_date = models.DateTimeField(auto_now=True, verbose_name='发布日期')
image = models.ImageField(upload_to='images/question_images/', verbose_name='图片', blank=True, null=True)
choice_a = models.CharField(max_length=300)
choice_b = models.CharField(max_length=300)
choice_c = models.CharField(max_length=300)
choice_d = models.CharField(max_length=300)
answer = models.CharField(choices=(('A', 'A'), ('B', 'B'), ('C', 'C'), ('D', 'D')), max_length=10)
class Meta:
verbose_name = '问题'
verbose_name_plural = verbose_name
class UserManager(BaseUserManager): # 自定义Manager管理器
def _create_user(self, username, password, email, **kwargs):
if not username:
raise ValueError("请传入用户名!")
if not password:
raise ValueError("请传入密码!")
if not email:
raise ValueError("请传入邮箱地址!")
user = self.model(username=username, email=email, **kwargs)
user.set_password(password)
user.save()
return user
def create_user(self, username, password, email, **kwargs): # 创建普通用户
kwargs['is_superuser'] = False
return self._create_user(username, password, email, **kwargs)
def create_superuser(self, username, password, email, **kwargs): # 创建超级用户
kwargs['is_superuser'] = True
kwargs['is_staff'] = True
return self._create_user(username, password, email, **kwargs)
class CyberUser(AbstractUser): # 自定义User
uid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
username = models.CharField(max_length=15, verbose_name="用户名", unique=True)
nickname = models.CharField(max_length=13, verbose_name="昵称", null=True, blank=True)
email = models.EmailField(verbose_name="邮箱", null=True, blank=True)
picture = models.ImageField(upload_to="images/avatars", verbose_name="用户头像", null=True, blank=True)
date_joined = models.DateTimeField(auto_now_add=True)
score = models.IntegerField(default=0)
USERNAME_FIELD = 'username' # 使用authenticate验证时使用的验证字段可以换成其他字段但验证字段必须是唯一的即设置了unique=True
REQUIRED_FIELDS = ['email'] # 创建用户时必须填写的字段除了该列表里的字段还包括password字段以及USERNAME_FIELD中的字段
EMAIL_FIELD = 'email' # 发送邮件时使用的字段
objects = UserManager()
def get_full_name(self):
return self.username
def get_short_name(self):
return self.username
class Meta:
verbose_name = "用户"
verbose_name_plural = verbose_name
class Choice(models.Model):
choice = models.CharField(choices=(('A', 'A'), ('B', 'B'), ('C', 'C'), ('D', 'D')), max_length=10)
question = models.ForeignKey(Question, on_delete=models.DO_NOTHING)
user = models.ForeignKey(get_user_model(), on_delete=models.DO_NOTHING)

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View File

@ -1,15 +0,0 @@
from django.urls import path
from . import views
urlpatterns = (
path("", views.home, name="home"),
path("ablout", views.about, name="about"),
path("register/", views.register, name="register"),
path("login/", views.login_view, name="login"),
path("logout/", views.logout_view, name="logout"),
path("create/", views.create_question, name="create"),
path("question/", views.get_question, name="get_question"),
path("answer/", views.answer, name="answer"),
path("history", views.history, name="history"),
path("history_detail", views.history_detail, name="history_detail"),
)

View File

@ -1,301 +0,0 @@
import uuid
from django.core.files import File
from django.http import JsonResponse, Http404, HttpResponse
from django.shortcuts import render, redirect
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from .form import RegisterForm, LoginForm, CreateForm, AnswerForm
from .models import CyberUser, Question, Choice
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from PIL import Image
from io import BytesIO
def compress_image(file_obj, max_size_bytes=1 * 1024 * 1024):
# 从文件对象读取数据并创建Image对象
img = Image.open(file_obj)
# 创建一个BytesIO对象来保存压缩后的WebP数据
output_buffer = BytesIO()
quality = 85
while True:
try:
img.save(output_buffer, 'webp', quality=quality)
except Exception as e:
print(f"Error saving image as WebP: {e}")
return None
output_buffer.seek(0)
new_size = len(output_buffer.read())
# 如果新的大小小于或等于5MB则退出循环
if new_size <= max_size_bytes:
break
# 如果新的大小大于5MB降低质量并重试
quality -= 5
if quality < 1:
print("Unable to compress the image to 5MB or less.")
return None
output_buffer.seek(0)
return output_buffer
def home(request):
content = {'user': request.user}
return render(request, 'home.html', content)
def about(request):
return HttpResponse("尚未完成")
@login_required(login_url='/exam/login')
def history(request):
page_size = 10
user = request.user
questions = Question.objects.filter(choice__user=user)
paginator = Paginator(questions, page_size)
page = request.GET.get('page', 1)
try:
# 尝试获取当前页的记录
question = paginator.page(page)
except PageNotAnInteger:
question = paginator.page(1)
except EmptyPage:
question = paginator.page(paginator.num_pages)
context = {'questions': question, 'page': paginator.page(page), 'paginator': paginator}
return render(request, 'history.html', context)
@login_required(login_url='/exam/login')
def history_detail(request):
questionID = request.GET.get('question')
user = request.user
if questionID:
question = Question.objects.get(uid=questionID)
if question is None:
return Http404
choice = Choice.objects.get(question=question,user=user)
if choice is None:
return Http404
context = {
'question': question,
'choice': choice,
'user': user,
'forward_url': request.META.get('HTTP_REFERER', '/'),
}
return render(request, 'history_detail.html', context)
else:
return Http404
def register(request):
if request.method == 'GET':
if request.user.is_active:
return redirect("/exam/")
return render(request, 'register.html', {'form': RegisterForm()})
elif request.method == 'POST':
if request.user.is_active:
return JsonResponse({
'code': 200,
'message': '已经登陆',
'data': 'failed',
})
form = RegisterForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
nickname = form.cleaned_data['nickname']
password = form.cleaned_data['password1']
email = form.cleaned_data['email']
username_exist = CyberUser.objects.filter(username=username).exists()
if username_exist:
return JsonResponse({"code": 400,
"message": "验证失败",
"data": {"username": "",
"password1": "",
"password2": "",
"email": "",
},
})
CyberUser.objects.create_user(
username=username,
nickname=nickname,
password=password,
email=email,
)
return JsonResponse({"code": 200,
"message": "验证通过,已注册",
"data": {"username": "",
"password1": "",
"password2": "",
"email": "",
},
})
else:
return JsonResponse({"code": 400, "message": "验证失败", "data": {"username": form.errors.get("username"),
"password1": form.errors.get("password1"),
"password2": form.errors.get("password2"),
"email": form.errors.get("email"),
"nickname": form.errors.get("nickname")}})
else:
raise Http404
def login_view(request):
if request.method == 'GET':
if request.user.is_active:
return redirect("/exam/")
return render(request, 'login.html', {'form': LoginForm()})
elif request.method == 'POST':
if request.user.is_active:
return JsonResponse(
{
'code': 200,
'message': '已经登陆',
'data': 'abort',
}
)
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(request, username=username, password=password)
if user and user.is_active:
login(request, user)
request.session['username'] = username
request.session.set_expiry(1800)
return JsonResponse(
{
"code": 200,
"message": '登陆成功',
"data": username,
}
)
elif user and user.is_active:
return JsonResponse(
{
"code": 400,
"message": "用户状态错误,请联系管理员修正",
"data": "user is not active",
}
)
else:
return JsonResponse(
{
"code": 400,
"message": "用户名或密码错误",
"data": None,
}
)
else:
return JsonResponse(
{
"code": 400,
"message": "验证失败,用户名或密码格式错误",
"data": form.errors.get(),
}
)
else:
raise Http404
def logout_view(request):
logout(request)
return redirect('/exam/login')
@login_required(login_url='/exam/login')
def create_question(request):
if request.method == 'GET':
return render(request, 'create.html', {'form': CreateForm})
elif request.method == 'POST':
form = CreateForm(request.POST, request.FILES)
if form.is_valid():
text = form.cleaned_data['text']
image = form.cleaned_data['image']
a = form.cleaned_data['a']
b = form.cleaned_data['b']
c = form.cleaned_data['c']
d = form.cleaned_data['d']
answer = form.cleaned_data['answer']
new_question = Question(
question_text=text,
choice_a=a,
choice_b=b,
choice_c=c,
choice_d=d,
answer=answer,
)
if image:
image = compress_image(image)
new_question.image = File(image, name=f'{str(uuid.uuid4())}.webp')
new_question.save()
return JsonResponse(
{
'code': 200,
'message': 'success',
'data': '',
}
)
else:
return JsonResponse(
{
'code': 400,
'message': '参数不正确',
'data': form.errors
}
)
@login_required(login_url='/exam/login')
def get_question(request):
user = request.user
question = Question.objects.exclude(choice__user=user).order_by('?').first()
return render(request, "question.html", {'question': question, 'form': AnswerForm, 'user': request.user})
@login_required(login_url='/exam/login')
def answer(request):
if request.method == 'POST':
form = AnswerForm(request.POST)
if form.is_valid():
user = request.user
user_ans = form.cleaned_data['answer']
questionID = form.cleaned_data['questionID']
question = Question.objects.get(uid=questionID)
if Choice.objects.filter(user=user, question=question).exists():
return JsonResponse(
{
'code': 200,
'message': '该问题已经回答过了',
'data': '',
}
)
choice = Choice(user=user, question=question, choice=user_ans)
choice.save()
if user_ans == question.answer:
user.score = user.score + 1
user.save()
return JsonResponse(
{
'code': 200,
'message': 'success',
'data': {
'correction': user_ans == question.answer,
'answer': question.answer,
},
}
)
else:
return JsonResponse(
{
'code': 400,
'message': '参数错误',
'data': '表单不可用',
}
)
else:
return Http404

View File

@ -1,22 +0,0 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'CyberExam.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 860 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 860 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 860 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 312 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 233 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 337 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 289 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 800 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,31 +0,0 @@
"use strict";
$(document).ready(function() {
// Plugins init
$(".highlight")[0] && hljs.initHighlightingOnLoad();
// Copy code blocks to clipboard
$("figure.highlight, div.highlight").each(function() {
var t = '<div class="code-clipboard"><button class="btn-clipboard" title="Copy to clipboard">Copy</button></div>';
$(this).before(t);
$(".btn-clipboard").tooltip().on("mouseleave", function() {
$(this).tooltip("hide")
});
});
var t = new Clipboard(".btn-clipboard", {
target: function(e) {
return e.parentNode.nextElementSibling
}
});
t.on("success", function(t) {
e(t.trigger).attr("title", "Copied!").tooltip("_fixTitle").tooltip("show").attr("title", "Copy to clipboard").tooltip("_fixTitle");
t.clearSelection()
});
t.on("error", function(t) {
var n = /Mac/i.test(navigator.userAgent) ? "⌘" : "Ctrl-";
var r = "Press " + n + "C to copy";
e(t.trigger).attr("title", r).tooltip("_fixTitle").tooltip("show").attr("title", "Copy to clipboard").tooltip("_fixTitle")
});
});

File diff suppressed because one or more lines are too long

View File

@ -1,198 +0,0 @@
"use strict";
$(window).on("load", function() {
}),
$(window).on('load resize', function() {
// Background image holder - Static hero with fullscreen autosize
if ($('.spotlight').length) {
$('.spotlight').each(function() {
var $this = $(this);
var holderHeight;
if ($this.data('spotlight') == 'fullscreen') {
if ($this.data('spotlight-offset')) {
var offsetHeight = $('body').find($this.data('spotlight-offset')).height();
holderHeight = $(window).height() - offsetHeight;
}
else {
holderHeight = $(window).height();
}
if ($(window).width() > 991) {
$this.find('.spotlight-holder').css({
'height': holderHeight + 'px'
});
}
else {
$this.find('.spotlight-holder').css({
'height': 'auto'
});
}
}
})
}
}),
$(document).ready(function() {
// Plugins init
$(".scrollbar-inner")[0] && $(".scrollbar-inner").scrollbar().scrollLock();
$('[data-stick-in-parent="true"]')[0] && $('[data-stick-in-parent="true"]').stick_in_parent();
$('.selectpicker')[0] && $('.selectpicker').selectpicker();
$('.textarea-autosize')[0] && autosize($('.textarea-autosize'));
$('[data-toggle="tooltip"]').tooltip();
$('[data-toggle="popover"]').each(function() {
var popoverClass = '';
if($(this).data('color')) {
popoverClass = 'popover-'+$(this).data('color');
}
$(this).popover({
trigger: 'focus',
template: '<div class="popover '+ popoverClass +'" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>'
})
});
// Floating label
$('.form-control').on('focus blur', function(e) {
$(this).parents('.form-group').toggleClass('focused', (e.type === 'focus' || this.value.length > 0));
}).trigger('blur');
// Custom input file
$('.custom-input-file').each(function() {
var $input = $(this),
$label = $input.next('label'),
labelVal = $label.html();
$input.on('change', function(e) {
var fileName = '';
if (this.files && this.files.length > 1)
fileName = (this.getAttribute('data-multiple-caption') || '').replace('{count}', this.files.length);
else if (e.target.value)
fileName = e.target.value.split('\\').pop();
if (fileName)
$label.find('span').html(fileName);
else
$label.html(labelVal);
});
// Firefox bug fix
$input.on('focus', function() {
$input.addClass('has-focus');
})
.on('blur', function() {
$input.removeClass('has-focus');
});
});
// NoUI Slider
if ($(".input-slider-container")[0]) {
$('.input-slider-container').each(function() {
var slider = $(this).find('.input-slider');
var sliderId = slider.attr('id');
var minValue = slider.data('range-value-min');
var maxValue = slider.data('range-value-max');
var sliderValue = $(this).find('.range-slider-value');
var sliderValueId = sliderValue.attr('id');
var startValue = sliderValue.data('range-value-low');
var c = document.getElementById(sliderId),
d = document.getElementById(sliderValueId);
noUiSlider.create(c, {
start: [parseInt(startValue)],
connect: [true, false],
//step: 1000,
range: {
'min': [parseInt(minValue)],
'max': [parseInt(maxValue)]
}
});
c.noUiSlider.on('update', function(a, b) {
d.textContent = a[b];
});
})
}
if ($("#input-slider-range")[0]) {
var c = document.getElementById("input-slider-range"),
d = document.getElementById("input-slider-range-value-low"),
e = document.getElementById("input-slider-range-value-high"),
f = [d, e];
noUiSlider.create(c, {
start: [parseInt(d.getAttribute('data-range-value-low')), parseInt(e.getAttribute('data-range-value-high'))],
connect: !0,
range: {
min: parseInt(c.getAttribute('data-range-value-min')),
max: parseInt(c.getAttribute('data-range-value-max'))
}
}), c.noUiSlider.on("update", function(a, b) {
f[b].textContent = a[b]
})
}
// Scroll to anchor with animation
$('.scroll-me, .toc-entry a').on('click', function(event) {
var hash = $(this).attr('href');
var offset = $(this).data('scroll-to-offset') ? $(this).data('scroll-to-offset') : 0;
// Animate scroll to the selected section
$('html, body').stop(true, true).animate({
scrollTop: $(hash).offset().top - offset
}, 600);
event.preventDefault();
});
}),
$(document).ready(function() {
$("body").on("click", "[data-action]", function(e) {
e.preventDefault();
var $this = $(this);
var action = $this.data('action');
var target = '';
switch (action) {
case "offcanvas-open":
target = $this.data("target"), $(target).addClass("open"), $("body").append('<div class="body-backdrop" data-action="offcanvas-close" data-target=' + target + " />");
break;
case "offcanvas-close":
target = $this.data("target"), $(target).removeClass("open"), $("body").find(".body-backdrop").remove();
break;
case 'aside-open':
target = $this.data('target');
$this.data('action', 'aside-close');
$this.addClass('toggled');
$(target).addClass('toggled');
$('.content').append('<div class="body-backdrop" data-action="aside-close" data-target='+target+' />');
break;
case 'aside-close':
target = $this.data('target');
$this.data('action', 'aside-open');
$('[data-action="aside-open"], '+target).removeClass('toggled');
$('.content, .header').find('.body-backdrop').remove();
break;
}
})
});

View File

@ -1,24 +0,0 @@
/*!
* IE10 viewport hack for Surface/desktop Windows 8 bug
* Copyright 2014-2017 The Bootstrap Authors
* Copyright 2014-2017 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
// See the Getting Started docs for more information:
// https://getbootstrap.com/getting-started/#support-ie10-width
(function () {
'use strict'
if (navigator.userAgent.match(/IEMobile\/10\.0/)) {
var msViewportStyle = document.createElement('style')
msViewportStyle.appendChild(
document.createTextNode(
'@-ms-viewport{width:auto!important}'
)
)
document.head.appendChild(msViewportStyle)
}
}())

View File

@ -1,44 +0,0 @@
/*
* jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
*
* Uses the built in easing capabilities added In jQuery 1.1
* to offer multiple easing options
*
* TERMS OF USE - EASING EQUATIONS
*
* Open source under the BSD License.
*
* Copyright é 2001 Robert Penner
* All rights reserved.
*
* TERMS OF USE - jQuery Easing
*
* Open source under the BSD License.
*
* Copyright é 2008 George McGinley Smith
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the author nor the names of contributors may be used to endorse
* or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
jQuery.easing.jswing=jQuery.easing.swing;jQuery.extend(jQuery.easing,{def:"easeOutQuad",swing:function(e,f,a,h,g){return jQuery.easing[jQuery.easing.def](e,f,a,h,g)},easeInQuad:function(e,f,a,h,g){return h*(f/=g)*f+a},easeOutQuad:function(e,f,a,h,g){return -h*(f/=g)*(f-2)+a},easeInOutQuad:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f+a}return -h/2*((--f)*(f-2)-1)+a},easeInCubic:function(e,f,a,h,g){return h*(f/=g)*f*f+a},easeOutCubic:function(e,f,a,h,g){return h*((f=f/g-1)*f*f+1)+a},easeInOutCubic:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f*f+a}return h/2*((f-=2)*f*f+2)+a},easeInQuart:function(e,f,a,h,g){return h*(f/=g)*f*f*f+a},easeOutQuart:function(e,f,a,h,g){return -h*((f=f/g-1)*f*f*f-1)+a},easeInOutQuart:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f*f*f+a}return -h/2*((f-=2)*f*f*f-2)+a},easeInQuint:function(e,f,a,h,g){return h*(f/=g)*f*f*f*f+a},easeOutQuint:function(e,f,a,h,g){return h*((f=f/g-1)*f*f*f*f+1)+a},easeInOutQuint:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f*f*f*f+a}return h/2*((f-=2)*f*f*f*f+2)+a},easeInSine:function(e,f,a,h,g){return -h*Math.cos(f/g*(Math.PI/2))+h+a},easeOutSine:function(e,f,a,h,g){return h*Math.sin(f/g*(Math.PI/2))+a},easeInOutSine:function(e,f,a,h,g){return -h/2*(Math.cos(Math.PI*f/g)-1)+a},easeInExpo:function(e,f,a,h,g){return(f==0)?a:h*Math.pow(2,10*(f/g-1))+a},easeOutExpo:function(e,f,a,h,g){return(f==g)?a+h:h*(-Math.pow(2,-10*f/g)+1)+a},easeInOutExpo:function(e,f,a,h,g){if(f==0){return a}if(f==g){return a+h}if((f/=g/2)<1){return h/2*Math.pow(2,10*(f-1))+a}return h/2*(-Math.pow(2,-10*--f)+2)+a},easeInCirc:function(e,f,a,h,g){return -h*(Math.sqrt(1-(f/=g)*f)-1)+a},easeOutCirc:function(e,f,a,h,g){return h*Math.sqrt(1-(f=f/g-1)*f)+a},easeInOutCirc:function(e,f,a,h,g){if((f/=g/2)<1){return -h/2*(Math.sqrt(1-f*f)-1)+a}return h/2*(Math.sqrt(1-(f-=2)*f)+1)+a},easeInElastic:function(f,h,e,l,k){var i=1.70158;var j=0;var g=l;if(h==0){return e}if((h/=k)==1){return e+l}if(!j){j=k*0.3}if(g<Math.abs(l)){g=l;var i=j/4}else{var i=j/(2*Math.PI)*Math.asin(l/g)}return -(g*Math.pow(2,10*(h-=1))*Math.sin((h*k-i)*(2*Math.PI)/j))+e},easeOutElastic:function(f,h,e,l,k){var i=1.70158;var j=0;var g=l;if(h==0){return e}if((h/=k)==1){return e+l}if(!j){j=k*0.3}if(g<Math.abs(l)){g=l;var i=j/4}else{var i=j/(2*Math.PI)*Math.asin(l/g)}return g*Math.pow(2,-10*h)*Math.sin((h*k-i)*(2*Math.PI)/j)+l+e},easeInOutElastic:function(f,h,e,l,k){var i=1.70158;var j=0;var g=l;if(h==0){return e}if((h/=k/2)==2){return e+l}if(!j){j=k*(0.3*1.5)}if(g<Math.abs(l)){g=l;var i=j/4}else{var i=j/(2*Math.PI)*Math.asin(l/g)}if(h<1){return -0.5*(g*Math.pow(2,10*(h-=1))*Math.sin((h*k-i)*(2*Math.PI)/j))+e}return g*Math.pow(2,-10*(h-=1))*Math.sin((h*k-i)*(2*Math.PI)/j)*0.5+l+e},easeInBack:function(e,f,a,i,h,g){if(g==undefined){g=1.70158}return i*(f/=h)*f*((g+1)*f-g)+a},easeOutBack:function(e,f,a,i,h,g){if(g==undefined){g=1.70158}return i*((f=f/h-1)*f*((g+1)*f+g)+1)+a},easeInOutBack:function(e,f,a,i,h,g){if(g==undefined){g=1.70158}if((f/=h/2)<1){return i/2*(f*f*(((g*=(1.525))+1)*f-g))+a}return i/2*((f-=2)*f*(((g*=(1.525))+1)*f+g)+2)+a},easeInBounce:function(e,f,a,h,g){return h-jQuery.easing.easeOutBounce(e,g-f,0,h,g)+a},easeOutBounce:function(e,f,a,h,g){if((f/=g)<(1/2.75)){return h*(7.5625*f*f)+a}else{if(f<(2/2.75)){return h*(7.5625*(f-=(1.5/2.75))*f+0.75)+a}else{if(f<(2.5/2.75)){return h*(7.5625*(f-=(2.25/2.75))*f+0.9375)+a}else{return h*(7.5625*(f-=(2.625/2.75))*f+0.984375)+a}}}},easeInOutBounce:function(e,f,a,h,g){if(f<g/2){return jQuery.easing.easeInBounce(e,f*2,0,h,g)*0.5+a}return jQuery.easing.easeOutBounce(e,f*2-g,0,h,g)*0.5+h*0.5+a}});

View File

@ -1,165 +0,0 @@
/*!
* JavaScript Cookie v2.1.4
* https://github.com/js-cookie/js-cookie
*
* Copyright 2006, 2015 Klaus Hartl & Fagner Brack
* Released under the MIT license
*/
;(function (factory) {
var registeredInModuleLoader = false;
if (typeof define === 'function' && define.amd) {
define(factory);
registeredInModuleLoader = true;
}
if (typeof exports === 'object') {
module.exports = factory();
registeredInModuleLoader = true;
}
if (!registeredInModuleLoader) {
var OldCookies = window.Cookies;
var api = window.Cookies = factory();
api.noConflict = function () {
window.Cookies = OldCookies;
return api;
};
}
}(function () {
function extend () {
var i = 0;
var result = {};
for (; i < arguments.length; i++) {
var attributes = arguments[ i ];
for (var key in attributes) {
result[key] = attributes[key];
}
}
return result;
}
function init (converter) {
function api (key, value, attributes) {
var result;
if (typeof document === 'undefined') {
return;
}
// Write
if (arguments.length > 1) {
attributes = extend({
path: '/'
}, api.defaults, attributes);
if (typeof attributes.expires === 'number') {
var expires = new Date();
expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);
attributes.expires = expires;
}
// We're using "expires" because "max-age" is not supported by IE
attributes.expires = attributes.expires ? attributes.expires.toUTCString() : '';
try {
result = JSON.stringify(value);
if (/^[\{\[]/.test(result)) {
value = result;
}
} catch (e) {}
if (!converter.write) {
value = encodeURIComponent(String(value))
.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
} else {
value = converter.write(value, key);
}
key = encodeURIComponent(String(key));
key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);
key = key.replace(/[\(\)]/g, escape);
var stringifiedAttributes = '';
for (var attributeName in attributes) {
if (!attributes[attributeName]) {
continue;
}
stringifiedAttributes += '; ' + attributeName;
if (attributes[attributeName] === true) {
continue;
}
stringifiedAttributes += '=' + attributes[attributeName];
}
return (document.cookie = key + '=' + value + stringifiedAttributes);
}
// Read
if (!key) {
result = {};
}
// To prevent the for loop in the first place assign an empty array
// in case there are no cookies at all. Also prevents odd result when
// calling "get()"
var cookies = document.cookie ? document.cookie.split('; ') : [];
var rdecode = /(%[0-9A-Z]{2})+/g;
var i = 0;
for (; i < cookies.length; i++) {
var parts = cookies[i].split('=');
var cookie = parts.slice(1).join('=');
if (cookie.charAt(0) === '"') {
cookie = cookie.slice(1, -1);
}
try {
var name = parts[0].replace(rdecode, decodeURIComponent);
cookie = converter.read ?
converter.read(cookie, name) : converter(cookie, name) ||
cookie.replace(rdecode, decodeURIComponent);
if (this.json) {
try {
cookie = JSON.parse(cookie);
} catch (e) {}
}
if (key === name) {
result = cookie;
break;
}
if (!key) {
result[name] = cookie;
}
} catch (e) {}
}
return result;
}
api.set = api;
api.get = function (key) {
return api.call(api, key);
};
api.getJSON = function () {
return api.apply({
json: true
}, [].slice.call(arguments));
};
api.defaults = {};
api.remove = function (key, attributes) {
api(key, '', extend(attributes, {
expires: -1
}));
};
api.withConverter = init;
return api;
}
return init(function () {});
}));

View File

@ -1,33 +0,0 @@
// Theme components
@import "components/_alerts.scss";
@import "components/_avatars.scss";
@import "components/_badge.scss";
@import "components/_buttons.scss";
@import "components/_card.scss";
@import "components/_close.scss";
@import "components/_custom-forms.scss";
@import "components/_delimiters.scss";
@import "components/_dropdown.scss";
@import "components/_footer.scss";
@import "components/_forms.scss";
@import "components/_icons.scss";
@import "components/_input-group.scss";
@import "components/_list-group.scss";
@import "components/_masks.scss";
@import "components/_modal.scss";
@import "components/_nav.scss";
@import "components/_navbar.scss";
@import "components/_pagination.scss";
@import "components/_popover.scss";
@import "components/_progress.scss";
@import "components/_section.scss";
@import "components/_sidebar.scss";
@import "components/_spotlight.scss";
@import "components/_tables.scss";
@import "components/_tooltip.scss";
@import "components/_type.scss";
// Vendor
@import "components/vendor/_bootstrap-select.scss";
@import "components/vendor/_bootstrap-tagsinput.scss";
@import "components/vendor/_nouislider.scss";

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