diff --git a/cdcontent/__init__.py b/cdcontent/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/cdcontent/admin.py b/cdcontent/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/cdcontent/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/cdcontent/apps.py b/cdcontent/apps.py new file mode 100644 index 0000000..91e1491 --- /dev/null +++ b/cdcontent/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class CdcontentConfig(AppConfig): + name = 'cdcontent' diff --git a/cdcontent/forms.py b/cdcontent/forms.py new file mode 100644 index 0000000..0cb1770 --- /dev/null +++ b/cdcontent/forms.py @@ -0,0 +1,55 @@ +# Third Party Stuff +from django import forms +from django.db.models import Q + +# Spoken Tutorial Stuff +from .models import TutorialResource +from csc.models import FossCategory +import json +def jsonify(data): + return json.loads(data.replace("u'", "'").replace("'", '"')) + +class CDContentForm(forms.Form): + healthfosslist = list(FossCategory.objects.filter(show_on_homepage = 0, foss__contains='Health').values_list('id','foss')) + + foss_list = list(TutorialResource.objects.filter(Q(status = 1)|Q(status = 2), tutorial_detail__foss__show_on_homepage = 1).values_list('tutorial_detail__foss_id', 'tutorial_detail__foss__foss').order_by('tutorial_detail__foss__foss').distinct())+healthfosslist + foss_list.insert(0, ('', 'Select FOSS Category')) + + foss_category = forms.ChoiceField( + choices = foss_list, + required = True, + error_messages = {'required':'FOSS category field is required.'} + ) + level = forms.ChoiceField( + choices = [('', 'Select Level'), (0, 'All'), (1, 'Basic'), (2, 'Intermediate'), (3, 'Advanced')], + required = True, + error_messages = {'required':'Level field is required.'} + ) + language = forms.MultipleChoiceField( + required = True, + error_messages = {'required':'Languages field is required.'}, + choices = [('', 'Select Languages')] + ) + selected_foss = forms.CharField( + required = True, + error_messages = {'required': 'Add atleast one foss and language, before pressing "Create ZIP file" button'}, + widget=forms.HiddenInput() + ) + + def __init__(self, *args, **kwargs): + super(CDContentForm, self).__init__(*args, **kwargs) + #self.fields['language'].choices = ['nothing'] + if args: + print("args out ",args) + if ('foss_category' in args[0]) and ('level' in args[0]): + print("args in ",args[0]) + if args[0]['foss_category'] and args[0]['foss_category'] != '' and args[0]['foss_category'] != 'None': + try: + tmp_level = int(args[0]['level']) + except: + tmp_level = '' + if tmp_level: + lang_recs = list(TutorialResource.objects.filter(Q(status = 1)|Q(status = 2), tutorial_detail__foss_id = int(args[0]['foss_category']), tutorial_detail__level_id = int(tmp_level)).values_list('language_id', 'language__name').order_by('language__name').distinct()) + else: + lang_recs = list(TutorialResource.objects.filter(Q(status = 1)|Q(status = 2), tutorial_detail__foss_id = int(args[0]['foss_category'])).values_list('language_id', 'language__name').order_by('language__name').distinct()) + self.fields['language'].choices = lang_recs diff --git a/cdcontent/migrations/0001_initial.py b/cdcontent/migrations/0001_initial.py new file mode 100644 index 0000000..8a6c886 --- /dev/null +++ b/cdcontent/migrations/0001_initial.py @@ -0,0 +1,186 @@ +# Generated by Django 3.0.3 on 2022-09-28 05:34 + +import datetime +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Answer', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('uid', models.IntegerField()), + ('body', models.TextField()), + ('date_created', models.DateTimeField(auto_now_add=True)), + ('date_modified', models.DateTimeField(auto_now=True)), + ], + options={ + 'db_table': 'website_answer', + 'managed': False, + }, + ), + migrations.CreateModel( + name='FossCategory', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('foss', models.CharField(max_length=255, unique=True)), + ('description', models.TextField()), + ('status', models.BooleanField(max_length=2)), + ('is_learners_allowed', models.BooleanField(default=0, max_length=2)), + ('is_translation_allowed', models.BooleanField(default=0, max_length=2)), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ('show_on_homepage', models.PositiveSmallIntegerField(default=0, help_text='0:Series, 1:Display on home page, 2:Archived')), + ('available_for_nasscom', models.BooleanField(default=True, help_text='If unchecked, this foss will not be available for nasscom')), + ('available_for_jio', models.BooleanField(default=True, help_text='If unchecked, this foss will not be available for jio and spoken-tutorial.in')), + ('csc_dca_programme', models.BooleanField(default=True, help_text='If unchecked, this foss will not be available for csc-dca programme')), + ], + options={ + 'verbose_name': 'FOSS', + 'verbose_name_plural': 'FOSSes', + 'db_table': 'creation_fosscategory', + 'ordering': ('foss',), + 'managed': False, + }, + ), + migrations.CreateModel( + name='FossSuperCategory', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, unique=True)), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ], + options={ + 'verbose_name': 'FOSS Category', + 'verbose_name_plural': 'FOSS Categories', + 'db_table': 'creation_fosssupercategory', + 'ordering': ('name',), + 'managed': False, + }, + ), + migrations.CreateModel( + name='Language', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, unique=True)), + ('code', models.CharField(default='en', max_length=10)), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ], + options={ + 'db_table': 'creation_language', + 'ordering': ('name',), + 'managed': False, + }, + ), + migrations.CreateModel( + name='Question', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('uid', models.IntegerField()), + ('category', models.CharField(max_length=200)), + ('tutorial', models.CharField(max_length=200)), + ('minute_range', models.CharField(max_length=10)), + ('second_range', models.CharField(max_length=10)), + ('title', models.CharField(max_length=200)), + ('body', models.TextField()), + ('date_created', models.DateTimeField(auto_now_add=True)), + ('date_modified', models.DateTimeField(auto_now=True)), + ('views', models.IntegerField(default=1)), + ('status', models.IntegerField(default=1)), + ], + options={ + 'db_table': 'website_question', + 'get_latest_by': 'date_created', + 'managed': False, + }, + ), + migrations.CreateModel( + name='TutorialCommonContent', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('slide', models.CharField(max_length=255)), + ('slide_status', models.PositiveSmallIntegerField(default=0)), + ('code', models.CharField(max_length=255)), + ('code_status', models.PositiveSmallIntegerField(default=0)), + ('assignment', models.CharField(max_length=255)), + ('assignment_status', models.PositiveSmallIntegerField(default=0)), + ('prerequisite_status', models.PositiveSmallIntegerField(default=0)), + ('additional_material', models.CharField(blank=True, max_length=255, null=True)), + ('additional_material_status', models.PositiveSmallIntegerField(default=0)), + ('keyword', models.TextField()), + ('keyword_status', models.PositiveSmallIntegerField(default=0)), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ], + options={ + 'verbose_name': 'Tutorial Common Content', + 'db_table': 'creation_tutorialcommoncontent', + 'managed': False, + }, + ), + migrations.CreateModel( + name='TutorialDetail', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('tutorial', models.CharField(max_length=255)), + ('order', models.IntegerField()), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ], + options={ + 'verbose_name': 'Tutorial Detail', + 'db_table': 'creation_tutorialdetail', + 'managed': False, + }, + ), + migrations.CreateModel( + name='TutorialResource', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('outline', models.TextField()), + ('outline_status', models.PositiveSmallIntegerField(default=0)), + ('script', models.URLField(max_length=255)), + ('script_status', models.PositiveSmallIntegerField(default=0)), + ('timed_script', models.URLField(max_length=255)), + ('video', models.CharField(max_length=255)), + ('video_id', models.CharField(blank=True, default=None, max_length=255, null=True)), + ('playlist_item_id', models.CharField(blank=True, default=None, max_length=255, null=True)), + ('video_thumbnail_time', models.TimeField(default='00:00:00')), + ('video_status', models.PositiveSmallIntegerField(default=0)), + ('status', models.PositiveSmallIntegerField(default=0)), + ('version', models.PositiveSmallIntegerField(default=0)), + ('hit_count', models.PositiveIntegerField(default=0)), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ('publish_at', models.DateTimeField(null=True)), + ('submissiondate', models.DateTimeField(default=datetime.datetime(2000, 1, 2, 12, 0))), + ('assignment_status', models.PositiveSmallIntegerField(default=0)), + ('extension_status', models.PositiveIntegerField(default=0)), + ], + options={ + 'db_table': 'creation_tutorialresource', + 'managed': False, + }, + ), + migrations.CreateModel( + name='Level', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('level', models.CharField(max_length=255)), + ('code', models.CharField(max_length=10)), + ], + options={ + 'verbose_name': 'Tutorial Level', + 'db_table': 'creation_level', + }, + ), + ] diff --git a/cdcontent/migrations/__init__.py b/cdcontent/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/cdcontent/models.py b/cdcontent/models.py new file mode 100644 index 0000000..b9c0839 --- /dev/null +++ b/cdcontent/models.py @@ -0,0 +1,221 @@ +from django.db import models +from django.contrib.auth.models import User +from csc.models import FossCategory +import datetime + +# Create your models here. +class Level(models.Model): + level = models.CharField(max_length=255) + code = models.CharField(max_length=10) + + class Meta(object): + verbose_name = 'Tutorial Level' + db_table = 'creation_level' + + + def __str__(self): + return self.level + +class FossSuperCategory(models.Model): + name = models.CharField(max_length=255, unique=True) + created = models.DateTimeField(auto_now_add=True) + updated = models.DateTimeField(auto_now=True) + + class Meta(object): + verbose_name = 'FOSS Category' + verbose_name_plural = 'FOSS Categories' + ordering = ('name',) + managed = False + db_table = 'creation_fosssupercategory' + + def __str__(self): + return self.name + +class FossCategory(models.Model): + foss = models.CharField(unique=True, max_length=255) + description = models.TextField() + status = models.BooleanField(max_length=2) + is_learners_allowed = models.BooleanField(max_length=2,default=0 ) + is_translation_allowed = models.BooleanField(max_length=2, default=0) + # user = models.ForeignKey(User, on_delete=models.PROTECT ) + category = models.ManyToManyField(FossSuperCategory) + created = models.DateTimeField(auto_now_add=True) + updated = models.DateTimeField(auto_now=True) + show_on_homepage = models.PositiveSmallIntegerField(default=0, help_text ='0:Series, 1:Display on home page, 2:Archived') + available_for_nasscom = models.BooleanField(default=True, help_text ='If unchecked, this foss will not be available for nasscom' ) + available_for_jio = models.BooleanField(default=True, help_text ='If unchecked, this foss will not be available for jio and spoken-tutorial.in' ) + csc_dca_programme = models.BooleanField(default=True, help_text ='If unchecked, this foss will not be available for csc-dca programme' ) + class Meta(object): + verbose_name = 'FOSS' + verbose_name_plural = 'FOSSes' + ordering = ('foss', ) + managed = False + db_table = 'creation_fosscategory' + + def __str__(self): + return self.foss + +class TutorialDetail(models.Model): + foss = models.ForeignKey(FossCategory, on_delete=models.PROTECT ) + tutorial = models.CharField(max_length=255) + level = models.ForeignKey(Level, on_delete=models.PROTECT ) + order = models.IntegerField() + user = models.ForeignKey(User, on_delete=models.PROTECT ) + created = models.DateTimeField(auto_now_add=True) + updated = models.DateTimeField(auto_now=True) + + class Meta(object): + verbose_name = 'Tutorial Detail' + unique_together = (('foss', 'tutorial', 'level'),) + managed = False + db_table = 'creation_tutorialdetail' + + def __str__(self): + return self.tutorial +class TutorialCommonContent(models.Model): + tutorial_detail = models.OneToOneField( + TutorialDetail, related_name='tutorial_detail',on_delete=models.PROTECT) + slide = models.CharField(max_length=255) + slide_user = models.ForeignKey(User, related_name='slides', on_delete=models.PROTECT ) + slide_status = models.PositiveSmallIntegerField(default=0) + + code = models.CharField(max_length=255) + code_user = models.ForeignKey(User, related_name='codes', on_delete=models.PROTECT ) + code_status = models.PositiveSmallIntegerField(default=0) + + assignment = models.CharField(max_length=255) + assignment_user = models.ForeignKey(User, related_name='assignments', on_delete=models.PROTECT ) + assignment_status = models.PositiveSmallIntegerField(default=0) + + prerequisite = models.ForeignKey( + TutorialDetail, related_name='prerequisite', blank=True, null=True, on_delete=models.PROTECT ) + prerequisite_user = models.ForeignKey(User, related_name='prerequisite', on_delete=models.PROTECT ) + prerequisite_status = models.PositiveSmallIntegerField(default=0) + + additional_material = models.CharField( + max_length=255, blank=True, null=True) + additional_material_user = models.ForeignKey( + User, related_name='additional_material', null=True, default=None, on_delete=models.PROTECT ) + additional_material_status = models.PositiveSmallIntegerField(default=0) + + keyword = models.TextField() + keyword_user = models.ForeignKey(User, related_name='keywords', on_delete=models.PROTECT ) + keyword_status = models.PositiveSmallIntegerField(default=0) + + created = models.DateTimeField(auto_now_add=True) + updated = models.DateTimeField(auto_now=True) + + class Meta(object): + verbose_name = 'Tutorial Common Content' + managed = False + db_table = 'creation_tutorialcommoncontent' + + + def keyword_as_list(self): + return self.keyword.split(',') + +class Language(models.Model): + name = models.CharField(max_length=255, unique=True) + user = models.ForeignKey(User, on_delete=models.PROTECT ) + code = models.CharField(max_length=10, default='en') + created = models.DateTimeField(auto_now_add=True) + updated = models.DateTimeField(auto_now=True) + + class Meta(object): + ordering = ('name',) + managed = False + db_table = 'creation_language' + + def __str__(self): + return self.name + +class TutorialResource(models.Model): + tutorial_detail = models.ForeignKey(TutorialDetail, on_delete=models.PROTECT ) + common_content = models.ForeignKey(TutorialCommonContent, on_delete=models.PROTECT ) + language = models.ForeignKey(Language, on_delete=models.PROTECT ) + + outline = models.TextField() + outline_user = models.ForeignKey(User, related_name='outlines', on_delete=models.PROTECT ) + outline_status = models.PositiveSmallIntegerField(default=0) + + script = models.URLField(max_length=255) + script_user = models.ForeignKey(User, related_name='scripts', on_delete=models.PROTECT ) + script_status = models.PositiveSmallIntegerField(default=0) + timed_script = models.URLField(max_length=255) + + video = models.CharField(max_length=255) + video_id = models.CharField( + max_length=255, null=True, blank=True, default=None) + playlist_item_id = models.CharField( + max_length=255, null=True, blank=True, default=None) + video_thumbnail_time = models.TimeField(default='00:00:00') + video_user = models.ForeignKey(User, related_name='videos', on_delete=models.PROTECT ) + video_status = models.PositiveSmallIntegerField(default=0) + status = models.PositiveSmallIntegerField(default=0) + version = models.PositiveSmallIntegerField(default=0) + hit_count = models.PositiveIntegerField(default=0) + created = models.DateTimeField(auto_now_add=True) + updated = models.DateTimeField(auto_now=True) + publish_at = models.DateTimeField(null=True) + # the last submission date for the tutorial + submissiondate = models.DateTimeField(default=datetime.datetime(2000, 1, 2, 12, 00)) + # 0 - Not Assigned to anyone , 1 - Assigned & work in progress , 2 - Completed (= published / PR ) + assignment_status = models.PositiveSmallIntegerField(default=0) + # 0 - Not Extended , 1 - Extended , 2 - Tutorial Terminated from user + extension_status = models.PositiveIntegerField(default=0) + + class Meta: + unique_together = ('tutorial_detail', 'language',) + managed = False + db_table = 'creation_tutorialresource' + + def get_absolute_url(self): + from django.urls import reverse + return reverse('watch_tutorial', args=[self.tutorial_detail.foss.foss, self.tutorial_detail.tutorial, self.language]) + + + + +# Forums models + +class Question(models.Model): + uid = models.IntegerField() + category = models.CharField(max_length=200) + tutorial = models.CharField(max_length=200) + minute_range = models.CharField(max_length=10) + second_range = models.CharField(max_length=10) + title = models.CharField(max_length=200) + body = models.TextField() + date_created = models.DateTimeField(auto_now_add=True) + date_modified = models.DateTimeField(auto_now=True) + views = models.IntegerField(default=1) + status = models.IntegerField(default=1) + # votes = models.IntegerField(default=0) + + def get_slugified_title(self): + return self.title.replace(' ', '-') + + def user(self): + user = User.objects.get(id=self.uid) + return user.username + + class Meta(object): + db_table = 'website_question' + get_latest_by = "date_created" + managed = False + +class Answer(models.Model): + uid = models.IntegerField() + question = models.ForeignKey(Question, on_delete=models.PROTECT ) + body = models.TextField() + date_created = models.DateTimeField(auto_now_add=True) + date_modified = models.DateTimeField(auto_now=True) + # votes = models.IntegerField(default=0) + + def user(self): + user = User.objects.get(id=self.uid) + return user.username + + class Meta(object): + db_table = 'website_answer' + managed = False \ No newline at end of file diff --git a/cdcontent/templates/cdcontent/answer_to_question.html b/cdcontent/templates/cdcontent/answer_to_question.html new file mode 100644 index 0000000..15fb259 --- /dev/null +++ b/cdcontent/templates/cdcontent/answer_to_question.html @@ -0,0 +1,185 @@ + + + + + + {% block title %} + Spoken Tutorial Forums + {% endblock %} + + + + + + + + +
+
+
+ +
+
+
+
+
+ {% block content %} +
+
+
+
+ {{ question.title }} +
+ +
+
+ {{ question.body|safe }} +
+
+ + + + + {{ question.category }} + + + + + + + + {{ question.tutorial}} + + + + + + + + {{ question.minute_range }} min + + + + + + + + {{ question.second_range }} sec + + + + + + + + + {{ question.date_created|date:"d-m-y" }}, {{ question.date_created|time }} + + + + + {{ question.user }} + + +
+
+
+{% if answer %} +

Answers:

+ + + +{% for ans in answer %} +
+
+
+ +
+ {{ ans.body|safe }} +
+ + + + + {{ ans.date_created|date:"d-m-y" }}, {{ ans.date_created|time }} + + + + + {{ ans.user }} + + +
+ +
+
+ + {% for comment in ans.answercomment_set.all %} +
+
+ {{ comment.body|safe }} +
+ + + + + {{ comment.date_created|date:"d-m-y" }}, {{ comment.date_created|time }} + + + + + {{ comment.user }} + + +
+ {% endfor %} + + + + +
+
+

+
+
+{% endfor %} +{% else %} +

No answers yet

+ {% endif %} + Click here to reply/comment online + {% endblock %} +
+
+
+ +
+ + diff --git a/cdcontent/templates/cdcontent/cdcontent_home.html b/cdcontent/templates/cdcontent/cdcontent_home.html new file mode 100644 index 0000000..a6d9d73 --- /dev/null +++ b/cdcontent/templates/cdcontent/cdcontent_home.html @@ -0,0 +1,102 @@ +{% extends 'csc_base.html'%} +{% load widget_tweaks %} +{% load static %} +{% block content %} + +
+
+
+ {% comment %} {% endcomment %} +

Download CD Content

+
+
+ {% csrf_token %} +
+
+ {{ form.selected_foss.errors }} +
+
+
+ +
+ {% render_field form.foss_category class+="form-control foss_category" tabindex="1" %} + {{ form.foss_category.errors }} + Please select FOSS + {% render_field form.selected_foss class+='selected_foss' %} +
+
+
+ +
+ {% render_field form.level class+="form-control level" tabindex="2" %} + {{ form.level.errors }} + Please select the Level +
+
+
+ +
+ {% render_field form.language class+="form-control language" tabindex="3" %} + {{ form.language.errors }} + For selecting multiple languages, please use + <CTRL> + Click. +
+
+
+
+ + + +
+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+ + +{% endblock %} + + +{% block script %} + + + + + + + +{% endblock %} + diff --git a/cdcontent/templates/cdcontent/home.html b/cdcontent/templates/cdcontent/home.html new file mode 100644 index 0000000..6def7fd --- /dev/null +++ b/cdcontent/templates/cdcontent/home.html @@ -0,0 +1,281 @@ +{% load cdcontentdata %} + + + + + Search Tutorials | spoken-tutorial.org + + + + + + + + + + +
+ +
+ +
+ +
+
+
+

Search Tutorials

+
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+ +
+ + +

+

Spoken Tutorial Forums:

+
+ + +

+

Spoken Tutorial Supplementary Material:

+
+ + +
+
+
+
+
+ +
+ + + + + + + diff --git a/cdcontent/templates/cdcontent/index.html b/cdcontent/templates/cdcontent/index.html new file mode 100644 index 0000000..a95b08e --- /dev/null +++ b/cdcontent/templates/cdcontent/index.html @@ -0,0 +1,9 @@ + + + Search Tutorials | spoken-tutorial.org + + + + + + diff --git a/cdcontent/templates/cdcontent/tutorial_search.html b/cdcontent/templates/cdcontent/tutorial_search.html new file mode 100644 index 0000000..7db9b9a --- /dev/null +++ b/cdcontent/templates/cdcontent/tutorial_search.html @@ -0,0 +1,172 @@ +{% load cdcontentdata %} + + + + + Search Tutorials | spoken-tutorial.org + + + + + + + + +
+ +
+ +
+ +
+
+
+

Search Tutorials

+
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+ {% for record in collection %} +
+
+ +
+
+ +
+

Foss: {{ record.tutorial_detail.foss }} - {{ record.language }}

+

Outline: {{ record.outline|len_cutter:200 }}

+
+
+
+
+
{{ record.tutorial_detail.level.level }}
+ +
+
+
+ {% endfor %} +
+
+
+
+ +
+ + + + + + + diff --git a/cdcontent/templates/cdcontent/watch_tutorial.html b/cdcontent/templates/cdcontent/watch_tutorial.html new file mode 100644 index 0000000..349b15f --- /dev/null +++ b/cdcontent/templates/cdcontent/watch_tutorial.html @@ -0,0 +1,684 @@ +{% load cdcontentdata %} + + + + + {{ tr_rec.tutorial_detail.tutorial }} - {{ tr_rec.language.name }} | spoken-tutorial.org + + + + + + + + + + +
+ +
+ +
+ + + + + +
+
+
+

{{ tr_rec.tutorial_detail.tutorial }} - {{ tr_rec.language.name }}

+ +
+
+ +
+
+
+ +
+ +
+
+
+ +
+ +
Outline:
{{ tr_rec.outline }}
+
+ +
+
+
+
+ + + + + + +
+ + + + + + + + diff --git a/cdcontent/templatetags/cdcontentdata.py b/cdcontent/templatetags/cdcontentdata.py new file mode 100644 index 0000000..64da400 --- /dev/null +++ b/cdcontent/templatetags/cdcontentdata.py @@ -0,0 +1,81 @@ +from django import template +import zipfile +import os +from django.conf import settings + +register = template.Library() +def get_zip_content(path): + file_names = None + try: + zf = zipfile.ZipFile(path, 'r') + file_names = zf.namelist() + return file_names + except Exception as e: + return False + +def get_review_status_list(key): + status_list = ['Pending', 'Waiting for Admin Review', 'Waiting for Domain Review', 'Waiting for Quality Review', 'Accepted', 'Need Improvement', 'Not Required'] + return status_list[key] + +def get_review_status_symbol(key): + status_list = ['fa fa-1 fa-minus-circle review-pending-upload', 'fa fa-1 fa-check-circle review-admin-review', 'fa fa-1 fa-check-circle review-domain-review', 'fa fa-1 fa-check-circle review-quality-review', 'fa fa-1 fa-check-circle review-accepted', 'fa fa-1 fa-times-circle review-pending-upload', 'fa fa-1 fa-ban review-accepted'] + return status_list[key] + +def get_srt_files(tr): + data = '' + k = tr.video.rfind(".") + new_srtfile = tr.video[:k] + '.srt' + if tr.language.name != 'English': + if os.path.isfile(settings.MEDIA_ROOT + 'videos/' + str(tr.tutorial_detail.foss_id) + '/' + str(tr.tutorial_detail_id) + '/' + new_srtfile.replace(tr.language.name, 'English')): + data += '' + if os.path.isfile(settings.MEDIA_ROOT + 'videos/' + str(tr.tutorial_detail.foss_id) + '/' + str(tr.tutorial_detail_id) + '/' + new_srtfile): + data += '' + return data + +def cd_instruction_sheet(foss, lang): + file_path = settings.MEDIA_ROOT + 'videos/' + str(foss.id) + '/' + foss.foss.replace(' ', '-') + '-Instruction-Sheet-' + lang.name + '.pdf' + if lang.name != 'English': + if os.path.isfile(file_path): + file_path = '../' + foss.foss.replace(' ', '-') + '-Instruction-Sheet-' + lang.name + '.pdf' + return file_path + + + file_path = settings.MEDIA_ROOT + 'videos/' + str(foss.id) + '/' + foss.foss.replace(' ', '-') + '-Instruction-Sheet-English.pdf' + if os.path.isfile(file_path): + file_path = '../' + foss.foss.replace(' ', '-') + '-Instruction-Sheet-English.pdf' + return file_path + return False + +def cd_installation_sheet(foss, lang): + file_path = settings.MEDIA_ROOT + 'videos/' + str(foss.id) + '/' + foss.foss.replace(' ', '-') + '-Installation-Sheet-' + lang.name + '.pdf' + if lang.name != 'English': + if os.path.isfile(file_path): + file_path = '../' + foss.foss.replace(' ', '-') + '-Installation-Sheet-' + lang.name + '.pdf' + return file_path + + file_path = settings.MEDIA_ROOT + 'videos/' + str(foss.id) + '/' + foss.foss.replace(' ', '-') + '-Installation-Sheet-English.pdf' + if os.path.isfile(file_path): + file_path = '../' + foss.foss.replace(' ', '-') + '-Installation-Sheet-English.pdf' + return file_path + return False + +def get_foss_name(foss, key): + return foss[key]['foss'] + +def len_cutter(srting, limit): + return srting[:limit] + (srting[limit:] and '..') + +def get_lang_details(foss, key): + data = '' + for lang_key, lang_detail in list(foss[key]['langs'].items()): + data += '' + return data +register.filter('get_srt_files', get_srt_files) +register.filter('cd_instruction_sheet', cd_instruction_sheet) +register.filter('cd_installation_sheet', cd_installation_sheet) +register.filter('get_review_status_symbol', get_review_status_symbol) +register.filter('get_review_status_list', get_review_status_list) +register.filter('get_zip_content', get_zip_content) +register.filter('get_foss_name', get_foss_name) +register.filter('len_cutter', len_cutter) +register.filter('get_lang_details', get_lang_details) \ No newline at end of file diff --git a/cdcontent/tests.py b/cdcontent/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/cdcontent/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/cdcontent/urls.py b/cdcontent/urls.py new file mode 100644 index 0000000..b57076a --- /dev/null +++ b/cdcontent/urls.py @@ -0,0 +1,12 @@ +# Third Party Stuff +from django.conf.urls import url +from .views import * +app_name = 'cdcontent' +urlpatterns = [ + # Main pages dispatcher + url(r'^$', home, name="cdcontenthome"), + url(r'^ajax-fill-languages/$', ajax_fill_languages, name="ajax_fill_languages"), + url(r'^ajax-add-foss/$', ajax_add_foss, name="ajax_add_foss"), + url(r'^ajax-show-added-foss/$', ajax_show_added_foss, name="ajax_show_added_foss"), + url(r'^create_cd_download/(\w+)/', internal_computation, name="create_cd_download"), +] \ No newline at end of file diff --git a/cdcontent/views.py b/cdcontent/views.py new file mode 100644 index 0000000..00fe693 --- /dev/null +++ b/cdcontent/views.py @@ -0,0 +1,528 @@ + +# Standard Library +from builtins import str +import json +import os +import zipfile +from datetime import datetime,date + +# Third Party Stuff +from django.conf import settings + +from django.db.models import Q +from django.http import HttpResponse +from django.shortcuts import render +from django.views.decorators.csrf import csrf_protect, csrf_exempt +from django.template.context_processors import csrf + +from django.contrib.auth.decorators import login_required +# Spoken Tutorial Stuff +from cdcontent.forms import * +from csc.decorators import is_vle +from .models import Language, FossCategory,Level,Question,Answer +# Create your views here. +def zipdir(src_path, dst_path, archive): + for root, dirs, dir_files in os.walk(src_path): + for dir_file in dir_files: + archive.write(os.path.join(root, dir_file), os.path.join(dst_path, dir_file)) + + +def humansize(nbytes): + suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'] + + if nbytes == 0: + return '0 B' + + i = 0 + + while nbytes >= 1024 and i < len(suffixes) - 1: + nbytes /= 1024. + i += 1 + + f = ('%.1f' % nbytes).rstrip('0').rstrip('.') + return '%s %s' % (f, suffixes[i]) + + +def add_sheets(archive, foss, lang): + instruction_file = 'videos/{}/{}-Instruction-Sheet-{}.pdf'.format(foss.id, + foss.foss.replace(' ', '-'), + lang.name) + + installation_file = 'videos/{}/{}-Installation-Sheet-{}.pdf'.format(foss.id, + foss.foss.replace(' ', '-'), + lang.name) + instruction_file_path = '{}{}'.format(settings.MEDIA_ROOT, instruction_file) + installation_file_path = '{}{}'.format(settings.MEDIA_ROOT, installation_file) + + if os.path.isfile(instruction_file_path): + new_file_path = 'spoken/{}'.format(instruction_file) + archive.write(instruction_file_path, new_file_path) + + if os.path.isfile(installation_file_path): + new_file_path = 'spoken/{}'.format(installation_file) + archive.write(installation_file_path, new_file_path) + + +def get_all_foss_details(selectedfoss): + all_foss_details = {} + + for key, values in list(selectedfoss.items()): + foss_rec = FossCategory.objects.get(pk=key) + + if not all_foss_details.get(foss_rec.id, None): + all_foss_details[foss_rec.id] = {} + + all_foss_details[foss_rec.id]['foss'] = foss_rec.foss + + if not all_foss_details[foss_rec.id].get('langs', None): + all_foss_details[foss_rec.id]['langs'] = {} + + for value in values[0]: + language = Language.objects.get(pk=value) + all_foss_details[foss_rec.id]['langs'][language.id] = language.name + return all_foss_details + + +def add_side_by_side_tutorials(archive, languages): + languages.add('English') + available_langs = set() + + for language in languages: + filepath = '{}/videos/32/714/Side-by-Side-Method-{}.ogv'.format(settings.MEDIA_ROOT, language) + + if os.path.isfile(filepath): + available_langs.add(language) + archive.write(filepath, 'spoken/videos/Side-by-Side-Method-{}.ogv'.format(language)) + + return available_langs + +def add_forum_video(archive): + filepath = '{}/videos/32/1450/Spoken-Tutorial-Forums-English.ogv'.format(settings.MEDIA_ROOT) + if os.path.isfile(filepath): + archive.write(filepath, 'spoken/videos/Spoken-Tutorial-Forums-English.ogv') + +def add_suplementary_video(archive): + filepath = '{}/videos/32/1537/Spoken-Tutorial-Supplementary-Material-English.ogv'.format(settings.MEDIA_ROOT) + if os.path.isfile(filepath): + archive.write(filepath, 'spoken/videos/Spoken-Tutorial-Supplementary-Material-English.ogv') + + +def get_static_files(): + return { + '/static/spoken/css/bootstrap.min.css': 'spoken/includes/css/bootstrap.min.css', + '/static/spoken/css/font-awesome.min.css': 'spoken/includes/css/font-awesome.min.css', + '/static/spoken/css/main.css': 'spoken/includes/css/main.css', + '/static/spoken/css/video-js.min.css': 'spoken/includes/css/video-js.min.css', + '/static/spoken/images/favicon.ico': 'spoken/includes/images/favicon.ico', + '/static/spoken/images/logo.png': 'spoken/includes/images/logo.png', + '/static/spoken/js/jquery-1.11.0.min.js': 'spoken/includes/js/jquery-1.11.0.min.js', + '/static/spoken/js/bootstrap.min.js': 'spoken/includes/js/bootstrap.min.js', + '/static/spoken/js/video.js': 'spoken/includes/js/video.js', + '/static/spoken/images/thumb-even.png': 'spoken/includes/images/thumb-even.png', + '/static/spoken/images/Basic.png': 'spoken/includes/images/Basic.png', + '/static/spoken/images/Intermediate.png': 'spoken/includes/images/Intermediate.png', + '/static/spoken/images/Advanced.png': 'spoken/includes/images/Advanced.png', + '/static/cdcontent/templates/readme.txt': 'spoken/README.txt', + '/static/cdcontent/templates/index.html': 'spoken/index.html', + '/static/forum_website/css/bootstrap.min.css': 'spoken/includes/css/bootstrap_forum.min.css', + '/static/forum_website/css/main.css': 'spoken/includes/css/main_forum.css', + '/static/forum_website/css/nice-bar.css': 'spoken/includes/css/nice-bar.css', + '/static/forum_website/css/theme.blue.css': 'spoken/includes/css/theme.blue.css', + '/static/forum_website/slick/slick.css': 'spoken/includes/css/slick.css', + '/static/forum_website/images/cc-logo-88x31.png': 'spoken/includes/images/cc-logo-88x31.png' + + } + + +def calculate_directory_size(dir_path): + folder_size = 0.0 + + try: + if os.path.isdir(dir_path): + for (path, dirs, files) in os.walk(dir_path): + for file_name in files: + filename = os.path.join(path, file_name) + folder_size += os.path.getsize(filename) + except Exception as e: + folder_size = 0.0 + print(e) + + return folder_size + + +def calculate_static_file_size(): + fsize = 0.0 + + try: + static_files = get_static_files() + dir_path = '{}/static/spoken/fonts'.format(settings.BASE_DIR) + + for key, value in list(static_files.items()): + filepath = '{}{}'.format(settings.BASE_DIR, key) + + if os.path.isfile(filepath): + fsize += os.path.getsize(filepath) + + fsize += calculate_directory_size(dir_path) + except Exception as e: + fsize = 0.0 + print(e) + + return fsize + + +def add_static_files(archive): + zipdir(settings.BASE_DIR + '/static/spoken/fonts', 'spoken/includes/fonts/', archive) + static_files = get_static_files() + + for key, value in list(static_files.items()): + filepath = '{}{}'.format(settings.BASE_DIR, key) + + if os.path.isfile(filepath): + archive.write(filepath, value) + + +def convert_template_to_html_file(archive, filename, request, template, ctx): + try: + html = render(request,template, ctx).content + except Exception as e: + print(e) + + html_string = html.decode('utf-8') + html_string = html_string.replace('Content-Type: text/html; charset=utf-8', '').strip("\n") + archive.writestr(filename, html_string) + + +def collect_common_files(tr_rec, common_files): + common_files_path = 'videos/{}/{}/resources'.format(tr_rec.tutorial_detail.foss_id, tr_rec.tutorial_detail_id) + + # if tr_rec.common_content.slide_status > 0: + # common_files.add('{}/{}'.format(common_files_path, tr_rec.common_content.slide)) + + if tr_rec.common_content.assignment_status > 0 and tr_rec.common_content.assignment_status != 6: + common_files.add('{}/{}'.format(common_files_path, tr_rec.common_content.assignment)) + + if tr_rec.common_content.code_status > 0 and tr_rec.common_content.code_status != 6: + common_files.add('{}/{}'.format(common_files_path, tr_rec.common_content.code)) + + if tr_rec.common_content.additional_material_status > 0 and tr_rec.common_content.additional_material_status != 6: + common_files.add('{}/{}'.format(common_files_path, tr_rec.common_content.additional_material)) + + + +def add_common_files(archive, common_files): + for filepath in common_files: + if os.path.isfile(os.path.join(settings.MEDIA_ROOT, filepath)): + archive.write(os.path.join(settings.MEDIA_ROOT, filepath), 'spoken/' + filepath) + + +def add_srt_file(archive, tr_rec, filepath, eng_flag, srt_files): + ptr = filepath.rfind(".") + filepath = filepath[:ptr] + '.srt' + + if os.path.isfile(os.path.join(settings.MEDIA_ROOT, filepath)): + archive.write(os.path.join(settings.MEDIA_ROOT, filepath), 'spoken/' + filepath) + + if eng_flag: + filepath = 'videos/{}/{}/{}-English.srt'.format(tr_rec.tutorial_detail.foss_id, tr_rec.tutorial_detail_id, + tr_rec.tutorial_detail.tutorial.replace(' ', '-')) + + if os.path.isfile(os.path.join(settings.MEDIA_ROOT, filepath)) and filepath not in srt_files: + srt_files.add(filepath) + archive.write(os.path.join(settings.MEDIA_ROOT, filepath), 'spoken/' + filepath) + + +def internal_computation(request, user_type): + zipfile_name = '{}.zip'.format(datetime.now().strftime('%Y%m%d%H%M%S%f')) + # file_obj = open('{}cdimage/{}'.format(settings.MEDIA_ROOT, zipfile_name), 'wb') + zip_file_name = os.path.join(settings.MEDIA_ROOT, 'cdimage',zipfile_name) + + + + file_obj = open(zip_file_name, 'wb') + archive = zipfile.ZipFile(file_obj, 'w', zipfile.ZIP_DEFLATED, allowZip64=True) + try: + selectedfoss = json.loads(request.POST.get('selected_foss', {})) + except: + selectedfoss = request.POST.get('selected_foss', {}) + all_foss_details = get_all_foss_details(selectedfoss) + eng_rec = Language.objects.get(name="English") + languages = set() + + for key, values in list(selectedfoss.items()): + foss_rec = FossCategory.objects.get(pk=key) + level = int(values[1]) + eng_flag = True + srt_files = set() + common_files = set() + + if str(eng_rec.id) in values[0]: + eng_flag = False + + t_resource_qs = TutorialResource.objects.filter(Q(status=1) | Q(status=2), + tutorial_detail__foss_id=key) + + if level: + t_resource_qs = t_resource_qs.filter(tutorial_detail__level_id=level) + for value in values[0]: + language = Language.objects.get(pk=value) + add_sheets(archive, foss_rec, language) + + tr_recs = t_resource_qs.filter(language_id=value).order_by( + 'tutorial_detail__level', 'tutorial_detail__order', 'language__name') + + languages.add(language.name) + + for rec in tr_recs: + filepath = 'videos/{}/{}/{}'.format(key, rec.tutorial_detail_id, rec.video) + # get list of questions of a particular tutorial + question_s = Question.objects.filter(category=foss_rec.foss.replace(' ','-'),tutorial=rec.tutorial_detail.tutorial.replace(' ','-')).order_by('-date_created') + + + if os.path.isfile(os.path.join(settings.MEDIA_ROOT, filepath)): + archive.write(os.path.join(settings.MEDIA_ROOT, filepath), 'spoken/' + filepath) + + # add srt file to archive + add_srt_file(archive, rec, filepath, eng_flag, srt_files) + + # collect common files + collect_common_files(rec, common_files) + + tutorial_path = '{}/{}/'.format(rec.tutorial_detail.foss_id, rec.tutorial_detail_id) + filepath = 'spoken/videos/{}show-video-{}.html'.format(tutorial_path, rec.language.name) + ctx = {'tr_rec': rec, 'tr_recs': tr_recs, + 'media_path': settings.MEDIA_ROOT, 'tutorial_path': tutorial_path,'question_s': question_s} + + # convert_template_to_html_file(archive, filepath, request, + # "cdcontent/templates/watch_tutorial.html", ctx) + convert_template_to_html_file(archive, filepath, request, + "cdcontent/watch_tutorial.html", ctx) + # for each question find the answers + for question in question_s: + answer=Answer.objects.filter(question=question) + ctx = {'question': question, 'answer': answer} + filepath = 'spoken/videos/' + str(foss_rec.id) + '/' + str(rec.tutorial_detail_id) + '/answer-to-question-' + str(question.id) + '.html' + #ToDo + # convert_template_to_html_file(archive, filepath, request, "cdcontent/templates/answer_to_question.html", ctx) + convert_template_to_html_file(archive, filepath, request, "cdcontent/answer_to_question.html", ctx) + + + + + filepath = 'spoken/videos/' + str(foss_rec.id) + '/list-videos-' + language.name + '.html' + ctx = {'collection': tr_recs, 'foss_details': all_foss_details, + 'foss': foss_rec.id, 'lang': language.id} + #ToDo + # convert_template_to_html_file(archive, filepath, request,"cdcontent/templates/tutorial_search.html", ctx) + convert_template_to_html_file(archive, filepath, request,"cdcontent/tutorial_search.html", ctx) + + # add common files for current foss + add_common_files(archive, common_files) + + # add side-by-side tutorials for selected languages + languages = add_side_by_side_tutorials(archive, languages) + add_forum_video(archive) + add_suplementary_video(archive) + + ctx = {'foss_details': all_foss_details, 'foss':'' , + 'lang': '', 'languages': languages} + #ToDo + # convert_template_to_html_file(archive, 'spoken/videos/home.html', request,"cdcontent/templates/home.html", ctx) + convert_template_to_html_file(archive, 'spoken/videos/home.html', request,"cdcontent/home.html", ctx) + + # add all required static files to archive + add_static_files(archive) + archive.close() + + file_obj.close() + file_path= os.path.join(settings.MEDIA_ROOT, 'cdimage',zipfile_name) + + # file_path= os.path.dirname(os.path.realpath(__file__))+'/../media/cdimage/{}'.format(zipfile_name) + # file_path= os.path.dirname(os.path.realpath(__file__))+'/../media/cdimage/{}'.format(zipfile_name) + + # file_path1= os.path.join() + response = HttpResponse(open(file_path, 'rb'), content_type='application/zip') + return zipfile_name + if user_type == 'paid': + return zipfile_name + elif user_type == 'general': + return response + +# @csrf_exempt +@login_required +@is_vle +def home(request): + if request.method == 'POST': + form = CDContentForm(request.POST) + if form.is_valid(): + try: + zipfile_name = internal_computation(request, 'paid') + # wrapper = FileWrapper(temp) + # response = HttpResponse(wrapper, content_type='application/zip') + # response['Content-Disposition'] = 'attachment; filename=spoken-tutorial-cdcontent.zip' + # response['Content-Length'] = temp.tell() + # return response + context = {'path': '/media/cdimage/{}'.format(zipfile_name), 'status': True} + except Exception as e: + print(e) + context = {'path': '', 'status': False} + return HttpResponse(json.dumps(context), content_type='application/json') + else: + form = CDContentForm() + # states = State.objects.order_by('name') + + context = {'form': form,} + context.update(csrf(request)) + return render(request, "cdcontent/cdcontent_home.html", context) + +@csrf_exempt +def ajax_fill_languages(request): + data = '' + fossid = request.POST.get('foss', '') + levelid = int(request.POST.get('level', 0)) + if fossid: + if levelid: + lang_recs = TutorialResource.objects.filter( + Q(status=1) | Q(status=2), tutorial_detail__foss_id=fossid, + tutorial_detail__level_id=levelid).values_list( + 'language_id', 'language__name').order_by('language__name').distinct() + else: + lang_recs = TutorialResource.objects.filter( + Q(status=1) | Q(status=2), tutorial_detail__foss_id=fossid).values_list( + 'language_id', 'language__name').order_by('language__name').distinct() + for row in lang_recs: + data = data + '' + + return HttpResponse(json.dumps(data), content_type='application/json') + + +@csrf_exempt +def ajax_add_foss(request): + foss = request.POST.get('foss', '') + level = int(request.POST.get('level', 0)) + selectedfoss = {} + try: + langs = json.loads(request.POST.get('langs', [])) + except: + langs = [] + try: + selectedfoss = json.loads(request.POST.get('selectedfoss', '')) + except: + pass + if foss and langs: + selectedfoss[foss] = [langs, level] + data = json.dumps(selectedfoss) + return HttpResponse(json.dumps(data), content_type='application/json') + + +@csrf_exempt +def ajax_show_added_foss(request): + try: + tmp = json.loads(request.POST.get('selectedfoss', {})) + except: + tmp = {} + + + data = '' + fsize_total = 0.0 + languages = set() + eng_rec = Language.objects.get(name="English") + + for key, values in list(tmp.items()): + langs_list = list(values[0]) + foss, level = FossCategory.objects.get(pk=key), int(values[1]) + langs = ', '.join(list( + Language.objects.filter(id__in=list(values[0])).order_by('name').values_list('name', flat=True))) + if level: + tr_recs = TutorialResource.objects.filter(Q(status=1) | Q( + status=2), tutorial_detail__foss=foss, tutorial_detail__level_id=level, language_id__in=langs_list) + level_txt = Level.objects.get(pk=level) + else: + tr_recs = TutorialResource.objects.filter(Q(status=1) | Q( + status=2), tutorial_detail__foss=foss, language_id__in=langs_list) + level_txt = 'All' + + fsize = 0.0 + eng_flag = True + srt_files = set() + common_files = set() + + if str(eng_rec.id) in langs_list: + eng_flag = False + + for rec in tr_recs: + try: + languages.add(rec.language.name) + # calculate video size + filepath = 'videos/{}/{}/{}'.format(foss.id, rec.tutorial_detail_id, rec.video) + if os.path.isfile(os.path.join(settings.MEDIA_ROOT, filepath)): + fsize += os.path.getsize(os.path.join(settings.MEDIA_ROOT, filepath)) + # calculate str file size + ptr = filepath.rfind(".") + filepath = filepath[:ptr] + '.srt' + if os.path.isfile(os.path.join(settings.MEDIA_ROOT, filepath)): + fsize += os.path.getsize(os.path.join(settings.MEDIA_ROOT, filepath)) + if eng_flag: + filepath = 'videos/{}/{}/{}-English.srt'.format( + key, rec.tutorial_detail_id, rec.tutorial_detail.tutorial.replace(' ', '-')) + if os.path.isfile(os.path.join(settings.MEDIA_ROOT, filepath)) and filepath not in srt_files: + fsize += os.path.getsize(os.path.join(settings.MEDIA_ROOT, filepath)) + # append common files path to list + common_files_path = '{}/videos/{}/{}/resources'.format(settings.MEDIA_ROOT, key, + rec.tutorial_detail_id) + # if rec.common_content.slide_status > 0: + # common_files.add('{}/{}'.format(common_files_path, rec.common_content.slide)) + + if rec.common_content.assignment_status > 0 and rec.common_content.assignment_status != 6: + common_files.add('{}/{}'.format(common_files_path, rec.common_content.assignment)) + + if rec.common_content.code_status > 0 and rec.common_content.code_status != 6: + common_files.add('{}/{}'.format(common_files_path, rec.common_content.code)) + + if rec.common_content.additional_material_status > 0 and rec.common_content.additional_material_status != 6: + common_files.add('{}/{}'.format(common_files_path, rec.common_content.additional_material)) + except Exception: + continue + + # calculate common files size + for filepath in common_files: + if os.path.isfile(filepath): + fsize += os.path.getsize(filepath) + fsize_total += fsize + + + data += '{}{}{}{}'.format(foss.foss,level_txt, langs, humansize(fsize),foss.id) + + fsize = 0.0 + languages.add(eng_rec.name) + + # calculate size for side-by-side tutorials + for language in languages: + filepath = '{}/videos/32/714/Side-by-Side-Method-{}.ogv'.format(settings.MEDIA_ROOT, language) + + if os.path.isfile(filepath): + fsize += os.path.getsize(filepath) + + # calculate size for forum video + filepath = '{}/videos/32/1450/Spoken-Tutorial-Forums-English.ogv'.format(settings.MEDIA_ROOT) + if os.path.isfile(filepath): + fsize += os.path.getsize(filepath) + + # calculate size for suplementary video + filepath = '{}/videos/32/1537/Spoken-Tutorial-Supplementary-Material-English.ogv'.format(settings.MEDIA_ROOT) + if os.path.isfile(filepath): + fsize += os.path.getsize(filepath) + + # calculate static file size + fsize += calculate_static_file_size() + + fsize_total += fsize + data += 'Extra files{}'.format(humansize(fsize)) + + #check if user is registered + # user_details = check_user_details(request,fsize_total ) + #ToDo + user_details = ['RP',2000] + + output = {0: data, 1: humansize(fsize_total), 2:user_details} + return HttpResponse(json.dumps(output), content_type='application/json') diff --git a/cms/__init__.py b/cms/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/cms/admin.py b/cms/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/cms/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/cms/api/__init__.py b/cms/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/cms/api/serializers.py b/cms/api/serializers.py new file mode 100644 index 0000000..87ae09e --- /dev/null +++ b/cms/api/serializers.py @@ -0,0 +1,21 @@ +from rest_framework import serializers + +from cms.models import State,District + +class StateSerializer(serializers.ModelSerializer): + class Meta: + model = State + fields = ["id","name"] + readonly = ["id", "name"] + +class DistrictSerializer(serializers.ModelSerializer): + class Meta: + model = District + fields = ["id","name","state"] + readonly = ["id","name","state"] + +class DistrictDetailSerializer(serializers.ModelSerializer): + class Meta: + model = District + fields = ["id","name"] + readonly = ["id","name"] \ No newline at end of file diff --git a/cms/api/urls.py b/cms/api/urls.py new file mode 100644 index 0000000..daf1b0a --- /dev/null +++ b/cms/api/urls.py @@ -0,0 +1,18 @@ +from django.urls import path +from django.urls import re_path + +from rest_framework import permissions + +from drf_yasg.views import get_schema_view +from drf_yasg import openapi + + +import os + +from cms.api.views import StateList,DistrictList,DistrictDetail + +urlpatterns = [ + path('states/',StateList.as_view(),name="state_list"), + path('districts/',DistrictDetail.as_view(),name="state_districts"), + path('districts/',DistrictList.as_view(),name="district_list"), +] \ No newline at end of file diff --git a/cms/api/views.py b/cms/api/views.py new file mode 100644 index 0000000..b454cf7 --- /dev/null +++ b/cms/api/views.py @@ -0,0 +1,33 @@ +from rest_framework import generics +from rest_framework.authentication import TokenAuthentication +from rest_framework.permissions import IsAuthenticated + +from cms.api.serializers import StateSerializer,DistrictSerializer,DistrictDetailSerializer +from cms.models import State,District + +class StateList(generics.ListAPIView): + # permission_classes = [IsAuthenticated] + # authentication_classes = [TokenAuthentication] + queryset = State.objects.all() + serializer_class = StateSerializer + +class DistrictList(generics.ListAPIView): + # permission_classes = [IsAuthenticated] + # authentication_classes = [TokenAuthentication] + queryset = District.objects.all() + serializer_class = DistrictSerializer + + +class DistrictDetail(generics.ListAPIView): + lookup_field = "state_id" + serializer_class =DistrictDetailSerializer + + def get_queryset(self): + + state_id = self.kwargs['state_id'] + print(f"state_id ******> {state_id}") + print(f"Count : {District.objects.filter(state_id=state_id).count()}") + return District.objects.filter(state_id=state_id) + + + \ No newline at end of file diff --git a/cms/apps.py b/cms/apps.py new file mode 100644 index 0000000..7ef3fea --- /dev/null +++ b/cms/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class CmsConfig(AppConfig): + name = 'cms' diff --git a/cms/migrations/0001_initial.py b/cms/migrations/0001_initial.py new file mode 100644 index 0000000..6e8e376 --- /dev/null +++ b/cms/migrations/0001_initial.py @@ -0,0 +1,60 @@ +# Generated by Django 3.0.3 on 2022-07-18 08:40 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='State', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('code', models.CharField(max_length=3)), + ('name', models.CharField(max_length=50)), + ('slug', models.CharField(max_length=100)), + ('latitude', models.DecimalField(blank=True, decimal_places=4, max_digits=10, null=True)), + ('longtitude', models.DecimalField(blank=True, decimal_places=4, max_digits=10, null=True)), + ('img_map_area', models.TextField()), + ('has_map', models.BooleanField(default=1)), + ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('updated', models.DateTimeField(auto_now=True, null=True)), + ], + options={ + 'unique_together': {('code', 'name')}, + }, + ), + migrations.CreateModel( + name='District', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('code', models.CharField(max_length=3)), + ('name', models.CharField(max_length=200)), + ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('updated', models.DateTimeField(auto_now=True, null=True)), + ('state', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='cms.State')), + ], + options={ + 'unique_together': {('state', 'code', 'name')}, + }, + ), + migrations.CreateModel( + name='City', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=200)), + ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('updated', models.DateTimeField(auto_now=True, null=True)), + ('state', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='cms.State')), + ], + options={ + 'unique_together': {('name', 'state')}, + }, + ), + ] diff --git a/cms/migrations/__init__.py b/cms/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/cms/models.py b/cms/models.py new file mode 100644 index 0000000..a6d0e08 --- /dev/null +++ b/cms/models.py @@ -0,0 +1,54 @@ +from django.db import models + +# Create your models here. +class State(models.Model): + code = models.CharField(max_length=3) + name = models.CharField(max_length=50) + slug = models.CharField(max_length = 100) + latitude = models.DecimalField( + null=True, + max_digits=10, + decimal_places=4, + blank=True + ) + longtitude = models.DecimalField( + null=True, + max_digits=10, + decimal_places=4, + blank=True + ) + img_map_area = models.TextField() + has_map = models.BooleanField(default=1) + created = models.DateTimeField(auto_now_add = True, null=True) + updated = models.DateTimeField(auto_now = True, null=True) + + def __str__(self): + return self.name + + class Meta(object): + unique_together = (("code","name"),) + +class District(models.Model): + state = models.ForeignKey(State, on_delete=models.PROTECT ) + code = models.CharField(max_length=3) + name = models.CharField(max_length=200) + created = models.DateTimeField(auto_now_add = True, null=True) + updated = models.DateTimeField(auto_now = True, null=True) + + def __str__(self): + return self.name + + class Meta(object): + unique_together = (("state", "code","name"),) + +class City(models.Model): + state = models.ForeignKey(State, on_delete=models.PROTECT ) + name = models.CharField(max_length=200) + created = models.DateTimeField(auto_now_add = True, null=True) + updated = models.DateTimeField(auto_now = True, null=True) + + def __str__(self): + return self.name + + class Meta(object): + unique_together = (("name","state"),) \ No newline at end of file diff --git a/cms/tests.py b/cms/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/cms/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/cms/urls.py b/cms/urls.py new file mode 100644 index 0000000..09465e6 --- /dev/null +++ b/cms/urls.py @@ -0,0 +1,11 @@ +from django import views +from csc.vle_views import CSCLogin +from .views import * +from django.urls import path + +app_name = 'csc' +urlpatterns = [ + + path('load_district/', load_district, name="load_district"), + path('load_city/', load_city, name="load_city"), +] \ No newline at end of file diff --git a/cms/views.py b/cms/views.py new file mode 100644 index 0000000..e6492eb --- /dev/null +++ b/cms/views.py @@ -0,0 +1,21 @@ +from django.shortcuts import render +from django.views.decorators.csrf import csrf_exempt +from .models import District,City +from django.http import JsonResponse +from django.views.generic.edit import CreateView +# Create your views here. +@csrf_exempt +def load_district(request): + id = request.POST.get('id',0) + districts = District.objects.filter(state_id=id).values('id','name') + district_lst = [item for item in districts] + data = {'districts':district_lst} + return JsonResponse(data) + +@csrf_exempt +def load_city(request): + id = request.POST.get('id',0) + cities = City.objects.filter(state_id=id).values('id','name') + data = {'cities':list(cities)} + return JsonResponse(data) + diff --git a/csc/admin.py b/csc/admin.py index 8c38f3f..342746e 100644 --- a/csc/admin.py +++ b/csc/admin.py @@ -1,3 +1,8 @@ from django.contrib import admin - +from .models import FossCategory,CertifiateCategories,CategoryCourses,CSCFossMdlCourses # Register your models here. +admin.site.register(FossCategory) +admin.site.register(CertifiateCategories) +admin.site.register(CategoryCourses) +admin.site.register(CSCFossMdlCourses) + diff --git a/csc/ajax.py b/csc/ajax.py new file mode 100644 index 0000000..1da1168 --- /dev/null +++ b/csc/ajax.py @@ -0,0 +1,85 @@ +from .models import Student, Student_Foss +from django.http import JsonResponse +from django.views.decorators.csrf import csrf_exempt +from .models import VLE,Vle_csc_foss,Student_Foss,TestRequest, CSC,StudentTest, Test + +@csrf_exempt +def get_foss_from_csc(request): + student = Student.objects.get(user = request.user) + + csc = request.POST['csc'] + vle = VLE.objects.get(csc_id = csc) + print(csc) + vle_csc_foss = Vle_csc_foss.objects.filter(vle=vle) + sf = Student_Foss.objects.filter(student=student,csc_foss__in = vle_csc_foss) + + # fosses = [(x.csc_foss.spoken_foss.foss,x.csc_foss.spoken_foss.id) for x in sf] + fosses = [x.csc_foss.spoken_foss for x in sf] + applied = [x.foss for x in TestRequest.objects.filter(student=student)] + print(f'fosses : {fosses}') + print(f'applied : {applied}') + available_foss = [] + for foss in fosses: + if not foss in applied: + available_foss.append((foss.foss,foss.id)) + # data = {} + # for foss in fosses: + # data[foss[1]] = fos + print(f'available_foss : {available_foss}') + print(fosses) + return JsonResponse({'fosses' : available_foss}) + + +@csrf_exempt +def raise_test_request(request): + student = Student.objects.get(user = request.user) + csc = request.POST['csc'] + foss = request.POST['foss'] + foss_id = request.POST['foss_id'] + vle = VLE.objects.get(csc_id = csc) + + try: + TestRequest.objects.get(student=student,vle=vle,foss_id=foss_id) + csc_obj = CSC.objects.get(id=csc) + msg = f'Test request already submitted for {foss} in csc center - {csc_obj.city} [id: {csc_obj.csc_id}].' + + return JsonResponse({'msg' : msg}) + except TestRequest.DoesNotExist: + TestRequest.objects.create(student=student,vle=vle,foss_id=foss_id,status=0) + msg = f"Test request raised for {foss} !" + return JsonResponse({'msg' : msg}) +@csrf_exempt +def apply_for_test(request): + context = {} + test_id = request.POST.get('test_id') + student = Student.objects.get(user=request.user) + + try: + StudentTest.objects.create(student=student,test_id=test_id,status=0) + print("Ceated succesfully ") + msg = f"appied !" + except Exception as e: + msg = f"faied !" + + + return JsonResponse({'msg' : msg}) + +@csrf_exempt +def ajax_mark_attendance(request): + data = {} + print(request.POST) + test_id = request.POST.get('test_id') + students = request.POST.getlist('students[]') + st = StudentTest.objects.filter(test_id=test_id,student_id__in=students) + for item in st: + item.test_status = 1 + item.save() + # StudentTest.objects.bulk_update(st,'test_status') + st = [x.student for x in StudentTest.objects.filter(test_id=test_id)] + total_enrolled = len(st) + attending = StudentTest.objects.filter(test_status=1).count() + pending = total_enrolled - attending + data['total_enrolled'] = total_enrolled + data['attending'] = attending + data['pending'] = pending + return JsonResponse(data) \ No newline at end of file diff --git a/csc/api/__init__.py b/csc/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/csc/api/serializers.py b/csc/api/serializers.py new file mode 100644 index 0000000..7ac862c --- /dev/null +++ b/csc/api/serializers.py @@ -0,0 +1,242 @@ +from functools import partial +from django.contrib.auth.models import User, Group + + +from rest_framework import serializers + +from csc.models import Student, Student_certificate_course,CertifiateCategories, VLE, CSC, Transaction,CategoryCourses,Student_Foss +from csc.api.utility import send_pwd_mail,map_foss_to_student + +from csc.utils import getFirstName,getLastName + +from django.contrib.auth.hashers import make_password +import random +import string +class CertifiateCategoriesSerializer(serializers.ModelSerializer): + + class Meta: + model = CertifiateCategories + fields = ["category_cert","code","title"] + +class StudentCertificateCourseSerializer(serializers.ModelSerializer): + cert_category = serializers.SlugRelatedField( + slug_field='code', + queryset=CertifiateCategories.objects.all() + ) + class Meta: + model = Student_certificate_course + fields = ["cert_category","programme_starting_date"] + +class UserForVLESerializer(serializers.ModelSerializer): + class Meta: + model = User + fields = ["email"] + +class VLESerializer(serializers.ModelSerializer): + user = UserForVLESerializer() + class Meta: + model = VLE + fields = ["user"] + +class UserSerializer(serializers.ModelSerializer): + class Meta: + model = User + fields = ["first_name","last_name","email"] + + +class StudentSerializer(serializers.ModelSerializer): + user = UserSerializer() + certificate_course = StudentCertificateCourseSerializer(many=True) + vle_id = VLESerializer(many=True) + + class Meta: + model = Student + fields = ["certificate_course","user","gender","dob","phone","edu_qualification","vle_id","state","city","district","pincode","address","date_of_registration","category","occupation"] + + + def create(self, validated_data): + user = validated_data.pop('user') + user['username'] = user['email'] + + try: + User.objects.create(**user) + except (Exception): + raise serializers.ValidationError(f"Request Failed : User with email {user['email']} already exists.") + u = User.objects.get(email=user['email']) + course_data = validated_data.pop('certificate_course') + vle_ids = validated_data.pop('vle_id') + vle_email = vle_ids[0]['user']['email'] + validated_data['user_id'] = u.id # validated_data updated + student = Student.objects.create(**validated_data) + try: + vle_spk = VLE.objects.get(user__email=vle_email) + student.vle_id.add(vle_spk.id) + except User.DoesNotExist: + raise serializers.ValidationError(f"User with email {vle_email} does not exists.") + for data in course_data: + Student_certificate_course.objects.create(student=student, **data) + student_group = Group.objects.get(name='STUDENT') + student_group.user_set.add(u) + send_pwd_mail(u) + #map courses + map_foss_to_student(student) + + return student + + def update(self,instance,validated_data): + student = instance + user_obj = student.user + has_user = 'user' in validated_data + has_courses = 'certificate_course' in validated_data + has_vle_ids = 'vle_id' in validated_data + user = [] + course_data = [] + vle_ids = [] + if has_user : user = validated_data.pop('user') + if has_courses : course_data = validated_data.pop('certificate_course') + if has_vle_ids : vle_ids = validated_data.pop('vle_id') + + instance = super(StudentSerializer,self).update(instance,validated_data) + existing_courses = [x.cert_category for x in student.certificate_course.all()] + + for data in course_data: + if data['cert_category'] in existing_courses: + continue + Student_certificate_course.objects.create(student=student, **data) + map_foss_to_student(instance,fdate=data['programme_starting_date']) + + if has_user: + s = UserSerializer(user_obj,data=user) + if s.is_valid(): + s.save() + # if 'email' in user: + # send_pwd_mail(user_obj) + if "email" in user: + user_obj.username = user['email'] + user_obj.email = user['email'] + user_obj.save() + send_pwd_mail(user_obj) + for item in vle_ids: + student.vle_id.add(*vle_ids) + + return instance + + + def validate_certificate_course(self, value): + if not value: + raise serializers.ValidationError("certificate_course field cannot be empty") + courses = [] + for item in value: + if item['cert_category'] in courses: + raise serializers.ValidationError(f"Duplicate entry for {item['cert_category']}") + else: + courses.append(item['cert_category']) + return value + + def validate_vle_id(self, value): + vle_email = value[0]['user']['email'] + if not User.objects.filter(email=vle_email).exists(): + raise serializers.ValidationError(f"VLE with email {vle_email} does not exist.") + + return value + + +class VLEUserSerializer(serializers.ModelSerializer): + full_name = serializers.SerializerMethodField('get_full_name') + name = serializers.CharField(write_only = True) + + def get_full_name(self, user): + return f"{user.first_name} {user.last_name}" + + class Meta: + model = User + fields = ['email','full_name','name'] + +class CSCSerializer(serializers.ModelSerializer): + class Meta: + model = CSC + fields = ['csc_id','institute','state','city','district','block','address','pincode','plan'] + +class TransactionSerializer(serializers.ModelSerializer): + class Meta: + model = Transaction + fields = ['transcdate'] + +class VLECSCSerializer(serializers.ModelSerializer): + csc = CSCSerializer() + user = VLEUserSerializer() + transaction_date = TransactionSerializer(many=True) + class Meta: + model = VLE + fields = ['csc','user','phone','transaction_date'] + + def create(self, validated_data): + user = {} + userdata = validated_data.pop('user') + user['username'] = userdata['email'] + user['email'] = userdata['email'] + user['first_name'] = getFirstName(userdata['name']) + user['last_name'] = getLastName(userdata['name']) + try: + User.objects.create(**user) + except Exception as e: + raise serializers.ValidationError(f"Request Failed : User with email {user['email']} already exists.") + u = User.objects.get(email=user['email']) + csc_data = validated_data.pop('csc') + s = CSCSerializer(data=csc_data) + s.is_valid(raise_exception=True) + obj = s.save() + transaction_data = validated_data.pop('transaction_date') + validated_data['user_id'] = u.id # validated_data updated + validated_data['csc_id'] = obj.id # validated_data updated + vle = VLE.objects.create(**validated_data) + vle_group = Group.objects.get(name='VLE') + vle_group.user_set.add(u) + t = Transaction.objects.create(vle=vle,csc=obj,transcdate=transaction_data[0]['transcdate']) + send_pwd_mail(u) + return vle + + def validate_user(self, value): + try: + vle_email = value['email'] + if User.objects.filter(email=vle_email).exists(): + raise serializers.ValidationError(f"VLE with email {vle_email} already exist.") + except Exception as e: + print(e) + + return value + + def update(self,instance,validated_data): + vle = instance + has_user = 'user' in validated_data + has_transaction = 'transaction_date' in validated_data + has_csc = 'csc' in validated_data + + if has_csc : csc_data = validated_data.pop('csc') + if has_transaction : transaction_data = validated_data.pop('transaction_date')[0] + if has_user : user_data = validated_data.pop('user') + instance = super(VLECSCSerializer,self).update(instance,validated_data) + if has_csc: + c = CSCSerializer(instance.csc,csc_data,partial=True) + c.is_valid(raise_exception=True) + c.save() + if has_transaction : + t = Transaction.objects.create(vle=instance,csc=instance.csc,transcdate=transaction_data['transcdate']) + if has_user: + user_obj = instance.user + if "email" in user_data: + user_obj.username = user_data['email'] + user_obj.email = user_data['email'] + user_obj.save() + send_pwd_mail(user_obj) + + if "name" in user_data: + user_obj.first_name = getFirstName(user_data['name']) + user_obj.last_name = getLastName(user_data['name']) + + user_obj.save() + # u = VLEUserSerializer(instance.user,user_data,partial=True) + # u.is_valid(raise_exception=True) + # u.save() + + return instance \ No newline at end of file diff --git a/csc/api/urls.py b/csc/api/urls.py new file mode 100644 index 0000000..b392c8d --- /dev/null +++ b/csc/api/urls.py @@ -0,0 +1,45 @@ +from django.urls import path +from django.urls import re_path + +from rest_framework import permissions + +from drf_yasg.views import get_schema_view +from drf_yasg import openapi + + +import os + +from csc.api.views import StudentListCreate,SutdentDetail,VLEListCreate,VLEDetail,studentTest +from rest_framework_swagger.views import get_swagger_view +schema_view = get_swagger_view(title='Pastebin API') + +schema_view = get_schema_view( + openapi.Info( + title="Spoken Tutorial - CSC API", + default_version="v1", + description="API for student data", + ), + url=f"http://127.0.0.1:8000/csc/", + public=True, + permission_classes=[permissions.AllowAny], +) + +urlpatterns = [ + path('students/',StudentListCreate.as_view(),name="create_list_student"), + path('students/',SutdentDetail.as_view(),name="detail_student"), + path('vles/',VLEListCreate.as_view(),name="create_list_student"), + path('vles/',VLEDetail.as_view(),name="detail_student"), + path('tests/students/',studentTest,name="student_test"), + # path('',schema_view) +] + + +urlpatterns += [ + re_path( + r"^swagger(?P\.json|\.yaml)$", + schema_view.with_ui("swagger", cache_timeout=0), + name="schema-swagger-ui", + ), + re_path(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'), + +] \ No newline at end of file diff --git a/csc/api/utility.py b/csc/api/utility.py new file mode 100644 index 0000000..ef36bce --- /dev/null +++ b/csc/api/utility.py @@ -0,0 +1,90 @@ +from datetime import datetime +from email import message +from urllib import request + + +from django.contrib.auth.models import User +from django.core.mail import send_mail +from django.conf import settings + +import random, string +from csc.models import Student_certificate_course,CategoryCourses,Student_Foss +from django.db import IntegrityError +from csc.utils import is_user_vle, is_user_student +from django.template.loader import render_to_string +def send_pwd_mail(u): + print(u.username) + pwd = ''.join(random.choices(string.ascii_letters,k=10)) + print(pwd) + u.set_password(pwd) + u.save() + + from_email = getattr(settings, "NO_REPLY_MAIL", "no-reply@spoken-tutorial.org") + print(from_email) + subject = "Login credentials for Spoken Tutorial - CSC" + if is_user_student(u): + message = f""" + Dear {u.get_full_name()}, + Thank you for registering under Spoken Tutorial(IIT Bombay) courses. + Below are the login details for Spoken Tutorial Dashboard. + Link to Login: https://spoken-tutorial.in/login/ + + username : {u.username} + password : {pwd} + + Thanks & Regards, + Team, + Spoken Tutorial + """ + path = 'student_mail_template.html' + if is_user_vle(u): + print('USER IS VLE') + message = f""" + Dear {u.get_full_name()}, + + Welcome to IIT Bombay Spoken Tutorial Program. We are happy to be partnered with CSC Academy to + empower youth from all over the country via VLEs. + Please use the below Login details for the Spoken Tutorial Dashboard: + Link to Login: https://spoken-tutorial.in/login/ + + username : {u.username} + password : {pwd} + + Please click the following training link to know the process of + Student Registration Instructions : https://docs.google.com/document/d/1z8-s4sSl7viPqJ8WAFeeNmoJUVLRPv2L9jLOrfN6ln0/edit?usp=sharing + Course Allotment Instructions : https://docs.google.com/document/d/1Mv23iijOVuS6eCcHCgYKbbxopjk_SkSfExXW-61G2AQ/edit?usp=sharing + + In case of any query, please feel free to contact at animation-hackathon@cscacademy.org. + + Thanks & Regards, + Team, + Spoken Tutorial + """ + path = 'vle_mail_template.html' + html_content = render_to_string(path, {'full_name':u.get_full_name(),'username':u.username,'password':pwd}) + try: + print(f"/n/nSending mail ; username,pwd : {u.username},{pwd}".ljust(40,'*')) + send_mail( + subject, + message, + from_email, + [u.email], + fail_silently=False, + html_message = html_content + ) + print("***************mail send******") + except Exception as e: + print(e) + print(f"Failed to send mail to user : {u.email}") + +def map_foss_to_student(student,fdate=datetime.today()): + cert_courses = Student_certificate_course.objects.filter(student=student) + print(f"\n\ncert_courses ***** {cert_courses}\n") + l = [] + for course in cert_courses: + fosses = CategoryCourses.objects.filter(certificate_category_id=course.cert_category_id).values('foss') + for foss in fosses: + try: + Student_Foss.objects.create(student=student,cert_category=course.cert_category,csc_foss_id=foss['foss'],foss_start_date=fdate) + except IntegrityError as e: + print(e) \ No newline at end of file diff --git a/csc/api/views.py b/csc/api/views.py new file mode 100644 index 0000000..264b258 --- /dev/null +++ b/csc/api/views.py @@ -0,0 +1,80 @@ +from rest_framework import generics,status +from rest_framework.authentication import TokenAuthentication +from rest_framework.permissions import IsAuthenticated +from rest_framework.response import Response +from django.http import JsonResponse,HttpResponse + +from csc.api.serializers import StudentSerializer,VLECSCSerializer +from csc.models import Student, VLE, Student_Foss,CategoryCourses,CSCTestAtttendance +from csc.utils import TEST_COMPLETED_BY_STUDENT,PASS_GRADE +import json + +class StudentListCreate(generics.ListCreateAPIView): + permission_classes = [IsAuthenticated] + authentication_classes = [TokenAuthentication] + queryset = Student.objects.all() + serializer_class = StudentSerializer + +class SutdentDetail(generics.RetrieveUpdateAPIView): + permission_classes = [IsAuthenticated] + authentication_classes = [TokenAuthentication] + lookup_field = "user__email" + queryset = Student.objects.all() + serializer_class = StudentSerializer + +class VLEListCreate(generics.ListCreateAPIView): + permission_classes = [IsAuthenticated] + authentication_classes = [TokenAuthentication] + queryset = VLE.objects.all() + serializer_class = VLECSCSerializer + +class VLEDetail(generics.RetrieveUpdateAPIView): + permission_classes = [IsAuthenticated] + authentication_classes = [TokenAuthentication] + lookup_field = "user__email" + queryset = VLE.objects.all() + serializer_class = VLECSCSerializer + +def studentTest(request,user__email): + d = {} + d['email'] = user__email + try: + student = Student.objects.get(user__email=user__email) + courses = set() + cert_categories = [courses.add(x.cert_category) for x in Student_Foss.objects.filter(student=student)] + scores = {} + ta = CSCTestAtttendance.objects.filter(student=student,status__gte=TEST_COMPLETED_BY_STUDENT).order_by('-updated') + if ta: + last_test_date = ta[0].updated.date() + d['last_updated'] = last_test_date + else: + d['last_updated'] = None + # else: + # d['last_updated'] = 'No test taken' + for item in ta: + scores[item.test.foss.foss] = item.mdlgrade + for course in courses: + d[course.code] = { + 'title' : course.title + } + fosses = [x.foss for x in CategoryCourses.objects.filter(certificate_category=course)] + ta_temp = CSCTestAtttendance.objects.filter(student=student,status__gte=TEST_COMPLETED_BY_STUDENT,test__foss__in=fosses).order_by('-updated') + if ta_temp: + d[course.code]['last_test_date'] = ta_temp[0].updated.date() + else: + d[course.code]['last_test_date'] = None + temp = dict() + for foss in fosses: + temp[foss.foss] = scores.get(foss.foss,'NA') + + d[course.code]['foss'] = temp + b = [ x == 'NA' or float(x) < PASS_GRADE for x in temp.values()] + if True in b: + d[course.code]['status'] = 0 + else: + d[course.code]['status'] = 1 + except Student.DoesNotExist as e: + return HttpResponse(status=404) + return JsonResponse(d) + + \ No newline at end of file diff --git a/csc/backends.py b/csc/backends.py new file mode 100644 index 0000000..ee3e8ad --- /dev/null +++ b/csc/backends.py @@ -0,0 +1,62 @@ + +from urllib import request +from django.contrib.auth.backends import ModelBackend +from django.contrib.auth.models import User +from django.db.models import Q +from django.contrib.auth.hashers import check_password +from .models import VLE, CSC +from datetime import datetime as dt +from datetime import timedelta +import requests +from django.conf import settings +from .cron import add_vle,add_transaction +from django.contrib import messages + +class CSCBackend(ModelBackend): + def authenticate(self, request, username=None, password=None): + try: + user = User.objects.get(Q(username=username) | Q(email=username)) + pwd_exists = user.password + if pwd_exists: + pwd_valid = check_password(password, pwd_exists) + if pwd_valid: + return user + + except: + user = check_updated_vle(username,request) + return user + return None + + +def check_updated_vle(username,request): + last_update_date = VLE.objects.order_by('user__date_joined').last().user.date_joined + delta_date = last_update_date - timedelta(2) + payload = {'date':delta_date} + url = getattr(settings, "URL_FETCH_VLE", "http://exam.cscacademy.org/shareiitbombayspokentutorial") + response = requests.get(url,params=payload) + if response.status_code == 200: + data = response.json() + data = data['req_data'] + emails = [x['email'] for x in data] + + for item in data: + if username == item['email']: + try: + csc = CSC.objects.get(csc_id=item['csc_id']) + except CSC.DoesNotExist: + print(f"csc - {item['csc_id']} does not exists") + CSC.objects.create( + csc_id=item.get('csc_id'),institute=item.get('institute',''),state=item.get('state',''), + city=item.get('city',''),district=item.get('district',''),block=item.get('block',''), + address=item.get('address',''),pincode=item.get('pincode',''),plan=item.get('plan',''), + activation_status=1 + ) + csc = CSC.objects.get(csc_id=item.get('csc_id')) + add_vle(item,csc) + vle = VLE.objects.get(user__email=username) + add_transaction(vle,csc,item['transcdate']) + # messages.add_message(request,messages.INFO,'hello') + return vle.user + else: + # messages.add_message(request,messages.INFO,'hello') + return None diff --git a/csc/cron.py b/csc/cron.py index 208e9b1..fedb5be 100644 --- a/csc/cron.py +++ b/csc/cron.py @@ -1,3 +1,4 @@ +from datetime import datetime from django.db import IntegrityError import requests from django.conf import settings @@ -10,6 +11,9 @@ from django.db.models import Q # import utils as u from django.core.mail import send_mail +from django.contrib.auth.models import Group +from .utils import get_tenure_end_date +from django.template.loader import render_to_string def update_vle_data(): #CRON TASK url = getattr(settings, "URL_FETCH_VLE", "http://exam.cscacademy.org/shareiitbombayspokentutorial") @@ -66,6 +70,7 @@ def update_vle_data(): #CRON TASK address=item.get('address',''),pincode=item.get('pincode',''),plan=item.get('plan',''), activation_status=1 ) + csc = CSC.objects.get(csc_id=item.get('csc_id')) print(f"csc - {item['csc_id']} created") csc_created.append(f"{item['csc_id']} ({item['email']})") add_vle(item,csc) @@ -86,22 +91,36 @@ def send_password_mail(user,password): subject = "Login credentials for Spoken Tutorial :" from_email = getattr(settings, "NO_REPLY_MAIL", "no-reply@spoken-tutorial.org") to_email = user.email - message = """ - Your login information for Spoken Tutorial is : - username : {to_email} - password : {password} - Login link : "https://spoken-tutorial.in/login/" + message = f""" + Dear {user.get_full_name()}, + + Welcome to IIT Bombay Spoken Tutorial Program. We are happy to be partnered with CSC Academy to + empower youth from all over the country via VLEs. + Please use the below Login details for the Spoken Tutorial Dashboard: + Link to Login: https://spoken-tutorial.in/login/ - Best Wishes, - Admin - Spoken Tutorials - IIT Bombay. - """ + username : {user.username} + password : {password} + + Please click the following training link to know the process of + Student Registration Instructions : https://docs.google.com/document/d/1z8-s4sSl7viPqJ8WAFeeNmoJUVLRPv2L9jLOrfN6ln0/edit?usp=sharing + Course Allotment Instructions : https://docs.google.com/document/d/1Mv23iijOVuS6eCcHCgYKbbxopjk_SkSfExXW-61G2AQ/edit?usp=sharing + + In case of any query, please feel free to contact at animation-hackathon@cscacademy.org. + + Thanks & Regards, + Team, + Spoken Tutorial + """ + path = 'vle_mail_template.html' + html_content = render_to_string(path, {'full_name':user.get_full_name(),'username':user.username,'password':password}) try: - print(f"sending mail .....{to_email},{password}") - # send_mail(subject,message,from_email,to_email,fail_silently=False) - except: + print(f"sending mails .....{to_email},{password}") + send_mail(subject,message,from_email,[to_email],fail_silently=False,html_message=html_content) + print(f"mail sent success") + except Exception as e: print("Error in sending mail") + print(e) def send_log_mail(message): @@ -109,7 +128,7 @@ def send_log_mail(message): from_email = getattr(settings, "NO_REPLY_MAIL", "no-reply@spoken-tutorial.org") to_email = "web-query@spoken-tutorial.org" try: - # send_mail(subject,message,from_email,to_email,fail_silently=False) + send_mail(subject,message,from_email,to_email,fail_silently=False) print(f"sending mail .....{to_email},{message}") except: print("Unable to send csc update mail to web-team") @@ -138,7 +157,9 @@ def add_vle(item,csc): email=item['email'],is_staff=0,is_active=1 ) print(f"user for vle {item.get('email')} created") + # IMPORTANT ToDo: REMOVE static pwd password = ''.join([ random.choice(string.ascii_letters+string.digits) for x in range(8)]) + enc_password = make_password(password) user.password = enc_password user.save() @@ -148,13 +169,20 @@ def add_vle(item,csc): vle = VLE.objects.create( csc=csc,user=user,phone=item['phone'],status=1 ) + vle_group = Group.objects.get(name='VLE') + vle_group.user_set.add(user) print(f"created vle .... {user}") except IntegrityError as e: print(f"vle already exists ....") vle = VLE.objects.get(Q(csc=csc) and Q(user=user)) tdate = item.get('transcdate').split()[0] + + tdate = datetime.strptime(tdate,'%Y-%m-%d') + print(f"tdate ************************ {tdate}") try: - transaction = Transaction.objects.create(vle=vle,csc=csc,transcdate=tdate,tenure=None,tenure_end_date=None) + tenure_end_date = get_tenure_end_date(tdate) + print(f"**tenure_end_date : {tenure_end_date}") + transaction = Transaction.objects.create(vle=vle,csc=csc,transcdate=tdate,tenure=None,tenure_end_date=tenure_end_date) except Exception as e: print(e) diff --git a/csc/decorators.py b/csc/decorators.py index 9afdfcb..3a38487 100644 --- a/csc/decorators.py +++ b/csc/decorators.py @@ -1,7 +1,7 @@ from email import message from django.contrib import messages from django.core.exceptions import PermissionDenied -from utils import * +from .utils import is_user_vle,is_user_student,is_csc_team_role # decorator def is_vle(view_func): @@ -14,3 +14,22 @@ def wrapper(request,*args,**kwargs): raise PermissionDenied() return wrapper +def is_student(view_func): + def wrapper(request,*args,**kwargs): + # ToDo : Role for STUDENT in group + if is_user_student(request.user): + return view_func(request,*args,**kwargs) + else: + messages.add_message(request,messages.INFO,'Access denied') + raise PermissionDenied() + return wrapper + +def is_csc_team(view_func): + def wrapper(request,*args,**kwargs): + # ToDo : Role for VLE in group + if is_csc_team_role(request.user): + return view_func(request,*args,**kwargs) + else: + messages.add_message(request,messages.INFO,'Access denied') + raise PermissionDenied() + return wrapper \ No newline at end of file diff --git a/csc/migrations/0004_auto_20220726_1601.py b/csc/migrations/0004_auto_20220726_1601.py new file mode 100644 index 0000000..d7b0af5 --- /dev/null +++ b/csc/migrations/0004_auto_20220726_1601.py @@ -0,0 +1,140 @@ +# Generated by Django 3.0.3 on 2022-07-26 10:31 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('cms', '0001_initial'), + ('csc', '0003_auto_20220601_2308'), + ] + + operations = [ + migrations.CreateModel( + name='FossCategory', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('foss', models.CharField(max_length=255, unique=True)), + ('description', models.TextField()), + ('status', models.BooleanField(max_length=2)), + ('is_learners_allowed', models.BooleanField(default=0, max_length=2)), + ('is_translation_allowed', models.BooleanField(default=0, max_length=2)), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ('show_on_homepage', models.PositiveSmallIntegerField(default=0, help_text='0:Series, 1:Display on home page, 2:Archived')), + ('available_for_nasscom', models.BooleanField(default=True, help_text='If unchecked, this foss will not be available for nasscom')), + ('available_for_jio', models.BooleanField(default=True, help_text='If unchecked, this foss will not be available for jio and spoken-tutorial.in')), + ('csc_dca_programme', models.BooleanField(default=True, help_text='If unchecked, this foss will not be available for csc-dca programme')), + ], + options={ + 'verbose_name': 'FOSS', + 'verbose_name_plural': 'FOSSes', + 'ordering': ('foss',), + }, + ), + migrations.CreateModel( + name='FossSuperCategory', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, unique=True)), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ], + options={ + 'verbose_name': 'FOSS Category', + 'verbose_name_plural': 'FOSS Categories', + 'ordering': ('name',), + }, + ), + migrations.CreateModel( + name='Student', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('student_id', models.CharField(max_length=255)), + ('gender', models.CharField(blank=True, max_length=10)), + ('dob', models.DateField(blank=True)), + ('phone', models.CharField(blank=True, max_length=32)), + ('edu_qualification', models.CharField(blank=True, max_length=255)), + ('pincode', models.CharField(blank=True, max_length=6)), + ('address', models.CharField(blank=True, max_length=255)), + ('date_of_registration', models.DateField()), + ('city', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='cms.City')), + ('district', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='cms.District')), + ('state', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='cms.State')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ('vle_id', models.ManyToManyField(to='csc.VLE')), + ], + ), + migrations.CreateModel( + name='Vle_csc_foss', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('programme_type', models.CharField(choices=[('', '-- None --'), ('dca', 'DCA Programme'), ('individual', 'Individual Course')], max_length=100)), + ('created', models.DateField(blank=True, null=True)), + ('updated', models.DateField(auto_now=True, null=True)), + ('spoken_foss', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='csc.FossCategory')), + ('vle', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='csc.VLE')), + ], + options={ + 'unique_together': {('spoken_foss', 'programme_type')}, + }, + ), + migrations.CreateModel( + name='Test', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('tdate', models.DateField()), + ('ttime', models.TimeField()), + ('publish', models.BooleanField()), + ('slug', models.SlugField(max_length=40)), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ('note_student', models.TextField(blank=True, null=True)), + ('note_invigilator', models.TextField(blank=True, null=True)), + ('test_name', models.CharField(blank=True, max_length=252, null=True)), + ('foss', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='csc.FossCategory')), + ('vle', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='csc.VLE')), + ], + ), + migrations.CreateModel( + name='Invigilator', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('phone', models.CharField(max_length=32)), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ('added_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='added_by_user', to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ('vle', models.ManyToManyField(to='csc.VLE')), + ], + ), + migrations.CreateModel( + name='InvigilationRequest', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('status', models.IntegerField()), + ('invigilator', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='csc.Invigilator')), + ('test', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='csc.Test')), + ], + ), + migrations.AddField( + model_name='fosscategory', + name='category', + field=models.ManyToManyField(to='csc.FossSuperCategory'), + ), + migrations.CreateModel( + name='Student_Foss', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('csc_foss', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='csc.Vle_csc_foss')), + ('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='csc.Student')), + ], + options={ + 'unique_together': {('student', 'csc_foss')}, + }, + ), + ] diff --git a/csc/migrations/0005_studenttest.py b/csc/migrations/0005_studenttest.py new file mode 100644 index 0000000..75fb817 --- /dev/null +++ b/csc/migrations/0005_studenttest.py @@ -0,0 +1,23 @@ +# Generated by Django 3.0.3 on 2022-07-27 05:51 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('csc', '0004_auto_20220726_1601'), + ] + + operations = [ + migrations.CreateModel( + name='StudentTest', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('status', models.IntegerField()), + ('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='csc.Student')), + ('test', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='csc.Test')), + ], + ), + ] diff --git a/csc/migrations/0006_auto_20220901_1138.py b/csc/migrations/0006_auto_20220901_1138.py new file mode 100644 index 0000000..209e5e0 --- /dev/null +++ b/csc/migrations/0006_auto_20220901_1138.py @@ -0,0 +1,34 @@ +# Generated by Django 3.0.3 on 2022-09-01 06:08 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('csc', '0005_studenttest'), + ] + + operations = [ + migrations.AddField( + model_name='studenttest', + name='test_status', + field=models.IntegerField(default=0), + ), + migrations.AlterUniqueTogether( + name='studenttest', + unique_together={('student', 'test')}, + ), + migrations.CreateModel( + name='TestRequest', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('status', models.IntegerField()), + ('created', models.DateTimeField(auto_now_add=True)), + ('foss', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='csc.FossCategory')), + ('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='csc.Student')), + ('vle', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='csc.VLE')), + ], + ), + ] diff --git a/csc/migrations/0007_categorycourses_certifiatecategories.py b/csc/migrations/0007_categorycourses_certifiatecategories.py new file mode 100644 index 0000000..518b6cb --- /dev/null +++ b/csc/migrations/0007_categorycourses_certifiatecategories.py @@ -0,0 +1,34 @@ +# Generated by Django 3.0.3 on 2022-09-07 12:19 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('csc', '0006_auto_20220901_1138'), + ] + + operations = [ + migrations.CreateModel( + name='CertifiateCategories', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('code', models.CharField(max_length=100, unique=True)), + ('title', models.CharField(max_length=255, unique=True)), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ], + ), + migrations.CreateModel( + name='CategoryCourses', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ('certificate_category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='csc.CertifiateCategories')), + ('foss', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='csc.FossCategory')), + ], + ), + ] diff --git a/csc/migrations/0008_auto_20220912_1719.py b/csc/migrations/0008_auto_20220912_1719.py new file mode 100644 index 0000000..3ab02b2 --- /dev/null +++ b/csc/migrations/0008_auto_20220912_1719.py @@ -0,0 +1,33 @@ +# Generated by Django 3.0.3 on 2022-09-12 11:49 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('csc', '0007_categorycourses_certifiatecategories'), + ] + + operations = [ + migrations.AlterField( + model_name='student_foss', + name='csc_foss', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='csc.FossCategory'), + ), + migrations.CreateModel( + name='Student_certificate_course', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('programme_starting_date', models.DateField(blank=True, null=True)), + ('created', models.DateField(blank=True, null=True)), + ('updated', models.DateField(auto_now=True, null=True)), + ('cert_category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='csc.CertifiateCategories')), + ('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='csc.Student')), + ], + options={ + 'unique_together': {('student', 'cert_category')}, + }, + ), + ] diff --git a/csc/migrations/0009_auto_20220915_1344.py b/csc/migrations/0009_auto_20220915_1344.py new file mode 100644 index 0000000..8e7e918 --- /dev/null +++ b/csc/migrations/0009_auto_20220915_1344.py @@ -0,0 +1,19 @@ +# Generated by Django 3.0.3 on 2022-09-15 08:14 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('csc', '0008_auto_20220912_1719'), + ] + + operations = [ + migrations.AlterField( + model_name='student_certificate_course', + name='student', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='student_cert', to='csc.Student'), + ), + ] diff --git a/csc/migrations/0010_auto_20220915_1402.py b/csc/migrations/0010_auto_20220915_1402.py new file mode 100644 index 0000000..6b65e2d --- /dev/null +++ b/csc/migrations/0010_auto_20220915_1402.py @@ -0,0 +1,19 @@ +# Generated by Django 3.0.3 on 2022-09-15 08:32 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('csc', '0009_auto_20220915_1344'), + ] + + operations = [ + migrations.AlterField( + model_name='student_certificate_course', + name='cert_category', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='category_cert', to='csc.CertifiateCategories'), + ), + ] diff --git a/csc/migrations/0011_auto_20220915_1445.py b/csc/migrations/0011_auto_20220915_1445.py new file mode 100644 index 0000000..599aae9 --- /dev/null +++ b/csc/migrations/0011_auto_20220915_1445.py @@ -0,0 +1,19 @@ +# Generated by Django 3.0.3 on 2022-09-15 09:15 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('csc', '0010_auto_20220915_1402'), + ] + + operations = [ + migrations.AlterField( + model_name='student_certificate_course', + name='student', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='certificate_course', to='csc.Student'), + ), + ] diff --git a/csc/migrations/0012_auto_20220920_0805.py b/csc/migrations/0012_auto_20220920_0805.py new file mode 100644 index 0000000..284d7c3 --- /dev/null +++ b/csc/migrations/0012_auto_20220920_0805.py @@ -0,0 +1,23 @@ +# Generated by Django 3.0.3 on 2022-09-20 02:35 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('csc', '0011_auto_20220915_1445'), + ] + + operations = [ + migrations.AddField( + model_name='student', + name='category', + field=models.CharField(blank=True, max_length=255, null=True), + ), + migrations.AddField( + model_name='student', + name='occupation', + field=models.CharField(blank=True, max_length=255, null=True), + ), + ] diff --git a/csc/migrations/0013_auto_20220927_0026.py b/csc/migrations/0013_auto_20220927_0026.py new file mode 100644 index 0000000..f007d7e --- /dev/null +++ b/csc/migrations/0013_auto_20220927_0026.py @@ -0,0 +1,23 @@ +# Generated by Django 3.0.3 on 2022-09-26 18:56 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('csc', '0012_auto_20220920_0805'), + ] + + operations = [ + migrations.AddField( + model_name='student_foss', + name='student_cert_course', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='csc.Student_certificate_course'), + ), + migrations.AlterUniqueTogether( + name='student_foss', + unique_together={('student', 'csc_foss', 'student_cert_course')}, + ), + ] diff --git a/csc/migrations/0013_auto_20220927_0844.py b/csc/migrations/0013_auto_20220927_0844.py new file mode 100644 index 0000000..c17a7fe --- /dev/null +++ b/csc/migrations/0013_auto_20220927_0844.py @@ -0,0 +1,19 @@ +# Generated by Django 3.0.3 on 2022-09-27 03:14 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('csc', '0012_auto_20220920_0805'), + ] + + operations = [ + migrations.AlterField( + model_name='transaction', + name='vle', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='transaction_date', to='csc.VLE'), + ), + ] diff --git a/csc/migrations/0014_auto_20220928_1104.py b/csc/migrations/0014_auto_20220928_1104.py new file mode 100644 index 0000000..4c75fab --- /dev/null +++ b/csc/migrations/0014_auto_20220928_1104.py @@ -0,0 +1,32 @@ +# Generated by Django 3.0.3 on 2022-09-28 05:34 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('csc', '0013_auto_20220927_0026'), + ] + + operations = [ + migrations.AddField( + model_name='student_foss', + name='cert_category', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='csc.CertifiateCategories'), + ), + migrations.AddField( + model_name='student_foss', + name='foss_start_date', + field=models.DateField(blank=True, null=True), + ), + migrations.AlterUniqueTogether( + name='student_foss', + unique_together={('student', 'csc_foss', 'cert_category')}, + ), + migrations.RemoveField( + model_name='student_foss', + name='student_cert_course', + ), + ] diff --git a/csc/migrations/0015_merge_20220929_0012.py b/csc/migrations/0015_merge_20220929_0012.py new file mode 100644 index 0000000..b741c47 --- /dev/null +++ b/csc/migrations/0015_merge_20220929_0012.py @@ -0,0 +1,14 @@ +# Generated by Django 3.0.3 on 2022-09-28 18:42 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('csc', '0013_auto_20220927_0844'), + ('csc', '0014_auto_20220928_1104'), + ] + + operations = [ + ] diff --git a/csc/migrations/0016_auto_20220930_1304.py b/csc/migrations/0016_auto_20220930_1304.py new file mode 100644 index 0000000..c89a1e1 --- /dev/null +++ b/csc/migrations/0016_auto_20220930_1304.py @@ -0,0 +1,74 @@ +# Generated by Django 3.0.3 on 2022-09-30 07:34 + +import datetime +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('csc', '0015_merge_20220929_0012'), + ] + + operations = [ + migrations.AlterField( + model_name='csc', + name='address', + field=models.CharField(blank=True, max_length=255, null=True), + ), + migrations.AlterField( + model_name='csc', + name='block', + field=models.CharField(blank=True, max_length=100, null=True), + ), + migrations.AlterField( + model_name='csc', + name='city', + field=models.CharField(blank=True, max_length=100, null=True), + ), + migrations.AlterField( + model_name='csc', + name='institute', + field=models.CharField(blank=True, max_length=255, null=True), + ), + migrations.AlterField( + model_name='csc', + name='pincode', + field=models.CharField(blank=True, max_length=6, null=True), + ), + migrations.AlterField( + model_name='csc', + name='plan', + field=models.CharField(max_length=255), + ), + migrations.AlterField( + model_name='student', + name='address', + field=models.CharField(blank=True, max_length=255, null=True), + ), + migrations.AlterField( + model_name='student', + name='date_of_registration', + field=models.DateField(default=datetime.date(2022, 9, 30)), + ), + migrations.AlterField( + model_name='student', + name='dob', + field=models.DateField(blank=True, null=True), + ), + migrations.AlterField( + model_name='student', + name='edu_qualification', + field=models.CharField(blank=True, max_length=255, null=True), + ), + migrations.AlterField( + model_name='student', + name='gender', + field=models.CharField(blank=True, max_length=10, null=True), + ), + migrations.AlterField( + model_name='student', + name='pincode', + field=models.CharField(blank=True, max_length=6, null=True), + ), + ] diff --git a/csc/migrations/0017_auto_20221104_1204.py b/csc/migrations/0017_auto_20221104_1204.py new file mode 100644 index 0000000..06bd6fd --- /dev/null +++ b/csc/migrations/0017_auto_20221104_1204.py @@ -0,0 +1,105 @@ +# Generated by Django 3.0.3 on 2022-11-04 06:34 + +import datetime +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('csc', '0016_auto_20220930_1304'), + ] + + operations = [ + migrations.RemoveField( + model_name='test', + name='test_name', + ), + migrations.AddField( + model_name='invigilator', + name='password_mail_sent', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='student', + name='mdl_mail_sent', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='test', + name='invigilator', + field=models.ManyToManyField(blank=True, null=True, to='csc.Invigilator'), + ), + migrations.AddField( + model_name='test', + name='participant_count', + field=models.IntegerField(blank=True, null=True), + ), + migrations.AddField( + model_name='test', + name='status', + field=models.PositiveIntegerField(default=0), + ), + migrations.AlterField( + model_name='invigilator', + name='phone', + field=models.CharField(blank=True, max_length=32, null=True), + ), + migrations.AlterField( + model_name='invigilator', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='invi', to=settings.AUTH_USER_MODEL), + ), + migrations.AlterField( + model_name='student', + name='date_of_registration', + field=models.DateField(default=datetime.date(2022, 11, 4)), + ), + migrations.AlterField( + model_name='test', + name='publish', + field=models.BooleanField(default=True), + ), + migrations.AlterField( + model_name='test', + name='vle', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='csc.VLE'), + ), + migrations.CreateModel( + name='CSCFossMdlCourses', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('mdlcourse_id', models.PositiveIntegerField()), + ('mdlquiz_id', models.PositiveIntegerField()), + ('foss', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='cscfoss', to='csc.FossCategory')), + ('testfoss', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='testfoss', to='csc.FossCategory')), + ], + ), + migrations.RemoveField( + model_name='invigilator', + name='added_by', + ), + migrations.CreateModel( + name='CSCTestAtttendance', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('mdluser_id', models.PositiveIntegerField()), + ('mdlcourse_id', models.PositiveIntegerField(default=0)), + ('mdlquiz_id', models.PositiveIntegerField(default=0)), + ('mdlattempt_id', models.PositiveIntegerField(default=0)), + ('status', models.PositiveSmallIntegerField(default=0)), + ('mdlgrade', models.DecimalField(decimal_places=5, default=0.0, max_digits=12)), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ('student', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='csc.Student')), + ('test', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='csc.Test')), + ], + options={ + 'verbose_name': 'Test Attendance', + 'unique_together': {('test', 'mdluser_id')}, + }, + ), + ] diff --git a/csc/migrations/0018_auto_20221121_1727.py b/csc/migrations/0018_auto_20221121_1727.py new file mode 100644 index 0000000..a6c0b43 --- /dev/null +++ b/csc/migrations/0018_auto_20221121_1727.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.3 on 2022-11-21 11:57 + +import datetime +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('csc', '0017_auto_20221104_1204'), + ] + + operations = [ + migrations.AlterUniqueTogether( + name='csctestatttendance', + unique_together={('mdlcourse_id', 'mdluser_id')}, + ), + ] diff --git a/csc/migrations/0019_auto_20221121_1831.py b/csc/migrations/0019_auto_20221121_1831.py new file mode 100644 index 0000000..c8c6dcb --- /dev/null +++ b/csc/migrations/0019_auto_20221121_1831.py @@ -0,0 +1,19 @@ +# Generated by Django 3.0.3 on 2022-11-21 13:01 + +import datetime +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('csc', '0018_auto_20221121_1727'), + ] + + operations = [ + migrations.AddField( + model_name='student', + name='dca_count', + field=models.IntegerField(default=0), + ), + ] diff --git a/csc/models.py b/csc/models.py index a9cc687..af27673 100644 --- a/csc/models.py +++ b/csc/models.py @@ -1,24 +1,103 @@ - from __future__ import unicode_literals +from audioop import reverse +from email.policy import default from django.db import models from django.contrib.auth.models import User from django.forms import ChoiceField +from spokenlogin.models import * +from model_utils import Choices +from cms.models import State, District, City +from django.forms import widgets +from datetime import date +from django.template.defaultfilters import slugify +# from csc.utils import TEST_OPEN + + +TEST_OPEN = 0 +REJECTED = 0 +APPROVED = 1 +PROGRAMME_TYPE_CHOICES = Choices( + ('', ('-- None --')),('dca', ('DCA Programme')), ('individual', ('Individual Course')) + ) + + +class FossSuperCategory(models.Model): + name = models.CharField(max_length=255, unique=True) + created = models.DateTimeField(auto_now_add=True) + updated = models.DateTimeField(auto_now=True) + + class Meta(object): + verbose_name = 'FOSS Category' + verbose_name_plural = 'FOSS Categories' + ordering = ('name',) + + def __str__(self): + return self.name + +class FossCategory(models.Model): + foss = models.CharField(unique=True, max_length=255) + description = models.TextField() + status = models.BooleanField(max_length=2) + is_learners_allowed = models.BooleanField(max_length=2,default=0 ) + is_translation_allowed = models.BooleanField(max_length=2, default=0) + # user = models.ForeignKey(User, on_delete=models.PROTECT ) + category = models.ManyToManyField(FossSuperCategory) + created = models.DateTimeField(auto_now_add=True) + updated = models.DateTimeField(auto_now=True) + show_on_homepage = models.PositiveSmallIntegerField(default=0, help_text ='0:Series, 1:Display on home page, 2:Archived') + available_for_nasscom = models.BooleanField(default=True, help_text ='If unchecked, this foss will not be available for nasscom' ) + available_for_jio = models.BooleanField(default=True, help_text ='If unchecked, this foss will not be available for jio and spoken-tutorial.in' ) + csc_dca_programme = models.BooleanField(default=True, help_text ='If unchecked, this foss will not be available for csc-dca programme' ) + class Meta(object): + verbose_name = 'FOSS' + verbose_name_plural = 'FOSSes' + ordering = ('foss', ) + + def __str__(self): + return self.foss + + +class CertifiateCategories(models.Model): + code = models.CharField(max_length=100, unique = True) + title = models.CharField(max_length=255, unique=True) + created = models.DateTimeField(auto_now_add=True) + updated = models.DateTimeField(auto_now=True) + + def __str__(self): + return f"{self.code} - {self.title}" + + +class CategoryCourses(models.Model): + certificate_category = models.ForeignKey(CertifiateCategories,on_delete=models.CASCADE) + foss = models.ForeignKey(FossCategory,on_delete=models.CASCADE) + created = models.DateTimeField(auto_now_add=True) + updated = models.DateTimeField(auto_now=True) + + def __str__(self): + return f"{self.certificate_category.code} - {self.foss.foss}" + + + class CSC(models.Model): CSC_PLAN = [('College Level Subscription','College Level Subscription'), ('School Level Subscription','School Level Subscription')] csc_id = models.CharField(max_length=50) # id provided by csc - institute = models.CharField(max_length=255) + institute = models.CharField(max_length=255,null=True,blank=True) state = models.CharField(max_length=100) - city = models.CharField(max_length=100) + city = models.CharField(max_length=100,null=True,blank=True) district = models.CharField(max_length=100) - block = models.CharField(max_length=100) - address = models.CharField(max_length=255) - pincode = models.CharField(max_length=6) - plan = models.CharField(choices=CSC_PLAN,max_length=100) + block = models.CharField(max_length=100,null=True,blank=True) + address = models.CharField(max_length=255,null=True,blank=True) + pincode = models.CharField(max_length=6,null=True,blank=True) + # plan = models.CharField(choices=CSC_PLAN,max_length=100) + plan = models.CharField(max_length=255) activation_status = models.BooleanField(default=True) # If the csc is inactivated for some reason ; payment not done + def __str__(self): + + return f"{self.city},{self.district}" class VLE(models.Model): @@ -29,11 +108,15 @@ class VLE(models.Model): class Meta: unique_together = ('csc','user') + + def __str__(self): + return f"{self.user.first_name.title()} {self.user.last_name.title()}" + class Transaction(models.Model): TRANSACTION_TENURE = [('quarterly','quarterly'),('biannually','biannually'),('annually','annually')] - vle = models.ForeignKey(VLE,on_delete=models.CASCADE) + vle = models.ForeignKey(VLE,on_delete=models.CASCADE,related_name='transaction_date') csc = models.ForeignKey(CSC,on_delete=models.CASCADE) transcdate = models.DateField(null=False) tenure = models.CharField(choices=TRANSACTION_TENURE,max_length=10,null=True,blank=True) @@ -43,5 +126,191 @@ class Meta: unique_together = ('vle','csc','transcdate') +class Vle_csc_foss(models.Model): + + programme_type = models.CharField(choices=PROGRAMME_TYPE_CHOICES, max_length=100) +# spoken_foss = models.IntegerField() + spoken_foss = models.ForeignKey(FossCategory,on_delete=models.CASCADE) + created = models.DateField(blank=True,null=True) + updated = models.DateField(auto_now = True, null=True) + vle = models.ForeignKey(VLE,on_delete=models.CASCADE) + + #unique together + class Meta(object): + unique_together = (("spoken_foss","programme_type"),) + def __str__(self): + return self.spoken_foss.foss + + + + + +# =========== Student models start =================================== + +class Student(models.Model): + student_id = models.CharField(max_length=255) + user = models.ForeignKey(User,on_delete=models.CASCADE) + gender = models.CharField(max_length=10,blank=True,null=True) + dob = models.DateField(blank=True,null=True) + phone = models.CharField(max_length=32,blank=True) + edu_qualification = models.CharField(max_length=255,blank=True,null=True) + vle_id = models.ManyToManyField(VLE) #if student joins another csc due to location change + state = models.ForeignKey(State,on_delete=models.CASCADE,blank=True,null=True) + city = models.ForeignKey(City,on_delete=models.CASCADE,blank=True,null=True) + district = models.ForeignKey(District,on_delete=models.CASCADE,blank=True,null=True) + pincode = models.CharField(max_length=6,blank=True,null=True) + address = models.CharField(max_length=255,blank=True,null=True) + date_of_registration = models.DateField(default=date.today()) + occupation = models.CharField(max_length=255,blank=True,null=True) + category = models.CharField(max_length=255,blank=True,null=True) + mdl_mail_sent = models.BooleanField(default=False) + dca_count = models.IntegerField(default=0) + + +class Student_certificate_course(models.Model): + student = models.ForeignKey(Student,on_delete=models.CASCADE,related_name='certificate_course') + cert_category = models.ForeignKey(CertifiateCategories,on_delete=models.CASCADE,related_name='category_cert') + programme_starting_date = models.DateField(blank=True,null=True) + created = models.DateField(blank=True,null=True) + updated = models.DateField(auto_now = True, null=True) + + class Meta: + unique_together = ('student','cert_category') + + def __str__(self): + return f"{self.cert_category.code}" + + +class Student_Foss(models.Model): + student = models.ForeignKey(Student,on_delete=models.CASCADE) + csc_foss = models.ForeignKey(FossCategory,on_delete=models.CASCADE) + cert_category = models.ForeignKey(CertifiateCategories, on_delete=models.CASCADE, null=True) + foss_start_date = models.DateField(blank=True,null=True) + + class Meta: + unique_together = ('student','csc_foss', 'cert_category') + + + def __str__(self): + return f"{self.csc_foss.foss}" +# =========== Student models ens =================================== + + + +class Invigilator(models.Model): + user = models.ForeignKey(User,on_delete=models.CASCADE,related_name='invi') + phone = models.CharField(max_length=32,null=True,blank=True) + vle = models.ManyToManyField(VLE) + # vle = models.ForeignKey(VLE,on_delete=models.CASCADE,related_name='invig') + # added_by = models.ForeignKey(User,on_delete=models.CASCADE,related_name='added_by_user') + created = models.DateTimeField(auto_now_add=True) + updated = models.DateTimeField(auto_now=True) + password_mail_sent = models.BooleanField(default=False) + + def __str__(self): + return f"{self.user.first_name} {self.user.last_name} - {self.user.email}" + +class Test(models.Model): + foss = models.ForeignKey(FossCategory,on_delete=models.CASCADE) + # mdlfoss = models.ForeignKey(FossCategory,on_delete=models.CASCADE) + tdate = models.DateField() + ttime = models.TimeField() + invigilator = models.ManyToManyField(Invigilator,blank=True,null=True) + publish = models.BooleanField(default=True) + vle = models.ForeignKey(VLE,on_delete=models.CASCADE,null=True,blank=True) + note_student = models.TextField(blank=True,null=True) + note_invigilator = models.TextField(blank=True,null=True) + status = models.PositiveIntegerField(default=TEST_OPEN)# + # test_name = models.CharField(max_length=252,blank=True,null=True) + participant_count = models.IntegerField(null=True,blank=True) + slug = models.SlugField(max_length=40) + created = models.DateTimeField(auto_now_add=True) + updated = models.DateTimeField(auto_now=True) + #ToDO : Add status ; to mark if completed or cancellled + + # class Meta: + # widgets = { + # 'tdate':widgets.DateInput(attrs={'type': 'date'}) + # } + def get_absolute_url(self): + # return f"{self.foss}" + return reverse("detail_test",kwargs={"slug": self.slug}) + + def __str__(self): + return f"{self.foss} ".ljust(25,'-') + f" ( {self.tdate.strftime('%b %d')}, {self.ttime.strftime('%I:%M %p')} )" + + def __repr__(self): + return f"{self.foss} - {self.tdate}" + + def save(self, *args, **kwargs): # new + if not self.slug: + self.slug = slugify(self.id) + return super().save(*args, **kwargs) + +class InvigilationRequest(models.Model): + invigilator = models.ForeignKey(Invigilator,on_delete=models.CASCADE) + test = models.ForeignKey(Test,on_delete=models.CASCADE) + status = models.IntegerField() #0-pending, 1-accepted, 2-rejected + +class StudentTest(models.Model): + student = models.ForeignKey(Student,on_delete=models.CASCADE) + test = models.ForeignKey(Test,on_delete=models.CASCADE) + status = models.IntegerField() #0 : Rejected, 1 : Approved + test_status = models.IntegerField(default=0) #0: default - test not attended ; 1: attendance marked + def __str__(self): + return f"{self.id}" + + class Meta: + unique_together = [['student', 'test']] + +class TestRequest(models.Model): + student = models.ForeignKey(Student,on_delete=models.CASCADE) + foss = models.ForeignKey(FossCategory,on_delete=models.CASCADE) + vle = models.ForeignKey(VLE,on_delete=models.CASCADE) + status = models.IntegerField() + created = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return f"{self.id}" + +class CSCTestAtttendance(models.Model): + test = models.ForeignKey(Test, on_delete=models.PROTECT ) + student = models.ForeignKey(Student, on_delete=models.PROTECT ) + # mdluser_firstname = models.CharField(max_length = 100) + # mdluser_lastname = models.CharField(max_length = 100) + mdluser_id = models.PositiveIntegerField() + mdlcourse_id = models.PositiveIntegerField(default=0) + mdlquiz_id = models.PositiveIntegerField(default=0) + mdlattempt_id = models.PositiveIntegerField(default=0) + status = models.PositiveSmallIntegerField(default=0) + mdlgrade = models.DecimalField(max_digits=12, decimal_places=5, default=0.00) + created = models.DateTimeField(auto_now_add = True) + updated = models.DateTimeField(auto_now = True) + class Meta(object): + verbose_name = "Test Attendance" + unique_together = (("mdlcourse_id", "mdluser_id")) + + +class CSCFossMdlCourses(models.Model): + foss = models.ForeignKey(FossCategory, on_delete=models.PROTECT, related_name='trainingfoss', null=True) + mdlcourse_id = models.PositiveIntegerField() + mdlquiz_id = models.PositiveIntegerField() + testfoss = models.ForeignKey(FossCategory, on_delete=models.PROTECT, related_name='testfoss', null=True) + + def __str__(self): + return self.foss.foss + + def __str__(self): + return self.student.user.email + self.test.foss.foss + + +class CSCFossMdlCourses(models.Model): + foss = models.ForeignKey(FossCategory, on_delete=models.PROTECT, related_name='cscfoss', null=True) + mdlcourse_id = models.PositiveIntegerField() + mdlquiz_id = models.PositiveIntegerField() + testfoss = models.ForeignKey(FossCategory, on_delete=models.PROTECT, related_name='testfoss', null=True) + + def __str__(self): + return self.foss.foss \ No newline at end of file diff --git a/csc/stats/__init__.py b/csc/stats/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/csc/stats/urls.py b/csc/stats/urls.py new file mode 100644 index 0000000..e301bf9 --- /dev/null +++ b/csc/stats/urls.py @@ -0,0 +1,21 @@ +from django.urls import path +from django.urls import re_path + + +from csc.stats.views import * + + +urlpatterns = [ + path('',stats,name="stats_dashboard"), + path('ajax_stats/',ajax_stats,name="ajax_stats"), + path('ajax_csc_state_count/',get_csc_state_count,name="ajax_csc_state_count"), + path('ajax_vle_detail/',ajax_vle_detail,name="ajax_vle_detail"), + path('vle_stats/',VLEListView.as_view(),name="vle_stats"), + path('student_stats/',StudentListView.as_view(),name="student_stats"), + path('vle_report/',vle_report,name="vle_report"), + path('student_report/',student_report,name="student_report") + + + + +] \ No newline at end of file diff --git a/csc/stats/utility.py b/csc/stats/utility.py new file mode 100644 index 0000000..a212b8a --- /dev/null +++ b/csc/stats/utility.py @@ -0,0 +1,54 @@ +from django.db.models import Count,Q,F +from django.conf import settings + +from csc.models import CertifiateCategories, Student,Student_Foss,FossCategory, CSC, VLE + +TEST_VLE_COUNT=int(getattr(settings, "TEST_VLE_COUNT", 2)) +TEST_STUDENT_COUNT=int(getattr(settings, "TEST_STUDENT_COUNT", 1)) +TEST_VLE_EMAIL=getattr(settings, "TEST_VLE_EMAIL", ['ankitamk@gmail.com','roliimpex@gmail.com']) +TEST_STUDENT_EMAIL=getattr(settings, "TEST_STUDENT_EMAIL", ['kirti3192@gmail.com']) +TEST_CSC_ID=getattr(settings, "TEST_CSC_ID", [1,2]) + +qs_students = Student.objects.exclude(Q(user__email__in=TEST_STUDENT_EMAIL)) +qs_student_foss = Student_Foss.objects.exclude(Q(student__user__email__in=TEST_STUDENT_EMAIL)) +qs_csc = CSC.objects.exclude(Q(id__in=TEST_CSC_ID)) +qs_vle = VLE.objects.exclude(Q(user__email__in=TEST_VLE_EMAIL)) + + + + +def get_student_gender_stats(): + return qs_students.values('gender').annotate(count=Count('gender')).order_by('-count') + + +def get_student_category_stats(): + return qs_students.values('category').annotate(count=Count('category')).order_by('-count') + +def get_student_occupation_stats(): + return qs_students.values('occupation').annotate(count=Count('occupation')).order_by('-count') + +def get_student_certi_stats(): + return qs_student_foss.values('cert_category__code').annotate(count=Count('cert_category'),title=F('cert_category__title')).order_by('-count') + +def get_student_state_stats(): + return qs_csc.values('state').annotate(count=Count('state')).order_by('state') + +def get_student_foss_stats(start=0,end=len(qs_student_foss),type=''): + t = FossCategory.objects.filter(available_for_jio=1).order_by('foss') + indi = CertifiateCategories.objects.get(code='INDI') + if type: + q = [x['csc_foss__foss'] for x in qs_student_foss.filter(csc_foss__in=t,cert_category=indi).values('csc_foss__foss').annotate(count=Count('csc_foss__foss')).order_by('-count')] + else: + q = [x['csc_foss__foss'] for x in qs_student_foss.filter(csc_foss__in=t).values('csc_foss__foss').annotate(count=Count('csc_foss__foss')).order_by('-count')] + temp = [] + for x in range(start, end, 1): + try: + temp.append(q[x]) + except Exception as e: + # print(e) + pass + if type: + return qs_student_foss.filter(csc_foss__foss__in=temp,cert_category=indi).values('csc_foss__foss').annotate(count=Count('csc_foss__foss')).order_by('-count') + else: + return qs_student_foss.filter(csc_foss__foss__in=temp).values('csc_foss__foss').annotate(count=Count('csc_foss__foss')).order_by('-count') + \ No newline at end of file diff --git a/csc/stats/views.py b/csc/stats/views.py new file mode 100644 index 0000000..d0035f7 --- /dev/null +++ b/csc/stats/views.py @@ -0,0 +1,236 @@ +from django.shortcuts import render +from django.db.models import Count,F,Q +from django.http import JsonResponse +from django.views.generic import ListView +from django.views.decorators.csrf import csrf_exempt +from django.contrib.auth.decorators import login_required +from django.utils.decorators import method_decorator + +from django.contrib.auth.mixins import LoginRequiredMixin +from csc.models import CSC,VLE,Student, FossCategory, CertifiateCategories, Student_Foss +from cms.models import State, District +from csc.decorators import is_csc_team as dec_is_csc_team +from csc.utils import is_csc_team_role +from .utility import * + + +@login_required +@dec_is_csc_team +def stats(request): + context = {} + + total_vles = VLE.objects.count()-TEST_VLE_COUNT + total_students = Student.objects.count()-TEST_STUDENT_COUNT + total_foss = FossCategory.objects.filter(available_for_jio=True).count() + total_certificate_course = CertifiateCategories.objects.count() + context['total_vles'] = total_vles + context['total_students'] = total_students + context['total_foss'] = total_foss + context['total_certificate_course'] = total_certificate_course + + student_gender = get_student_gender_stats() + context['student_gender'] = student_gender + sct = get_student_certi_stats() + context['cert_count_tb'] = [x for x in sct] + + sft = get_student_foss_stats(0) + context['foss_count_tb'] = [x for x in sft] + csc_state = get_student_state_stats() + context['csc_state'] = csc_state + indi = CertifiateCategories.objects.get(code='INDI') + student_indi_foss=Student_Foss.objects.filter(cert_category=indi).values('csc_foss__foss').annotate(count=Count('csc_foss')).order_by('-count') + context['student_indi_foss'] = [x for x in student_indi_foss] + + return render(request, 'stats/stats.html', context) + + +def ajax_stats(request): + data = {} + + student_gender = get_student_gender_stats() + data['student_gender'] = [x for x in student_gender] + student_category = get_student_category_stats() + data['student_category'] = [x for x in student_category] + student_occupation = get_student_occupation_stats() + data['student_occupation'] = [x for x in student_occupation] + student_course=get_student_certi_stats() + data['student_course'] = [x for x in student_course] + + data['student_foss_1'] = [x for x in get_student_foss_stats(0,15)] + data['student_foss_2'] = [x for x in get_student_foss_stats(15,30)] + data['student_foss_3'] = [x for x in get_student_foss_stats(30,45)] + data['student_foss_4'] = [x for x in get_student_foss_stats(45,60)] + data['student_foss_5'] = [x for x in get_student_foss_stats(start=45)] + + csc_state = get_student_state_stats() + data['csc_state'] = [x for x in csc_state] + + data['student_indi_foss_1'] = [x for x in get_student_foss_stats(0,15,'indi')] + data['student_indi_foss_2'] = [x for x in get_student_foss_stats(15,30,'indi')] + data['student_indi_foss_3'] = [x for x in get_student_foss_stats(30,45,'indi')] + data['student_indi_foss_4'] = [x for x in get_student_foss_stats(45,60,'indi')] + data['student_indi_foss_5'] = [x for x in get_student_foss_stats(start=45,type='indi')] + + return JsonResponse(data) + +def get_csc_state_count(request): + data = {} + csc_state = CSC.objects.values('state').annotate(count=Count('state'),code=F('state')) + csc_state = [x for x in csc_state] + data['csc_state'] = csc_state + return JsonResponse(data) + +@method_decorator(login_required, name='dispatch') +class StudentListView(ListView): + paginate_by = 100 + model = Student + template_name = 'stats/student_stats.html' + + + def get_queryset(self): + raw = 'Select DATEDIFF(CURDATE(), `csc_student`.`dob`) from `csc_student` u where u.`id`=`csc_student`.id' + + qs = super().get_queryset() + qs = qs_students + # qs = qs.annotate(age2=find_age) + # qs = qs.annotate(age2=ExpressionWrapper(RawSQL(raw, ())/365),output_field=IntegerField()) + if self.request.GET.get('name'): + name = self.request.GET.get('name') + qs = qs.filter(Q(user__first_name__icontains=name)|Q(user__last_name__icontains=name)|Q(user__email__icontains=name)) + if self.request.GET.get('vle_name'): + name = self.request.GET.get('vle_name') + vles = VLE.objects.filter(Q(user__first_name__icontains=name)|Q(user__last_name__icontains=name)|Q(user__email__icontains=name)) + qs = qs.filter(vle_id__in=vles) + if self.request.GET.get('csc'): + csc = self.request.GET.get('csc') + csc = CSC.objects.get(csc_id=csc) + vle = VLE.objects.filter(csc=csc) + qs = qs.filter(vle_id__in=vle) + if self.request.GET.get('edu'): + edu = self.request.GET.get('edu') + qs = qs.filter(edu_qualification__icontains=edu) + if self.request.GET.get('state'): + state = self.request.GET.get('state') + state_obj = State.objects.get(name=state) + qs = qs.filter(state_id=state_obj.id) + if self.request.GET.get('district'): + district = self.request.GET.get('district') + district_obj = District.objects.get(name=district) + qs = qs.filter(district_id=district_obj.id) + + if self.request.GET.get('occupation'): + occupation = self.request.GET.get('occupation') + qs = qs.filter(occupation=occupation) + + return qs + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + edu = Student.objects.values('edu_qualification').distinct().order_by('edu_qualification') + context['edu'] = edu + context['states'] = State.objects.all().order_by('name') + context['districts'] = District.objects.all().order_by('name') + occupation = Student.objects.values('occupation').distinct().order_by('occupation') + context['occupation'] = occupation + query_str = self.request.GET + context['query_str'] = query_str + return context + + + +@method_decorator(login_required, name='dispatch') +class VLEListView(ListView): + paginate_by = 100 + model = VLE + template_name = 'stats/vle_stats.html' + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['states'] = State.objects.all().order_by('name') + context['districts'] = District.objects.all().order_by('name') + query_str = self.request.GET + context['query_str'] = query_str + return context + def get_queryset(self): + qs = super().get_queryset() + qs = qs_vle + if self.request.GET.get('name'): + name = self.request.GET.get('name') + qs = qs.filter(Q(user__first_name__icontains=name)|Q(user__last_name__icontains=name)|Q(user__email__icontains=name)) + if self.request.GET.get('csc_id'): + csc_id = self.request.GET.get('csc_id') + qs = qs.filter(csc__csc_id=csc_id) + if self.request.GET.get('state'): + state = self.request.GET.get('state') + qs = qs.filter(csc__state=state) + if self.request.GET.get('district'): + district = self.request.GET.get('district') + qs = qs.filter(csc__district=district) + return qs + +def student_stats(request): + context = {} + return render(request, 'stats/student_stats.html', context) + + +def vle_stats(request): + context = {} + return render(request, 'stats/vle_stats.html', context) + +@csrf_exempt +def ajax_vle_detail(request): + data = {} + vle_id = request.GET.get('vle_id') + vle = VLE.objects.get(id=vle_id) + data['name'] = vle.user.get_full_name() + data['email'] = vle.user.email + data['phone'] = vle.phone + data['csc_id'] = vle.csc.csc_id + data['state'] = vle.csc.state + data['district'] = vle.csc.district + data['address'] = vle.csc.address + data['pin'] = vle.csc.pincode + data['registered_on'] = vle.user.date_joined + print(f"Student.objects.filter(vle_id=vle_id) ****** {Student.objects.filter(vle_id=vle_id)}") + data['total_students'] = Student.objects.filter(vle_id=vle_id).count() + data['fosses'] = [x for x in Student_Foss.objects.filter(student__vle_id=vle_id).values('csc_foss__foss').annotate(count=Count('csc_foss'))] + data['courses'] = [x for x in Student_Foss.objects.filter(student__vle_id=vle_id).values('cert_category__code','cert_category__title').annotate(count=Count('cert_category'))] + data['students'] = [x for x in Student.objects.filter(vle_id=vle_id).values('user__first_name', 'user__last_name','user__email')] + cert_category = CertifiateCategories.objects.get(code='INDI') + data['indi_fosses'] = [x for x in Student_Foss.objects.filter(student__vle_id=vle_id,cert_category=cert_category).values('csc_foss__foss').annotate(count=Count('csc_foss'))] + + return JsonResponse(data) + +@login_required +def student_report(request): + context = {} + context['total_students'] = Student.objects.count() + student_course=Student_Foss.objects.values('cert_category__code','cert_category__title').annotate(count=Count('cert_category')) + context['student_course'] = student_course + student_foss=Student_Foss.objects.values('csc_foss__foss').annotate(count=Count('csc_foss')).order_by('csc_foss') + context['student_foss'] = student_foss + student_gender = Student.objects.values('gender').annotate(count=Count('gender')) + context['student_gender'] = student_gender + student_occupation = Student.objects.values('occupation').annotate(count=Count('occupation')).order_by('occupation') + context['student_occupation'] = student_occupation + edu = Student.objects.values('edu_qualification').distinct().annotate(count=Count('edu_qualification')).order_by('edu_qualification') + context['edu'] = edu + student_category = Student.objects.values('category').annotate(count=Count('category')).order_by('category') + context['student_category'] = student_category + student_state = Student.objects.values('state__name').annotate(count=Count('state')).order_by('state') + context['student_state'] = student_state + student_district = Student.objects.values('district__name').annotate(count=Count('district')).order_by('district') + context['student_district'] = student_district + + return render(request, 'stats/student_report.html', context) + +@login_required +@dec_is_csc_team +def vle_report(request): + context = {} + csc_state = CSC.objects.values('state').annotate(count=Count('state')).order_by('state') + context['csc_state'] = csc_state + csc_district = CSC.objects.values('district').annotate(count=Count('district')).order_by('district') + context['csc_district'] = csc_district + + return render(request, 'stats/vle_report.html', context) \ No newline at end of file diff --git a/csc/student_forms.py b/csc/student_forms.py new file mode 100644 index 0000000..8b148da --- /dev/null +++ b/csc/student_forms.py @@ -0,0 +1,21 @@ +from django import forms + +from .models import Student, Student_Foss +GEEKS_CHOICES =( + ("1", "One"), + ("2", "Two"), + ("3", "Three"), + ("4", "Four"), + ("5", "Five"), +) +class RaiseTestRequestForm(forms.Form): + foss = forms.ChoiceField(choices=GEEKS_CHOICES) + + def __init__(self, *args, **kwargs): + user = kwargs.pop('user', None) + student = Student.objects.get(user=user) + student_foss = Student_Foss.objects.filter(student=student) + data = [(x.csc_foss.spoken_foss.id,x.csc_foss.spoken_foss) for x in student_foss] + super(RaiseTestRequestForm,self).__init__(*args, **kwargs) + self.fields['foss'].choices = data + diff --git a/csc/student_urls.py b/csc/student_urls.py index e69de29..a0b5f85 100644 --- a/csc/student_urls.py +++ b/csc/student_urls.py @@ -0,0 +1,25 @@ +from django import views +from csc.student_views import * +from .views import * +from django.urls import path +from django.conf.urls import url +from .vle_views import * +from .ajax import get_foss_from_csc,raise_test_request,apply_for_test +app_name = 'csc' +urlpatterns = [ + path('', student_dashboard, name="student_dashboard"), + path('courses/', student_courses, name="courses"), + path('tests/', student_tests, name="student_tests"), + path('student_change_test_status/', student_change_test_status, name="student_change_test_status"), + path('list_foss_on_csc/', get_foss_from_csc, name="list_foss_on_csc"), + path('raise_test_req/', raise_test_request, name="raise_test_req"), + path('apply_for_test/', apply_for_test, name="apply_for_test"), + + + path('download_certificate/', download_certificate, name="download_certificate"), + + + + + +] \ No newline at end of file diff --git a/csc/student_utils.py b/csc/student_utils.py new file mode 100644 index 0000000..e69de29 diff --git a/csc/student_views.py b/csc/student_views.py index e69de29..8d34bc5 100644 --- a/csc/student_views.py +++ b/csc/student_views.py @@ -0,0 +1,172 @@ + +from datetime import date +from multiprocessing import context +from django.urls import reverse +from django.http import HttpResponseRedirect, JsonResponse +from django.shortcuts import render +from .models import CSCTestAtttendance, CertifiateCategories, Student, StudentTest, Student_Foss, Test, VLE, TestRequest, Vle_csc_foss,CategoryCourses,FossCategory,Student_certificate_course +from .utils import upcoming_foss_tests,check_student_test_status +from .student_forms import RaiseTestRequestForm +from django.contrib.auth.decorators import login_required +from .decorators import is_student +from django.db.models import Q +from .utils import TEST_COMPLETED_BY_STUDENT +from django.conf import settings + +TEST_WAITING_PERIOD = 10 +def student_tests(request): + context = {} + student = Student.objects.get(user=request.user) + context['student_id'] = student.id + + studentFoss = Student_Foss.objects.filter(student=student) + vles = student.vle_id.all() + tests_all = [] + test_status = {} + for vle in vles: + tests_vle = Test.objects.filter(vle=vle,foss__in=[x.csc_foss.foss for x in studentFoss]) + for test in tests_vle: + tests_all.append(test) + try: + test_status[test] = StudentTest.objects.get(test=test).status + except StudentTest.DoesNotExist: + test_status[test] = 0 + studentTests = StudentTest.objects.filter(student=student) + # tests_students = [x.test for x in tests_all] + context['tests_all'] = tests_all + context['test_status'] = test_status + + context['studentTests'] = studentTests + return render(request,'csc/student_tests.html',context) + +def student_change_test_status(request): + data = {} + status = request.GET.get('status') + id = request.GET.get('id') + student = Student.objects.get(user=request.user) + try: + st = StudentTest.objects.get(test_id=id) + st.status = status + st.save() + except StudentTest.DoesNotExist: + StudentTest.objects.create(test_id=id,student=student,status=status) + + return HttpResponseRedirect(reverse('student:student_tests')) + +@login_required +@is_student +def student_dashboard(request): + context = {} + student = Student.objects.get(user=request.user) + sf = Student_Foss.objects.filter(student=student) + courses = [x.cert_category for x in sf] + + indi = CertifiateCategories.objects.get(code='INDI') + indi_fosses = [x.csc_foss for x in Student_Foss.objects.filter(student=student,cert_category__code='INDI').order_by('csc_foss__foss')] + + d = {} + for course in courses: + d[course] = [x.foss for x in CategoryCourses.objects.filter(certificate_category=course)] + try: + d.pop(indi) + except: + pass + + context['student'] = student + context['CSC_ONLINE_TEST_URL'] = settings.CSC_ONLINE_TEST_URL + context['courses'] = d + context['fosses'] = indi_fosses + context['vle'] = student.vle_id.all()[0] + + return render(request,'csc/student_dashboard.html',context) + +@login_required +@is_student +def student_courses(request): + context = {} + student = Student.objects.get(user = request.user) + student_foss = Student_Foss.objects.filter(student=student) + in_progress_foss_data = {} + vles = [] + context = {} + # vles = VLE.objects.filter(user=request.user) + + individual_foss = {} + fosses = [x['foss'] for x in FossCategory.objects.filter(available_for_jio=True).values('foss')] + context['fosses'] = fosses + courses = CertifiateCategories.objects.exclude(code__in=['INDI']) + if request.GET.get('course_search'): + search_term = request.GET.get('search_term') + q_code = Q(certificate_category__code__icontains=search_term) + q_title = Q(certificate_category__title__icontains=search_term) + q_foss = Q(foss__foss__icontains=search_term) + courses = [x.certificate_category for x in CategoryCourses.objects.filter(q_code|q_title|q_foss)] + + else: + courses = CertifiateCategories.objects.exclude(code__in=['INDI']) + d = {} + for course in courses: + fosses = [x['foss__foss'] for x in CategoryCourses.objects.filter(certificate_category_id=course.id).values('foss__foss')] + # if course.code in d: + d[course] = fosses + print(f"\n\n{d}\n\n") + context['courses'] = d + + return render(request,'csc/student_courses.html',context) + +def student_tests(request): + context = {} + student = Student.objects.get(user=request.user) + open_tests = CSCTestAtttendance.objects.filter(student=student,status=OPEN_TEST) + completed_tests = CSCTestAtttendance.objects.filter(student=student,status__in=[TEST_COMPLETED_BY_STUDENT]) + context['open_tests']=open_tests + context['completed_tests']=completed_tests + # print(f"student.vle_id - {student.vle_id.all()}") + # vles = VLE.objects.filter(id__in=[x.id for x in student.vle_id.all()]) + # csc = [(x.csc.id,x.csc.csc_id, x.csc.city) for x in vles] + # # if len(csc) == 1: + # vle = VLE.objects.get(csc_id = csc[0]) + # # vle_csc_foss = Vle_csc_foss.objects.filter(vle=vle) + # # sf = Student_Foss.objects.filter(student=student,csc_foss__in = vle_csc_foss) + # sf = Student_Foss.objects.filter(student=student) + + # # fosses = [(x.csc_foss.spoken_foss.foss,x.csc_foss.spoken_foss.id) for x in sf] + # fosses = [x.csc_foss for x in sf] + # applied = [x.foss for x in TestRequest.objects.filter(student=student)] + # print(f'fosses : {fosses}') + # print(f'applied : {applied}') + # available_foss = [] + # for foss in fosses: + # if not foss in applied: + # available_foss.append((foss.foss,foss.id)) + # context['fosses'] = available_foss + + # context['csc'] = csc + # testReqs = TestRequest.objects.filter(student=student) + # context['test_requests'] = testReqs + + # student_foss = Student_Foss.objects.filter(student=student) + # in_progress_foss_data = {} + # for item in student_foss: + # csc_foss = item.csc_foss + # foss = csc_foss.foss + # vle = csc_foss.vle + + # upcoming_tests = upcoming_foss_tests(foss,vle) + # applied = check_student_test_status(upcoming_tests,student) + # print(f'before : {upcoming_tests}') + # try: + # upcoming_tests.remove(applied) + # except Exception as e: + # print(e) + + # print(f'after : {upcoming_tests}') + # in_progress_foss_data[foss] = {'applied' : applied, 'upcoming_tests' : upcoming_tests} + + # context['in_progress_foss_data'] = in_progress_foss_data + return render(request,'csc/student_tests.html',context) + +def download_certificate(request): + data = {} + print(f"download_certificate ************************************ ") + return JsonResponse(data) diff --git a/csc/templates/csc/_error_msg.html b/csc/templates/csc/_error_msg.html new file mode 100644 index 0000000..5caee34 --- /dev/null +++ b/csc/templates/csc/_error_msg.html @@ -0,0 +1,8 @@ +
+ {% for message in messages %} +
+ + {% endfor %} +
\ No newline at end of file diff --git a/csc/templates/csc/_pagination.html b/csc/templates/csc/_pagination.html new file mode 100644 index 0000000..1155396 --- /dev/null +++ b/csc/templates/csc/_pagination.html @@ -0,0 +1,51 @@ + \ No newline at end of file diff --git a/csc/templates/csc/courses.html b/csc/templates/csc/courses.html new file mode 100644 index 0000000..8cd5ab6 --- /dev/null +++ b/csc/templates/csc/courses.html @@ -0,0 +1,216 @@ +{% extends 'csc_base.html'%} +{% load crispy_forms_tags%} +{% load helper %} +{% block css %} + +{% endblock css %} + +{% block content %} +
+
+ +
+
+
+
+
+ + +
Search by course code, title or foss
+ +
+ +
+ +
+
+
+ + {% for key,value in courses.items %} +
+
+
+ {{key.code}} +
+
+
{{key.title}}
+
+ {% for foss in value %} +

{{foss}}

+ {% endfor %} +
+ +
+
+ {% comment %}

Enrolled : {{key.count}}

{% endcomment %} +
+
+
+ {% empty %} +
+

No results found.

+
+ {% endfor%} +
+
+
+ {% if request.user|has_group:"VLE" %} + + + + + + + + + + + + + + {% for key,value in individual_foss.items %} + + + + + + + + {% endfor %} + +
# Course Current Enrollment Certificates IssuedTotal Enrollment
+ + {{key}}{{value.total_students}}{{value.total_students}}
+ {% endif %} + {% if request.user|has_group:"STUENT" %} + + + + + + + + + {% for key,value in individual_foss.items %} + + + + {% endfor %} + +
# Course
+ +
+ {% endif %} +
+ {% comment %}
...
{% endcomment %} +
+
+ + + {% comment %}
+ + +
{% endcomment %} +
+ +{% endblock %} + +{% block script %} + + + + +{% endblock %} diff --git a/csc/templates/csc/create_invigilator.html b/csc/templates/csc/create_invigilator.html new file mode 100644 index 0000000..9229d73 --- /dev/null +++ b/csc/templates/csc/create_invigilator.html @@ -0,0 +1,62 @@ +{% extends 'csc_base.html'%} +{% load static %} +{% load crispy_forms_tags %} +{% block css %} + + +{% endblock css %} + +{% block content %} +
+
+

Add Invigilator

+
+ {% if messages %} +
    + {% for message in messages %} +
  • + +
  • + {% endfor %} +
+ {% endif %} +
+ {% csrf_token %} + {{form|crispy}} + +
+
+
+ + +{% endblock %} + +{% block script %} + + + + + +{% endblock %} + diff --git a/csc/templates/csc/csc_base.html b/csc/templates/csc/csc_base.html new file mode 100644 index 0000000..54928b9 --- /dev/null +++ b/csc/templates/csc/csc_base.html @@ -0,0 +1,145 @@ +{% load static %} +{% load helper %} +{% load crispy_forms_tags %} + + + + + + + + + + + {% block title%}CSC Academy{% endblock title%} + + + {% block css %}{% endblock css %} + + + + +
+ +
+ {% if user.is_authenticated %} + + {% include "sidebar.html" %} +
+ {% block content %} +
+ Problem in accessing index. +
+ {% endblock content %} +
+ + {% else %} +
+ {% block content_1 %} +
+ Problem in accessing index. +
+ {% endblock content_1 %} +
+ {% endif %} + + + +
+
+ + + + + + + {% block script %}{% endblock script %} + + + + + + \ No newline at end of file diff --git a/csc/templates/csc/invigilator 2.html b/csc/templates/csc/invigilator 2.html new file mode 100644 index 0000000..5549d90 --- /dev/null +++ b/csc/templates/csc/invigilator 2.html @@ -0,0 +1,163 @@ +{% extends 'csc_base.html'%} +{% load static %} +{% load crispy_forms_tags %} +{% block css %} + + +{% endblock css %} + +{% block content %} +
+ {% if messages %} +
    + {% for message in messages %} +
  • + +
  • + {% endfor %} +
+ {% endif %} + + +
+{% endblock %} + +{% block script %} + + + + + +{% endblock %} + diff --git a/csc/templates/csc/invigilator.html b/csc/templates/csc/invigilator.html new file mode 100644 index 0000000..7eb7808 --- /dev/null +++ b/csc/templates/csc/invigilator.html @@ -0,0 +1,128 @@ +{% extends 'csc_base.html'%} +{% load static %} +{% load crispy_forms_tags %} +{% block css %} + + +{% endblock css %} + +{% block content %} +
+ + +
+{% endblock %} + +{% block script %} + + + + + +{% endblock %} + diff --git a/csc/templates/csc/invigilator_confirm_delete.html b/csc/templates/csc/invigilator_confirm_delete.html new file mode 100644 index 0000000..086771c --- /dev/null +++ b/csc/templates/csc/invigilator_confirm_delete.html @@ -0,0 +1,12 @@ +
{% csrf_token %} + + + + +

Are you sure you want to delete "{{ object }}"?

+ + + + + +
\ No newline at end of file diff --git a/csc/templates/csc/invigilator_dashboard.html b/csc/templates/csc/invigilator_dashboard.html new file mode 100644 index 0000000..b1163e8 --- /dev/null +++ b/csc/templates/csc/invigilator_dashboard.html @@ -0,0 +1,142 @@ +{% extends 'csc_base.html' %} +{% load csc_tags %} +{% block css %} + + +{% endblock css %} + +{% block content %} +
+
+
+
Test Invigilation Requests
+ + +
+ +
+
+{% endblock %} + +{% block script %} + + + + +{% endblock %} diff --git a/csc/templates/csc/invigilators.html b/csc/templates/csc/invigilators.html new file mode 100644 index 0000000..12869fc --- /dev/null +++ b/csc/templates/csc/invigilators.html @@ -0,0 +1,284 @@ +{% extends 'csc_base.html'%} +{% load static %} +{% load crispy_forms_tags %} +{% block css %} + + +{% endblock css %} + +{% block content %} +
+
+ {{ form.non_field_errors }} + {% include "_error_msg.html" %} + +
+ +
+ + + +
+
+{% endblock %} + +{% block script %} + + + + + + + +{% endblock %} + diff --git a/csc/templates/csc/list_invigilators.html b/csc/templates/csc/list_invigilators.html new file mode 100644 index 0000000..def45b9 --- /dev/null +++ b/csc/templates/csc/list_invigilators.html @@ -0,0 +1,86 @@ +{% extends 'csc_base.html'%} +{% load static %} +{% load crispy_forms_tags %} +{% block css %} + + +{% endblock css %} + +{% block content %} +
+
+

Invigilators

+
+ {% if messages %} +
    + {% for message in messages %} +
  • + +
  • + {% endfor %} +
+ {% endif %} +
+ + + + + + + + + + + + + {% for item in invigilators %} + + + + + + + + + {% endfor %} + +
#NameEmailPhoneEdit
{{forloop.counter}}{{item.user.get_full_name}}{{item.user.email}}{{item.phone}}
+
+ +
+
+ + +{% endblock %} + +{% block script %} + + + + + +{% endblock %} + diff --git a/csc/templates/csc/login.html b/csc/templates/csc/login.html index 08e44a9..8739227 100644 --- a/csc/templates/csc/login.html +++ b/csc/templates/csc/login.html @@ -1,6 +1,89 @@ -

Log In

-
- {% csrf_token %} - {{ form.as_p }} - -
\ No newline at end of file +{% extends 'csc_base.html'%} +{% block css %} + +{% endblock %} +{% block content_1 %} +
+
+
+ + {% if messages %} +
    + {% for message in messages %} +
  • + +
  • + {% endfor %} +
+ {% endif %} +
+
+ + {% if form.non_field_errors %} +
    + {% for message in form.non_field_errors %} +
  • + +
  • + {% endfor %} +
+ {% endif %} +
+
+ {% csrf_token %} + +

CSC Login

+ +
+ + {{form.username.errors}} + + +
+
+ + + {{form.password.errors}} + + +
+ + + + +
+ + +
+ +
+{% endblock %} diff --git a/csc/templates/csc/mark_attendance.html b/csc/templates/csc/mark_attendance.html new file mode 100644 index 0000000..593a158 --- /dev/null +++ b/csc/templates/csc/mark_attendance.html @@ -0,0 +1,202 @@ +{% extends 'csc_base.html'%} +{% load csc_tags %} +{% block css %} + + +{% endblock css %} + +{% block content %} +
+
+
+
+ +
+
+
+ {{test.foss.foss | title }} + +
+
+ +
+

: {{test.tdate}}

+

: : {{test.ttime}}

+

Foss : {{test.foss.foss}}

+ +
+ +
+ + + + +
+
+

+

+

+ +
+
+
+
+
+ {% csrf_token %} + + + + + + + + + + + + + + {% for student,status in students %} + + + + + + + + + + + + {% endfor %} + + + +
#Nameemailcontact
{{forloop.counter}} + {{student.user.get_full_name | title}}{{student.user.email}}{{student.phone}} +
+ + + + + {% comment %} {% if item.test_status %} + + {% else %} + + {% endif %} {% endcomment %} +
+
+
+
+
+ +
+
+ {% if is_paginated %} + {% include "_pagination.html" %} + {% endif %} +
+ + +
+ +{% endblock %} + +{% block script %} + + + + + + + +{% endblock %} + + + diff --git a/csc/templates/csc/sidebar.html b/csc/templates/csc/sidebar.html new file mode 100644 index 0000000..fee61b3 --- /dev/null +++ b/csc/templates/csc/sidebar.html @@ -0,0 +1,147 @@ +{% load static %} +{% load helper %} + \ No newline at end of file diff --git a/csc/templates/csc/student_courses.html b/csc/templates/csc/student_courses.html new file mode 100644 index 0000000..d7e0237 --- /dev/null +++ b/csc/templates/csc/student_courses.html @@ -0,0 +1,191 @@ +{% extends 'csc_base.html'%} +{% load crispy_forms_tags%} +{% load helper %} +{% block css %} + +{% endblock css %} + +{% block content %} +
+
+ +
+
+
+
+
+ + +
Search by course code, title or foss
+ +
+ +
+ +
+
+
+ + {% for key,value in courses.items %} +
+
+
+ {{key.code}} +
+
+
{{key.title}}
+
+ {% for foss in value %} +

{{foss}}

+ {% endfor %} +
+ +
+
+ {% comment %}

Enrolled : {{key.count}}

{% endcomment %} +
+
+
+ {% empty %} +
+

No results found.

+
+ {% endfor%} +
+
+
+ + + + + + + + + + {% for foss in fosses %} + + + + + {% endfor %} + +
# Course
{{forloop.counter}}{{foss}}
+ + +
+ {% comment %}
...
{% endcomment %} +
+
+ + + {% comment %}
+ + +
{% endcomment %} +
+ +{% endblock %} + +{% block script %} + + + + +{% endblock %} diff --git a/csc/templates/csc/student_dashboard.html b/csc/templates/csc/student_dashboard.html new file mode 100644 index 0000000..c5cc810 --- /dev/null +++ b/csc/templates/csc/student_dashboard.html @@ -0,0 +1,411 @@ +{% extends "csc_base.html" %} +{% load static %} +{% load crispy_forms_tags%} +{% load csc_tags %} +{% block title%} CSC - VLE Dashboard {% endblock title%} +{% block css %} + + + + +{% endblock %} + + +{% block content%} + + +
+
+
+
{{ user.first_name | title }} {{ user.last_name | title }}
+ +
+
+
+
+
+ + CSC ID: {{ vle.csc.csc_id }} +
+
+ +
+
+ + {{ user.email }} +
+
+ +
+
+ + {{ student.id }} +
+
+ + {% comment %}
+ + + {{user.student.address | title}}, {{ user.student.city }}, {{ user.student.state }}
+ +
{% endcomment %} + +
+
+ +
+
+ + +
+ {% comment %}
+ +
+
+
+
+
+
+ Total students enrolled
+
{{total_students_enrolled}}
+
+
+ + +
+
+
+
+
+ {% endcomment %} + + + + + + + +
+
+
+
+ Courses +
+
+
+ {% for key,val in courses.items %} +
+
+

{{key.code}} : {{key.title}}

+
+ {% comment %}
Special title treatment
{% endcomment %} + + {% for item in val %} + + + + + + {% endfor %} +
+ {{item}} + + + {% with fossmdlcourse=item.id|get_csc_mdlcourseid %} + + + {% for course in fossmdlcourse %} + + + + {% with attendance=student.id|check_attendance:course.testfoss_id %} + + + {% if attendance.status == 1%} + + + + {% elif attendance.status >= 3%} + + {% with pass_entry=student.id|check_passgrade_exists:course.testfoss_id%} + + {% endwith %} + + {% endif %} + {% endwith %} + + + {% endfor %} + {% endwith %} + +
+
+
+
+ {% endfor %} + + {% comment %} {% for key,value in upcoming_test_stats.items %} +
+
+
+

{{key}}

+

{{value.date}} / {{value.time}}

+

Approved : {{value.approved}}

+

Rejected : {{value.rejected}}

+
+ +
+
+ {% endfor %} {% endcomment %} +
+
+
+
+
+
+
+ Individual FOSS +
+
+
+ {% for key in fosses %} +
+
+ + {{key}} + + {% with fossmdlcourse=key.id|get_csc_mdlcourseid %} + + + {% for course in fossmdlcourse %} + + + + {% with attendance=student.id|check_attendance:course.testfoss_id %} + + + {% if attendance.status == 1%} + + + + {% elif attendance.status >= 3%} + + {% with pass_entry=student.id|check_passgrade_exists:course.testfoss_id%} + + {% endwith %} + + {% endif %} + {% endwith %} + + + {% endfor %} + {% endwith %} + + +
+
+ {% endfor %} +
+
+
+
+ {% comment %}
+
+
+ Upcoming Tests +
+
+
+ {% for key,value in upcoming_test_stats.items %} +
+
+
+

{{key}}

+

{{value.date}} / {{value.time}}

+

Approved : {{value.approved}}

+

Rejected : {{value.rejected}}

+
+ +
+
+ {% endfor %} +
+
+
+
{% endcomment %} + +
+ +
+ +
+
+ +
+{% endblock %} + + + + + + + + +{% block script %} + + + +{% endblock %} diff --git a/csc/templates/csc/student_mail_template.html b/csc/templates/csc/student_mail_template.html new file mode 100644 index 0000000..e19d71d --- /dev/null +++ b/csc/templates/csc/student_mail_template.html @@ -0,0 +1,21 @@ + + + + + Order received + + + +

Dear {{full_name}},

+

Thank you for registering under Spoken Tutorial(IIT Bombay) courses.

+

Below are the login details for Spoken Tutorial Dashboard.

+

Link to Login: https://spoken-tutorial.in/login/

+ +

username : {{username}}

+

password : {{password}}

+ +

Thanks & Regards,

+

Team,

+

Spoken Tutorial

+ + \ No newline at end of file diff --git a/csc/templates/csc/student_profile.html b/csc/templates/csc/student_profile.html new file mode 100644 index 0000000..66dd44e --- /dev/null +++ b/csc/templates/csc/student_profile.html @@ -0,0 +1,146 @@ +{% extends 'csc_base.html'%} +{% load static %} +{% load crispy_forms_tags %} +{% block css %} + + +{% endblock css %} + +{% block content %} +
+
+ {{ form.non_field_errors }} + {% if messages %} +
    + {% for message in messages %} +
  • + +
  • + {% endfor %} +
+ {% endif %} +
+ +
+
+ + +
+
+
Student Profile
+
+
+
+ {% csrf_token %} + +
+ {{ form.fname|as_crispy_field }} +
+ +
+ {{ form.lname|as_crispy_field }} +
+ +
+ {{ form.dob|as_crispy_field }} +
+ +
+ {{ form.phone|as_crispy_field }} +
+ +
+ {{ form.edu_qualification|as_crispy_field }} +
+ +
+ {{ form.state|as_crispy_field }} +
+ +
+ {{ form.district|as_crispy_field }} +
+ +
+ {{ form.city|as_crispy_field }} +
+ +
+ {{ form.pincode|as_crispy_field }} +
+ +
+ {{ form.gender|as_crispy_field }} +
+ +
+ {{ form.pincode|as_crispy_field }} +
+ +
+ {{ form.address|as_crispy_field }} +
+ {% comment %} {% endcomment %} +
+
+
+
+ + + + + +
+ +
+
+ + + + +
+
+ {% for key, val in courses.items %} +
+
+
+ {{key}} +
+
+
    + {% for i in val %} +
  1. {{i}}
  2. + {% endfor %} +
+
+
+ {% endfor %} +
+
+
+ + +
+
+{% endblock %} + +{% block script %} + + + + +{% endblock %} + diff --git a/csc/templates/csc/student_stats.html b/csc/templates/csc/student_stats.html new file mode 100644 index 0000000..4736653 --- /dev/null +++ b/csc/templates/csc/student_stats.html @@ -0,0 +1 @@ +{{object_list}} \ No newline at end of file diff --git a/csc/templates/csc/student_tests.html b/csc/templates/csc/student_tests.html new file mode 100644 index 0000000..dcfbf27 --- /dev/null +++ b/csc/templates/csc/student_tests.html @@ -0,0 +1,205 @@ +{% extends 'csc_base.html'%} +{% load static %} +{% load crispy_forms_tags %} +{% block css %} + + +{% endblock css %} + +{% block content %} +
+
+ + +
+
+ + + + + + +
+
+ + +{% endblock %} + +{% block script %} + + + + +{% endblock %} + diff --git a/csc/templates/csc/students_list.html b/csc/templates/csc/students_list.html new file mode 100644 index 0000000..2366111 --- /dev/null +++ b/csc/templates/csc/students_list.html @@ -0,0 +1,223 @@ +{% extends 'csc_base.html'%} +{% block css %} + + +{% endblock css %} + +{% block content %} +
+
+
+
+
+
+ + +
+ +
+ + +
+
+ + +
Search by student name or email
+
+ {% comment %}
+ + +
{% endcomment %} + +
+ +
+ +
+
+
+ {% if is_indi %} + + {% endif %} + +
+
+

* Click on student name below to view student details.

+
+

Search results for : {{search_foss}}, {{search_course}}, {{search_name}}

+
+
+
+ +
+ + + + + + + + + + + + + {% for student in students %} + + + + + + + + {% endfor %} + +
# Name Email Contact Registration Date
+ + + {{student.user.first_name | title}} {{student.user.last_name | title}} + {{student.user.email}} {{student.phone}}{{student.date_of_registration}}
+
+ +
+
+
+
+ + +
+
+
+ +
+ + +
+
+
    +
  • Individual FOSS
  • + {% for foss in foss_individual %} +
  • +
    + + {{foss.foss}} +
    +
  • + {% endfor %} +
+ +
+ + +
+
+
+ +{% endblock %} + +{% block script %} + + + + + +{% comment %} {% endcomment %} + + + + + + + + +{% endblock %} diff --git a/csc/templates/csc/temp.html b/csc/templates/csc/temp.html new file mode 100644 index 0000000..5557e30 --- /dev/null +++ b/csc/templates/csc/temp.html @@ -0,0 +1,128 @@ +{% extends 'csc_base.html'%} +{% load csc_tags %} +{% block css %} + + + +{% endblock css %} + +{% block content %} +
+

Section coming soon !

+
+{% endblock %} + +{% block script %} + + + + + + + +{% endblock %} + + + + diff --git a/csc/templates/csc/test 2.html b/csc/templates/csc/test 2.html new file mode 100644 index 0000000..78a4021 --- /dev/null +++ b/csc/templates/csc/test 2.html @@ -0,0 +1,56 @@ +{% extends 'csc_base.html'%} +{% load static %} +{% load crispy_forms_tags %} +{% block css %} + + +{% endblock css %} + +{% block content %} +
+
+
+
+ {% if messages %} +
    + {% for message in messages %} +
  • + +
  • + {% endfor %} +
+ {% endif %} +

Create Test

+
+
+
+ {% csrf_token %} + {{form | crispy}} + +
+ +
+
+
+
+
+ +{% endblock %} + +{% block script %} + + + + +{% endblock %} + + + + diff --git a/csc/templates/csc/test.html b/csc/templates/csc/test.html new file mode 100644 index 0000000..590ec31 --- /dev/null +++ b/csc/templates/csc/test.html @@ -0,0 +1,54 @@ +{% extends 'csc_base.html'%} +{% load static %} +{% load crispy_forms_tags %} +{% block css %} + + +{% endblock css %} + +{% block content %} +
+
+
+ {% if messages %} +
    + {% for message in messages %} +
  • + +
  • + {% endfor %} +
+ {% endif %} +
+
+
+ {% csrf_token %} + {{form | crispy}} + +
+ +
+
+
+
+
+ +{% endblock %} + +{% block script %} + + + + +{% endblock %} + + + + diff --git a/csc/templates/csc/test_assign 2.html b/csc/templates/csc/test_assign 2.html new file mode 100644 index 0000000..0599f86 --- /dev/null +++ b/csc/templates/csc/test_assign 2.html @@ -0,0 +1,124 @@ +{% extends 'csc_base.html'%} +{% load static %} +{% load crispy_forms_tags %} +{% block css %} + + + +{% endblock css %} + +{% block content %} +
+ +
+ +
+
+ {% if messages %} +
    + {% for message in messages %} +
  • + +
  • + {% endfor %} +
+ {% endif %} +

Assign students to test :

+
+
+ {% csrf_token %} + {{test.id}} + +
+ {% if students %} +
+ + + + + + + + + + + {% for student in students %} + + + + + + {% endfor %} + +
#NameEmail
+
+ + +
+
{{student.user.get_full_name|title}}{{student.user.email}}
+ +
+ + {% endif %} +
+
+
+ +
+ +
+
+ +
+ +{% endblock %} + +{% block script %} + + + + + + + + + + + + + + + + +{% endblock %} + + + + diff --git a/csc/templates/csc/test_assign.html b/csc/templates/csc/test_assign.html new file mode 100644 index 0000000..d0226bc --- /dev/null +++ b/csc/templates/csc/test_assign.html @@ -0,0 +1,121 @@ +{% extends 'csc_base.html'%} +{% load static %} +{% load crispy_forms_tags %} +{% block css %} + + + +{% endblock css %} + +{% block content %} +
+ +
+ +
+
+ {% if messages %} +
    + {% for message in messages %} +
  • + +
  • + {% endfor %} +
+ {% endif %} +

Assign students to test :

+ +
+ {% csrf_token %} + {{test}} {{item.id}} + + +
+
+ + + + + + + + + + {% for student in students %} + + + + + + {% endfor %} + +
#NameEmail
+
+ + +
+
{{student.user.get_full_name|title}}{{student.user.email}}
+
+ +
+
+
+ +
+ +
+
+ +
+ +{% endblock %} + +{% block script %} + + + + + + + + + + + + + + + + +{% endblock %} + + + + diff --git a/csc/templates/csc/test_confirm_delete.html b/csc/templates/csc/test_confirm_delete.html new file mode 100644 index 0000000..07fbca2 --- /dev/null +++ b/csc/templates/csc/test_confirm_delete.html @@ -0,0 +1,76 @@ +{% extends 'csc_base.html'%} +{% load static %} +{% load crispy_forms_tags %} +{% block css %} + + +{% endblock css %} + +{% block content %} +
+
+ {{ form.non_field_errors }} + {% if messages %} +
    + {% for message in messages %} +
  • + +
  • + {% endfor %} +
+ {% endif %} +
+
+
+
+
+ Confirm delete ? +
+
+
{% csrf_token %} +

Are you sure you want to delete {% if test.foss %} + {{test.foss | title}} + {% else %}{{test.foss | title}} Test + {% endif %}, scheduled on {{test.tdate}}, {{test.ttime}}? + +

+ + {{ form }} + +
+ +
+
+
+
+ +
+
+{% endblock %} + +{% block script %} + + + + +{% endblock %} + diff --git a/csc/templates/csc/test_detail.html b/csc/templates/csc/test_detail.html new file mode 100644 index 0000000..d714972 --- /dev/null +++ b/csc/templates/csc/test_detail.html @@ -0,0 +1,88 @@ +{% extends 'csc_base.html'%} +{% block css %} + + +{% endblock css %} + +{% block content %} +
+ +
+ +
+
+
+ {% if messages %} +
    + {% for message in messages %} +
  • + +
  • + {% endfor %} +
+ {% endif %} +
+
+
+ {{test.foss | title}} Test +
+
+ + + + + + + + + + + + + + + + +
FOSS{{test.foss | title }}
Date{{test.tdate}}, {{test.ttime}}
Published{% if test.publish %}{% else %}{% endif %}
+
+
+
+ +
+
+ +
+ +{% endblock %} + +{% block script %} + + + + + + + + + + +{% endblock %} + + + + diff --git a/csc/templates/csc/test_form.html b/csc/templates/csc/test_form.html new file mode 100644 index 0000000..28ef6db --- /dev/null +++ b/csc/templates/csc/test_form.html @@ -0,0 +1,79 @@ +{% extends 'csc_base.html'%} +{% load crispy_forms_tags %} +{% block css %} + + +{% endblock css %} + +{% block content %} + +
+
+
+
+
+ Add Test +
+
+
{% csrf_token %} + {{ form | crispy }} + + +
+
+
+ +
+
+
+
+ Add Invigilator +
+
+
{% csrf_token %} + + + +
+
+
+
+
+
+ +{% endblock %} + +{% block script %} + + + + + + + + + + +{% endblock %} diff --git a/csc/templates/csc/test_list 2.html b/csc/templates/csc/test_list 2.html new file mode 100644 index 0000000..efbb78d --- /dev/null +++ b/csc/templates/csc/test_list 2.html @@ -0,0 +1,96 @@ +{% extends 'csc_base.html'%} +{% load static %} +{% load csc_tags %} +{% block css %} + + + + +{% endblock css %} + +{% block content %} +
+
+
+ + + + + + + + + + + + + + + + {% for test in tests %} + + + + + + + + + + + {% endfor %} + +
TestFOSSDateTimePublishedDeleteEditMark attendance
+ {% if test.test_name %} + {{test.test_name | title}} + {% else %} + {{test.foss | title}} Test + {% endif %} + {{test.foss | title }}{{test.tdate}}{{test.ttime}} + {% if test.publish %} + + {% else %} + + {% endif %} + {% if test.tdate|is_today %} + + + + attendance + {% else %} + NA + {% endif %} +
+
+ +
+
+ +
+ + +
+ +{% endblock %} + +{% block script %} + + +{% comment %} {% endcomment %} + + + + +{% endblock %} + + + + diff --git a/csc/templates/csc/test_list.html b/csc/templates/csc/test_list.html new file mode 100644 index 0000000..fa78ca1 --- /dev/null +++ b/csc/templates/csc/test_list.html @@ -0,0 +1,97 @@ +{% extends 'csc_base.html'%} +{% load static %} +{% load csc_tags %} +{% block css %} + + + + +{% endblock css %} + +{% block content %} +
+
+
+ + + + + + + + + + + + + + + + + {% for test in tests %} + + + + + + + + + + + + {% endfor %} + +
#TitleFOSSDateTimePublishedDeleteEdit
{{forloop.counter}} + {% if test.test_name %} + {{test.test_name | title}} + {% else %} + {{test.foss | title}} Test + {% endif %} + {{test.foss | title }}{{test.tdate}}{{test.ttime}} + {% if test.publish %} + + {% else %} + + {% endif %} + {% if test.tdate|is_today %} + + + + attendance + + {% endif %} +
+
+ +
+
+ +
+ + +
+ +{% endblock %} + +{% block script %} + + + + + + + +{% endblock %} + + + + diff --git a/csc/templates/csc/test_update_form.html b/csc/templates/csc/test_update_form.html new file mode 100644 index 0000000..eb380be --- /dev/null +++ b/csc/templates/csc/test_update_form.html @@ -0,0 +1,124 @@ +{% extends 'csc_base.html'%} +{% load crispy_forms_tags %} +{% block css %} + + +{% endblock css %} + +{% block content %} + +
+
+ +
+
+
+
+
+
+ Edit Test +
+
+
{% csrf_token %} + {{ form | crispy }} + +
+
+
+ +
+ +
+
+
+ Edit Invigilators +
+
+
{% csrf_token %} + {{ invigilationRequestForm | crispy}} + + +
+
+
+
+
+
+
+
+ + + + + + + + + + + + + {% for student in students %} + + + + + + + {% endfor %} + + + +
#NameEmailContact
{{forloop.counter}}{{student.user.get_full_name | title}}{{student.user.email}}{{student.phone}}
+
+
+
...
+
+ +
+
+ +{% endblock %} + +{% block script %} + + + + + + + + + + +{% endblock %} diff --git a/csc/templates/csc/update_invigilator.html b/csc/templates/csc/update_invigilator.html new file mode 100644 index 0000000..99a3cb2 --- /dev/null +++ b/csc/templates/csc/update_invigilator.html @@ -0,0 +1,62 @@ +{% extends 'csc_base.html'%} +{% load static %} +{% load crispy_forms_tags %} +{% block css %} + + +{% endblock css %} + +{% block content %} +
+
+

Update Invigilator

+
+ {% if messages %} +
    + {% for message in messages %} +
  • + +
  • + {% endfor %} +
+ {% endif %} +
+ {% csrf_token %} + {{form|crispy}} + +
+
+
+ + +{% endblock %} + +{% block script %} + + + + + +{% endblock %} + diff --git a/csc/templates/csc/update_test 2.html b/csc/templates/csc/update_test 2.html new file mode 100644 index 0000000..aca7c60 --- /dev/null +++ b/csc/templates/csc/update_test 2.html @@ -0,0 +1,42 @@ +{% extends 'csc_base.html'%} +{% load static %} +{% load csc_tags %} +{% load crispy_forms_tags %} +{% block css %} + + +{% endblock css %} + +{% block content %} +
+
+
+ {% csrf_token %} + {{form | crispy}} + +
+
+ + +
+
+ + +
+ +{% endblock %} + +{% block script %} + + +{% endblock %} + + + + diff --git a/csc/templates/csc/update_test.html b/csc/templates/csc/update_test.html new file mode 100644 index 0000000..a7e8cb9 --- /dev/null +++ b/csc/templates/csc/update_test.html @@ -0,0 +1,53 @@ +{% extends 'csc_base.html'%} +{% load static %} +{% load csc_tags %} +{% load crispy_forms_tags %} +{% block css %} + + +{% endblock css %} + +{% block content %} +
+
+ {% if messages %} +
    + {% for message in messages %} +
  • + +
  • + {% endfor %} +
+ {% endif %} +
+ {% csrf_token %} + {{form | crispy}} + +
+
+ + +
+ + + + + +{% endblock %} + +{% block script %} + + +{% endblock %} + + + + diff --git a/csc/templates/csc/vle.html b/csc/templates/csc/vle.html index 1632736..edf4ed4 100644 --- a/csc/templates/csc/vle.html +++ b/csc/templates/csc/vle.html @@ -1 +1,330 @@ -vle dashboard \ No newline at end of file +{% extends "csc_base.html" %} +{% load static %} +{% load crispy_forms_tags%} +{% block title%} CSC - VLE Dashboard {% endblock title%} +{% block css %} + + + + +{% endblock %} + + +{% block content%} + + +
+
+
+
{{ user.first_name | title }} {{ user.last_name | title }}
+ +
+
+
+
+
+ + CSC ID: {{ vle.csc.csc_id }} +
+
+ +
+
+ + {{ user.email }} +
+
+ +
+
+ + {{ vle.phone }} +
+
+ +
+ + + {{vle.csc.address | title}}, {{vle.csc.block}}, {{ vle.csc.city }}, {{ vle.csc.state }}
+ +
+
+ Plan: + {{ vle.csc.plan }} +
+ +
+
+ + +
+
+ +
+
+ + +
+
+
+
+
+
+ Total students enrolled
+
{{total_students_enrolled}}
+
+
+ + +
+
+
+
+
+ + +
+
+
+
+
+
+ Total tests - completed
+
{{total_tests_completed}}
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+ Total tests - upcoming
+
{{total_upcoming_tests}}
+
+
+ +
+
+
+
+
+ + + {% comment %}
+
+
+
+
+
Total certificates +
+
+
+
{{total_certificates_issued}}
+
+ +
+
+
+ + +
+
+
+
+
{% endcomment %} + + +
+ {% if upcoming_test_stats %} +
+
+
+ Upcoming Tests +
+
+
+ {% for key,value in upcoming_test_stats.items %} +
+
+
+

{{key}}

+

{{value.date}} / {{value.time}}

+

Total Students : {{value.total_students}}

+
+
+
+ {% endfor %} +
+
+
+
+ {% endif %} + +
+ {% comment %}
+
+

Enrollment based on Course Type

+
+
DCA({{courses_offered_stats.dca}})
+
Individual({{courses_offered_stats.individual}})
+
+ + +
+
+
+ +
+ + + +
+
{% endcomment %} + + + {% comment %}
+
+

Enrollment for DCA Courses

+ +
+
+
+
+

Enrollment for Individual Courses

+ +
+
+
+
{% endcomment %} + +
+
+ {% for key,value in fosses_perc.items %} +
+
+

{{ key }}

+
+
+
+
+
+ {% endfor %} +
+
+
+ +
+{% endblock %} + +{% block script %} + + + +{% endblock %} diff --git a/csc/templates/csc/vle_mail_template.html b/csc/templates/csc/vle_mail_template.html new file mode 100644 index 0000000..f19093c --- /dev/null +++ b/csc/templates/csc/vle_mail_template.html @@ -0,0 +1,28 @@ + + + + + Order received + + + +

Dear {{full_name}},

+

Welcome to IIT Bombay Spoken Tutorial Program. We are happy to be partnered with CSC Academy to + empower youth from all over the country via VLEs.

+

Please use the below Login details for the Spoken Tutorial Dashboard:

+

Link to Login: https://spoken-tutorial.in/login/

+ +

username : {{username}}

+

password : {{password}}

+ +

Please click the following training link to know the process of

+

Student Registration Instructions : Click Here

+

Course Allotment Instructions : Click Here

+ +

In case of any query, please feel free to contact at animation-hackathon@cscacademy.org.

+ +

Thanks & Regards,

+

Team,

+

Spoken Tutorial

+ + \ No newline at end of file diff --git a/csc/templates/stats/stats.html b/csc/templates/stats/stats.html new file mode 100644 index 0000000..80db1cb --- /dev/null +++ b/csc/templates/stats/stats.html @@ -0,0 +1,310 @@ + +{% extends "stats/stats_base.html" %} +{% load static %} + +{% block custom_style %} + +{% endblock %} + {% block content %} +
+
+
+

Total VLE Registered

+

{{total_vles}}

+
+
+
+
+

Total Students Registered

+

{{total_students}}

+
+ +
+
+
+

Total FOSS

+

{{total_foss}}

+
+ +
+
+
+

Total Certificate Courses

+

{{total_certificate_course}}

+
+
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+ + + + +
+
+
+
+

+ +

+
+
+ + + + + + + + + + {% for item in foss_count_tb %} + + + + + + {% endfor %} + +
#FOSSStudent Count
{{forloop.counter}}{{item.csc_foss__foss}}{{item.count}}
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ + +
+
+
+
+

+ +

+
+
+ + + + + + + + + + {% for item in student_indi_foss %} + + + + + + {% endfor %} + +
#FOSSStudent Count
{{forloop.counter}}{{item.csc_foss__foss}}{{item.count}}
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ + +
+
+ +
+
+
+
+
+

+ +

+
+
+ + + + + + + + + + {% for item in csc_state %} + + + + + + + {% endfor %} + + + +
#StateCSC Count
{{forloop.counter}}{{item.state}}{{item.count}}
+
+
+
+ + +
+
+
+
+ + + + + + + + + {% endblock content %} + + {% block js_script %} + + + {% endblock js_script %} + diff --git a/csc/templates/stats/stats_base.html b/csc/templates/stats/stats_base.html new file mode 100644 index 0000000..357ccb4 --- /dev/null +++ b/csc/templates/stats/stats_base.html @@ -0,0 +1,174 @@ +{% load static %} + + + + + + + + + CSC Stats + + + + + + + + + + + {% block custom_style %} + {% endblock custom_style %} + + + + + +
+
+ + +
+ {% block content %} + + {% endblock content %} + + + + + + +
+
+
+ + + + + + + + + + + + {% block js_script %} + {% endblock js_script %} + + diff --git a/csc/templates/stats/student_report.html b/csc/templates/stats/student_report.html new file mode 100644 index 0000000..825d92d --- /dev/null +++ b/csc/templates/stats/student_report.html @@ -0,0 +1,250 @@ +{% extends "stats/stats_base.html" %} +{% load static %} +{% block custom_style %} + + +{% endblock custom_style %} +{% block content %} +
+
+ +
+
+
+ +
+ + + + + + + + + + {% for item in student_foss %} + + + + + + {% endfor %} + +
#FOSSStudent Count
{{forloop.counter}}{{item.csc_foss__foss}}{{item.count}}
+
+
+ + + + + + + + + + {% for item in student_occupation %} + + + + + + {% endfor %} + +
#OccupationStudent Count
{{forloop.counter}}{% if item.occupation %} + {{item.occupation}} + {% else %} Unknown + {% endif %}{{item.count}}
+
+
+ + + + + + + + + + {% for item in edu %} + + + + + + {% endfor %} + +
#EducationStudent Count
{{forloop.counter}}{% if item.edu_qualification %} + {{item.edu_qualification}} + {% else %} Unknown + {% endif %}{{item.count}}
+
+
+ + + + + + + + + + {% for item in student_category %} + + + + + + + {% endfor %} + +
#CategoryStudent Count
{{forloop.counter}}{% if item.category %} + {{item.category}} + {% else %} Unknown + {% endif %}{{item.count}}
+
+
+ + + + + + + + + + {% for item in student_state %} + + + + + + {% endfor %} + +
#StateStudent Count
{{forloop.counter}}{{item.state__name}}{{item.count}}
+
+
+ + + + + + + + + + {% for item in student_district %} + + + + + + {% endfor %} + +
#DistrictStudent Count
{{forloop.counter}}{{item.district__name}}{{item.count}}
+
+
+
+
+ + +
+
+{% endblock content %} + + + +{% block js_script %} + + + +{% endblock js_script %} + diff --git a/csc/templates/stats/student_stats.html b/csc/templates/stats/student_stats.html new file mode 100644 index 0000000..45145c5 --- /dev/null +++ b/csc/templates/stats/student_stats.html @@ -0,0 +1,167 @@ + +{% extends "stats/stats_base.html" %} +{% load static %} +{% block custom_style %} + +{% endblock custom_style %} +{% block content %} +
+
Search Student
+
+ +
+
+
+
+ + + {% comment %}
We'll never share your email with anyone else.
{% endcomment %} +
+
+
+
+ + +
+
+
+
+ + +
+ +
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+ + +
+
+
+
+
+ {% if query_str.name or query_str.vle_name or query_str.csc or query_str.edu or query_str.state or query_str.district or query_str.occupation %} + + + {% endif %} +
+ + + + + + + + + + + + + + + + + + + {% for student in object_list %} + + + + + + + + + + + + + + {% endfor %} + + + +
IDNameEmailGenderEducational QualificationVLEStateDistrictDate of RegistrationOccupationCategory
{{forloop.counter}}{{student.user.get_full_name | title}}{{student.user.email}}{{student.gender}}{{student.edu_qualification}} + {% for vle in student.vle_id.all %} + {{vle.user.email}} + {% endfor %} + {{student.state}}{{student.district}}{{student.date_of_registration}}{{student.occupation}}{{student.category}}
+ +{% endblock content %} + diff --git a/csc/templates/stats/vle_report.html b/csc/templates/stats/vle_report.html new file mode 100644 index 0000000..7b6035f --- /dev/null +++ b/csc/templates/stats/vle_report.html @@ -0,0 +1,126 @@ +{% extends "stats/stats_base.html" %} +{% load static %} +{% block custom_style %} + + +{% endblock custom_style %} +{% block content %} +
+
+ +
+
+
+
+ + + + + + + + + + {% for item in csc_state %} + + + + + + {% endfor %} + +
#StateVLE Count
{{forloop.counter}}{{item.state}}{{item.count}}
+
+
+ + + + + + + + + + {% for item in csc_district %} + + + + + + {% endfor %} + +
#DistrictVLE Count
{{forloop.counter}}{{item.district}}{{item.count}}
+
+
+
+
+{% endblock content %} + + + +{% block js_script %} + + + +{% endblock js_script %} + diff --git a/csc/templates/stats/vle_stats.html b/csc/templates/stats/vle_stats.html new file mode 100644 index 0000000..d5dc9e3 --- /dev/null +++ b/csc/templates/stats/vle_stats.html @@ -0,0 +1,316 @@ +{% extends "stats/stats_base.html" %} +{% load static %} +{% block custom_style %} + +{% endblock custom_style %} +{% block content %} +
+
Search VLE
+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + +
+
+
+ + + +
+
+ {% if query_str.name or query_str.csc_id or query_str.state or query_str.district %} + + + {% endif %} +
+ + + + + + + + + + + + + + + + {% for vle in object_list %} + + + + + + + + + + + {% endfor %} + + + +
IDNameCSC IDStateDistrictPlanDate of Joining
{{forloop.counter}} + {{vle.user.get_full_name | title}} + + {{vle.csc.csc_id}}{{vle.csc.state}}{{vle.csc.district}}{{vle.csc.plan}}{{vle.user.date_joined}}
+
+
+
VLE Details
+ +
+
+
+

Profile

+
+
+

+
+
+

+
+
+

+
+
+

CSC ID:

+
+
+

+
+
+

+ , - Pincode : +

+
+
+

+ Total Students : +

+
+
+
+
+
+
+

Students

+
+ + + + + +
NameEmail
+
+
+
+
+
+

Student-Course

+
+ + + + + {% comment %} {% endcomment %} + +
CodeCourse TitleStudents
+
+
+ +
+
+
+

Student-FOSS

+
+ + + + {% comment %} {% endcomment %} + +
FOSSStudents
+
+
+
+
+
+

Student-FOSS (Individual FOSS Only)

+
+ + + + {% comment %} {% endcomment %} + +
FOSS (Individual FOSS Only)Students
+
+
+
+
+
+
+
+{% endblock content %} + +{% block js_script %} + +{% endblock js_script %} + diff --git a/csc/templatetags/__init__.py b/csc/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/csc/templatetags/csc_tags.py b/csc/templatetags/csc_tags.py new file mode 100644 index 0000000..e1f065b --- /dev/null +++ b/csc/templatetags/csc_tags.py @@ -0,0 +1,58 @@ +from django import template +import datetime +register = template.Library() +from csc.models import * +from csc.utils import TEST_COMPLETED_BY_STUDENT,PASS_GRADE, TEST_ATTENDANCE_MARKED +from csc.utils import get_valid_animation_fosses + +def is_today(value): + return value == datetime.date.today() + +register.filter('is_today', is_today) + + +@register.filter +def get_csc_mdlcourseid(eventfossid): + try: + csccourse = CSCFossMdlCourses.objects.filter(foss=eventfossid) + except CSCFossMdlCourses.DoesNotExist: + return None + + return csccourse + + +@register.filter +def check_attendance(studentid, testfossid): + try: + print(testfossid) + attendance = CSCTestAtttendance.objects.filter(test__foss_id=testfossid, student_id=studentid).first() + print(attendance,"######################") + return attendance + except Exception as e: + print(e) + return None + + + +# @register.filter +# def check_passgrade_exists(studentid, testfossid): +# # valid_fosses = get_valid_animation_fosses() +# valid_fosses = [x.test.foss.id for x in CSCTestAtttendance.objects.filter(student_id=studentid)] +# if testfossid in valid_fosses: +# try: +# pass_entry = CSCTestAtttendance.objects.filter(test__foss__id=testfossid, student_id=studentid, status__gte=TEST_COMPLETED_BY_STUDENT, mdlgrade__gte=PASS_GRADE) +# return pass_entry +# except: +# return None +# else: + # return None + + +@register.filter +def check_passgrade_exists(studentid, testfossid): + try: + pass_entry = CSCTestAtttendance.objects.filter(test__foss__id=testfossid, student_id=studentid, status__gte=TEST_COMPLETED_BY_STUDENT, mdlgrade__gte=PASS_GRADE).first() + return pass_entry + except: + return None + diff --git a/csc/tests.py b/csc/tests.py index 7ce503c..ae59c25 100644 --- a/csc/tests.py +++ b/csc/tests.py @@ -1,3 +1,32 @@ from django.test import TestCase +from .models import * # Create your tests here. +def students_approve_tests(test_id,status,count,smax=50): + test_id =test_id + test = Test.objects.get(id=test_id) + sf = Student_Foss.objects.filter(csc_foss__spoken_foss=test.foss) + print(f"sf -- {sf}") + temp=0 + for item in sf: + print(f"For loop: {item}") + if temp < count: + try: + student = item.student + print(f"{temp} ---- {student}") + print(f"{student.id} , {smax}") + if student.id < smax: + print("student.id < smax") + st=StudentTest.objects.get(student=student,test=test) + st.status = status + st.save() + print('saved existinng studdent') + temp+=1 + else: + print(f"student.id > smax:") + except StudentTest.DoesNotExist: + print('exception') + StudentTest.objects.create(student=student,test=test,status=status) + print('new obbject created ') + + diff --git a/csc/utils.py b/csc/utils.py index 447ade5..24db5e2 100644 --- a/csc/utils.py +++ b/csc/utils.py @@ -1,6 +1,222 @@ +from django.db.models import OuterRef,Exists, Count from genericpath import exists from tokenize import group +import datetime + +from mdl.models import MdlUser +from csc.models import * +# from csc.models import Test +# from .models import REJECTED, APPROVED +from datetime import date,timedelta +from django.db.models import Count +from django.conf import settings +from django.core.mail import send_mail +# from reportlab.pdfgen import canvas +# from reportlab.pdfbase.ttfonts import TTFont +# from reportlab.pdfbase import pdfmetrics +# from reportlab.lib.styles import ParagraphStyle +# from reportlab.platypus import Paragraph +# from reportlab.lib.units import cm + +# from PyPDF2 import PdfFileWriter, PdfFileReader + +# from io import StringIO, BytesIO + +import random, string + +TEST_OPEN=0 +TEST_ATTENDANCE_MARKED=1 +TEST_ONGOING=2 +TEST_COMPLETED_BY_STUDENT=3 +TEST_CLOSED_BY_VLE=4 +PASS_GRADE=40.00 + +# from reportlab.pdfgen import canvas +# from reportlab.pdfbase.ttfonts import TTFont +# from reportlab.pdfbase import pdfmetrics +# from reportlab.lib.styles import ParagraphStyle +# from reportlab.platypus import Paragraph +# from reportlab.lib.units import cm + +# from PyPDF2 import PdfFileWriter, PdfFileReader + +# from io import StringIO, BytesIO + +from django.http import HttpResponse + +# from reportlab.pdfgen import canvas +# from reportlab.pdfbase.ttfonts import TTFont +# from reportlab.pdfbase import pdfmetrics +# from reportlab.lib.styles import ParagraphStyle +# from reportlab.platypus import Paragraph +# from reportlab.lib.units import cm + +# from PyPDF2 import PdfFileWriter, PdfFileReader + +# from io import StringIO, BytesIO + +from django.http import HttpResponse def is_user_vle(user): - print("\n\n user is VLE \n\n") return user.groups.filter(name="VLE").exists() + +def is_user_student(user): + return user.groups.filter(name="STUDENT").exists() + +def is_csc_team_role(user): + return user.groups.filter(name="CSC-TEAM").exists() + +def is_user_invigilator(user): + return user.groups.filter(name="INVIGILATOR").exists() + +def get_upcoming_test_stats(vle): + tests = Test.objects.filter(tdate__gte=datetime.datetime.now().date(),vle=vle) + d = {} + for test in tests: + total_students = CSCTestAtttendance.objects.filter(test=test).count() + key = test.foss.foss + d[key] = {'total_students' : total_students,'date': test.tdate, 'time': test.ttime, 'id':test.id } + return d + +def get_courses_offered_stats(): + d = {} + dca = Student_certificate_course.objects.filter(cert_category__code='DCA').count() + individual = Student_certificate_course.objects.filter(cert_category__code='INDI').count() + d['dca'] = dca + d['individual'] = individual + return d + +def get_programme_stats(): + course_count_result = (Student_certificate_course.objects.values('cert_category__code').annotate(scount=Count('cert_category__code')).order_by()) + print(course_count_result) + d = {} + for item in course_count_result: + d[item['cert_category__code']]=item['scount'] + course_count = [x for x in course_count_result] + print(f"course_count\n\n\n\n{course_count}") + return d + return course_count + + +def get_foss_enroll_percent(vle): + csc_foss = [x for x in FossCategory.objects.filter(available_for_jio=True)] + d = {} + total = Student_Foss.objects.filter(csc_foss__in = csc_foss).count() + for item in csc_foss: + d[item.foss] = ((Student_Foss.objects.filter(csc_foss = item).count())/total)*100 + return d + + +def upcoming_foss_tests(foss,vle): + tests = Test.objects.filter(foss=foss,vle=vle,tdate__gt=date.today()) + return list(tests) + +def check_student_test_status(test,student): + studentTest = StudentTest.objects.filter(test__in=test,student=student) + if studentTest: + return studentTest[0].test + return False + +def getFirstName(name): + formatted = name.split() + if formatted: + return formatted[0] + return '' + +def getLastName(name): + formatted = name.split(maxsplit=1) + if len(formatted)>1: + return formatted[1] + return '' + +def get_tenure_end_date(tdate): + subscription_period = getattr(settings, "CSC_SUBSCRIPTION_PERIOD", 100) + end_date = tdate + timedelta(100) + return end_date + + +def get_valid_students_for_test(vle,test): + foss = test.foss + other_tests = Test.objects.filter(foss=foss).exclude(id=test.id) + students = Student.objects.filter(vle_id=vle.id,student_foss__csc_foss_id=foss.id,student_foss__foss_start_date__lte=datetime.date.today()-timedelta(days=10)).annotate(assigned=Exists(CSCTestAtttendance.objects.filter(student_id=OuterRef('id'),test=test))).annotate(ineligible=Exists(CSCTestAtttendance.objects.filter(student_id=OuterRef('id'),test__in=other_tests))) + return students + +def get_all_foss_for_vle(vle): + students = Student.objects.filter(vle_id=vle.id) + fosses = Student_Foss.objects.filter(student_id__in=students).values('csc_foss').distinct() + return FossCategory.objects.filter(id__in=[x['csc_foss'] for x in fosses]).order_by('foss') + +def send_pwd_mail_to_invi(u): + pwd = ''.join(random.choices(string.ascii_letters,k=10)) + u.set_password(pwd) + u.save() + invi = Invigilator.objects.get(user=u) + from_email = getattr(settings, "NO_REPLY_MAIL", "no-reply@spoken-tutorial.org") + subject = "Login credentials for Spoken Tutorial - CSC" + message = f""" + Dear {u.get_full_name()}, + Below are the login details for Spoken Tutorial Dashboard. + Link to Login: https://spoken-tutorial.in/login/ + + username : {u.username} + password : {pwd} + + Thanks & Regards, + Team, + Spoken Tutorial + """ + try: + send_mail(subject,message,from_email,[u.email],fail_silently=False) + + invi.password_mail_sent = 1 + invi.save() + except Exception as e: + invi.password_mail_sent = 0 + invi.save() + print(e) + print(f"Failed to send mail to user : {u.email}") + +def send_mdl_mail(u,pwd): + student = Student.objects.get(user=u) + mdluser = MdlUser.objects.filter(email=u.email)[0] + # pwd = ''.join(random.choices(string.ascii_letters,k=10)) + u.set_password(pwd) + u.save() + + from_email = getattr(settings, "NO_REPLY_MAIL", "no-reply@spoken-tutorial.org") + print(f"2 SENDING Email ************************ {u.email}") + MDL_URL=getattr(settings, "MDL_URL", "") + subject = "Login credentials for Moodle Spoken Tutorial - CSC" + message = f""" + Dear {u.get_full_name()}, + Below are the login details for Moodle Dashboard for Spoken Tutorial Test. + Link to Moodle Login: {MDL_URL} + + username : {mdluser.username} + password : {pwd} + + Thanks & Regards, + Team, + Spoken Tutorial + """ + print(f"3 SENDING Email ************************ {u.email}") + try: + print(f"4 SENDING Email ************************ {u.email}") + send_mail(subject,message,from_email,[u.email],fail_silently=False) + student.mdl_mail_sent = True + student.save() + print(f"5 SENDING Email ************************ {u.email}") + except Exception as e: + print(f"6 SENDING Email ************************ {u.email}") + student.mdl_mail_sent = False + student.save() + print(e) + print(f"Failed to send mail to user : {u.email}") + print(f"7 SENDING Email ************************ {u.email}") + +def get_valid_animation_fosses(): + course = CertifiateCategories.objects.get(code = 'IT07') + fosses = [x.foss.id for x in CategoryCourses.objects.filter(certificate_category=course)] + return FossCategory.objects.filter(id__in=fosses).order_by('foss') + + diff --git a/csc/vle_forms.py b/csc/vle_forms.py new file mode 100644 index 0000000..9669cfb --- /dev/null +++ b/csc/vle_forms.py @@ -0,0 +1,120 @@ +from django.forms import Form, ModelForm, Textarea, TextInput +from django import forms + +from csc.models import * +from spokenlogin.models import * + +from .utils import get_valid_animation_fosses + +class FossForm(forms.Form): + programme_type = forms.ChoiceField(required=True, choices=PROGRAMME_TYPE_CHOICES) + spoken_foss = forms.ModelMultipleChoiceField(queryset=FossCategory.objects.filter(available_for_jio=True)) + + # class Meta(object): + # model = Vle_csc_foss + # exclude = ['created','updated'] + + def __init__(self, *args, **kwargs): + initial = '' + if 'instance' in kwargs: + initial = kwargs["instance"] + + if 'user' in kwargs: + user = kwargs["user"] + del kwargs["user"] + + + super(FossForm, self).__init__(*args, **kwargs) + + self.fields['programme_type'].choices = PROGRAMME_TYPE_CHOICES + + if kwargs and 'data' in kwargs: + if kwargs['data']['programme_type'] != '': + programme_type = kwargs['data']['programme_type'] + + if programme_type == 'dca': + fosses = SpokenFoss.objects.filter(csc_dca_programme=True, available_for_jio=True).order_by('foss') + else: + fosses = SpokenFoss.objects.filter(csc_dca_programme=False, available_for_jio=True).order_by('foss') + + # self.fields['spoken_foss'].queryset = fosses + self.fields['spoken_foss'].initial = kwargs['data']['spoken_foss'] + + +class StudentForm(forms.ModelForm): + GENDER = (('f','female'),('m','male')) + fname = forms.CharField(max_length=120,label='First Name') + lname = forms.CharField(max_length=120,label='Last Name') + gender = forms.ChoiceField(choices = GENDER) + + class Meta: + model = Student + fields = ['gender','dob','phone','edu_qualification','state','city','district','pincode','address'] + labels = { + 'fname' :'First Nameing' + } + + +# class InvigilatorForm(forms.ModelForm): +# phone = forms.CharField(max_length=15,required=False) +# class Meta: +# model = User +# fields = ['first_name','last_name','email','phone'] + # email = forms.EmailField() + # fname = forms.CharField(max_length=120,label='First Name') + # lname = forms.CharField(max_length=120,label='Last Name') + # phone = forms.CharField(max_length=32,label='Contact Number') + +class InvigilatorForm(forms.Form): + email = forms.EmailField(max_length=200,required=False) + first_name = forms.CharField(max_length=200,required=False) + last_name = forms.CharField(max_length=200,required=False) + phone = forms.CharField(max_length=20,required=False) + + +class InvigilationRequestForm(forms.Form): + + test = forms.ModelChoiceField(queryset=None,widget=forms.Select(attrs={'disabled':'disabled'})) + invigilators = forms.ModelMultipleChoiceField(queryset=None) + + def __init__(self, *args, **kwargs): + vle_id = kwargs.pop('vle_id') + test_id = kwargs.pop('test_id') + + + super(InvigilationRequestForm,self).__init__(*args, **kwargs) + vle = VLE.objects.get(id=vle_id) + self.fields['test'].queryset = Test.objects.filter(vle=vle) + self.fields['test'].initial = test_id + self.fields['invigilators'].queryset = Invigilator.objects.filter(vle=vle) + l = InvigilationRequest.objects.filter(test_id=test_id).values('invigilator') + l = [x['invigilator'] for x in l] + self.fields['invigilators'].initial = l + + +class TestForm(forms.ModelForm): + class Meta: + model = Test + fields = ['foss','tdate','ttime','invigilator','publish'] + widgets = { + 'tdate' : forms.DateInput(attrs={'type': 'date'}), + 'ttime' : forms.DateInput(attrs={'type': 'time'},format='%H:%M') + } + labels = { + 'tdate' : 'Test Date', + 'ttime' : 'Test Time', + 'invigilator' : 'Invigilators' + } + help_texts = { + 'tdate' : 'Format : DD/MM/YYYY', + } + + def __init__(self, *args, **kwargs): + user = kwargs.pop('user') + vle = VLE.objects.get(user=user) + super(TestForm, self).__init__(*args, **kwargs) + # r = get_all_foss_for_vle(vle) + # print(f"r ************* {len(r)}") + # self.fields['foss'].queryset = get_all_foss_for_vle(vle) #IMPORTANT : For querying foss valid for the vle + + self.fields['foss'].queryset = get_valid_animation_fosses() \ No newline at end of file diff --git a/csc/vle_models.py b/csc/vle_models.py index e69de29..0dff170 100644 --- a/csc/vle_models.py +++ b/csc/vle_models.py @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/csc/vle_urls.py b/csc/vle_urls.py index 4f75517..6a344f3 100644 --- a/csc/vle_urls.py +++ b/csc/vle_urls.py @@ -2,11 +2,56 @@ from csc.vle_views import CSCLogin from .views import * from django.urls import path -from .vle_views import vle_dashboard +from django.conf.urls import url +from .vle_views import * +from .ajax import ajax_mark_attendance app_name = 'csc' urlpatterns = [ - path('login/', CSCLogin.as_view(), name="login"), - path('vle/', vle_dashboard, name="vle_dashboard") + path('login/', CSCLogin.as_view(redirect_authenticated_user=True), name="login"), + path('vle/', vle_dashboard, name="vle_dashboard"), + path('students/', student_list, name="student_list"), + path('student//', student_profile, name="student_profile"), + path('courses/', courses, name="courses"), + path('assign_foss/', assign_foss, name="assign_foss"), + path('get_course_stats/', get_course_stats, name="get_course_stats"), + path('get_stats/', get_stats, name="get_stats"), + + path('test/', test, name="test"), + path('test_assign/', test_assign, name="test_assign"), + path('test_list/', test_list, name="test_list"), + # path('add_test/', TestCreateView.as_view(), name="add_test"), + path('mark_attendance/', mark_attendance, name="mark_attendance"), + # path('detail_test/', TestDetailView.as_view(), name="detail_test"), + path('detail_test/', TestDetailView.as_view(), name="detail_test"), + # path('update_test/', TestUpdateView.as_view(), name="update_test"), + path('update_test/', update_test, name="update_test"), + path('delete_test/', TestDeleteView.as_view(), name="delete_test"), + path('list_test/', TestListView.as_view(), name="list_test"), + path('invigilator/', invigilator, name="invigilator"), + path('invigilators/', invigilators, name="invigilators"), + # path('invigilator_dashboard/', invigilator_dashboard, name="invigilator_dashboard"), + path('verify_invigilator_email/', verify_invigilator_email, name="verify_invigilator_email"), + path('add_invigilator/', add_invigilator, name="add_invigilator"), + path('review_invigilation_request/', review_invigilation_request, name="review_invigilation_request"), + path('add_invigilator_to_test/', add_invigilator_to_test, name="add_invigilator_to_test"), + # path('delete_invigilator/', delete_invigilator, name="delete_invigilator"), + + path('create_invigilator/', create_invigilator, name="create_invigilator"), + path('view_invigilators/', view_invigilators, name="view_invigilators"), + path('invigilators//', update_invigilator, name="update_invigilator"), + path('invigilators/delete//', InvigilatorDeleteView.as_view(), name="delete_invigilator"), + + path('invigilator_dashboard/', invi_dashboard, name="invi_dashboard"), + + url( + r'^get-foss-option/', + GetFossOptionView.as_view() + ), + + # ajax + path('ajax_mark_attendance/', ajax_mark_attendance, name="ajax_mark_attendance"), + path('check_vle_email/', check_vle_email, name="check_vle_email") + ] \ No newline at end of file diff --git a/csc/vle_views.py b/csc/vle_views.py index aa96821..97f097b 100644 --- a/csc/vle_views.py +++ b/csc/vle_views.py @@ -1,8 +1,62 @@ -from django.urls import reverse -from re import template +from django.conf import settings +from django.contrib import messages +from django.contrib.auth.decorators import login_required +from django.contrib.auth.hashers import make_password +from django.contrib.auth.models import Group from django.contrib.auth.views import LoginView -from django.shortcuts import render +from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage +from django.db import IntegrityError +from django.db.models import OuterRef,Exists,Q, Exists, OuterRef +from django.forms.models import model_to_dict +from django.http import HttpResponseRedirect, JsonResponse +from django.shortcuts import render,get_object_or_404, redirect +from django.urls import reverse,reverse_lazy +from django.utils.decorators import method_decorator +from django.views.decorators.csrf import csrf_exempt +from django.views.generic import View,ListView,DeleteView,DetailView,UpdateView +from django.views.generic.edit import CreateView + +from csc.models import * +from mdl.models import * +from spokenlogin.models import * + +from .cron import add_vle,add_transaction +from .decorators import is_vle +from .models import TEST_OPEN from .utils import * +from .vle_forms import * + +import logging +import random +import requests +import string +import hashlib + +STUDENT_ENROLLED_FOR_TEST = 0 +ATTENDANCE_MARKED = 1 + +class JSONResponseMixin(object): + """ + A mixin that can be used to render a JSON response. + """ + def render_to_json_response(self, context, **response_kwargs): + """ + Returns a JSON response, transforming 'context' to make the payload. + """ + return JsonResponse( + self.get_data(context), + **response_kwargs + ) + + def get_data(self, context): + """ + Returns an object that will be serialized as JSON by json.dumps(). + """ + # Note: This is *EXTREMELY* naive; in reality, you'll need + # to do much more complex handling to ensure that arbitrary + # objects -- such as Django model instances or querysets + # -- can be serialized as JSON. + return context class CSCLogin(LoginView): template_name = 'csc/login.html' @@ -10,10 +64,819 @@ class CSCLogin(LoginView): def get_redirect_url(self): if is_user_vle(self.request.user): return reverse('csc:vle_dashboard') + if is_user_student(self.request.user): return reverse('csc:vle_dashboard') # ToDo if student ; redirect to student dashboard - +@login_required +@is_vle def vle_dashboard(request): context = {} - return render(request, 'csc/vle.html',context) + vle = VLE.objects.filter(user=request.user).first() + + context['vle'] = vle + context['user'] = request.user + context['upcoming_test_stats'] = get_upcoming_test_stats(vle) + context['courses_offered_stats'] = get_courses_offered_stats() + context['total_students_enrolled'] = Student.objects.filter(vle_id=vle).count() + context['total_tests_completed'] = Test.objects.filter(vle=vle,tdate__lt=datetime.datetime.today().date()).count() + context['total_upcoming_tests'] = Test.objects.filter(vle=vle,tdate__gte=datetime.datetime.today().date()).count() + context['total_certificates_issued'] = StudentTest.objects.filter(status=4).count() #ToDo check condition + + return render(request, 'csc/vle.html', context) + +@login_required +@is_vle +def courses(request): + context = {} + vles = VLE.objects.filter(user=request.user) + for vle in vles: + individual_foss = {} + fosses = FossCategory.objects.filter(available_for_jio=True) + indi_students = Student_certificate_course.objects.filter(cert_category__code='INDI', student__in=Student.objects.filter(vle_id=vle.id)).values_list('student_id') + + for item in fosses: + students = Student_Foss.objects.filter(csc_foss=item.id, student__in=indi_students).count() + individual_foss[item.foss] = {'total_students':students} + + context['individual_foss'] = individual_foss + vle = VLE.objects.filter(user=request.user)[0] + courses = CertifiateCategories.objects.exclude(code__in=['INDI']) + if request.GET.get('course_search'): + search_term = request.GET.get('search_term') + q_code = Q(certificate_category__code__icontains=search_term) + q_title = Q(certificate_category__title__icontains=search_term) + q_foss = Q(foss__foss__icontains=search_term) + courses = [x.certificate_category for x in CategoryCourses.objects.filter(q_code|q_title|q_foss)] + else: + courses = CertifiateCategories.objects.exclude(code__in=['INDI']) + d = {} + for course in courses: + fosses = [x['foss__foss'] for x in CategoryCourses.objects.filter(certificate_category_id=course.id).values('foss__foss')] + d[course] = fosses + print(f"\n\n{d}\n\n") + context['courses'] = d + + return render(request,'csc/courses.html',context) + +@method_decorator(csrf_exempt, name='dispatch') +class GetFossOptionView(JSONResponseMixin, View): + def dispatch(self, *args, **kwargs): + return super(GetFossOptionView, self).dispatch(*args, **kwargs) + + def post(self, request, *args, **kwargs): + programme_type = self.request.POST.get('programme_type') + context = {} + foss_option = "" + if programme_type == 'dca': + fosses = FossCategory.objects.filter(csc_dca_programme=True, available_for_jio=True).order_by('foss') + else: + fosses = FossCategory.objects.filter(csc_dca_programme=False, available_for_jio=True).order_by('foss') + for foss in fosses: + foss_option += "" + context = { + 'spoken_foss_option' : foss_option, + } + return self.render_to_json_response(context) + +@login_required +@is_vle +def student_list(request): + context={} + vle = VLE.objects.filter(user=request.user).first() + students = [] + course = request.GET.get('course') + foss = request.GET.get('foss') + name = request.GET.get('name') + # dates = request.GET.get('dates') + findividual = FossCategory.objects.filter(available_for_jio=True) + context['foss_individual'] = [x for x in findividual] + indi_id = CertifiateCategories.objects.get(code="INDI").id + indi_course = Student_certificate_course.objects.filter(student_id=OuterRef('id'),cert_category_id=indi_id) + s = Student.objects.filter(vle_id=vle.id).annotate(indi=Exists(indi_course)) + distinct_courses = set() + vle_courses = Student_certificate_course.objects.filter(student__in=s) + # vle_courses = Student_certificate_course.objects.all() + for item in vle_courses: + # print(item.cert_category) + distinct_courses.add(item.cert_category) + context['distinct_courses'] = distinct_courses + distinct_foss = set() + vle_fosses = Student_Foss.objects.filter(student__in=s) + for item in vle_fosses: + distinct_foss.add(item.csc_foss) + l = list(distinct_foss) + l.sort(key=lambda x: x.foss.title()) + context['distinct_foss'] = l + print(s.query) + # all_students = Student.objects.filter(vle_id=vle.id) + if name!=None: + context['search_name'] = name + s = s.filter(Q(user__first_name__icontains=name)|Q(user__last_name__icontains=name)|Q(user__email__icontains=name)) + if course!='0' and course!=None: + try: + context['search_course'] = CertifiateCategories.objects.get(id=course) + except Exception as e: + print(e) + if CertifiateCategories.objects.get(id=course).code == 'INDI': + context['is_indi'] = True + try: + s = s.filter(id__in=[x.student.id for x in Student_certificate_course.objects.filter(cert_category__id=course)]) + except Exception as e: + print(e) + if foss!='0' and foss!=None: + try: + context['search_foss'] = FossCategory.objects.get(id=foss) + except Exception as e: + print(e) + try: + s = s.filter(id__in=[x.student.id for x in Student_Foss.objects.filter(csc_foss=foss)]) + except Exception as e: + print(e) + if not (course or foss or name): + context['is_indi'] = True + for item in s: + students.append(item) + context['students'] = students + context['students'] = s + + return render(request,'csc/students_list.html',context) + + +def student_profile(request,id): + context={} + student = Student.objects.get(id=id) + initial={'fname': student.user.first_name , 'lname': student.user.last_name, 'state' :student.state} + form = StudentForm(instance=student,initial=initial) + context['form'] = form + s_categories = Student_certificate_course.objects.filter(student=student) + d = {} + for category in s_categories: + fosses = [x.csc_foss.foss for x in Student_Foss.objects.filter(student=student,cert_category=category.cert_category)] + d[category.cert_category] = fosses + context['courses'] = d + return render(request,'csc/student_profile.html',context) + +@csrf_exempt +def get_course_stats(request): + vles = VLE.objects.filter(user=request.user) + stats = {} + fosses = [] + enrollment = [] + for vle in vles: + csc_foss = Vle_csc_foss.objects.filter(vle=vle) + for item in csc_foss: + foss = item.spoken_foss.foss + stats[foss] = Student_Foss.objects.filter(csc_foss=item).count() + fosses.append(foss) + enrollment.append(Student_Foss.objects.filter(csc_foss=item).count()) + + return JsonResponse({'stats':stats,'fosses':fosses,'enrollment':enrollment,'len':len(fosses)}) + +class TestListView(ListView): + model = Test + template_name = 'csc/test_list.html' + context_object_name = 'tests' + paginate_by = 25 + + def get_context_data(self, **kwargs): + context = super(TestListView, self).get_context_data(**kwargs) + vle = VLE.objects.filter(user = self.request.user).first() + tests = Test.objects.filter(vle = vle) + # tests = Test.objects.filter(vle = vle).annotate(attendance=ExpressionWrapper(F('tdate')==date.today(),output_field=BooleanField())) + page = self.request.GET.get('page') + paginator = Paginator(tests, self.paginate_by) + try: + tests = paginator.page(page) + except PageNotAnInteger: + tests = paginator.page(1) + except EmptyPage: + tests = paginator.page(paginator.num_pages) + context['tests'] = tests + + test_req = [x for x in TestRequest.objects.filter(vle=vle)] + context['test_req'] = test_req + + return context + + +@method_decorator(login_required, name='dispatch') +class TestCreateView(CreateView): + model = Test + template_name = 'csc/test_form.html' + # fields = ['test_name','foss','tdate','ttime','note_student','note_invigilator','publish'] + fields = ['foss','tdate','ttime','publish'] + success_url = reverse_lazy('csc:list_test') + + def get_form(self, *args, **kwargs): + form = super(TestCreateView, self).get_form(*args, **kwargs) + vle = VLE.objects.filter(user=self.request.user).first() + vle_foss = Vle_csc_foss.objects.filter(vle=vle) + fosses = FossCategory.objects.filter(id__in=[x.spoken_foss.id for x in vle_foss]) + form.fields['foss'].queryset = fosses + form.fields['tdate'].widget = widgets.DateInput(attrs={'type': 'date'}) + form.fields['ttime'].widget = widgets.DateInput(attrs={'type': 'time'}) + return form + + def get_form_kwargs(self): + kwargs = super(TestCreateView, self).get_form_kwargs() + # kwargs['invi'] = self.request.user # pass the 'user' in kwargs + return kwargs + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + # user = self.request.user + # context["ticket_list"] = user.ticket_set.all() + vle = VLE.objects.filter(user=self.request.user).first() + context['tests'] = Test.objects.filter(vle=vle) + context['invigilators'] = Invigilator.objects.filter(vle=vle) + return context + + def form_valid(self, form): + vle = VLE.objects.filter(user=self.request.user).first() + form.instance.vle = vle + print(form) + + messages.success(self.request,"Test added successfully.") + return super().form_valid(form) + +@method_decorator(login_required, name='dispatch') +class TestDeleteView(DeleteView): + model = Test + template_name = 'csc/test_confirm_delete.html' + success_url = reverse_lazy('csc:list_test') + + def form_valid(self, form): + print('form is valid') + +@method_decorator(login_required, name='dispatch') +class TestDetailView(DetailView): + model = Test + template_name = 'csc/test_detail.html' + context_object_name = 'test' + + +@method_decorator(login_required, name='dispatch') +class TestUpdateView(UpdateView): + model = Test + template_name = 'csc/test_update_form.html' + context_object_name = 'test' + # fields = ('test_name','foss', 'tdate', 'ttime', 'note_student', 'note_invigilator', 'publish' ) + fields = ('foss', 'tdate', 'ttime', 'publish' ) + + + def get_success_url(self): + messages.success(self.request,"Test updated successfully.") + return reverse_lazy('csc:detail_test', kwargs={'pk': self.object.id}) + + def get_form(self, *args, **kwargs): + form = super(TestUpdateView, self).get_form(*args, **kwargs) + vle = VLE.objects.filter(user=self.request.user).first() + vle_foss = Vle_csc_foss.objects.filter(vle=vle) + fosses = FossCategory.objects.filter(id__in=[x.spoken_foss.id for x in vle_foss]) + form.fields['foss'].queryset = fosses + form.fields['tdate'].widget = widgets.DateInput(attrs={'type': 'date'}) + form.fields['ttime'].widget = widgets.DateInput(attrs={'type': 'time'}) + t = str(self.get_object().ttime).split(' ')[0] + form.fields['ttime'].initial = t + return form + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + vle = VLE.objects.filter(user=self.request.user).first() + id = vle.id + vle = VLE.objects.filter(user=self.request.user).first() + invigilationRequestForm = InvigilationRequestForm(vle_id=id,test_id=self.get_object().id) + context['invigilationRequestForm'] = invigilationRequestForm + t = str(self.get_object().ttime).split(' ')[0] + context['t']=t + test = self.get_object() + students = [x.student for x in StudentTest.objects.filter(test = test)] + context['students'] = students + return context + +def invigilators(request): + context = {} + form = InvigilatorForm() + if request.method == 'POST': + form = InvigilatorForm(request.POST) + if form.is_valid(): + email = form.cleaned_data['email'] + fname = form.cleaned_data['fname'] + lname = form.cleaned_data['lname'] + phone = form.cleaned_data['phone'] + try: + user = User.objects.create( + username=email,first_name=fname,last_name=lname, + email=email,is_staff=0,is_active=1 + ) + password = ''.join([ random.choice(string.ascii_letters+string.digits) for x in range(8)]) + enc_password = make_password(password) + user.password = enc_password + user.save() + invigilator=Invigilator.objects.create(user=user,phone=phone,added_by=request.user) + group = Group.objects.get(name='INVIGILATOR') + group.user_set.add(user) + messages.success(request,"Invigilator added successfully.") + except Exception as e: + print(f"Exception while creating invigilator user: {e}") + messages.error(request,"Error occurred while adding invigilator.") + + return render(request, 'invigilators.html', {'form': form}) + + context['form'] = form + vle = VLE.objects.filter(user=request.user).first() + context['invigilators'] = Invigilator.objects.filter(vle=vle) + return render(request, 'csc/invigilators.html',context) + +@csrf_exempt +def verify_invigilator_email(request): + USER_AND_INVIGIlATOR = 1 + USER_NOT_INVIGIlATOR = 2 + NOT_USER = 0 + MULTIPLE_USER = 3 + USER_AND_OWN_INVIGIlATOR = 4 + data = {} + data['status'] = 0 + email = request.GET.get('email','') + if email: + try: + user = User.objects.get(email=email) + is_invigilator = Invigilator.objects.filter(user=user) + invigilator_role = is_user_invigilator(user) + if (is_invigilator or invigilator_role): + vle = VLE.objects.filter(user=request.user)[0] + invigilator = is_invigilator[0] + if(vle in invigilator.vle.all()): + data['status'] = USER_AND_OWN_INVIGIlATOR + data['fname'] = user.first_name + data['lname'] = user.last_name + data['phone'] = is_invigilator[0].phone + else: + data['status'] = USER_AND_INVIGIlATOR + data['fname'] = user.first_name + data['lname'] = user.last_name + data['phone'] = is_invigilator[0].phone + + return JsonResponse(data) + else: + data['status'] = USER_NOT_INVIGIlATOR + data['fname'] = user.first_name + data['lname'] = user.last_name + # data['fname'] = user.first_name + except User.MultipleObjectsReturned as e: + print(f"User.MultipleObjectsReturne : {e}") + data['status'] = MULTIPLE_USER + except User.DoesNotExist: + data['status'] = NOT_USER + return JsonResponse(data) + +# @csrf_exempt +def add_invigilator(request): + vle = VLE.objects.filter(user=request.user).first() + try: + invigilator_email = request.POST.get('invigilator_email') + invigilator_exist = request.POST.get('flag',False) + + invigilator_user = User.objects.get(email=invigilator_email) + if invigilator_exist: + invigilator = Invigilator.objects.get(user=invigilator_user) + else: + invigilator = Invigilator.objects.create(user=invigilator_user,phone=request.POST.get('phone'),added_by=request.user) + + invigilator.vle.add(vle) + messages.success(request,"Invigilator successfullly assigned to CSC.") + except Exception as e: + print(f"Exception : {e}") + messages.error(request,"An error occcured while adding invigilator.") + + data = {} + return JsonResponse(data) + + +def invigilator_dashboard(request): + context = {} + invigilator = Invigilator.objects.get(user=request.user) + pending = InvigilationRequest.objects.filter(invigilator=invigilator,status=0) + accepted = InvigilationRequest.objects.filter(invigilator=invigilator,status=1) + rejected = InvigilationRequest.objects.filter(invigilator=invigilator,status=2) + all = InvigilationRequest.objects.filter(invigilator=invigilator) + context['pending'] = pending + context['accepted'] = accepted + context['rejected'] = rejected + context['all'] = all + return render(request,'csc/invigilator_dashboard.html',context) + +def add_invigilator_to_test(request): + data = {} + context = {} + test = request.POST.get('test_id') + test_id = request.POST.get('test',test) + invigilators = request.POST.getlist('invigilators') + test = Test.objects.get(id=int(test_id)) + for invigilator in invigilators: + InvigilationRequest.objects.create(invigilator_id=int(invigilator),test=test,status=0) + + return HttpResponseRedirect(reverse('csc:update_test',kwargs={'pk':test_id}) ) + +def review_invigilation_request(request): + status = request.GET.get("review") + id = request.GET.get("item") + obj = InvigilationRequest.objects.get(id=id) + obj.status = int(status) + obj.save() + print(f'status : {request.GET.get("review")}') + return HttpResponseRedirect(reverse('csc:invigilator_dashboard') ) + +def get_stats(request): + data = {} + data['upcoming_tests'] = get_upcoming_test_stats() + data['course_type_offered'] = get_courses_offered_stats() + data['course_count_result'] = get_programme_stats() + return JsonResponse(data) + +def mark_attendance(request,id): + context = {} + + test = Test.objects.get(id=id) + # st = [x.student for x in StudentTest.objects.filter(test=test)] + print("\n\n") + print(f"1********************************") + st = [(x.student,x.status) for x in CSCTestAtttendance.objects.filter(test=test)] + print(f"2********************************") + context['test'] = test + context['students'] = st + total_enrolled = len(st) + attending = StudentTest.objects.filter(test_status=1).count() + pending = total_enrolled - attending + context['total_enrolled'] = total_enrolled + context['attending'] = attending + context['pending'] = pending + + if request.method == 'POST': + print(f"3********************************") + student_attendance = request.POST.getlist('student_attendance') + print(f"student_attendance\n\n ************************ {student_attendance}") + #present + CSCTestAtttendance.objects.filter(test=test,student_id__in=student_attendance).update(status=TEST_ATTENDANCE_MARKED) + #absent + CSCTestAtttendance.objects.exclude(test=test,student_id__in=student_attendance).update(status=0) + st = [(x.student,x.status) for x in CSCTestAtttendance.objects.filter(test=test)] + context['students'] = st + + total_enrolled = CSCTestAtttendance.objects.filter(test=test).count() + pending = CSCTestAtttendance.objects.filter(test=test,status=STUDENT_ENROLLED_FOR_TEST).count() + attendance_marked = total_enrolled - pending + context['total_enrolled'] = total_enrolled + context['attending'] = attendance_marked + context['pending'] = pending + return render(request,'csc/mark_attendance.html',context) + +@csrf_exempt +def check_vle_email(request): + data = {} + email = request.POST.get('email','') + print(f"email - :{email}") + # Code to be used later when csc adds date payload in api + # last_update_date = VLE.objects.order_by('user__date_joined').last().user.date_joined + # delta_date = last_update_date - timedelta(2) + # payload = {'date':delta_date} + url = getattr(settings, "URL_FETCH_VLE", "http://exam.cscacademy.org/shareiitbombayspokentutorial") + # response = requests.get(url,params=payload) + response = requests.get(url) + data['status'] = 0 + if response.status_code == 200: + result = response.json()['req_data'] + # result = response.json() + # result = result['req_data'] + for item in result: + if email == item['email']: + logging.debug("Found email matching csc.") + try: + csc = CSC.objects.get(csc_id=item['csc_id']) + except CSC.DoesNotExist: + print(f"**csc - {item['csc_id']} does not exists") + CSC.objects.create( + csc_id=item.get('csc_id'),institute=item.get('institute_name',''),state=item.get('state',''), + city=item.get('city',''),district=item.get('district',''),block=item.get('block',''), + address=item.get('address',''),pincode=item.get('pincode',''),plan=item.get('plan',''), + activation_status=1 + ) + csc = CSC.objects.get(csc_id=item.get('csc_id')) + add_vle(item,csc) + vle = VLE.objects.get(user__email=email) + add_transaction(vle,csc,item['transcdate']) + # messages.add_message(request,messages.INFO,'hello') + data['status'] = 1 + else: + data['status'] = 2 + + return JsonResponse(data) + + + +# Test related views start +def test(request): + context = {} + form = TestForm(user=request.user) + if request.method == 'POST': + form = TestForm(request.POST,user=request.user) + if form.is_valid(): + test_data=form.save(commit=False) + vle = VLE.objects.filter(user=request.user)[0] + test_data.vle = vle + test_data.save() + form.save_m2m() + # messages.success(request,"Test added successfully.") + messages.add_message(request,messages.SUCCESS,f'Test added successfully.') + context['form'] = form + + return render(request,'csc/test.html',context) + +def test_assign(request): + context = {} + vle = VLE.objects.get(user=request.user) + students = [x['id'] for x in Student.objects.filter(vle_id=vle.id).values('id')] + valid_foss_for_tests = [x['csc_foss'] for x in Student_Foss.objects.filter(student_id__in=students).values('csc_foss').distinct()] + tests = Test.objects.filter(vle=vle,status=TEST_OPEN,foss_id__in=valid_foss_for_tests).order_by('-tdate','foss__foss') + context['tests'] = tests + test = request.POST.get('test') + if test and test!='0': + context['test'] = test + try: + test = tests.get(id=int(test)) + context['test'] = test.id + foss = test.foss + context['students'] = get_valid_students_for_test(vle,test) + except Exception as e: + print(e) + else: + return render(request,'csc/test_assign.html',context) + + if request.method == 'POST' and request.POST.get('action_type') == 'add_students': + assigned_students = request.POST.getlist('students') + try: + fossMdlCourse = CSCFossMdlCourses.objects.filter(foss=foss)[0] #ToDo Change + mdlcourse_id = fossMdlCourse.mdlcourse_id + mdlquiz_id = fossMdlCourse.mdlquiz_id + for email in assigned_students: + user = User.objects.get(Q(username=email) | Q(email=email)) + student = Student.objects.get(user=user) + try: + mdluser=MdlUser.objects.get(email=email) + except MdlUser.DoesNotExist: + pwd = ''.join(random.choices(string.ascii_letters,k=10)) + encryp_pwd = hashlib.md5((pwd).encode('utf-8')).hexdigest() + mdluser = MdlUser.objects.create(username=email,firstname=user.first_name,lastname=user.last_name,email=email,password=encryp_pwd,mnethostid=1,confirmed=1) + send_mdl_mail(user,pwd) + mdluser = MdlUser.objects.get(email=email) + except MdlUser.MultipleObjectsReturned as e: + mdluser=MdlUser.objects.filter(email=email)[0] + print(e) + try: + ta = CSCTestAtttendance.objects.create(test=test,student=student,mdluser_id=mdluser.id,mdlcourse_id=mdlcourse_id,status=0,mdlquiz_id=mdlquiz_id) + except IntegrityError as e: + print(e) + if request.POST.get('action_type') == 'add_students': + nta = CSCTestAtttendance.objects.filter(test=test).exclude(student__user__email__in=assigned_students) + for item in nta: + item.delete() + else: + print(f"\n\n action type is NOT add_students **************************** ") + messages.add_message(request,messages.SUCCESS,f'Test assigned to the students.') + except Exception as e: + print(e) + messages.error(request,"No test in moodle for the selected foss.Please contact support.") + return render(request,'csc/test_assign.html',context) + return render(request,'csc/test_assign.html',context) + + +def test_list(request): + context = {} + vle = VLE.objects.get(user=request.user) + tests = Test.objects.filter(vle=vle) + context['tests'] = tests + return render(request,'csc/test_list.html',context) + +def update_test(request,pk): + context = {} + if request.method == 'GET': + test = Test.objects.filter(id=pk)[0] + d = model_to_dict(test) + td = model_to_dict(test) + td['foss'] = test.foss.id + form = TestForm(initial=td,user=request.user) + # form = TestForm(initial=model_to_dict(test),user=request.user) + if request.method == 'POST': + t = Test.objects.get(id=pk) + form = TestForm(request.POST,instance=t,user=request.user) + if form.is_valid(): + form.save() + messages.add_message(request,messages.SUCCESS,f'Test updated.') + + context['form'] = form + + return render(request,'csc/update_test.html',context) + +def invigilator(request): + context = {} + vle = VLE.objects.get(user=request.user) + invigilators = Invigilator.objects.filter(vle=vle) + context['invigilators']=invigilators + form_empty = InvigilatorForm() + context['form_empty']=form_empty + + form = InvigilatorForm() + add = request.POST.get('add') + edit = request.POST.get('edit') + + if request.method == 'GET': + if request.GET.get('invi'): + invi = request.GET.get('invi') + invi_obj = Invigilator.objects.get(id=invi) + i = model_to_dict(invi_obj.user) + i['phone'] = invi_obj.phone + form = InvigilatorForm(initial=i) + context['invi_id']=invi_obj.id + if request.method == 'POST': + if add: + form = InvigilatorForm(request.POST) + if form.is_valid(): + email = form.cleaned_data['email'] + phone=form.cleaned_data['phone'] + check_user = User.objects.filter(Q(email=email) | Q(username=email)) + if check_user: + check_user_invi = Invigilator.objects.filter(user=check_user[0],vle=vle) + if check_user_invi: + messages.add_message(request,messages.ERROR,f'Invigilator with email {email} already exists in your account.No changes have been made.') + return render(request,'csc/invigilator.html',context) + else: + invi=Invigilator.objects.create(user=check_user[0],phone=phone,vle=vle) + messages.add_message(request,messages.INFO,f'User with email {email} already exists in the system & has been assigned to you as an invigilator.') + return render(request,'csc/invigilator.html',context) + + u=form.save(commit=False) + u.username = email + u.save() + invi=Invigilator.objects.create(user=u,phone=phone,vle=vle) + messages.add_message(request,messages.SUCCESS,f'Invigilator with email {email} is added.') + if edit: + invi = request.POST.get('invi_id') + invi_obj = Invigilator.objects.get(id=invi) + context['invi_id']=invi_obj.id + i = model_to_dict(invi_obj.user) + i['phone'] = invi_obj.phone + form = InvigilatorForm(request.POST,instance=invi_obj.user) + if form.is_valid(): + u=form.save(commit=False) + # u.username = form.cleaned_data['email'] + u.save() + invi_obj.phone=form.cleaned_data['phone'] + invi_obj.save() + messages.add_message(request,messages.SUCCESS,f'Invigilator details updated successfully.') + else: + print(f"\n\n 11 errors*********************\n{form.errors}") + context['form'] = form + context['invigilator'] = form + + + + + return render(request,'csc/invigilator.html',context) + + +def create_invigilatordelete_invigilator(request): + data = {} + try: + + invi=request.GET.get("invi") + i=Invigilator.objects.get(id=invi) + email = i.user.email + i.delete() + messages.add_message(request,messages.SUCCESS,f'Invigilator {email} deleted successfully.') + data['status'] = 1 + except: + data['status'] = 0 + # return redirect('/csc/invigilator') + return JsonResponse(data) + +# invigilator views + +def create_invigilator(request): + context ={} + send_mail = False + vle = VLE.objects.get(user=request.user) + form = InvigilatorForm(request.POST or None) + context['form'] = form + if form.is_valid(): + email = form.cleaned_data['email'] + first_name = form.cleaned_data['first_name'] + last_name = form.cleaned_data['last_name'] + phone = form.cleaned_data['phone'] + try: + user = User.objects.get(email=email) + messages.add_message(request,messages.SUCCESS,f'User with this email {email} already exists & assigned to you as an Invigilator.') + except User.DoesNotExist: + user = User.objects.create(username=email,email=email,first_name=first_name,last_name=last_name) + send_mail = True + messages.add_message(request,messages.SUCCESS,f'User email {email} is assigned to you as an Invigilator.') + except User.MultipleObjectsReturned: + user = User.objects.filter(email=email)[0] + messages.add_message(request,messages.SUCCESS,f'User with this email {email} already exists & assigned to you as an Invigilator.') + try: + # Invigilator.objects.create(user=user,vle=vle,phone=phone) + i=Invigilator.objects.create(user=user,phone=phone) + print(f"invi ************************************ {i}") + i.vle.add(vle) + invi_group = Group.objects.get(name='INVIGILATOR') + invi_group.user_set.add(user) + if send_mail: + send_pwd_mail_to_invi(user) + except IntegrityError: + messages.add_message(request,messages.ERROR,f'User with this email {email} has already been assigned to you as an Invigilator.') + except Exception as e: + print(e) + return render(request,'csc/create_invigilator.html',context) + +def view_invigilators(request): + context = {} + vle = VLE.objects.get(user=request.user) + invigilators = Invigilator.objects.filter(vle=vle) + context['invigilators'] = invigilators + return render(request,'csc/list_invigilators.html',context) + +def update_invigilator(request,id): + context = {} + invi = get_object_or_404(Invigilator, id = id) + # form = InvigilatorForm(request.POST or None) + if request.method == 'GET': + data = {'phone': invi.phone, 'first_name': invi.user.first_name,'last_name': invi.user.last_name,'email': invi.user.email} + form = InvigilatorForm(initial=data) + form.fields['email'].disabled = True + context['form'] = form + else: + + + form = InvigilatorForm(request.POST) + if form.is_valid(): + phone = form.cleaned_data['phone'] + first_name = form.cleaned_data['first_name'] + last_name = form.cleaned_data['last_name'] + invi.phone = phone + invi.save() + user = invi.user + user.first_name = first_name + user.last_name = last_name + user.save() + else: + print(f"4 error ****************************** {form.non_field_errors}") + data = {'phone': invi.phone, 'first_name': invi.user.first_name,'last_name': invi.user.last_name,'email': invi.user.email} + form = InvigilatorForm(initial=data) + form.fields['email'].disabled = True + context['form'] = form + return render(request,'csc/update_invigilator.html',context) + +def delete_invigilator(request, id): + context ={} + obj = get_object_or_404(Invigilator, id = id) + if request.method =="POST": + obj.delete() + return redirect('csc:view_invigilators') + return render(request, "delete_view.html", context) + +class InvigilatorDeleteView(DeleteView): + model = Invigilator + success_url ="/" + template_name = "csc/invigilator_confirm_delete.html" + +def invi_dashboard(request): + context = {} + invi = Invigilator.objects.get(user=request.user) + upcoming_tests = Test.objects.filter(invigilator=invi,tdate__gte=datetime.datetime.today()) + completed_tests = Test.objects.filter(invigilator=invi,tdate__lt=datetime.datetime.today()) + context['upcoming_tests'] = upcoming_tests + context['completed_tests'] = completed_tests + return render(request,'csc/invigilator_dashboard.html',context) + + +# ajax functions +@csrf_exempt +def assign_foss(request): + vle = VLE.objects.get(user=request.user) + students = request.POST.getlist('student[]') + fosses = request.POST.getlist('foss[]') + f = FossCategory.objects.filter(foss__in=[x for x in fosses]).values_list('foss') + foss_name = ', '.join([x[0] for x in f]) + for student in students: + #check if student has individual + for foss in fosses: + try: + f = FossCategory.objects.get(foss=foss) + s = Student.objects.get(id=int(student)) + c = CertifiateCategories.objects.get(code='INDI') + scc = Student_certificate_course.objects.get(student=s,cert_category=c) + Student_Foss.objects.create(student=s,csc_foss=f,cert_category=scc.cert_category,foss_start_date=datetime.date.today()) + except Exception as e: + print(e) + + return JsonResponse({'foss':foss_name,'student_count':len(students)}) \ No newline at end of file diff --git a/logs/utils.py b/logs/utils.py index 345a9f7..9457a7f 100644 --- a/logs/utils.py +++ b/logs/utils.py @@ -24,7 +24,7 @@ def get_payload(instance): } }, "object": { - "id": "https://spoken-tutorial.in/spoken/tutorial-search/?search_foss={}&search_language={}".format(instance.foss, instance.language), + "id": "https://beta.spoken-tutorial.in/spoken/tutorial-search/?search_foss={}&search_language={}".format(instance.foss, instance.language), "definition": { "name": { "en-US": "Spoken-Tutorial-"+instance.foss.replace(' ', '-')+"-"+instance.language diff --git a/logs/views.py b/logs/views.py index d6eed1b..c08399d 100644 --- a/logs/views.py +++ b/logs/views.py @@ -3,8 +3,9 @@ from rest_framework.response import Response from rest_framework import status from rest_framework.permissions import IsAuthenticated +from drf_yasg.utils import swagger_auto_schema from .models import TutorialProgress - +@swagger_auto_schema(methods=['post'], auto_schema=None) @api_view(['POST']) @permission_classes([IsAuthenticated]) def save_tutorial_progress(request): @@ -15,9 +16,11 @@ def save_tutorial_progress(request): return Response(serializer.data, status=status.HTTP_200_OK) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) +@swagger_auto_schema(methods=['get','post'], auto_schema=None) @api_view(['GET','POST']) @permission_classes([IsAuthenticated]) def get_set_tutorial_progress(request): + try: tp=TutorialProgress.objects.get( user=request.user, diff --git a/mdl/__init__.py b/mdl/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/mdl/admin.py b/mdl/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/mdl/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/mdl/apps.py b/mdl/apps.py new file mode 100644 index 0000000..8cc5932 --- /dev/null +++ b/mdl/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class MdlConfig(AppConfig): + name = 'mdl' diff --git a/mdl/migrations/0001_initial.py b/mdl/migrations/0001_initial.py new file mode 100644 index 0000000..08fe410 --- /dev/null +++ b/mdl/migrations/0001_initial.py @@ -0,0 +1,68 @@ +# Generated by Django 3.0.3 on 2022-10-31 07:16 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='MdlQuizAttempts', + fields=[ + ('id', models.BigIntegerField(primary_key=True, serialize=False)), + ('quiz', models.BigIntegerField()), + ('userid', models.BigIntegerField()), + ('attempt', models.IntegerField(unique=True)), + ('uniqueid', models.BigIntegerField(unique=True)), + ('layout', models.TextField()), + ('currentpage', models.BigIntegerField()), + ('preview', models.IntegerField()), + ('state', models.CharField(max_length=48)), + ('timestart', models.BigIntegerField()), + ('timefinish', models.BigIntegerField()), + ('timemodified', models.BigIntegerField()), + ('timemodifiedoffline', models.BigIntegerField()), + ('timecheckstate', models.BigIntegerField(blank=True, null=True)), + ('sumgrades', models.DecimalField(blank=True, decimal_places=5, max_digits=12, null=True)), + ], + options={ + 'db_table': 'mdl_quiz_attempts', + 'managed': False, + }, + ), + migrations.CreateModel( + name='MdlQuizGrades', + fields=[ + ('id', models.BigIntegerField(primary_key=True, serialize=False)), + ('quiz', models.BigIntegerField()), + ('userid', models.BigIntegerField()), + ('grade', models.DecimalField(decimal_places=5, max_digits=12)), + ('timemodified', models.BigIntegerField()), + ], + options={ + 'db_table': 'mdl_quiz_grades', + 'managed': False, + }, + ), + migrations.CreateModel( + name='MdlUser', + fields=[ + ('id', models.BigIntegerField(primary_key=True, serialize=False)), + ('username', models.CharField(max_length=255, unique=True)), + ('password', models.CharField(max_length=96)), + ('idnumber', models.CharField(max_length=765)), + ('firstname', models.CharField(max_length=300)), + ('lastname', models.CharField(max_length=300)), + ('email', models.CharField(max_length=300)), + ], + options={ + 'db_table': 'mdl_user', + 'managed': False, + }, + ), + ] diff --git a/mdl/migrations/__init__.py b/mdl/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/mdl/models.py b/mdl/models.py new file mode 100644 index 0000000..2f28b5e --- /dev/null +++ b/mdl/models.py @@ -0,0 +1,50 @@ +from django.db import models + +# Create your models here. +class MdlUser(models.Model): + id = models.BigIntegerField(primary_key=True) + username = models.CharField(unique=True, max_length=255) + password = models.CharField(max_length=96) + idnumber = models.CharField(max_length=765) + firstname = models.CharField(max_length=300) + lastname = models.CharField(max_length=300) + email = models.CharField(max_length=300) + confirmed = models.IntegerField() + mnethostid = models.IntegerField() + class Meta(object): + db_table = 'mdl_user' + managed = False + +class MdlQuizGrades(models.Model): + id = models.BigIntegerField(primary_key=True) + quiz = models.BigIntegerField() + userid = models.BigIntegerField() + grade = models.DecimalField(max_digits=12, decimal_places=5) + timemodified = models.BigIntegerField() + class Meta(object): + db_table = 'mdl_quiz_grades' + managed = False + +class MdlQuizAttempts(models.Model): + id = models.BigIntegerField(primary_key=True) + quiz = models.BigIntegerField() + userid = models.BigIntegerField() + attempt = models.IntegerField(unique=True) + uniqueid = models.BigIntegerField(unique=True) + layout = models.TextField() + currentpage = models.BigIntegerField() + preview = models.IntegerField() + state = models.CharField(max_length=48) + timestart = models.BigIntegerField() + timefinish = models.BigIntegerField() + timemodified = models.BigIntegerField() + timemodifiedoffline = models.BigIntegerField() + timecheckstate = models.BigIntegerField(null=True, blank=True) + sumgrades = models.DecimalField(null=True, max_digits=12, decimal_places=5, blank=True) + class Meta(object): + db_table = 'mdl_quiz_attempts' + managed = False + + + + \ No newline at end of file diff --git a/mdl/tests.py b/mdl/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/mdl/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/mdl/views.py b/mdl/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/mdl/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/requirements.txt b/requirements.txt index c593f72..1f692dd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,9 +2,48 @@ Django==3.0.3 mysqlclient==1.4.6 python-dotenv==0.11.0 django-crispy-forms==1.8.1 -djangorestframework==3.11.0 -django-model-utils==4.0.0 +asgiref==3.5.2 +certifi==2022.9.14 +chardet==3.0.4 +coreapi==2.3.3 +coreschema==0.0.4 +defusedxml==0.7.1 +diff-match-patch==20200713 +django-crontab==0.7.1 django-import-export==2.0.2 +django-model-utils==4.0.0 django-mysql==3.4.0 +django-rest-swagger==2.2.0 +djangorestframework==3.11.0 +drf-yasg==1.21.3 +et-xmlfile==1.1.0 +idna==2.10 +inflection==0.5.1 +isodate==0.6.1 +itypes==1.2.0 +Jinja2==3.1.2 +lxml==4.9.1 +MarkupPy==1.14 +MarkupSafe==2.1.1 +odfpy==1.4.1 +openapi-codec==1.3.2 +openpyxl==3.0.10 +packaging==21.3 +pyparsing==3.0.9 python3-saml==1.9.0 -requests==2.24.0 \ No newline at end of file +pytz==2022.2.1 +PyYAML==6.0 +requests==2.24.0 +ruamel.yaml==0.17.21 +ruamel.yaml.clib==0.2.6 +simplejson==3.17.6 +six==1.16.0 +sqlparse==0.4.2 +tablib==3.2.1 +uritemplate==4.1.1 +urllib3==1.25.11 +xlrd==2.0.1 +xlwt==1.3.0 +xmlsec==1.3.13 +django-widget-tweaks==1.4.3 + diff --git a/spoken/api.py b/spoken/api.py index b82d1ca..e70f94b 100644 --- a/spoken/api.py +++ b/spoken/api.py @@ -1,10 +1,12 @@ +from django.urls import reverse from rest_framework.renderers import TemplateHTMLRenderer from rest_framework.response import Response from rest_framework.views import APIView from .utils import * from logs.models import TutorialProgress,CourseProgress - +from csc.utils import is_user_vle,is_user_student class TutorialSearchAPI(APIView): + swagger_schema = None """ Search tutorial based on get url parameters. Parameters: (search_foss, search_language) @@ -45,6 +47,10 @@ def get(self, request, format=None): except: context["time_completed"] = 0 context["video_status"] = False + if is_user_vle(request.user): + context["is_csc_vle"] = is_user_vle(request.user) + if is_user_student(request.user): + context["is_csc_student"] = is_user_student(request.user) context["foss_lang_list"] = get_all_foss_lang() return Response(context) \ No newline at end of file diff --git a/spoken/templates/spoken/base.html b/spoken/templates/spoken/base.html index ed5d1ea..47c8b02 100644 --- a/spoken/templates/spoken/base.html +++ b/spoken/templates/spoken/base.html @@ -1,4 +1,5 @@ {% load static%} +{% load helper %} {% load crispy_forms_tags %} @@ -6,19 +7,16 @@ - - + - - {% block title%}Spoken Tutorial{% endblock title%} {% block css %}{% endblock css %} - +
{% else %} + + {% endif %}
@@ -73,6 +116,7 @@ + diff --git a/spoken/templates/spoken/home.html b/spoken/templates/spoken/home.html index 875b92e..1de840d 100644 --- a/spoken/templates/spoken/home.html +++ b/spoken/templates/spoken/home.html @@ -358,7 +358,7 @@

Contact

+ 91 22 25764229

contact@spoken-tutorial.org

-
+
{% if messages %}
    {% for message in messages %} diff --git a/spoken/templatetags/helper.py b/spoken/templatetags/helper.py index 51f5f64..d22cd74 100644 --- a/spoken/templatetags/helper.py +++ b/spoken/templatetags/helper.py @@ -33,4 +33,8 @@ def get_formatted_year(start,end): formatted_date=start.strftime("%d")+' '+start.strftime("%b")+' - '+end.strftime("%d")+' '+end.strftime("%b")+' '+start.strftime("%Y") else: formatted_date=start.strftime("%d")+' '+start.strftime("%b")+' '+start.strftime("%Y")+' - '+end.strftime("%d")+' '+end.strftime("%b")+' '+end.strftime("%Y") - return formatted_date \ No newline at end of file + return formatted_date + +@register.filter(name='has_group') +def has_group(user, group_name): + return user.groups.filter(name=group_name).exists() \ No newline at end of file diff --git a/spoken/views.py b/spoken/views.py index e1974c9..9b9146c 100644 --- a/spoken/views.py +++ b/spoken/views.py @@ -1,6 +1,7 @@ from django.shortcuts import render, redirect from django.conf import settings # Create your views here. +from django.urls import reverse from django.http import HttpResponse, HttpResponseRedirect from .models import ContactMsg, Products, Nav, Blended_workshops, Jobfair, Internship, Testimonials, MediaTestimonials, Award from django_ers.models import * @@ -29,6 +30,7 @@ import numpy as np from django.conf import settings + today = datetime.today().strftime('%Y-%m-%d') def home(request): @@ -74,6 +76,11 @@ def home(request): c = ContactForm() # return HttpResponse("Hello, world. You're at the spoken landing page.") + group = [x.name for x in request.user.groups.all()] + # if 'VLE' in group: + # return HttpResponseRedirect(reverse('csc:vle_dashboard')) + # if 'STUDENT' in group: + # return HttpResponseRedirect(reverse('student:student_dashboard')) navs = Nav.objects.filter(status=1) products = Products.objects.all().order_by('order') now = timezone.now() @@ -94,6 +101,7 @@ def home(request): #api/jobfairs/ class JobFairList(APIView): + swagger_schema = None def get(self,request): # jobfairs = Jobfair.objects.all() jobfairs = Event.objects.filter(type='JOB') diff --git a/spoken_main_website/settings.py b/spoken_main_website/settings.py index 48c0cdc..c820049 100644 --- a/spoken_main_website/settings.py +++ b/spoken_main_website/settings.py @@ -1,4 +1,5 @@ from dotenv import load_dotenv +from django.contrib.messages import constants as messages """ Django settings for spoken_main_website project. @@ -27,6 +28,7 @@ # SECURITY WARNING: don't run with debug turned on in production! DEBUG = os.getenv("DEBUG") + ALLOWED_HOSTS = ["*"] # Application definition @@ -48,6 +50,14 @@ 'csc', 'django_crontab', 'django_ers', + 'cms', + 'cdcontent', + 'rest_framework.authtoken', + 'drf_yasg', + 'widget_tweaks', + # 'masquerade', + 'mdl', + # 'rest_framework_swagger', ] @@ -57,6 +67,7 @@ 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', + # 'masquerade.middleware.MasqueradeMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'sso.middleware.SSO', @@ -68,7 +79,9 @@ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates'), - os.path.join(BASE_DIR, 'spoken', 'templates', 'spoken'),], + os.path.join(BASE_DIR, 'spoken', 'templates', 'spoken'), + os.path.join(BASE_DIR, 'csc', 'templates', 'csc'), + ], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ @@ -116,6 +129,23 @@ 'HOST': os.getenv("ERS_DB_HOST"), 'PORT':'', }, + 'forums': { + 'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'. + 'NAME': os.getenv("FDB"), # Or path to database file if using sqlite3. + 'USER': os.getenv("FDB_USER"), + 'PASSWORD': os.getenv("FDB_PASS"), + 'HOST': os.getenv("FDB_DB_HOST"), # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP. + 'PORT': '', # Set to empty string for default. + }, + 'moodle': { + 'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'. + 'NAME': os.getenv("MDL"), # Or path to database file if using sqlite3. + 'USER': os.getenv("MDL_USER"), + 'PASSWORD': os.getenv("MDL_PASS"), + 'HOST': os.getenv("MDL_DB_HOST"), # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP. + 'PORT': '', # Set to empty string for default. + }, + } @@ -173,8 +203,9 @@ SAML_FOLDER = os.path.join(BASE_DIR, 'saml') AUTHENTICATION_BACKENDS = [ + 'csc.backends.CSCBackend', 'spokenlogin.backends.SpokenBackend', - 'sso.backends.SSOBackend', + # 'sso.backends.SSOBackend', 'django.contrib.auth.backends.ModelBackend' ] @@ -195,7 +226,13 @@ REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': [ 'rest_framework.renderers.JSONRenderer' + ], + 'DEFAULT_AUTHENTICATION_CLASSES':[ + "rest_framework.authentication.BasicAuthentication", + "rest_framework.authentication.SessionAuthentication", + "rest_framework.authentication.TokenAuthentication", ] + } LOGIN_URL='/login/' @@ -228,3 +265,31 @@ CRONJOBS = [ ('8 13 * * *', 'csc.cron.update_vle_data') ] +SWAGGER_SETTINGS = { + "SECURITY_DEFINITIONS":{ + "Token": {"type": "apiKey", "name": "Authorization", + "in": "header"}, + "Basic": {"type": "basic"}, + } +} + +MESSAGE_TAGS = { + messages.INFO: 'info', + messages.SUCCESS: 'success', + messages.WARNING: 'warning', + messages.ERROR: 'danger', + +} +CSC_SUBSCRIPTION_PERIOD = 100 + + +TEST_VLE_COUNT=os.getenv("TEST_VLE_COUNT") +TEST_STUDENT_COUNT=os.getenv("TEST_STUDENT_COUNT") +TEST_VLE_EMAIL=os.getenv("TEST_VLE_EMAIL").split(' ') +TEST_STUDENT_EMAIL=os.getenv("TEST_STUDENT_EMAIL").split(' ') +TEST_CSC_ID=os.getenv("TEST_CSC_ID").split(' ') + +CSC_ONLINE_TEST_URL = os.getenv("CSC_ONLINE_TEST_URL") +MDL_URL = os.getenv("MDL_URL") + + diff --git a/spoken_main_website/urls.py b/spoken_main_website/urls.py index 7b1d1ac..dac35e9 100644 --- a/spoken_main_website/urls.py +++ b/spoken_main_website/urls.py @@ -20,6 +20,7 @@ from django.conf import settings from django.conf.urls.static import static from django.contrib.auth import views as auth_views +from spokenlogin import views urlpatterns = [ path('admin/', admin.site.urls), @@ -30,7 +31,20 @@ url(r'^$', spoken_views.home, name='home'), path('logout/', auth_views.LogoutView.as_view(), name='logout'), path('dashboard/', spoken_views.dashboard, name='dashboard'), - path('login/', auth_views.LoginView.as_view(template_name='spokenlogin/login.html',redirect_authenticated_user=True), name='login'), + path('login/', auth_views.LoginView.as_view(template_name='spokenlogin/login.html',redirect_authenticated_user=True), name='login_other'), # path('csc/', include('csc.vle_urls')), + path('csc/student/', include('csc.student_urls', namespace='student')), path('csc/', include('csc.vle_urls', namespace='csc')), + path('csc/api/v1/', include('csc.api.urls')), + path('csc/stats/', include('csc.stats.urls')), + path('cms/api/v1/', include('cms.api.urls')), + path('cdcontent/', include('cdcontent.urls')), + + path('accounts/', include('django.contrib.auth.urls')), + # path('masquerade/', include('masquerade.urls')), + + + + path('change/', views.change, name='change'), + path('password/', views.password, name='password') ]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/spokenlogin/backends.py b/spokenlogin/backends.py index d23dd24..29d4eb4 100644 --- a/spokenlogin/backends.py +++ b/spokenlogin/backends.py @@ -25,7 +25,7 @@ def authenticate(self, request, username=None, password=None): user.save() return user except SpokenUser.DoesNotExist: - return None + return None def get_user(self, user_id): try: diff --git a/spokenlogin/router.py b/spokenlogin/router.py index d52dcdd..5fbfede 100644 --- a/spokenlogin/router.py +++ b/spokenlogin/router.py @@ -1,13 +1,22 @@ class SpokenRouter: def db_for_read(self, model, **hints): + if model._meta.db_table == 'website_question' or model._meta.db_table == 'website_answer': + return 'forums' if model._meta.app_label == 'spokenlogin': return 'spk' + if model._meta.app_label == 'cdcontent': + return 'spk' + if model._meta.app_label == 'mdl': + return 'moodle' + return None def db_for_write(self, model, **hints): if model._meta.app_label == 'spokenlogin': return 'spk' + if model._meta.app_label == 'mdl': + return 'moodle' return 'default' def allow_relation(self, obj1, obj2, **hints): diff --git a/spokenlogin/templates/registration/change.html b/spokenlogin/templates/registration/change.html new file mode 100644 index 0000000..1ed27a2 --- /dev/null +++ b/spokenlogin/templates/registration/change.html @@ -0,0 +1,24 @@ +{% extends 'spoken/base.html' %} +{% load crispy_forms_tags %} +{% block content %} +
    + {% include 'spokenlogin/messages.html' %} +
    +

    Change Password

    +
    +
    +
    + {% csrf_token %} +
    + + +
    +
    + + +
    + +
    +
    +
    +{% endblock %} diff --git a/spokenlogin/templates/registration/done.html b/spokenlogin/templates/registration/done.html new file mode 100644 index 0000000..b3c378e --- /dev/null +++ b/spokenlogin/templates/registration/done.html @@ -0,0 +1,5 @@ +

    Change Password Done

    +
    +

    Password Change Succesfull, Login In.

    + Log In +
    \ No newline at end of file diff --git a/spokenlogin/templates/registration/login.html b/spokenlogin/templates/registration/login.html new file mode 100644 index 0000000..c194eda --- /dev/null +++ b/spokenlogin/templates/registration/login.html @@ -0,0 +1,108 @@ +{% extends 'spoken/base.html' %} +{% load crispy_forms_tags %} +{% block content %} +
    + +
    + + {% include 'spokenlogin/messages.html' %} +
    +

    Login

    +
    + {% csrf_token %} + {{ form|crispy }} + +
    + +
    + + {% comment %} + {% comment %} +
    +

    Not a user ?

    + Register +
    +
    + {% endcomment %} +
    +
    + + + +{% endblock %} + +{% block script %} + + + +{% endblock %} \ No newline at end of file diff --git a/spokenlogin/templates/registration/password.html b/spokenlogin/templates/registration/password.html new file mode 100644 index 0000000..a59d379 --- /dev/null +++ b/spokenlogin/templates/registration/password.html @@ -0,0 +1,16 @@ +{% extends 'spoken/base.html' %} +{% load crispy_forms_tags %} +{% block content %} +
    + {% include 'spokenlogin/messages.html' %} +
    +

    Forget Password

    +
    +
    + {% csrf_token %} + + + +
    +
    +{% endblock %} diff --git a/spokenlogin/templates/spokenlogin/login.html b/spokenlogin/templates/spokenlogin/login.html index 0be52a0..9ae2637 100644 --- a/spokenlogin/templates/spokenlogin/login.html +++ b/spokenlogin/templates/spokenlogin/login.html @@ -4,9 +4,9 @@
    -
    +{% endblock %} + +{% block script %} + + + {% endblock %} \ No newline at end of file diff --git a/spokenlogin/views.py b/spokenlogin/views.py index 91ea44a..2600b2e 100644 --- a/spokenlogin/views.py +++ b/spokenlogin/views.py @@ -1,3 +1,30 @@ -from django.shortcuts import render +from django.shortcuts import render, redirect +from django.contrib.auth.models import User +from csc.api.utility import send_pwd_mail +from django.contrib import messages # Create your views here. +def password(request): + if request.method == 'POST': + email = request.POST['email'] + try: + user = User.objects.get(username=email) + send_pwd_mail(user) + messages.add_message(request, messages.SUCCESS, 'Password Mail Sent Successfully.') + return redirect('/') + except User.DoesNotExist: + messages.add_message(request, messages.WARNING, 'User DoesNotExist.') + return redirect('/') + return render(request, 'registration/password.html') + +def change(request): + if request.method == 'POST': + user = User.objects.get(username=request.user.username) + new = request.POST['new'] + confirm = request.POST['confirm'] + if new == confirm: + user.set_password(new) + user.save() + messages.add_message(request, messages.SUCCESS, 'Password Changed Successfully') + return redirect('/') + return render(request, 'registration/change.html') diff --git a/static/cdcontent/css/cdcontent.css b/static/cdcontent/css/cdcontent.css new file mode 100644 index 0000000..83b57be --- /dev/null +++ b/static/cdcontent/css/cdcontent.css @@ -0,0 +1,256 @@ +.add-foss{margin-right: 15px;} + #id_language {min-height: 180px;} + .delete-btn{padding: 0;color: red;} + #user_file_size{padding-bottom: 10px;} + .rate-chart{overflow: hidden;} + .rate-chart *{overflow: hidden;} + .payment-details{font-weight: bold;} + .display-foss{height: auto;overflow:hidden;} + #key-btn{ + border: 2px solid #286090; + font-weight: bold; + font-size: 1rem; + color: #286090; + background-color: white; + padding: 5px 20px 5px 20px; + font-family: "Times New Roman", Times, serif; + font-family: Arial, Helvetica, sans-serif; + margin-left: 20px; + border-radius: 5px; + } + .c-blue{ + color: rgb(1, 87, 155); +} +.c-card{ + border: 1px solid rgba(0,0,0,.125); + display: flex; + flex-direction: column; + border-radius: .25rem; + margin:2px 15px; + padding-left: 0!important; + padding-right: 0!important; +} +.c-card-header{ + font-weight: 400; + line-height: 1.5 + color:rgb(1, 87, 155); + text-align: left; + padding:.5rem 1.25rem; + background-color: rgba(0,0,0,.03); + border-bottom: 1px solid rgba(0,0,0,.125); + box-sizing: border-box; + font-size: 1.4rem; + background-color: rgba(1, 87, 155,0.8); + color: white; +} +.c-card-title{ + font-size:1.4rem!important; + color:rgb(1, 87, 155); +} +.c-card-body{ + padding:0 1.25rem; + height: 240px; + border: 1px solid rgb(1, 87, 155); +} +.c-card-body li{ + font-size:1.1rem; + line-height: 1.5; +} +.fa-check{ + color:#43A047; + margin-right: 16px; +} +.fa-times{ + color: #F44335; + margin-right: 16px; +} +.custom-btn{ + padding: 4px 12px 4px 12px; + color: rgb(1, 87, 155); + border-radius: 5px; + font-size: 1.1rem; + border: 1px solid rgb(1, 87, 155); + background-color: white; +} +.c-btn{ + padding: 6px 12px 6px 12px; + color: rgb(1, 87, 155); + border-radius: 5px; + font-size: 1.1rem; +} +.c-btn:hover{ + border: 1px solid rgb(1, 87, 155); + padding: 6px 12px 6px 12px; + background-color: rgb(1, 87, 155); + color: white; + border-radius: 5px; +} + +.sidebar-box { + max-height: 180px; + position: relative; + overflow: hidden; + z-index: 2; + background-color: #e3f2fd; + background-color: #e0f2f1; + background-color: rgba(224,242,241,0.2); +} +.sidebar-box .read-more { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + text-align: center; + margin: 0; padding: 2px 0; + font-size: 1.2rem; + background-image: linear-gradient(to bottom, transparent, black); + background-image: linear-gradient(to bottom, transparent, rgba(224,242,241,0.8)); + background-image: linear-gradient(to bottom, transparent, rgba(255,255,255,0.8)); +} +.sidebar-box .read-more span{ + border-bottom: 2px solid rgb(1, 87, 155); + padding: 2px 5px; + font-size: 1.2rem; +} +.fa-check-circle{ + margin-top: 10px; + margin-left: 10px; + color: green; + font-size: 1.4rem!important; +} +.collapsible { + background-color: #777; + color: white; + cursor: pointer; + padding: 15px; + width: 100%; + border: none; + text-align: left; + outline: none; + font-size: 15px; +} + +.active, .collapsible:hover { + background-color: #555; +} + +.content { + padding: 0 18px; + max-height: 0; + overflow: hidden; + transition: max-height 0.2s ease-out; + background-color: #f1f1f1; +} + +.bounce { + -moz-animation: bounce 3s infinite; + -webkit-animation: bounce 3s infinite; + animation: bounce 3s infinite; +} +@-moz-keyframes bounce { + 0%, 20%, 50%, 80%, 100% { + -moz-transform: translateY(0); + transform: translateY(0); + } + 40% { + -moz-transform: translateY(-20px); + transform: translateY(-20px); + } + 60% { + -moz-transform: translateY(-15px); + transform: translateY(-15px); + } +} +@-webkit-keyframes bounce { + 0%, 20%, 50%, 80%, 100% { + -webkit-transform: translateY(0); + transform: translateY(0); + } + 40% { + -webkit-transform: translateY(-20px); + transform: translateY(-20px); + } + 60% { + -webkit-transform: translateY(-15px); + transform: translateY(-15px); + } +} +@keyframes bounce { + 0%, 20%, 50%, 80%, 100% { + -moz-transform: translateY(0); + -ms-transform: translateY(0); + -webkit-transform: translateY(0); + transform: translateY(0); + } + 40% { + -moz-transform: translateY(-20px); + -ms-transform: translateY(-20px); + -webkit-transform: translateY(-20px); + transform: translateY(-20px); + } + 60% { + -moz-transform: translateY(-15px); + -ms-transform: translateY(-15px); + -webkit-transform: translateY(-15px); + transform: translateY(-15px); + } +} + +#email-info{ + padding: 5px; +} +#registered-success-msg{ + display: none; +} +#forgot_pwd{ + color: #e65100; + text-decoration: underline; + margin-top: 10px; +} +#organizer_paid_msg{ + font-size: 1.1rem; + color: rgb(1, 87, 155); + border: 1px solid rgb(1, 87, 155); + padding: 10px 5px; +} +.no-past-foss{ + border: 1px solid rgba(1, 87, 155,0.5); + padding: 6px 10px; +} +.fa-chevron-down{ + font-size: 2rem; + color: rgb(1, 87, 155); +} +.chevron{ + float: right; + color: white; + font-size: 1.2rem; +} +.policy-title{ + margin-top: 32px; + display: flex; + flex-direction:column; +} +.user-message-highlight{ + border: 1px solid rgba(1, 87, 155,0.2); + padding: 2%; + box-shadow: 0 8px 6px -6px #01579B; + margin-top: 20px; +} +#download-zip-btn{ + border: 1px solid white; + background-color: #286090; + color: white; + padding: 10px 20px; + border-radius: 5px; + font-weight: bold; + font-size: 1.1rem; +} +.organizer_paid_info{ + font-size: 0.9rem; + color: rgba(1, 87, 155,0.8); + text-align: left; +} +.user-message{ + margin-top: 20px; +} \ No newline at end of file diff --git a/static/cdcontent/js/cdcontent.js b/static/cdcontent/js/cdcontent.js new file mode 100644 index 0000000..d42d23d --- /dev/null +++ b/static/cdcontent/js/cdcontent.js @@ -0,0 +1,202 @@ +$(document).ready(function(){ + $('.create_zip').prop('disabled', true); + + // clear level & language field on selecting new foss + $('.foss_category').on("change", function(){ + $('.level').val(''); + $('.language').html(''); + if($('.foss_category').val() == '') { + $('.level').attr("disabled", "disabled"); + $('.language').attr("disabled", "disabled"); + }else { + $('.level').removeAttr('disabled'); + } + }); + // clear level & language field on selecting new foss end + + $('.level').on("change", function(){ + var foss = $('.foss_category').val(); + var level = $(this).val(); + $('.language').html(''); + $('.language').attr("disabled", "disabled"); + if(foss && level) { + $.ajax({ + url: "/cdcontent/ajax-fill-languages/", + type: "POST", + data: { + foss: foss, + level: level + }, + beforeSend: function() { + $('.ajax-refresh-language').show(); + }, + success: function(data) { + // loading languages + if(data) { + $('.language').html(data); + $('.language').removeAttr('disabled'); + } + $('.ajax-refresh-language').hide(); + } + }); + } + }); + + $('.add_foss_lang').on("click", function(){ + $('.added-foss').show(); + foss = $('.foss_category').val(); + level = $('.level').val(); + langs = JSON.stringify($('.language').val()); + selectedfoss = $('.selected_foss').val(); + if(foss && langs && level) { + $.ajax({ + url: "/cdcontent/ajax-add-foss/", + type: "POST", + data: { + foss: foss, + langs: langs, + level: level, + selectedfoss: selectedfoss, + }, + beforeSend: function() { + $('.add_foss_lang').css('display', 'none'); + $('.ajax-refresh-add-foss').show(); + }, + success: function(data) { + data = JSON.parse(data); + console.log('data'); + console.log(data); + if(data) { + data = JSON.stringify(data); + if(data != '{}') { + $('.selected_foss').val(data); + selectedfoss = $('.selected_foss').val(); + } else { + $('.selected_foss').val(''); + } + } + selectedfoss: $('.selected_foss').val(); + show_added_foss(selectedfoss); + $('.ajax-refresh-add-foss').hide(); + $('.add_foss_lang').show(); + } + }); + $('.add_foss_lang').show(); + $('.ajax-refresh-add-foss').hide(); + } + }); + + $(".cdcontentform").on( "submit", function(event) { + event.preventDefault(); + var url = $(location).attr('href'); + $('.download-link').html('Loading... please do not refresh the page, we are preparing your download link'); + var posting = $.post(url, $(this).serialize()); + posting.done(function(data) { + if(data.status) { + var downloadLink = 'Download CD Content'; + var message = 'You are part of our paid service.
    Happy Downloading.' + $('.download-link').html(downloadLink); + $('.user-message').html(message); + } else { + var message = 'Somethings went wrong! please refresh the page and try again.' + $('.download-link').html(message); + } + }); + posting.fail(function() { + var message = 'Something went wrong! please refresh the page and try again.' + $('.download-link').html(message); + }); + }); + + $('#download_btn').click(function() { + $('#paymodal').modal('hide'); + $('#rate-div').hide(); + }); + +}); + +function delete_foss(elem){ + var foss_id = elem.parentNode.id; + var foss_lang_obj = JSON.parse(selectedfoss); + var foss_to_delete = foss_lang_obj[foss_id]; + var langs = foss_to_delete[0]; + var size = foss_to_delete[1]; + delete foss_lang_obj[foss_id]; + selectedfoss = JSON.stringify(foss_lang_obj); + $('.selected_foss').val(selectedfoss); + var add_foss_btn = document.getElementsByClassName("add_foss_lang"); + show_added_foss(selectedfoss); + if (Object.keys(foss_lang_obj).length === 0) { + $('.added-foss').hide(); + document.getElementById("amount_to_pay").value = '0'; + } + $('.ajax-refresh-add-foss').hide(); + $('.add_foss_lang').show(); +} + +function show_added_foss(selected_foss){ + $.ajax({ + url: "/cdcontent/ajax-show-added-foss/", + type: "POST", + data: { + selectedfoss : selected_foss, + }, + beforeSend: function() { + $('.add_foss_lang').css('display', 'none'); + $('.ajax-refresh-add-foss').show(); + }, + success: function(data) { + header = 'Selected FOSS List: ~ Total Size : '+data[1]+'FOSSLevelLanguagesSize'; + if(data) { + $('.added-foss').html(header + data[0]); + + var foss_table = document.getElementById("added-foss"); + var row_count = document.getElementById("added-foss").rows.length; + for (var i = 0 ;i < row_count; i++) { + var x = document.getElementById("added-foss").rows[i].cells.length; + if (x==5) { + var content = '' + var td = document.getElementById("added-foss").rows[i].cells[4]; + td.innerHTML = content; + } + } + if(data[2][0]=='UR') { + var message = '' + $('.create_zip').prop('disabled', true); + $('.user-message').html(message); + $('.download-a').html("Download"); + $("#rate-div").show(); + // $("#user_file_size").html("Foss Purchase (INR)"); + document.getElementById("amount_to_pay").value = data[2][1]; + } + if(data[2][0]=='RP') { + var message = 'You are part of our paid service.
    Happy Downloading.
    Please click on Create Zip file to proceed.' + $('.create_zip').prop('disabled', false); + $('.user-message').html(message); + $('.download-a').html("Download"); + $("#rate-div").hide(); + $('.user-message').addClass("user-message-highlight"); + } + else { + $('.create_zip').prop('disabled', true); + $('.user-message').html(message); + $('.download-a').html("Download"); + + $("#rate-div").show(); + // $("#user_file_size").html("Foss Purchase (INR)"); + document.getElementById("amount_to_pay").value = data[2][1]; + } + if (Object.keys(JSON.parse(selectedfoss)).length === 0) { + document.getElementById("amount_to_pay").value = '0'; + } + } + $('.ajax-refresh-add-foss').hide(); + } + }); +} + + + + + + diff --git a/static/cdcontent/templates/answer_to_question.html b/static/cdcontent/templates/answer_to_question.html new file mode 100644 index 0000000..15fb259 --- /dev/null +++ b/static/cdcontent/templates/answer_to_question.html @@ -0,0 +1,185 @@ + + + + + + {% block title %} + Spoken Tutorial Forums + {% endblock %} + + + + + + + + +
    +
    +
    + +
    +
    +
    +
    +
    + {% block content %} +
    +
    +
    +
    + {{ question.title }} +
    + +
    +
    + {{ question.body|safe }} +
    +
    + + + + + {{ question.category }} + + + + + + + + {{ question.tutorial}} + + + + + + + + {{ question.minute_range }} min + + + + + + + + {{ question.second_range }} sec + + + + + + + + + {{ question.date_created|date:"d-m-y" }}, {{ question.date_created|time }} + + + + + {{ question.user }} + + +
    +
    +
    +{% if answer %} +

    Answers:

    + + + +{% for ans in answer %} +
    +
    +
    + +
    + {{ ans.body|safe }} +
    + + + + + {{ ans.date_created|date:"d-m-y" }}, {{ ans.date_created|time }} + + + + + {{ ans.user }} + + +
    + +
    +
    + + {% for comment in ans.answercomment_set.all %} +
    +
    + {{ comment.body|safe }} +
    + + + + + {{ comment.date_created|date:"d-m-y" }}, {{ comment.date_created|time }} + + + + + {{ comment.user }} + + +
    + {% endfor %} + + + + +
    +
    +

    +
    +
    +{% endfor %} +{% else %} +

    No answers yet

    + {% endif %} + Click here to reply/comment online + {% endblock %} +
    +
    +
    + +
    + + diff --git a/static/cdcontent/templates/cdcontent_home.html b/static/cdcontent/templates/cdcontent_home.html new file mode 100644 index 0000000..e2c9073 --- /dev/null +++ b/static/cdcontent/templates/cdcontent_home.html @@ -0,0 +1,546 @@ +{% extends 'spoken/templates/base.html' %} +{% load widget_tweaks %} +{% load tz %} +{% load static %} +{% block title %}CD Content Creation{% endblock %} +{% block cssblock %} + +{% endblock %} + +{% block heading %} +CD Content Creation + +{% if user.is_authenticated and organizer_paid == '0' %} + + + +{% endif %} + +{% endblock %} +{% block announcement %} +
    + {% get_notifications as notifications %} + {% if notifications %} + {% for notification in notifications %} +
    +
    +
    + {{ notification.body|safe }} +
    +
    +
    + {% endfor %} + {% endif %} +
    +{% endblock %} +{% block search %} {% endblock %} + +{% block content %} +
    +
    +
    +
    +{% if payee_list%} + + + + + + + + + + + + + {% for item in payee_list %} + + + + + + + + + {% if item.is_past_due and item.status == 1 %} + + {% csrf_token %} + + + + {% elif item.status == 2 %} + + {% elif item.status == 0 %} + + {% else %} + + {% endif %} + + {% endfor %} + {% else %} +

    No Past FOSS Purchases !

    + {% endif %} + +
    #Date Of PurchaseFOSS Courses (Level , Language) ExpiryReceiptDownload Link
    {{forloop.counter}}{{item.created}} + {% for p in item.cdfosslanguages_set.all %} + {% if forloop.last %} + {% if p.level %} + {{p.foss}} ({{p.level}} , {{p.lang}}) + {% else %} + {{p.foss}} (All , {{p.lang}}) + {% endif %} + + {% else %} + {% if p.level %} + {{p.foss}} ({{p.level}} , {{p.lang}}) , + {% else %} + {{p.foss}} (All , {{p.lang}}) , + {% endif %} + + {% endif %} + {% endfor %} + {{item.expiry}} + {%for pay_tr_obj in item.payment_transaction.all%} +
    + {% csrf_token %} + + + + + + + + +
    + +{%endfor%} +
    + + Payment UnsuccessfulPayment IncompleteExpired
    +
    +
    +
    +
    + + + + + + + + + +
    + +
    +
    +
    + +
    +
    +
    +

    + Hello learner! +
    + Thank you for being an ardent supporter of the Spoken Tutorial project. Because of the pandemic and difficult conditions, the funding available to this project has gone down. And, we have been asked to raise the funds required to run this project on our own. We request you to pay a small contribution for bulk downloads. This facility is available free of cost to institutions that pay a nominal amount as annual subscription. +
    + Either way, your contribution will help us continue to serve you through Spoken Tutorials. +
    + We look forward to your support. +

    +
    +
    +
    + + + + +
    +
    +
    + +
    + {% csrf_token %} +
    +
    + {{ form.selected_foss.errors }} +
    +
    +
    + +
    + {% render_field form.foss_category class+="form-control foss_category" tabindex="1" %} + {{ form.foss_category.errors }} + Please select FOSS + {% render_field form.selected_foss class+='selected_foss' %} +
    +
    +
    + +
    + {% render_field form.level class+="form-control level" tabindex="2" %} + {{ form.level.errors }} + Please select the Level +
    +
    +
    + +
    + {% render_field form.language class+="form-control language" tabindex="3" %} + {{ form.language.errors }} + For selecting multiple languages, please use + <CTRL> + Click. +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    + +
    +
    + + +
    +
    +
    +
    +
    + + + + + + + + +{% endblock %} + + +{% block jsblock %} + + + + +{% endblock %} + diff --git a/static/cdcontent/templates/home.html b/static/cdcontent/templates/home.html new file mode 100644 index 0000000..9925913 --- /dev/null +++ b/static/cdcontent/templates/home.html @@ -0,0 +1,281 @@ +{% load cdcontentdata %}{% load cmsdata %} + + + + + Search Tutorials | spoken-tutorial.org + + + + + + + + + + +
    + +
    + +
    + +
    +
    +
    +

    Search Tutorials

    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    + +
    + + +

    +

    Spoken Tutorial Forums:

    +
    + + +

    +

    Spoken Tutorial Supplementary Material:

    +
    + + +
    +
    +
    +
    +
    + +
    + + + + + + + diff --git a/static/cdcontent/templates/index.html b/static/cdcontent/templates/index.html new file mode 100644 index 0000000..a95b08e --- /dev/null +++ b/static/cdcontent/templates/index.html @@ -0,0 +1,9 @@ + + + Search Tutorials | spoken-tutorial.org + + + + + + diff --git a/static/cdcontent/templates/readme.txt b/static/cdcontent/templates/readme.txt new file mode 100644 index 0000000..3ce65e0 --- /dev/null +++ b/static/cdcontent/templates/readme.txt @@ -0,0 +1,47 @@ +---------------------------------------------------------------------- +Steps for installation of software (for Organisers) +---------------------------------------------------------------------- +1. Open the "index.html" file in Firefox/Chrome web browser. +2. The "Side-by-Side Method" video appears by default. +3. Select the required Foss category, select a language and press "Submit" button, to view the videos. +4. Select the first tutorial from the list. +5. After this, refer to the "Installation Sheet" provided below the video player and follow the instructions to install the software on your machine. + +------------------------------------------------------------------------- +Steps for learning from the tutorials (for Learners) +------------------------------------------------------------------------- + +1. Open the "index.html" file in Firefox/Chrome web browser +2. Watch the "Side-by-Side Method" video. +3. Select the required Foss category, select a language and press "Submit" button, to view the videos. +4. Select the first tutorial from the list. +5. After this, refer to the "Instruction Sheet" provided below the video player. + +-------------------------------------------------------- +Steps to access Subtitles (for Learners) +-------------------------------------------------------- + +For Firefox web browser on Linux and Windows OS + +1. Type "about:config" in the address bar. +2. Once the config page is loaded, accept the permissions. +3. Then search for the option "security.fileuri.strict_origin_policy". +4. Change "Value" to "false" by double clicking on "true". +5. Now go to the tutorial and play it, subtitles will not appear yet. +6. In the player, locate the "CC" icon on the bottom right side of the VCR control bar. +7. Hover on the "CC" icon to see the list of languages. +8. Click on the language you want. +9. Steps 1 to 4 need to be done only for the first time. Firefox will remember this setup. + +For Chrome web browser on Linux OS + +1. If you have opened Chrome already, please close all the Chrome windows. +2. Open terminal. +3. Type "google-­chrome ­­--allow­-file-­access-­from-­files" and press Enter key. +4. Now open the "index.html" file in Chrome browser. +5. Go to the tutorial and play it. +6. In the player, locate the "CC" icon on the bottom right side of the VCR control bar. +7. Hover on the "CC" icon to see the list of languages. +8. Choose the language as per your choice. +9. Steps 2 and 3 need to be done only for the first time. Chrome will remember this setup. + diff --git a/static/cdcontent/templates/tutorial_search.html b/static/cdcontent/templates/tutorial_search.html new file mode 100644 index 0000000..d44bfab --- /dev/null +++ b/static/cdcontent/templates/tutorial_search.html @@ -0,0 +1,172 @@ +{% load cdcontentdata %}{% load cmsdata %} + + + + + Search Tutorials | spoken-tutorial.org + + + + + + + + +
    + +
    + +
    + +
    +
    +
    +

    Search Tutorials

    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + {% for record in collection %} +
    +
    + +
    +
    + +
    +

    Foss: {{ record.tutorial_detail.foss }} - {{ record.language }}

    +

    Outline: {{ record.outline|len_cutter:200 }}

    +
    +
    +
    +
    +
    {{ record.tutorial_detail.level.level }}
    + +
    +
    +
    + {% endfor %} +
    +
    +
    +
    + +
    + + + + + + + diff --git a/static/cdcontent/templates/watch_tutorial.html b/static/cdcontent/templates/watch_tutorial.html new file mode 100644 index 0000000..55d9f2d --- /dev/null +++ b/static/cdcontent/templates/watch_tutorial.html @@ -0,0 +1,684 @@ +{% load creationdata %}{% load cdcontentdata %} + + + + + {{ tr_rec.tutorial_detail.tutorial }} - {{ tr_rec.language.name }} | spoken-tutorial.org + + + + + + + + + + +
    + +
    + +
    + + + + + +
    +
    +
    +

    {{ tr_rec.tutorial_detail.tutorial }} - {{ tr_rec.language.name }}

    + +
    +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    Outline:
    {{ tr_rec.outline }}
    +
    + +
    +
    +
    +
    + + + + + + +
    + + + + + + + + diff --git a/static/forum_website/css/bootstrap.min.css b/static/forum_website/css/bootstrap.min.css new file mode 100644 index 0000000..0abcb3a --- /dev/null +++ b/static/forum_website/css/bootstrap.min.css @@ -0,0 +1 @@ +@import url("http://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,700italic,400,300,700");/*! normalize.css v2.1.3 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden],template{display:none}html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a{background:transparent}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{margin:.67em 0;font-size:2em}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}hr{height:0;-moz-box-sizing:content-box;box-sizing:content-box}mark{color:#000;background:#ff0}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid #c0c0c0}legend{padding:0;border:0}button,input,select,textarea{margin:0;font-family:inherit;font-size:100%}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{padding:0;box-sizing:border-box}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:2cm .5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.table td,.table th{background-color:#fff!important}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}*,*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:62.5%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;line-height:1.428571429;color:#222;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#008cba;text-decoration:none}a:hover,a:focus{color:#00526e;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}img{vertical-align:middle}.img-responsive{display:block;height:auto;max-width:100%}.img-rounded{border-radius:0}.img-thumbnail{display:inline-block;height:auto;max-width:100%;padding:4px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:0;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:21px;margin-bottom:21px;border:0;border-top:1px solid #ddd}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{margin-top:21px;margin-bottom:10.5px}h1 small,h2 small,h3 small,h1 .small,h2 .small,h3 .small{font-size:65%}h4,h5,h6{margin-top:10.5px;margin-bottom:10.5px}h4 small,h5 small,h6 small,h4 .small,h5 .small,h6 .small{font-size:75%}h1,.h1{font-size:39px}h2,.h2{font-size:32px}h3,.h3{font-size:26px}h4,.h4{font-size:19px}h5,.h5{font-size:15px}h6,.h6{font-size:13px}p{margin:0 0 10.5px}.lead{margin-bottom:21px;font-size:17px;font-weight:200;line-height:1.4}@media(min-width:768px){.lead{font-size:22.5px}}small,.small{font-size:85%}cite{font-style:normal}.text-muted{color:#999}.text-primary{color:#008cba}.text-primary:hover{color:#006687}.text-warning{color:#e99002}.text-warning:hover{color:#b67102}.text-danger{color:#f04124}.text-danger:hover{color:#d32a0e}.text-success{color:#43ac6a}.text-success:hover{color:#358753}.text-info{color:#5bc0de}.text-info:hover{color:#31b0d5}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.page-header{padding-bottom:9.5px;margin:42px 0 21px;border-bottom:1px solid #ddd}ul,ol{margin-top:0;margin-bottom:10.5px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}.list-inline>li:first-child{padding-left:0}dl{margin-top:0;margin-bottom:21px}dt,dd{line-height:1.428571429}dt{font-weight:bold}dd{margin-left:0}@media(min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10.5px 21px;margin:0 0 21px;border-left:5px solid #ddd}blockquote p{font-size:18.75px;font-weight:300;line-height:1.25}blockquote p:last-child{margin-bottom:0}blockquote small,blockquote .small{display:block;line-height:1.428571429;color:#6f6f6f}blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #ddd;border-left:0}blockquote.pull-right p,blockquote.pull-right small,blockquote.pull-right .small{text-align:right}blockquote.pull-right small:before,blockquote.pull-right .small:before{content:''}blockquote.pull-right small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}blockquote:before,blockquote:after{content:""}address{margin-bottom:21px;font-style:normal;line-height:1.428571429}code,kbd,pre,samp{font-family:Monaco,Menlo,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;white-space:nowrap;background-color:#f9f2f4;border-radius:0}pre{display:block;padding:10px;margin:0 0 10.5px;font-size:14px;line-height:1.428571429;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:0}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}@media(min-width:768px){.container{width:750px}}@media(min-width:992px){.container{width:970px}}@media(min-width:1200px){.container{width:1170px}}.row{margin-right:-15px;margin-left:-15px}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666666666666%}.col-xs-10{width:83.33333333333334%}.col-xs-9{width:75%}.col-xs-8{width:66.66666666666666%}.col-xs-7{width:58.333333333333336%}.col-xs-6{width:50%}.col-xs-5{width:41.66666666666667%}.col-xs-4{width:33.33333333333333%}.col-xs-3{width:25%}.col-xs-2{width:16.666666666666664%}.col-xs-1{width:8.333333333333332%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666666666666%}.col-xs-pull-10{right:83.33333333333334%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666666666666%}.col-xs-pull-7{right:58.333333333333336%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666666666667%}.col-xs-pull-4{right:33.33333333333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.666666666666664%}.col-xs-pull-1{right:8.333333333333332%}.col-xs-pull-0{right:0}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666666666666%}.col-xs-push-10{left:83.33333333333334%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666666666666%}.col-xs-push-7{left:58.333333333333336%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666666666667%}.col-xs-push-4{left:33.33333333333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.666666666666664%}.col-xs-push-1{left:8.333333333333332%}.col-xs-push-0{left:0}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666666666666%}.col-xs-offset-10{margin-left:83.33333333333334%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666666666666%}.col-xs-offset-7{margin-left:58.333333333333336%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666666666667%}.col-xs-offset-4{margin-left:33.33333333333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.666666666666664%}.col-xs-offset-1{margin-left:8.333333333333332%}.col-xs-offset-0{margin-left:0}@media(min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666666666666%}.col-sm-10{width:83.33333333333334%}.col-sm-9{width:75%}.col-sm-8{width:66.66666666666666%}.col-sm-7{width:58.333333333333336%}.col-sm-6{width:50%}.col-sm-5{width:41.66666666666667%}.col-sm-4{width:33.33333333333333%}.col-sm-3{width:25%}.col-sm-2{width:16.666666666666664%}.col-sm-1{width:8.333333333333332%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666666666666%}.col-sm-pull-10{right:83.33333333333334%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666666666666%}.col-sm-pull-7{right:58.333333333333336%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666666666667%}.col-sm-pull-4{right:33.33333333333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.666666666666664%}.col-sm-pull-1{right:8.333333333333332%}.col-sm-pull-0{right:0}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666666666666%}.col-sm-push-10{left:83.33333333333334%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666666666666%}.col-sm-push-7{left:58.333333333333336%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666666666667%}.col-sm-push-4{left:33.33333333333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.666666666666664%}.col-sm-push-1{left:8.333333333333332%}.col-sm-push-0{left:0}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666666666666%}.col-sm-offset-10{margin-left:83.33333333333334%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666666666666%}.col-sm-offset-7{margin-left:58.333333333333336%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666666666667%}.col-sm-offset-4{margin-left:33.33333333333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.666666666666664%}.col-sm-offset-1{margin-left:8.333333333333332%}.col-sm-offset-0{margin-left:0}}@media(min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666666666666%}.col-md-10{width:83.33333333333334%}.col-md-9{width:75%}.col-md-8{width:66.66666666666666%}.col-md-7{width:58.333333333333336%}.col-md-6{width:50%}.col-md-5{width:41.66666666666667%}.col-md-4{width:33.33333333333333%}.col-md-3{width:25%}.col-md-2{width:16.666666666666664%}.col-md-1{width:8.333333333333332%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666666666666%}.col-md-pull-10{right:83.33333333333334%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666666666666%}.col-md-pull-7{right:58.333333333333336%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666666666667%}.col-md-pull-4{right:33.33333333333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.666666666666664%}.col-md-pull-1{right:8.333333333333332%}.col-md-pull-0{right:0}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666666666666%}.col-md-push-10{left:83.33333333333334%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666666666666%}.col-md-push-7{left:58.333333333333336%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666666666667%}.col-md-push-4{left:33.33333333333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.666666666666664%}.col-md-push-1{left:8.333333333333332%}.col-md-push-0{left:0}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666666666666%}.col-md-offset-10{margin-left:83.33333333333334%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666666666666%}.col-md-offset-7{margin-left:58.333333333333336%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666666666667%}.col-md-offset-4{margin-left:33.33333333333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.666666666666664%}.col-md-offset-1{margin-left:8.333333333333332%}.col-md-offset-0{margin-left:0}}@media(min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666666666666%}.col-lg-10{width:83.33333333333334%}.col-lg-9{width:75%}.col-lg-8{width:66.66666666666666%}.col-lg-7{width:58.333333333333336%}.col-lg-6{width:50%}.col-lg-5{width:41.66666666666667%}.col-lg-4{width:33.33333333333333%}.col-lg-3{width:25%}.col-lg-2{width:16.666666666666664%}.col-lg-1{width:8.333333333333332%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666666666666%}.col-lg-pull-10{right:83.33333333333334%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666666666666%}.col-lg-pull-7{right:58.333333333333336%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666666666667%}.col-lg-pull-4{right:33.33333333333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.666666666666664%}.col-lg-pull-1{right:8.333333333333332%}.col-lg-pull-0{right:0}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666666666666%}.col-lg-push-10{left:83.33333333333334%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666666666666%}.col-lg-push-7{left:58.333333333333336%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666666666667%}.col-lg-push-4{left:33.33333333333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.666666666666664%}.col-lg-push-1{left:8.333333333333332%}.col-lg-push-0{left:0}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666666666666%}.col-lg-offset-10{margin-left:83.33333333333334%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666666666666%}.col-lg-offset-7{margin-left:58.333333333333336%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666666666667%}.col-lg-offset-4{margin-left:33.33333333333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.666666666666664%}.col-lg-offset-1{margin-left:8.333333333333332%}.col-lg-offset-0{margin-left:0}}table{max-width:100%;background-color:transparent}th{text-align:left}.table{width:100%;margin-bottom:21px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.428571429;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover>tbody>tr:hover>td,.table-hover>tbody>tr:hover>th{background-color:#f5f5f5}table col[class*="col-"]{position:static;display:table-column;float:none}table td[class*="col-"],table th[class*="col-"]{display:table-cell;float:none}.table>thead>tr>.active,.table>tbody>tr>.active,.table>tfoot>tr>.active,.table>thead>.active>td,.table>tbody>.active>td,.table>tfoot>.active>td,.table>thead>.active>th,.table>tbody>.active>th,.table>tfoot>.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>.active:hover,.table-hover>tbody>.active:hover>td,.table-hover>tbody>.active:hover>th{background-color:#e8e8e8}.table>thead>tr>.success,.table>tbody>tr>.success,.table>tfoot>tr>.success,.table>thead>.success>td,.table>tbody>.success>td,.table>tfoot>.success>td,.table>thead>.success>th,.table>tbody>.success>th,.table>tfoot>.success>th{background-color:#dff0d8}.table-hover>tbody>tr>.success:hover,.table-hover>tbody>.success:hover>td,.table-hover>tbody>.success:hover>th{background-color:#d0e9c6}.table>thead>tr>.danger,.table>tbody>tr>.danger,.table>tfoot>tr>.danger,.table>thead>.danger>td,.table>tbody>.danger>td,.table>tfoot>.danger>td,.table>thead>.danger>th,.table>tbody>.danger>th,.table>tfoot>.danger>th{background-color:#f2dede}.table-hover>tbody>tr>.danger:hover,.table-hover>tbody>.danger:hover>td,.table-hover>tbody>.danger:hover>th{background-color:#ebcccc}.table>thead>tr>.warning,.table>tbody>tr>.warning,.table>tfoot>tr>.warning,.table>thead>.warning>td,.table>tbody>.warning>td,.table>tfoot>.warning>td,.table>thead>.warning>th,.table>tbody>.warning>th,.table>tfoot>.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>.warning:hover,.table-hover>tbody>.warning:hover>td,.table-hover>tbody>.warning:hover>th{background-color:#faf2cc}@media(max-width:767px){.table-responsive{width:100%;margin-bottom:15.75px;overflow-x:scroll;overflow-y:hidden;border:1px solid #ddd;-ms-overflow-style:-ms-autohiding-scrollbar;-webkit-overflow-scrolling:touch}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:21px;font-size:22.5px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}select[multiple],select[size]{height:auto}select optgroup{font-family:inherit;font-size:inherit;font-style:inherit}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}input[type="number"]::-webkit-outer-spin-button,input[type="number"]::-webkit-inner-spin-button{height:auto}output{display:block;padding-top:7px;font-size:15px;line-height:1.428571429;color:#6f6f6f;vertical-align:middle}.form-control{display:block;width:100%;height:35px;padding:6px 12px;font-size:15px;line-height:1.428571429;color:#6f6f6f;vertical-align:middle;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)}.form-control:-moz-placeholder{color:#999}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee}textarea.form-control{height:auto}.form-group{margin-bottom:15px}.radio,.checkbox{display:block;min-height:21px;padding-left:20px;margin-top:10px;margin-bottom:10px;vertical-align:middle}.radio label,.checkbox label{display:inline;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{float:left;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:normal;vertical-align:middle;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],.radio[disabled],.radio-inline[disabled],.checkbox[disabled],.checkbox-inline[disabled],fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"],fieldset[disabled] .radio,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:0}select.input-sm{height:30px;line-height:30px}textarea.input-sm{height:auto}.input-lg{height:47px;padding:10px 16px;font-size:19px;line-height:1.33;border-radius:0}select.input-lg{height:47px;line-height:47px}textarea.input-lg{height:auto}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline{color:#e99002}.has-warning .form-control{border-color:#e99002;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#b67102;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #febc53;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #febc53}.has-warning .input-group-addon{color:#e99002;background-color:#fcf8e3;border-color:#e99002}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline{color:#f04124}.has-error .form-control{border-color:#f04124;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#d32a0e;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #f79483;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #f79483}.has-error .input-group-addon{color:#f04124;background-color:#f2dede;border-color:#f04124}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline{color:#43ac6a}.has-success .form-control{border-color:#43ac6a;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#358753;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #85d0a1;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #85d0a1}.has-success .input-group-addon{color:#43ac6a;background-color:#dff0d8;border-color:#43ac6a}.form-control-static{margin-bottom:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#626262}@media(min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block}.form-inline select.form-control{width:auto}.form-inline .radio,.form-inline .checkbox{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:none;margin-left:0}}.form-horizontal .control-label,.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .radio,.form-horizontal .checkbox{min-height:28px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}.form-horizontal .form-control-static{padding-top:7px}@media(min-width:768px){.form-horizontal .control-label{text-align:right}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:15px;font-weight:normal;line-height:1.428571429;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;background-image:none;border:1px solid transparent;border-radius:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus{color:#333;text-decoration:none}.btn:active,.btn.active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#333;background-color:#e7e7e7;border-color:#dadada}.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{color:#333;background-color:#d3d3d3;border-color:#bbb}.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#e7e7e7;border-color:#dadada}.btn-default .badge{color:#e7e7e7;background-color:#fff}.btn-primary{color:#fff;background-color:#008cba;border-color:#0079a1}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{color:#fff;background-color:#006d91;border-color:#004b63}.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#008cba;border-color:#0079a1}.btn-primary .badge{color:#008cba;background-color:#fff}.btn-warning{color:#fff;background-color:#e99002;border-color:#d08002}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{color:#fff;background-color:#c17702;border-color:#935b01}.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#e99002;border-color:#d08002}.btn-warning .badge{color:#e99002;background-color:#fff}.btn-danger{color:#fff;background-color:#f04124;border-color:#ea2f10}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{color:#fff;background-color:#dc2c0f;border-color:#b1240c}.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#f04124;border-color:#ea2f10}.btn-danger .badge{color:#f04124;background-color:#fff}.btn-success{color:#fff;background-color:#43ac6a;border-color:#3c9a5f}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{color:#fff;background-color:#388f58;border-color:#2b6e44}.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#43ac6a;border-color:#3c9a5f}.btn-success .badge{color:#43ac6a;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{color:#fff;background-color:#39b3d7;border-color:#269abc}.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-link{font-weight:normal;color:#008cba;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#00526e;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#999;text-decoration:none}.btn-lg{padding:10px 16px;font-size:19px;line-height:1.33;border-radius:0}.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:0}.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:0}.btn-block{display:block;width:100%;padding-right:0;padding-left:0}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;transition:height .35s ease}@font-face{font-family:'Glyphicons Halflings';src:url('../fonts/glyphicons-halflings-regular.eot');src:url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/glyphicons-halflings-regular.woff') format('woff'),url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('../fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';-webkit-font-smoothing:antialiased;font-style:normal;font-weight:normal;line-height:1;-moz-osx-font-smoothing:grayscale}.glyphicon:empty{width:1em}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:15px;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9.5px 0;overflow:hidden;background-color:rgba(0,0,0,0.2)}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.428571429;color:#555;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#262626;text-decoration:none;background-color:#eee}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#008cba;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.428571429;color:#999}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media(min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:0}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar .btn-group{float:left}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group,.btn-toolbar>.btn-group+.btn-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:0}.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:0}.btn-group-lg>.btn{padding:10px 16px;font-size:19px;line-height:1.33;border-radius:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child>.btn:last-child,.btn-group-vertical>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;border-collapse:separate;table-layout:fixed}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}[data-toggle="buttons"]>.btn>input[type="radio"],[data-toggle="buttons"]>.btn>input[type="checkbox"]{display:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*="col-"]{float:none;padding-right:0;padding-left:0}.input-group .form-control{width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:47px;padding:10px 16px;font-size:19px;line-height:1.33;border-radius:0}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:47px;line-height:47px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:0}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:15px;font-weight:normal;line-height:1;color:#6f6f6f;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:0}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:0}.input-group-addon.input-lg{padding:10px 16px;font-size:19px;border-radius:0}.input-group-addon input[type="radio"],.input-group-addon input[type="checkbox"]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;white-space:nowrap}.input-group-btn:first-child>.btn{margin-right:-1px}.input-group-btn:last-child>.btn{margin-left:-1px}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-4px}.input-group-btn>.btn:hover,.input-group-btn>.btn:active{z-index:2}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#999}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#999;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#008cba}.nav .nav-divider{height:1px;margin:9.5px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.428571429;border:1px solid transparent;border-radius:0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#6f6f6f;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media(min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media(min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:0}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#008cba}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media(min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media(min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;min-height:45px;margin-bottom:21px;border:1px solid transparent}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}@media(min-width:768px){.navbar{border-radius:0}}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}@media(min-width:768px){.navbar-header{float:left}}.navbar-collapse{max-height:340px;padding-right:15px;padding-left:15px;overflow-x:visible;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse.in{overflow-y:auto}@media(min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-right:0;padding-left:0}}.container>.navbar-header,.container>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media(min-width:768px){.container>.navbar-header,.container>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media(min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media(min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;padding:12px 15px;font-size:19px;line-height:21px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}@media(min-width:768px){.navbar>.container .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:5.5px;margin-right:15px;margin-bottom:5.5px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media(min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:6px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:21px}@media(max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:21px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media(min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:12px;padding-bottom:12px}.navbar-nav.navbar-right:last-child{margin-right:-15px}}@media(min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important}}.navbar-form{padding:10px 15px;margin-top:5px;margin-right:-15px;margin-bottom:5px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}@media(min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block}.navbar-form select.form-control{width:auto}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.navbar-form .radio input[type="radio"],.navbar-form .checkbox input[type="checkbox"]{float:none;margin-left:0}}@media(max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media(min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-form.navbar-right:last-child{margin-right:-15px}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-nav.pull-right>li>.dropdown-menu,.navbar-nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar-btn{margin-top:5px;margin-bottom:5px}.navbar-btn.btn-sm{margin-top:7.5px;margin-bottom:7.5px}.navbar-btn.btn-xs{margin-top:11.5px;margin-bottom:11.5px}.navbar-text{margin-top:12px;margin-bottom:12px}@media(min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}.navbar-text.navbar-right:last-child{margin-right:0}}.navbar-default{background-color:#333;border-color:#222}.navbar-default .navbar-brand{color:#fff}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-default .navbar-text{color:#fff}.navbar-default .navbar-nav>li>a{color:#fff}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#fff;background-color:#272727}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#fff;background-color:#272727}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:transparent}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:transparent}.navbar-default .navbar-toggle .icon-bar{background-color:#fff}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#222}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{color:#fff;background-color:#272727}@media(max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#fff}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:#272727}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#272727}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#fff}.navbar-default .navbar-link:hover{color:#fff}.navbar-inverse{background-color:#008cba;border-color:#006687}.navbar-inverse .navbar-brand{color:#fff}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#fff}.navbar-inverse .navbar-nav>li>a{color:#fff}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:#006687}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#006687}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:transparent}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:transparent}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#007196}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{color:#fff;background-color:#006687}@media(max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#006687}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#006687}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#fff}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:#006687}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#006687}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#fff}.navbar-inverse .navbar-link:hover{color:#fff}.breadcrumb{padding:8px 15px;margin-bottom:21px;list-style:none;background-color:#f5f5f5;border-radius:0}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#999;content:"/\00a0"}.breadcrumb>.active{color:#333}.pagination{display:inline-block;padding-left:0;margin:21px 0;border-radius:0}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.428571429;text-decoration:none;background-color:transparent;border:1px solid transparent}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:0;border-top-left-radius:0}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:0;border-bottom-right-radius:0}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{background-color:#eee}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;cursor:default;background-color:#008cba;border-color:#008cba}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#999;cursor:not-allowed;background-color:transparent;border-color:transparent}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:19px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:0;border-top-left-radius:0}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:0;border-bottom-right-radius:0}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:0;border-top-left-radius:0}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:0;border-bottom-right-radius:0}.pager{padding-left:0;margin:21px 0;text-align:center;list-style:none}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:transparent;border:1px solid transparent;border-radius:3px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;cursor:not-allowed;background-color:transparent}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.label[href]:hover,.label[href]:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#999}.label-default[href]:hover,.label-default[href]:focus{background-color:#808080}.label-primary{background-color:#008cba}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#006687}.label-success{background-color:#43ac6a}.label-success[href]:hover,.label-success[href]:focus{background-color:#358753}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#e99002}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#b67102}.label-danger{background-color:#f04124}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#d32a0e}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;line-height:1;color:#777;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#e7e7e7;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#008cba;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px;margin-bottom:30px;font-size:23px;font-weight:200;line-height:2.1428571435;color:inherit;background-color:#fafafa}.jumbotron h1,.jumbotron .h1{line-height:1;color:inherit}.jumbotron p{line-height:1.4}.container .jumbotron{border-radius:0}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1,.jumbotron .h1{font-size:67.5px}}.thumbnail{display:block;padding:4px;margin-bottom:21px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:0;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.thumbnail>img,.thumbnail a>img{display:block;height:auto;max-width:100%;margin-right:auto;margin-left:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#008cba}.thumbnail .caption{padding:9px;color:#222}.alert{padding:15px;margin-bottom:21px;border:1px solid transparent;border-radius:0}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:bold}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable{padding-right:35px}.alert-dismissable .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#fff;background-color:#43ac6a;border-color:#3c9a5f}.alert-success hr{border-top-color:#358753}.alert-success .alert-link{color:#e6e6e6}.alert-info{color:#fff;background-color:#5bc0de;border-color:#3db5d8}.alert-info hr{border-top-color:#2aabd2}.alert-info .alert-link{color:#e6e6e6}.alert-warning{color:#fff;background-color:#e99002;border-color:#d08002}.alert-warning hr{border-top-color:#b67102}.alert-warning .alert-link{color:#e6e6e6}.alert-danger{color:#fff;background-color:#f04124;border-color:#ea2f10}.alert-danger hr{border-top-color:#d32a0e}.alert-danger .alert-link{color:#e6e6e6}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:21px;margin-bottom:21px;overflow:hidden;background-color:#f5f5f5;border-radius:0;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:21px;color:#fff;text-align:center;background-color:#008cba;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-size:40px 40px}.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#43ac6a}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#e99002}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#f04124}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.media,.media-body{overflow:hidden;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{text-decoration:none;background-color:#f5f5f5}a.list-group-item.active,a.list-group-item.active:hover,a.list-group-item.active:focus{z-index:2;color:#fff;background-color:#008cba;border-color:#008cba}a.list-group-item.active .list-group-item-heading,a.list-group-item.active:hover .list-group-item-heading,a.list-group-item.active:focus .list-group-item-heading{color:inherit}a.list-group-item.active .list-group-item-text,a.list-group-item.active:hover .list-group-item-text,a.list-group-item.active:focus .list-group-item-text{color:#87e1ff}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:21px;background-color:#fff;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.panel-body{padding:15px}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel>.list-group{margin-bottom:0}.panel>.list-group .list-group-item{border-width:1px 0}.panel>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.panel>.list-group .list-group-item:last-child{border-bottom:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive{border-top:1px solid #ddd}.panel>.table>tbody:first-child th,.panel>.table>tbody:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:last-child>th,.panel>.table-responsive>.table-bordered>thead>tr:last-child>th,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th,.panel>.table-bordered>thead>tr:last-child>td,.panel>.table-responsive>.table-bordered>thead>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:-1;border-top-left-radius:-1}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:17px;color:inherit}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:-1;border-bottom-left-radius:-1}.panel-group .panel{margin-bottom:0;overflow:hidden;border-radius:0}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse .panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse .panel-body{border-top-color:#ddd}.panel-default>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#008cba}.panel-primary>.panel-heading{color:#fff;background-color:#008cba;border-color:#008cba}.panel-primary>.panel-heading+.panel-collapse .panel-body{border-top-color:#008cba}.panel-primary>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#008cba}.panel-success{border-color:#3c9a5f}.panel-success>.panel-heading{color:#43ac6a;background-color:#dff0d8;border-color:#3c9a5f}.panel-success>.panel-heading+.panel-collapse .panel-body{border-top-color:#3c9a5f}.panel-success>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#3c9a5f}.panel-warning{border-color:#d08002}.panel-warning>.panel-heading{color:#e99002;background-color:#fcf8e3;border-color:#d08002}.panel-warning>.panel-heading+.panel-collapse .panel-body{border-top-color:#d08002}.panel-warning>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#d08002}.panel-danger{border-color:#ea2f10}.panel-danger>.panel-heading{color:#f04124;background-color:#f2dede;border-color:#ea2f10}.panel-danger>.panel-heading+.panel-collapse .panel-body{border-top-color:#ea2f10}.panel-danger>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ea2f10}.panel-info{border-color:#3db5d8}.panel-info>.panel-heading{color:#5bc0de;background-color:#d9edf7;border-color:#3db5d8}.panel-info>.panel-heading+.panel-collapse .panel-body{border-top-color:#3db5d8}.panel-info>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#3db5d8}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#fafafa;border:1px solid #e8e8e8;border-radius:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-lg{padding:24px;border-radius:0}.well-sm{padding:9px;border-radius:0}.close{float:right;font-size:22.5px;font-weight:bold;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:auto;overflow-y:scroll}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0)}.modal-dialog{position:relative;z-index:1050;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.2);border-radius:0;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);background-clip:padding-box}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1030;background-color:#000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{min-height:16.428571429px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.428571429}.modal-body{position:relative;padding:20px}.modal-footer{padding:19px 20px 20px;margin-top:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}@media screen and (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,0.5);box-shadow:0 5px 15px rgba(0,0,0,0.5)}}.tooltip{position:absolute;z-index:1030;display:block;font-size:12px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#333;border-radius:0}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#333;border-width:5px 5px 0}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-top-color:#333;border-width:5px 5px 0}.tooltip.top-right .tooltip-arrow{right:5px;bottom:0;border-top-color:#333;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#333;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#333;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#333;border-width:0 5px 5px}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-bottom-color:#333;border-width:0 5px 5px}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-bottom-color:#333;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#333;border:1px solid #333;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:15px;font-weight:normal;line-height:18px;background-color:#333;border-bottom:1px solid #262626;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#333;border-bottom-width:0;content:" "}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#333;border-left-width:0;content:" "}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#333;border-top-width:0;content:" "}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#333;border-right-width:0;content:" "}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;height:auto;max-width:100%;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6);opacity:.5;filter:alpha(opacity=50)}.carousel-control.left{background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,0.5) 0),color-stop(rgba(0,0,0,0.0001) 100%));background-image:linear-gradient(to right,rgba(0,0,0,0.5) 0,rgba(0,0,0,0.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000',endColorstr='#00000000',GradientType=1)}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,0.0001) 0),color-stop(rgba(0,0,0,0.5) 100%));background-image:linear-gradient(to right,rgba(0,0,0,0.0001) 0,rgba(0,0,0,0.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000',endColorstr='#80000000',GradientType=1)}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;outline:0;opacity:.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;margin-left:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicons-chevron-left,.carousel-control .glyphicons-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;margin-left:-15px;font-size:30px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after{display:table;content:" "}.clearfix:after{clear:both}.clearfix:before,.clearfix:after{display:table;content:" "}.clearfix:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,tr.visible-xs,th.visible-xs,td.visible-xs{display:none!important}@media(max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-xs.visible-sm{display:block!important}table.visible-xs.visible-sm{display:table}tr.visible-xs.visible-sm{display:table-row!important}th.visible-xs.visible-sm,td.visible-xs.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-xs.visible-md{display:block!important}table.visible-xs.visible-md{display:table}tr.visible-xs.visible-md{display:table-row!important}th.visible-xs.visible-md,td.visible-xs.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-xs.visible-lg{display:block!important}table.visible-xs.visible-lg{display:table}tr.visible-xs.visible-lg{display:table-row!important}th.visible-xs.visible-lg,td.visible-xs.visible-lg{display:table-cell!important}}.visible-sm,tr.visible-sm,th.visible-sm,td.visible-sm{display:none!important}@media(max-width:767px){.visible-sm.visible-xs{display:block!important}table.visible-sm.visible-xs{display:table}tr.visible-sm.visible-xs{display:table-row!important}th.visible-sm.visible-xs,td.visible-sm.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-sm.visible-md{display:block!important}table.visible-sm.visible-md{display:table}tr.visible-sm.visible-md{display:table-row!important}th.visible-sm.visible-md,td.visible-sm.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-sm.visible-lg{display:block!important}table.visible-sm.visible-lg{display:table}tr.visible-sm.visible-lg{display:table-row!important}th.visible-sm.visible-lg,td.visible-sm.visible-lg{display:table-cell!important}}.visible-md,tr.visible-md,th.visible-md,td.visible-md{display:none!important}@media(max-width:767px){.visible-md.visible-xs{display:block!important}table.visible-md.visible-xs{display:table}tr.visible-md.visible-xs{display:table-row!important}th.visible-md.visible-xs,td.visible-md.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-md.visible-sm{display:block!important}table.visible-md.visible-sm{display:table}tr.visible-md.visible-sm{display:table-row!important}th.visible-md.visible-sm,td.visible-md.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-md.visible-lg{display:block!important}table.visible-md.visible-lg{display:table}tr.visible-md.visible-lg{display:table-row!important}th.visible-md.visible-lg,td.visible-md.visible-lg{display:table-cell!important}}.visible-lg,tr.visible-lg,th.visible-lg,td.visible-lg{display:none!important}@media(max-width:767px){.visible-lg.visible-xs{display:block!important}table.visible-lg.visible-xs{display:table}tr.visible-lg.visible-xs{display:table-row!important}th.visible-lg.visible-xs,td.visible-lg.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-lg.visible-sm{display:block!important}table.visible-lg.visible-sm{display:table}tr.visible-lg.visible-sm{display:table-row!important}th.visible-lg.visible-sm,td.visible-lg.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-lg.visible-md{display:block!important}table.visible-lg.visible-md{display:table}tr.visible-lg.visible-md{display:table-row!important}th.visible-lg.visible-md,td.visible-lg.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}.hidden-xs{display:block!important}table.hidden-xs{display:table}tr.hidden-xs{display:table-row!important}th.hidden-xs,td.hidden-xs{display:table-cell!important}@media(max-width:767px){.hidden-xs,tr.hidden-xs,th.hidden-xs,td.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-xs.hidden-sm,tr.hidden-xs.hidden-sm,th.hidden-xs.hidden-sm,td.hidden-xs.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-xs.hidden-md,tr.hidden-xs.hidden-md,th.hidden-xs.hidden-md,td.hidden-xs.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-xs.hidden-lg,tr.hidden-xs.hidden-lg,th.hidden-xs.hidden-lg,td.hidden-xs.hidden-lg{display:none!important}}.hidden-sm{display:block!important}table.hidden-sm{display:table}tr.hidden-sm{display:table-row!important}th.hidden-sm,td.hidden-sm{display:table-cell!important}@media(max-width:767px){.hidden-sm.hidden-xs,tr.hidden-sm.hidden-xs,th.hidden-sm.hidden-xs,td.hidden-sm.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-sm,tr.hidden-sm,th.hidden-sm,td.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-sm.hidden-md,tr.hidden-sm.hidden-md,th.hidden-sm.hidden-md,td.hidden-sm.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-sm.hidden-lg,tr.hidden-sm.hidden-lg,th.hidden-sm.hidden-lg,td.hidden-sm.hidden-lg{display:none!important}}.hidden-md{display:block!important}table.hidden-md{display:table}tr.hidden-md{display:table-row!important}th.hidden-md,td.hidden-md{display:table-cell!important}@media(max-width:767px){.hidden-md.hidden-xs,tr.hidden-md.hidden-xs,th.hidden-md.hidden-xs,td.hidden-md.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-md.hidden-sm,tr.hidden-md.hidden-sm,th.hidden-md.hidden-sm,td.hidden-md.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-md,tr.hidden-md,th.hidden-md,td.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-md.hidden-lg,tr.hidden-md.hidden-lg,th.hidden-md.hidden-lg,td.hidden-md.hidden-lg{display:none!important}}.hidden-lg{display:block!important}table.hidden-lg{display:table}tr.hidden-lg{display:table-row!important}th.hidden-lg,td.hidden-lg{display:table-cell!important}@media(max-width:767px){.hidden-lg.hidden-xs,tr.hidden-lg.hidden-xs,th.hidden-lg.hidden-xs,td.hidden-lg.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-lg.hidden-sm,tr.hidden-lg.hidden-sm,th.hidden-lg.hidden-sm,td.hidden-lg.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-lg.hidden-md,tr.hidden-lg.hidden-md,th.hidden-lg.hidden-md,td.hidden-lg.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-lg,tr.hidden-lg,th.hidden-lg,td.hidden-lg{display:none!important}}.visible-print,tr.visible-print,th.visible-print,td.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}.hidden-print,tr.hidden-print,th.hidden-print,td.hidden-print{display:none!important}}.navbar{font-size:13px;font-weight:300;border:0}.navbar .navbar-toggle:hover .icon-bar{background-color:#b3b3b3}.navbar-collapse{border-top-color:rgba(0,0,0,0.2);-webkit-box-shadow:none;box-shadow:none}.navbar .dropdown-menu{border:0}.navbar .dropdown-menu>li>a,.navbar .dropdown-menu>li>a:focus{font-size:13px;font-weight:300;background-color:transparent}.navbar .dropdown-header{color:rgba(255,255,255,0.5)}.navbar-default .dropdown-menu{background-color:#333}.navbar-default .dropdown-menu>li>a,.navbar-default .dropdown-menu>li>a:focus{color:#fff}.navbar-default .dropdown-menu>li>a:hover,.navbar-default .dropdown-menu>.active>a,.navbar-default .dropdown-menu>.active>a:hover{background-color:#272727}.navbar-inverse .dropdown-menu{background-color:#008cba}.navbar-inverse .dropdown-menu>li>a,.navbar-inverse .dropdown-menu>li>a:focus{color:#fff}.navbar-inverse .dropdown-menu>li>a:hover,.navbar-inverse .dropdown-menu>.active>a,.navbar-inverse .dropdown-menu>.active>a:hover{background-color:#006687}.btn{padding:14px 28px}.btn-lg{padding:16px 32px}.btn-sm{padding:8px 16px}.btn-xs{padding:4px 8px}.btn-group .btn~.dropdown-toggle{padding-right:16px;padding-left:16px}.btn-group .dropdown-menu{border-top-width:0}.btn-group.dropup .dropdown-menu{margin-bottom:0;border-top-width:1px;border-bottom-width:0}.btn-group .dropdown-toggle.btn-default~.dropdown-menu{background-color:#e7e7e7;border-color:#dadada}.btn-group .dropdown-toggle.btn-default~.dropdown-menu>li>a{color:#333}.btn-group .dropdown-toggle.btn-default~.dropdown-menu>li>a:hover{background-color:#d3d3d3}.btn-group .dropdown-toggle.btn-primary~.dropdown-menu{background-color:#008cba;border-color:#0079a1}.btn-group .dropdown-toggle.btn-primary~.dropdown-menu>li>a{color:#fff}.btn-group .dropdown-toggle.btn-primary~.dropdown-menu>li>a:hover{background-color:#006d91}.btn-group .dropdown-toggle.btn-success~.dropdown-menu{background-color:#43ac6a;border-color:#3c9a5f}.btn-group .dropdown-toggle.btn-success~.dropdown-menu>li>a{color:#fff}.btn-group .dropdown-toggle.btn-success~.dropdown-menu>li>a:hover{background-color:#388f58}.btn-group .dropdown-toggle.btn-info~.dropdown-menu{background-color:#5bc0de;border-color:#46b8da}.btn-group .dropdown-toggle.btn-info~.dropdown-menu>li>a{color:#fff}.btn-group .dropdown-toggle.btn-info~.dropdown-menu>li>a:hover{background-color:#39b3d7}.btn-group .dropdown-toggle.btn-warning~.dropdown-menu{background-color:#e99002;border-color:#d08002}.btn-group .dropdown-toggle.btn-warning~.dropdown-menu>li>a{color:#fff}.btn-group .dropdown-toggle.btn-warning~.dropdown-menu>li>a:hover{background-color:#c17702}.btn-group .dropdown-toggle.btn-danger~.dropdown-menu{background-color:#f04124;border-color:#ea2f10}.btn-group .dropdown-toggle.btn-danger~.dropdown-menu>li>a{color:#fff}.btn-group .dropdown-toggle.btn-danger~.dropdown-menu>li>a:hover{background-color:#dc2c0f}.lead{color:#6f6f6f}cite{font-style:italic}blockquote{color:#6f6f6f;border-left-width:1px}blockquote.pull-right{border-right-width:1px}blockquote small{font-size:12px;font-weight:300}table{font-size:12px}input,.form-control{padding:7px;font-size:12px}label,.control-label,.help-block,.checkbox,.radio{font-size:12px;font-weight:normal}.form-group .btn,.input-group-addon,.input-group-btn .btn{padding:8px 14px;font-size:12px}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{border-color:transparent}.nav-tabs>li>a{color:#222;background-color:#e7e7e7}.nav-tabs .caret{border-top-color:#222;border-bottom-color:#222}.nav-pills{font-weight:300}.breadcrumb{font-size:10px;font-weight:300;text-transform:uppercase;border:1px solid #ddd;border-radius:3px}.pagination{font-size:12px;font-weight:300;color:#999}.pagination>li>a,.pagination>li>span{margin-left:4px;color:#999}.pagination>.active>a,.pagination>.active>span{color:#fff}.pagination>li>a,.pagination>li:first-child>a,.pagination>li:last-child>a,.pagination>li>span,.pagination>li:first-child>span,.pagination>li:last-child>span{border-radius:3px}.pagination-lg>li>a{padding-right:22px;padding-left:22px}.pagination-sm>li>a{padding:0 5px}.pager{font-size:12px;font-weight:300;color:#999}.list-group{font-size:12px;font-weight:300}.alert{font-size:12px;font-weight:300}.alert a,.alert .alert-link{font-weight:normal;color:#fff;text-decoration:underline}.label{padding-right:1em;padding-left:1em;font-weight:300;border-radius:0}.label-default{color:#333;background-color:#e7e7e7}.badge{font-weight:300}.progress{height:22px;padding:2px;background-color:#f6f6f6;border:1px solid #ccc;-webkit-box-shadow:none;box-shadow:none}.dropdown-menu{padding:0;margin-top:0;font-size:12px}.dropdown-menu>li>a{padding:12px 15px}.dropdown-header{padding-right:15px;padding-left:15px;font-size:9px;text-transform:uppercase}.popover{font-size:12px;font-weight:300;color:#fff}.clearfix:before,.clearfix:after{display:table;content:" "}.clearfix:after{clear:both}.clearfix:before,.clearfix:after{display:table;content:" "}.clearfix:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed} \ No newline at end of file diff --git a/static/forum_website/css/main.css b/static/forum_website/css/main.css new file mode 100644 index 0000000..054f4d2 --- /dev/null +++ b/static/forum_website/css/main.css @@ -0,0 +1,388 @@ +@import url(http://fonts.googleapis.com/css?family=Varela+Round); +/* override bootstrap */ +hr { + border-top: 1px solid #424242; +} +.container>.navbar-header { + height: 45px; +} +.navbar>.container .navbar-brand { + margin-left: 0; +} +.navbar-default { + margin-bottom: 0; +} +#filter-container { + background: #f5f5f5; + padding: 15px; +} +#filter-form { + margin-bottom: 0; +} +.table .glyphicon { + margin-top: 2px; + font-size: .8em; + float: right; +} +/* override nicEditor */ +#questionInstance { + background: #ffffff !important; +} +/* main styles */ +body { + background: #fafafa; + box-shadow: 4px 0 10px #cccccc, -4px 0 10px #cccccc; + font-family: 'Varela Round', sans-serif; +} +#page-wrapper { + max-width: 970px; + margin:0 auto; + box-shadow: 0px 0px 15px #cccccc; +} +.container { + max-width: 970px; +} +#header-wrapper { + max-width: 970px; + margin:0 auto; + background: #ffffff; +} +#header-inner { +} +#logo { + width: 25px; + margin-top: -3px; + margin-right: 4px; +} +#content-wrapper { + position: relative; + max-width: 970px; + margin:0 auto; + padding: 15px 0 25px 0; + background: #ffffff; +} +#content-inner { + min-height: 600px; +} +#content{ +} +.question-critic, .answer-critic { + padding-left: 0; + padding-top: 15px; + text-align: center; +} +.question-critic { + font-size: 1.3em; +} +.answer-critic { + font-size: 1em; +} +.vote { + text-decoration: none; + color: #cccccc; +} +.vote:hover { + text-decoration: none; + cursor: pointer; +} +.voted { + color: orange; +} +/* .question-wrapper { */ +/* padding-left: 0; */ +/* } */ +#content .question { + position: relative; + padding: 15px 0 15px 0; + border-bottom: 1px solid #f5f5f5; +} +#content .editable { + padding: 15px 5px 15px 5px; + background: #fafafa; +} +#content .question .title a{ + padding: 0 0 7px 0; + font-size: 1.1em; + color: #424242; +} +#content .question .body { + padding: 10px; + background: #fafafa; +} +#content .question .category a, +#content .question .tutorial a, +#content .question .minute_range a, +#content .question .second_range a { + padding: 3px 5px; + margin: 0 5px 0 0; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + -o-border-radius: 3px; + border-radius: 3px; +} +#content .question .category a { + background: #a26dc8; + color: #ffffff; +} +#content .question .tutorial a { + background: #424242; + color: #ffffff; + width: 100px; + overflow: hidden; +} +#content .question .minute_range a { + background: #f5f5f5; + color: #424242; +} +#content .question .second_range a { + background: #f5f5f5; + color: #424242; +} +#question-details-edit { + position: relative; + top: 2px; + margin-top: 2px; + color: #43ac6a; +} +#content .question .meta{ + position: absolute; + right: 0px; + bottom: 0px; +} +#content .answer .meta{ + position: absolute; + right: 0px; + bottom: 0px; +} +#content .question .user{ + background: #f5f5f5; + padding: 2px 7px; +} +table .category { + color:#7395d9; + font-weight:bold; +} +table .tutorial { + color:#a26dc8; + font-weight:bold; +} +table .title a { + font-size: 1.1em; + color: #424242; +} +#similar-link { + display: none; +} +#questionNicPanel { + display: none; +} +.modify { + display: none; + position: absolute; + top: 0; + right:0; +} +.modify a.edit { +} +.modify a.save { + display: none; +} +.vs { + padding: 0px 5px !important; + font-size: x-small; +} +.hideme { + display: none; +} +.saving, .saved, .deleted, .hide-qmsg { + position: fixed; + z-index: 2000; + left: 45%; + top: 45%; + padding: 5px 10px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + -o-border-radius: 5px; + border-radius: 5px; + -webkit-box-shadow: 0px 0px 10px #cccccc; + -moz-box-shadow: 0px 0px 10px #cccccc; + -obox-shadow: 0px 0px 10px #cccccc; + box-shadow: 0px 0px 10px #cccccc; +} +.saving { + background: lightyellow; +} +.saved { + background: lightgreen; +} +.deleted, .hide-qmsg{ + background: #5bc0de; + color: white; +} +.question-midify{ + overflow: hidden; +} +.question-midify .delete-question, .question-midify .edit, .question-midify .save, .question-midify .hide-question{ + float: left; + margin: 0 3px; +} +#content .answer { + position: relative; + border-bottom: 1px solid #f5f5f5; + padding-top: 20px; + padding-bottom: 20px; + margin: 10px 0px; +} +#content .answer .body { +} +#content .answer .user { + padding: 2px 7px; + background: #f5f5f5; +} +.comments { + border-left: 1px solid #cccccc; +} +.comments .comment { + position: relative; + padding: 5px 5px; + border-bottom: 1px dotted #cccccc; +} +.comments .new-comment { + display: none; +} +.comments .add-comment { + margin: 2px; + padding: 1px 2px; + color: #000000; + background: #f5f5f5; +} +.comments .cancel-comment { + display: none; + margin: 2px; + padding: 1px 2px; + color: #ffffff; + background: #d34836; +} +.comments .post-comment { + display: none; + margin: 2px; + padding: 1px 2px; + color: #ffffff; + background: #42B449; +} +#footer-wrapper { + max-width: 970px; + margin:0 auto; + background-color: #2d2d2d; + color: #ffffff; +} +#footer-inner { + padding-top: 10px; + padding-bottom: 10px; +} +#footer-inner a{ + color: #ffffff; +} +#footer-inner .cc{ + font-size: 13px; + text-align: center; +} + +#footer-inner .cc-logo{ + padding-right: 5px; +} +.field_error { + border: 1px solid red; +} +.notification { + position: relative; + padding: 15px; + margin: 10px 0; + border-left: 2px solid #424242; + background: #f7f7f7; +} +.notification .remove { + position: absolute; + right: 10px; + top: 15px; +} +.my-question, +.my-answer { + position: relative; + margin: 10px auto; + padding: 15px; + border-left: 2px solid #424242; + background: #f7f7f7; +} +.my-question .date, +.my-answer .date { + position: absolute; + right: 5px; + bottom: 5px; +} +#content .comment { + min-height: 50px; +} +#content .comment .modify-wrapper { + display: none; +} +#content .comment .meta { + position: absolute; + right: 0px; + bottom: 0px; + font-size: small; +} +#content .comment .user { + padding: 2px 7px; + background: #f5f5f5; +} +/* carousel styles */ +.slick-next:before, +.slick-prev:before, +.slick-next:after, +.slick-prev:after { + color: #a26dc8; +} +.carousel, .slick-list { + height: 245px; + margin-right: -2px; +} +.carousel .thumbnail { + width: 97%; + height: 245px; + border: 1px solid #cccccc; +} +.carousel .thumbnail img { + height: 100px; +} +.carousel .caption .category { + display: block; + width: 100%; + white-space: nowrap; + overflow: hidden; + text-align: center; +} +.carousel .caption .latest { + display: block; + padding: 5px 0 5px 0; + border-top: 1px solid #cccccc; + width: 100%; + white-space: nowrap; + overflow: hidden; + text-align: center; +} +.carousel .caption .btn { + margin-top: 7px; +} +.parent-filter { + background: #FDF5E6; + transition: background 2.5s ease; +} +.category-title{ + height: 100px; + text-shadow: 1px 1px 1px #000, 3px 3px 5px blue; + line-height: 100px; + text-align: center; + font-size: 22px; + overflow: hidden; +} diff --git a/static/forum_website/css/nice-bar.css b/static/forum_website/css/nice-bar.css new file mode 100644 index 0000000..9294c7e --- /dev/null +++ b/static/forum_website/css/nice-bar.css @@ -0,0 +1,40 @@ +.nice-bar { + display: none; + width: 100%; + background: #0074D9; + border-bottom: 3px solid #ffffff; + font-size: 0.85em; +} +.nice-bar .nice-text { + width: 960px; + margin: 0 auto; + padding: 12px 0; + color: #ffffff; + font-weight: bold; +} +.nice-bar .nice-button { + padding: 2px 5px; + background: #111111; + color: #ffffff; + margin: 0 0 0 10px; + + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + -o-border-radius: 3px; + border-radius: 3px; +} +.nice-bar .nice-close { + float: right; + padding: 1px 7px 2px 7px; + background: #111111; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + -o-border-radius: 3px; + border-radius: 3px; +} +.nice-bar .nice-close:hover { + cursor: pointer; +} +.nice-bar span.ext{ + display: none; +} diff --git a/static/forum_website/css/theme.blue.css b/static/forum_website/css/theme.blue.css new file mode 100644 index 0000000..81debf3 --- /dev/null +++ b/static/forum_website/css/theme.blue.css @@ -0,0 +1,229 @@ +/************* + Blue Theme + *************/ +/* overall */ +.tablesorter-blue { + width: 100%; + background-color: #fff; + margin: 10px 0 15px; + text-align: left; + border-spacing: 0; + border: #cdcdcd 1px solid; + border-width: 1px 0 0 1px; +} +.tablesorter-blue th, +.tablesorter-blue td { + border: #cdcdcd 1px solid; + border-width: 0 1px 1px 0; +} + +/* header */ +.tablesorter-blue th, +.tablesorter-blue thead td { + font: 12px/18px Arial, Sans-serif; + font-weight: bold; + color: #000; + border-collapse: collapse; + padding: 4px; + text-shadow: 0 1px 0 rgba(204, 204, 204, 0.7); +} +.tablesorter-blue tbody td, +.tablesorter-blue tfoot th, +.tablesorter-blue tfoot td { + padding: 8px; + vertical-align: top; +} +.tablesorter-blue .header, +.tablesorter-blue .tablesorter-header { + /* black (unsorted) double arrow */ + background-image: url(data:image/gif;base64,R0lGODlhFQAJAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==); + /* white (unsorted) double arrow */ + /* background-image: url(data:image/gif;base64,R0lGODlhFQAJAIAAAP///////yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==); */ + /* image */ + /* background-image: url(images/black-unsorted.gif); */ + background-repeat: no-repeat; + background-position: center right; + padding: 7px 18px 7px 7px; + white-space: normal; + cursor: pointer; + font-size: 14px; +} +.tablesorter-blue .headerSortUp, +.tablesorter-blue .tablesorter-headerSortUp, +.tablesorter-blue .tablesorter-headerAsc { + background-color: #9fbfdf; + /* black asc arrow */ + background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7); + /* white asc arrow */ + /* background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7); */ + /* image */ + /* background-image: url(images/black-asc.gif); */ +} +.tablesorter-blue .headerSortDown, +.tablesorter-blue .tablesorter-headerSortDown, +.tablesorter-blue .tablesorter-headerDesc { + background-color: #8cb3d9; + /* black desc arrow */ + background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7); + /* white desc arrow */ + /* background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7); */ + /* image */ + /* background-image: url(images/black-desc.gif); */ +} +.tablesorter-blue thead .sorter-false { + background-image: none; + cursor: default; + padding: 4px; +} + +/* tfoot */ +.tablesorter-blue tfoot .tablesorter-headerSortUp, +.tablesorter-blue tfoot .tablesorter-headerSortDown, +.tablesorter-blue tfoot .tablesorter-headerAsc, +.tablesorter-blue tfoot .tablesorter-headerDesc { + /* remove sort arrows from footer */ + background-image: none; +} + +/* tbody */ +.tablesorter-blue td { + color: #3d3d3d; + background-color: #fff; + padding: 4px; + vertical-align: top; +} + +/* hovered row colors + you'll need to add additional lines for + rows with more than 2 child rows + */ +.tablesorter-blue tbody > tr.hover > td, +.tablesorter-blue tbody > tr:hover > td, +.tablesorter-blue tbody > tr:hover + tr.tablesorter-childRow > td, +.tablesorter-blue tbody > tr:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td, +.tablesorter-blue tbody > tr.even.hover > td, +.tablesorter-blue tbody > tr.even:hover > td, +.tablesorter-blue tbody > tr.even:hover + tr.tablesorter-childRow > td, +.tablesorter-blue tbody > tr.even:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td { + background-color: #d9d9d9; +} +.tablesorter-blue tbody > tr.odd.hover > td, +.tablesorter-blue tbody > tr.odd:hover > td, +.tablesorter-blue tbody > tr.odd:hover + tr.tablesorter-childRow > td, +.tablesorter-blue tbody > tr.odd:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td { + background-color: #bfbfbf; +} + +/* table processing indicator */ +.tablesorter-blue .tablesorter-processing { + background-position: center center !important; + background-repeat: no-repeat !important; + /* background-image: url(images/loading.gif) !important; */ + background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important; +} + +/* Zebra Widget - row alternating colors */ +.tablesorter-blue tbody tr.odd > td { + background-color: #ebf2fa; +} +.tablesorter-blue tbody tr.even > td { + background-color: #fff; +} + +/* Column Widget - column sort colors */ +.tablesorter-blue td.primary, +.tablesorter-blue tr.odd td.primary { + background-color: #99b3e6; +} +.tablesorter-blue tr.even td.primary { + background-color: #c2d1f0; +} +.tablesorter-blue td.secondary, +.tablesorter-blue tr.odd td.secondary { + background-color: #c2d1f0; +} +.tablesorter-blue tr.even td.secondary { + background-color: #d6e0f5; +} +.tablesorter-blue td.tertiary, +.tablesorter-blue tr.odd td.tertiary { + background-color: #d6e0f5; +} +.tablesorter-blue tr.even td.tertiary { + background-color: #ebf0fa; +} + +/* caption */ +caption { + background-color: #fff; +} + +/* filter widget */ +.tablesorter-blue .tablesorter-filter-row { + background-color: #eee; +} +.tablesorter-blue .tablesorter-filter-row td { + background-color: #eee; + line-height: normal; + text-align: center; /* center the input */ + -webkit-transition: line-height 0.1s ease; + -moz-transition: line-height 0.1s ease; + -o-transition: line-height 0.1s ease; + transition: line-height 0.1s ease; +} +/* optional disabled input styling */ +.tablesorter-blue .tablesorter-filter-row .disabled { + opacity: 0.5; + filter: alpha(opacity=50); + cursor: not-allowed; +} +/* hidden filter row */ +.tablesorter-blue .tablesorter-filter-row.hideme td { + /*** *********************************************** ***/ + /*** change this padding to modify the thickness ***/ + /*** of the closed filter row (height = padding x 2) ***/ + padding: 2px; + /*** *********************************************** ***/ + margin: 0; + line-height: 0; + cursor: pointer; +} +.tablesorter-blue .tablesorter-filter-row.hideme * { + height: 1px; + min-height: 0; + border: 0; + padding: 0; + margin: 0; + /* don't use visibility: hidden because it disables tabbing */ + opacity: 0; + filter: alpha(opacity=0); +} +/* filters */ +.tablesorter-blue input.tablesorter-filter, +.tablesorter-blue select.tablesorter-filter { + width: 98%; + height: auto; + margin: 0; + padding: 4px; + background-color: #fff; + border: 1px solid #bbb; + color: #333; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition: height 0.1s ease; + -moz-transition: height 0.1s ease; + -o-transition: height 0.1s ease; + transition: height 0.1s ease; +} +/* rows hidden by filtering (needed for child rows) */ +.tablesorter .filtered { + display: none; +} + +/* ajax error row */ +.tablesorter .tablesorter-errorRow td { + text-align: center; + cursor: pointer; + background-color: #e6bf99; +} diff --git a/static/forum_website/images/cc-logo-88x31.png b/static/forum_website/images/cc-logo-88x31.png new file mode 100644 index 0000000..f0a944e Binary files /dev/null and b/static/forum_website/images/cc-logo-88x31.png differ diff --git a/static/forum_website/slick/slick.css b/static/forum_website/slick/slick.css new file mode 100644 index 0000000..dc385ba --- /dev/null +++ b/static/forum_website/slick/slick.css @@ -0,0 +1,47 @@ +/* Slider */ +.slick-slider { position: relative; display: block; box-sizing: border-box; -moz-box-sizing: border-box; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -ms-touch-action: none; touch-action: none; -webkit-tap-highlight-color: transparent; } + +.slick-list { position: relative; overflow: hidden; display: block; margin: 0; padding: 0; } +.slick-list:focus { outline: none; } +.slick-loading .slick-list { background: white url(./ajax-loader.gif) center center no-repeat; } +.slick-list.dragging { cursor: pointer; cursor: hand; } + +.slick-slider .slick-list, .slick-track, .slick-slide, .slick-slide img { -webkit-transform: translate3d(0, 0, 0); -moz-transform: translate3d(0, 0, 0); -ms-transform: translate3d(0, 0, 0); -o-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } + +.slick-track { position: relative; left: 0; top: 0; display: block; zoom: 1; } +.slick-track:before, .slick-track:after { content: ""; display: table; } +.slick-track:after { clear: both; } +.slick-loading .slick-track { visibility: hidden; } + +.slick-slide { float: left; height: 100%; min-height: 1px; display: none; } +.slick-slide img { display: block; } +.slick-slide.slick-loading img { display: none; } +.slick-slide.dragging img { pointer-events: none; } +.slick-initialized .slick-slide { display: block; } +.slick-loading .slick-slide { visibility: hidden; } +.slick-vertical .slick-slide { display: block; height: auto; border: 1px solid transparent; } + +/* Icons */ +@font-face { font-family: "slick"; src: url("./fonts/slick.eot"); src: url("./fonts/slick.eot?#iefix") format("embedded-opentype"), url("./fonts/slick.woff") format("woff"), url("./fonts/slick.ttf") format("truetype"), url("./fonts/slick.svg#slick") format("svg"); font-weight: normal; font-style: normal; } +/* Arrows */ +.slick-prev, .slick-next { position: absolute; display: block; height: 20px; width: 20px; line-height: 0; font-size: 0; cursor: pointer; background: transparent; color: transparent; top: 50%; margin-top: -10px; padding: 0; border: none; outline: none; } +.slick-prev:focus, .slick-next:focus { outline: none; } +.slick-prev.slick-disabled:before, .slick-next.slick-disabled:before { opacity: 0.25; } + +.slick-prev:before, .slick-next:before { font-family: "slick"; font-size: 20px; line-height: 1; color: white; opacity: 0.85; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } + +.slick-prev { left: -25px; } +.slick-prev:before { content: "\2190"; } + +.slick-next { right: -25px; } +.slick-next:before { content: "\2192"; } + +/* Dots */ +.slick-slider { margin-bottom: 30px; } + +.slick-dots { position: absolute; bottom: -45px; list-style: none; display: block; text-align: center; padding: 0px; width: 100%; } +.slick-dots li { position: relative; display: inline-block; height: 20px; width: 20px; margin: 0px 5px; padding: 0px; cursor: pointer; } +.slick-dots li button { border: 0; background: transparent; display: block; height: 20px; width: 20px; outline: none; line-height: 0; font-size: 0; color: transparent; padding: 5px; cursor: pointer; outline: none; } +.slick-dots li button:focus { outline: none; } +.slick-dots li button:before { position: absolute; top: 0; left: 0; content: "\2022"; width: 20px; height: 20px; font-family: "slick"; font-size: 6px; line-height: 20px; text-align: center; color: black; opacity: 0.25; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } +.slick-dots li.slick-active button:before { opacity: 0.75; } diff --git a/static/spoken/csc.js b/static/spoken/csc.js new file mode 100644 index 0000000..55e378f --- /dev/null +++ b/static/spoken/csc.js @@ -0,0 +1,141 @@ +const colorList = ['rgb(216, 133, 163)','rgb(253, 187, 47)','rgb(230, 246, 157)','rgb(170, 222, 167)','rgb(100, 194, 166)','rgb(45, 135, 187)','rgb(155, 191, 224)','rgb(232, 160, 154)','rgb(251, 226, 159)','rgb(198, 214, 143)','rgb(255, 170, 165)','rgb(203, 226, 176)','rgb(220, 214, 247)','rgb(234, 144, 133)','rgb(164, 212, 174)','rgb(213, 151, 206)', +'rgb(72, 76, 127)','rgb(237, 154, 115)','rgb(222, 212, 115)','rgb(120, 176, 160)','rgb(92, 120, 147)','rgb(203, 155, 66)','rgb(215, 172, 212)','rgb(234, 138, 138)','rgb(66, 121, 150)','rgb(135, 142, 205)','rgb(42, 82, 138)','rgb(139, 79, 128)'] +console.log('a',colorList.length) +// function draw_course_enroll_stats(courses,type,id){ +function draw_course_enroll_stats(courses,type,id){ + let labels = []; + let data_points = []; + for (var key in courses){ + console.log(key,courses[key]); + labels.push(key); + data_points.push(courses[key]); + } + const data = { + labels: labels, + datasets: [{ + axis: 'y', + label:'', + backgroundColor: colorList.slice(labels.length), + borderColor: '#fff', + data: data_points, + borderWidth: 1, + // fill: false, + }] + }; + console.log("data") + console.log(data.datasets[0]) + var config = { + type: 'bar', + data: data, + options: { + indexAxis: 'y', + } + }; + const myChart = new Chart(document.getElementById(id),config); +} + + +function draw_prg_type_stats(d){ + console.log('printing d................') + console.log(d) + const labels = []; + const data_points = [] + for (const course in d) { + console.log(`${course}: ${d[course]}`); + labels.push(course); + data_points.push(d[course]); + } + console.log(labels) + backgroundColors = []; + for (const i in colorList) { + backgroundColors.push(colorList[i]); + } + const data = { + labels: labels, + datasets: [{ + label: 'Programme Type', + backgroundColor:backgroundColors, + borderColor: '#fff', + data: data_points, + }] + }; + var config = { + type: 'bar', + data: data, + }; + const myChart = new Chart(document.getElementById('prg_type'),config); +} + +function lockScroll() { + document.body.classList.toggle('lock-scroll'); +} +$(document).ready(function(){ + url = '/csc/get_stats/' + var upcoming_tests = {} + var course_type_offered = {} + + + course_count_result = {} + $.ajax({ + url : url, + type: "GET", + success: function(data, textStatus, jqXHR) + { + upcoming_tests = data['upcoming_tests'] + course_type_offered = data['course_type_offered'] + + course_count_result= data['course_count_result'] + + for (var key in upcoming_tests){ + + d = upcoming_tests[key]; + const labels = [ + 'Approved', + 'Rejected', + ]; + data_points = [d['approved'],d['rejected']]; + const data = { + labels: labels, + datasets: [{ + label: key, + backgroundColor: ['#94D0CC','#EEC4C4'], + borderColor: '#fff', + data: data_points, + }] + }; + var config = { + type: 'doughnut', + data: data, + options: { + borderWidth:1, + caretPadding: 10, + weight:1, + legend: { + display: false + }, + cutoutPercentage: 80, + } + }; + const myChart = new Chart(document.getElementById('test_'+String(d['id'])),config); + + + } + draw_prg_type_stats(data['course_count_result']); + // draw_course_enroll_stats(dca_students,'dca','dca_course'); + // draw_course_enroll_stats(individual_students,'individual','individual_course'); + }, + error: function (jqXHR, textStatus, errorThrown) + { + console.log("ERROR") + } + }); +}); + +function toggle_sidebar(){ + $("#sidebar_div").toggle(); + var element = document.getElementById("main_div"); + element.classList.add("col-md-12"); + var element = document.getElementById("wrapper"); + element.classList.add("container"); + +} \ No newline at end of file diff --git a/static/spoken/csc_style.css b/static/spoken/csc_style.css new file mode 100644 index 0000000..fb20ecc --- /dev/null +++ b/static/spoken/csc_style.css @@ -0,0 +1,1870 @@ +/*general*/ +:root{ + --footer-color:#002649; + --white:#fff; + --light :#F5F8FD ; + --dark :#02073F ; + --main-font-color :#413e66 ; + --shadow : 0 1px 5px rgb(104,104,104,0.5); + --btn-color:#18B1DC; /*rgb(24,177,220)*/ + --line-color:#C9D4F6; + --font:"Open Sans", sans-serif; + --section-padding:0 10%; + --orange:#EC6C06;/* #(236,108,6)*/ + +} +body{ + font-size: 16px; + font-family: "Open Sans", sans-serif; +} + +a{ + text-decoration: none; + color: var(--white); +} +h2{ + font-weight: bold; + color: var(--dark); + margin: 0; + font-family: "Open Sans", sans-serif; + text-align: center; +} +/* .btn{ + background: var(--btn-color); + background: var(--orange); + color: #fff; + padding: 0.6rem 1.3rem; + text-decoration: none; + border:0; + border-radius: 5px; + +} +.btn:hover{ + background:#fff; + border:1px solid #b71c1c; + color: rgb(0,0,0); +} */ +.btn1{ + color: var(--btn-color); + text-decoration: none; + border:0; + border-radius: 5px; + margin-bottom: auto; + margin-top: 10px; + color:var(--orange); + color:var(--btn-color); + font-weight: bold; + color:var(--dark); + font-size:0.8rem; +} +.btn1:hover{ + color:var(--btn-color); + font-weight: bold; + border-radius: 5px; +} +.app-i{ + margin-left:10px; +} + +.box{ + background:#ffffff; + position: relative; +} +.dropdown-item{ + color:rgba(0,0,0,1)!important; +} + +/*google fonts***************************/ +/* open-sans-300italic - latin */ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 300; + src: url('fonts/open-sans-v17-latin-300italic.eot'); /* IE9 Compat Modes */ + src: local('Open Sans Light Italic'), local('OpenSans-LightItalic'), + url('fonts/open-sans-v17-latin-300italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('fonts/open-sans-v17-latin-300italic.woff2') format('woff2'), /* Super Modern Browsers */ + url('fonts/open-sans-v17-latin-300italic.woff') format('woff'), /* Modern Browsers */ + url('fonts/open-sans-v17-latin-300italic.ttf') format('truetype'), /* Safari, Android, iOS */ + url('fonts/open-sans-v17-latin-300italic.svg#OpenSans') format('svg'); /* Legacy iOS */ +} + +/* open-sans-regular - latin */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + src: url('fonts/open-sans-v17-latin-regular.eot'); /* IE9 Compat Modes */ + src: local('Open Sans Regular'), local('OpenSans-Regular'), + url('fonts/open-sans-v17-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('fonts/open-sans-v17-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */ + url('fonts/open-sans-v17-latin-regular.woff') format('woff'), /* Modern Browsers */ + url('fonts/open-sans-v17-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */ + url('fonts/open-sans-v17-latin-regular.svg#OpenSans') format('svg'); /* Legacy iOS */ +} + +/* open-sans-600 - latin */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 600; + src: url('fonts/open-sans-v17-latin-600.eot'); /* IE9 Compat Modes */ + src: local('Open Sans SemiBold'), local('OpenSans-SemiBold'), + url('fonts/open-sans-v17-latin-600.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('fonts/open-sans-v17-latin-600.woff2') format('woff2'), /* Super Modern Browsers */ + url('fonts/open-sans-v17-latin-600.woff') format('woff'), /* Modern Browsers */ + url('fonts/open-sans-v17-latin-600.ttf') format('truetype'), /* Safari, Android, iOS */ + url('fonts/open-sans-v17-latin-600.svg#OpenSans') format('svg'); /* Legacy iOS */ +} +/*google fonts***************************/ + +/*navbar*//***************************************************************************/ +.navbar-nav > li{ + padding-left:5px; + padding-right:5px; + /*margin: 10px;*/ + color: #fff; +} + +.navbar-custom{ + min-height: 5rem; + background: var(--light); + font-weight: bold; + color: #fff; +} +.navbar-nav > li:last-child{ + margin-right:2%; +} +.navbar-nav a{ + font-family: "Open Sans", sans-serif; + text-transform: uppercase; + font-size: 0.8rem; + color: #fff; +} +.brand-custom{ + font-size: 0.8rem; + line-height: 1rem; + font-weight: 50; + letter-spacing: 0.05rem; + text-transform :uppercase; + color: var(--main-font-color); + margin-left:50px; +} + +nav button{ + color: #fff; +} +nav #logo{ + font-size: 1.4rem; + color: var(--orange); + /*color: var(--dark);*/ +} +nav img{ + width: 50px; +} +/*navbar*//***************************************************************************/ + +/*quote*//***************************************************************************/ +.quote{ + display: grid; + grid-template-columns: 1fr 4fr; + background-image: linear-gradient( + rgba(0, 38, 73, 0.6), + rgba(0, 38, 73, 0.5) + ), url('images/main_bg_2.jpg'); + + background-attachment: fixed; + min-height: 400px; + padding: 5% 10%; + padding-top: 10rem; + grid-gap: 1rem; + +} +.quote .image{ + justify-content: flex-end; + padding: 0; +} + +.quote img{ + max-width: 250px; + float: right; + border:2px solid #fff; +} + +.quote div{ + font-size: 1rem; + color: #ffffff; + font-family: "Open Sans", sans-serif; + font-weight: bold; + margin:0; + text-align: left; + justify-content: center; +} +.quote .name{ + float: right; +} +.quote .content{ + padding: 0; + border-top:2px solid rgb(255,255,255,0.8); + border-right:2px solid rgb(255,255,255,0.3); +} +/*quote*//***************************************************************************/ +/*about*//***************************************************************************/ +.about{ + display: grid; + grid-template-columns: 1fr 1fr; + grid-gap: 2rem; + box-shadow: var(--shadow); + border-radius: 10px; + margin:5rem 5%; + padding: 2% 2% 2% 2%; +} +.about .image{ + align-self: stretch; + justify-content: center; +} + +.about .content{ + line-height: 1.8rem; +} +.about h6{ + color:#696592; + font-style:italic; + font-weight: 400; + font-size: 1.2rem; + margin-bottom: 1rem; +} +.about h2{ + margin:2rem 0; +} +.about .content a{ + margin-top:5%; +} +/*about*//***************************************************************************/ + +/*donate*//***************************************************************************/ + +.is-shady { +animation: flyintoright .4s backwards; +background: #fff; +box-shadow: rgba(0, 0, 0, .1) 0 1px 0; +border-radius: 4px; +display: inline-block; +margin: 10px; +position: relative; +transition: all .2s ease-in-out; +border: 1px solid #004E95; +padding-top: 16px; +} +.is-shady:hover { +box-shadow: 0 10px 16px rgba(0, 0, 0, .13), 0 6px 6px rgba(0, 0, 0, .19); +} +.btn-info-spk{ + background: #002649; + color: #fff; + width: 50%; + height: 60px; + color: orange; + font-size: 1.2rem; +} + +.btn-info-spk:hover .btn-info-spk a{ + color: red!important; +} +.btn-info-spk a:hover { + color: black!important; +} +.btn-info-spk a{ + color: orange; + font-weight: bold; +} +/*donate*//***************************************************************************/ + +/*awards*//***************************************************************************/ + +/**********/ +#awards{ + background-image: linear-gradient( + rgba(0, 38, 73,0.9 ), + rgba(0, 38, 73,0.6) + ), url('images/awards-bg.jpg'); + background-size: cover; + background-attachment: fixed; + padding-top:4%; + padding-bottom:4%; + padding-right: 2%; + padding-left: 2%; + margin-top: 2%; +} +#awards{ + display: grid; + grid-template-columns: repeat(auto-fit,minmax(300px,1fr)); + grid-gap: 2rem; + min-height: 200px; + + +} +#awards .award-bg{ + display: flex; + align-items: center; + flex-direction: column; + min-height: 200px; + box-shadow: var(--shadow); + border:2px solid #fff; + +} +#awards .award-bg i{ + font-size: 2rem; + color: #fff; + line-height: 2.5rem; + margin-bottom: 2%; + color: var(--orange); +} +#awards .award-bg h5{ + color: #fff; + line-height: 2.5rem; + text-align: center; + font:var(--font); + font-size: 1.2rem; + font-weight: bold; + +} +#awards .award-bg .title{ + border-bottom: 1px solid #fff; + border-bottom: 2px solid var(--orange); +} + +#awards img{ + max-height: 200px; +} +/*awards*//***************************************************************************/ + +/*applications*/ +#applications{ + text-align: center; + padding:5% 5%; + padding-top: 0; +} + + +#applications .app +{ + background-color: #fff; + border-radius: 10px; + padding: 5%; + box-shadow: var(--shadow); + box-shadow : 0 1px 5px rgb(104,104,104,0.5); + position: relative; + /*background-color:rgba(0, 38, 73,1);*/ + opacity: 1; +} +/*#applications .app-name{ + display: flex; + justify-content: center; + align-items: center; + justify-content: space-around; + border-bottom: 1px solid whitesmoke; + padding-bottom: 2%; +}*/ +/*#applications .logo-bg{ + width: 100px; + height: 100px; + background-color: #fff; + border:2px solid #fff; + border-radius: 50%; +}*/ +#applications img{ + width: 100px; + height: 100px; +} + +#applications h4{ + color: var(--dark); + text-align: center; + font-weight: bold; + border-bottom: 2px solid var(--dark); + padding-bottom: 1%; + font-size: 1.2rem; + /*color: #fff;*/ +} +#applications p{ + color:rgba(0,0,0,0.8); + font-family: "Open Sans", sans-serif; + font-size: 0.9rem; + line-height: 1.2rem; + margin-bottom: 10%; + text-align: justify; + /*color: #fff;*/ +} +#applications .app-link{ + position: absolute; + bottom: 0px; + left: 0; + width: 100%; + padding:2% 4%; + /*border-top: 1px solid rgb(255,255,255,0.5);*/ + border-top: 1px solid rgb(2,7,63,0.5); + font-size: 1.2rem; +} + +#applications #products{ + display: grid; + grid-template-columns: repeat(auto-fit,minmax(240px,1fr)); + grid-gap: 2rem; + min-height: 200px; +} +#applications h2{ + color: var(--dark); + margin-bottom: 25px; +} +/*applications*/ + +/*applications*//***************************************************************************/ + +.box h4{ + font-family: var(--font); + font-size : 1.2rem; + font-weight: 900; + color: var(--main-font-color); + color: #004E96; + padding-bottom: 2px; + align-items: flex-end; +} +.box p{ + font-family: var(--font); + font-size: 0.9rem; + line-height: 1.5rem; + color: rgb(0,0,0,0.59); +} +.box a{ + text-decoration: none; + color: var(--btn-color); + position:absolute; + bottom:0px; +} +.box img{ + margin-bottom: 1rem; +} +.box .link-app{ + bottom: 0.5rem; +} + +.box-ls img{ + display: none; +} +.box-ll img{ + display: block; + } +/*applications*//***************************************************************************/ +/*activities*//***************************************************************************/ +.events{ + margin-top:2%; +} +.act-image{ + display: flex; + align-items: center; + justify-content: center; +} +.activities{ + display: grid; + grid-template-columns: 1fr 3fr; + background: var(--light); + font-size: 0.8rem; +} + +.activities .v-image{ + min-height: 400px; + min-width: 300px; + max-height: 300px; + background-color: #fff; + display: flex; + align-items: center; + justify-content: center; + display: none; +} +.activities{ + padding: 2% 2%; +} +.activities .h-image{ + min-height: 400px; + min-width: 300px; + display: flex; + align-items:center; + justify-content: center; +} +.activities .h-image img{ + min-width: 300px; + max-width:80%; +} + +.activities .a-content{ + min-height: 400px; + min-width: 300px; +} + +.activities .box-2{ + border:2px solid blue; +} +.activities .btn{ + background: var(--dark); + border:none; +} +.activities .btn:hover{ + color: #fff; + text-decoration: underline; +} + +.box-activities{ + display: grid; + grid-template-columns: 1fr; + grid-gap: 2rem; + padding:0; + margin: 0; + width: 100%; + margin-top: 2rem; +} +.link-explore{ + color: var(--btn-color); + font-size: 1rem; +} +.activities-container{ + display: grid; + grid-template-columns: 1fr; + justify-items: center; + grid-template-rows: auto; +} +.activities .fas{ + font-size: 1.5rem; +} +.btn-activities{ + display: grid; + grid-template-columns: repeat(3,1fr); +} + +.btn-activities .btn{ + min-width: 120px; + background: none; + color: #fff; + font-weight: bold; + max-width: 100%; + padding: 0; + +} +.btn-activities a{ + border: none; +} + +.btn-activities div{ + justify-content: center; + align-items: center; + background: var(--dark); + color: #fff; + /*position: relative;*/ + padding: 1%; + display: flex; + flex-wrap: wrap; +} + +.btn-activities div i{ + font-size:2rem; + } + +.activities-container i{ + color: var(--btn-color); + size: 1.5rem; + margin-right: 1rem; +} +.activities-event{ + padding: 1rem 0; + margin:0; + background-color: #fff; +} + +.activities-event p{ + line-height: 1.5rem; + font-size: 0.9rem; +} + +.filter_div span{ + padding:3% ; + font-size: 1rem; +} +.filter_div{ + padding: 2%; + margin:2%; +} +.filter-jobfair .activities-event{ + text-align:center; + margin: 0; +} +.filter-workshop .activities-event{ + text-align:center; + margin: 0; +} +.filter-internship .activities-event{ + text-align:center; + margin: 0; +} +.activities-event .date{ + border-right: 1px solid #e0e0e0; + margin-bottom: 10px; + margin-top: 10px; + border-left:5px solid var(--orange); +} +.date p{ + line-height: 1.5rem; +} +.activities-event { + box-shadow: 0 1px 5px rgb(104,104,104,0.5); + margin-right: 10px; + margin: 0; +} + +.box_card{ + box-shadow: var(--shadow); +} + +.activities-event:hover{ + background: #e1f5fe; +} + +.events h2{ + margin-bottom: 2rem; +} + +.activities-event img{ + border-radius: 50%; + max-width: 50px; +} + +.activities-event .content{ + text-align: left; + margin-left:10px; +} +.activities-event .content h6{ + font-size: 1.2rem; + color: var(--main-font-color); + font-weight: bold; + margin-bottom: 0.5rem; +} +#activities-filter button{ + background-color: var(--dark); + color: #fff; +} +.filter_div i{ + +} +/*activities*//***************************************************************************/ + +/*collaboration*//***************************************************************************/ +.collab{ + background-image: linear-gradient( + rgba(0, 0, 0, 0.4), + rgba(0, 0, 0, 0.5) + ), url('images/collab.jpg'); + background-size: cover; + background-attachment: fixed; + display: grid; + grid-template-columns: 1fr 1fr; + } +.collab .partners{ + border-right: 1px solid whitesmoke; + padding: 5% 2%; + background-color: var(--dark); + opacity: 0.9; + +} +.collab .partners .logos { + display: grid; + grid-template-columns: 1fr 1fr; + text-align: center; + padding-bottom: 10%; +} +.collab .partners h4 { + text-align: center; +} +.collab .partners a { + float: right; + margin:auto; + width: 150px; +} + +.collab .content{ + margin:5%; + color: #fff; + padding: 0 5%; + } +.collab h1{ + margin-bottom: 2rem; +} +.collab h2{ + margin-bottom: 2rem; + color: #fff; + font-size: 2rem; + text-decoration: none; +} +.collab a{ + margin-left: 50%; + margin-top: 2rem; + } +.collab p{ + line-height: 1.5rem; + font-weight: bold; +} +.collab .collab-nasscom{ + color: orange; + font-size: 2rem; +} +.collab-nasscom:hover{ + color: #fff; +} +/*collaboration*//***************************************************************************/ + +/*testimonial*//***************************************************************************/ +#testimonialCarousel{ + display: flex; + flex-direction: column; + justify-content: flex-end; +} +#testimonialCarousel .carousel-indicators{ + order: 10; + padding: 0; + margin: 0; + margin-top:20px; + +} +.carousel .testimonial-wrapper a{ + color: var(--dark); + padding-left: 1rem; + display: inline; + float: left; + margin-left: 0; + padding: 0; +} +.carousel .testimonial { + color: rgb(0,0,0,0.5); + padding: 2rem; + background: var(--light); + border-radius: 1rem; + margin-bottom: 15px; + height: 60%; + justify-content: left; + align-items: left; + position: relative; + +} +.carousel .testimonial p{ + font-size: 0.9rem; +} +.carousel .testimonial::after { + content: ""; + width: 15px; + height: 15px; + display: block; + background: var(--light); + border: 1px solid #efefef; + border-width: 0 0 1px 1px; + bottom: -8px; + left: 46px; + transform: rotateZ(-46deg); + position: absolute; +} +.testimonial i{ + color:var(--btn-color); + font-size: 2rem; +} +.carousel h2 { + margin: 2%; +} +.carousel h2::after { + content: ""; + width: 100px; + margin: 0 auto; + height: 4px; + border-radius: 1px; + left: 0; + right: 0; + bottom: -20px; +} +.carousel { + margin: 0 auto; + padding: 0 70px; +} +.carousel .item { + color: #999; + overflow: hidden; + min-height: 120px; + font-size: 13px; +} +.carousel .media { + padding: 0 0 0 0; +} + +.carousel .testimonial-wrapper { + padding: 0 10px; + +} +.carousel .testimonial { + color: rgb(0,0,0,0.6); + padding: 15px; + /*border: 1px solid #efefef;*/ + border-radius: 3px; + margin-bottom: 15px; + padding:2%; + min-height: 150px; + display: flex; + align-items: left; + flex-direction: column; + justify-content: left; + font-size: 1rem; + font-family: var(--font); + border-right:2px solid #004E95; + border-bottom:2px solid #004E95; + /*border:2px solid #004E95;*/ + /*background-color: #012549;*/ + /*color: #fff;*/ +} +.carousel .testimonial::after { + content: ""; + width: 15px; + height: 15px; + display: block; + /*background: #f1f1f1;*/ + background: #004E95; + border: 1px solid #efefef; + border-width: 0 0 1px 1px; + bottom: -8px; + left: 46px; + transform: rotateZ(-46deg); +} + +.carousel .overview { + padding: 3px 0 0 0; +} +.carousel .overview .details { + padding: 5px 0 8px; + font-size: 0.8rem; + margin-bottom: 40px; +} +.carousel .overview b { + text-transform: uppercase; + color :var(--btn-color); +} +.carousel-indicators li, .carousel-indicators li.active { + width: 18px; + height: 18px; + border-radius: 50%; + margin: 1px 2px; +} +.carousel-indicators li { + background: #e2e2e2; + border: 4px solid #fff; + +} +.carousel-indicators li.active { + color: #fff; + background: var(--orange); + border: 5px doublemargin-top:20px; +} +.carousel .testimonial-wrapper .btn { + padding:10px 20px; + color: #fff; +} +.carousel .testimonial-wrapper .btn:hover { + text-decoration: none; + color:var(--dark); +} + +.modal-title h5{ + color: var(--dark); +} +.modal-title h6{ + color: var(--btn-color); +} +/*testimonial*//***************************************************************************/ + +#applications2{ + text-align: center; + /*Theme 12*/ + background-image: -webkit-linear-gradient(30deg, #002649 50%, #004E95 50%); + background-size: cover; + background-attachment: fixed; + padding:5% 10%; +} + + +#applications2 .app +{ + background-color: #fff; + /* border-radius: 10px; + padding: 5%; */ + box-shadow: var(--shadow); + /* position: relative; */ +} + +#applications2 source{ + width: 100px; + height: 100px; +} + +#applications2 h5{ + color: var(--dark); + text-align: center; + font-weight: bold; + border-bottom: 2px solid var(--dark); +} +#applications2 p{ + color:rgb(0,0,0); + font-family: "Open Sans", sans-serif; + font-size: 0.9rem; + margin-bottom: 15%; +} +#applications2 .app-link{ + position: absolute; + bottom: 0px; + left: 0; + width: 100%; + padding:2% 4%; +} + +#applications2 #products{ + display: grid; + grid-template-columns: repeat(auto-fit,minmax(300px,1fr)); + grid-gap: 2rem; + min-height: 200px; +} + +/*applications*/ + +.video-testimonials{ + background: var(--light); + padding: 5%; + +} + +.video-testimonials .item{ + box-shadow: var(--shadow); + background: #fff; + height: 500px; + position:relative; +} +.video-testimonials .header{ + display: flex; + align-items: center; + justify-content: center; + +} +.video-testimonials .header video{ + margin: auto; + width:320px; + height: 240px; +} +.video-testimonials .content{ + padding: 10%; + height: 260px; + overflow: auto; +} +.video-testimonials .content h6{ + color: var(--btn-color); +} +.video-testimonials .content p{ + font-size: 0.8rem; + color: grey; +} +.video-testimonials .content .add-details{ + color: var(--btn-color); + border-bottom: 1px solid rgba(236,108,6,0.5); +} + +.video-testimonials .blank{ + position: sticky; + bottom: 0; + min-height: 25px; + width:100%; + z-index: 10; + background: #fff; +} +/*media testimonials*//***************************************************************************/ +.media-testimonials{ + margin-top: 5%; + padding:4% 15%; + background: var(--light); + +} +.media-testimonials-grid{ + display: grid; + grid-template-columns: 1fr; + grid-gap: 16px; + margin-bottom: 2%; + box-shadow: var(--shadow); + padding:5%; + border-radius: 10px; + background-color: #fff; +} +.media-testimonials video{ + min-width: 320px; + width:100%; +} +.media-testimonials .video-wrap{ + margin:0; + padding: 0; + height: 40%; +} +.media-testimonials h6{ + color: #004D94; + font-family: var(--font); + font-size: 0.9rem; +} +.media-testimonials p{ + color: rgb(0,0,0,0.6); + font-size: 0.9rem; + font-family: var(--font); +} + +/*media testimonials*//***************************************************************************/ + +/*info*//***************************************************************************/ +.info-wrapper{ + display: grid; + grid-template-columns: repeat(2,1fr); + padding: 0 10%; + grid-gap: 2rem; + margin-top: 2%; +} +.info-wrapper .info-style{ + box-shadow: var(--shadow); + padding: 1rem; + border-left: 10px solid #004E95;*/ + display: flex; +} + +.info-wrapper .info-style h2{ + color: #004E95; + +} +.info-wrapper .link-style a{ + color: var(--orange); + font-weight: bold; +} + +.info-wrapper a:hover{ + color: var(--btn-color); +} + + +.info-wrapper .about_pi .bio{ + display: grid; + grid-template-columns: 1fr 3fr; + grid-template-rows: 2; + line-height: 2rem; +} +.info-wrapper .about_pi .content{ + line-height: 2rem; +} + + +.info-wrapper .about_pi a{ + color: #004E95; + margin-right: 5%; +} + +.info-wrapper .content h5,h6,p,a{ + margin: 0; +} + +.about-content{ + padding: 2% 2%; +} +.info-wrapper .about_pi .bio img{ + grid-row: 1/3; + justify-content: center; + max-width: 80%; + justify-self:end; + margin: 0 1rem; + display: block; + min-width:140px; +} +.info-wrapper .about_pi .bio h5{ + grid-column: 2/3; +} +.info-wrapper .about_pi .bio h6{ + grid-column: 2/3; +} + +.info-wrapper .news{ + box-shadow: var(--shadow); +} +.info-wrapper .news *{ + text-align: left; +} +.news-content { + line-height: 2rem; +} +.news-content a{ + text-decoration: underline; + color: rgb(0,0,0); +} +/*info*//***************************************************************************/ + + +/*contact*//***************************************************************************/ +#contact{ + margin-top: 2%; +} +#contact .social-links { + line-height: 2.5rem; +} +#contact .contact-details { + line-height: 2.5rem; +} + +#contact .social-links a:hover{ + text-decoration: underline; + color: #fff; +} + +#contact h2{ + margin-bottom: 2rem; +} +.contact-wrapper{ + display: grid; + grid-template-columns: 1fr 1fr 2fr ; + grid-template-areas: 'social details form '; + padding-right: 5%; + padding-left: 5%; + padding-top: 5%; + padding-bottom: 8%; + color: #fff; +} +.contact-wrapper .social-links{ + min-width: 250px; + grid-area: social; + padding-top: 5%; +} +.contact-wrapper .contact-details{ + min-width: 300px; + grid-area: details; + padding-top: 5%; +} +.contact-wrapper .form{ + grid-area: form; + padding-top: 5%; +} +.contact-wrapper i{ + font-size: 1.5rem; + padding-right: 1rem; + +} +#contact button{ + margin-top: 20px; +} + +.blue-bg{ + background-color: #013A6B; + background-image: -webkit-linear-gradient(30deg, #002649 50%, #004E95 50%); + min-height: 250px; + border-bottom: 1px solid rgb(255,255,255,0.4); + } +/*contact*//***************************************************************************/ + +/*footer*//***************************************************************************/ +.footer-links ul{ + list-style-type: none; + padding-right: 5%; + } +.footer-links li h6{ + color: var(--white); + border-bottom: 1px solid rgb(255,255,255,0.4); + } + +.footer-links a:hover{ + text-decoration: underline; + color: var(--white); + } +.footer-links .logo{ + display: flex; + flex-direction: column; + align-items: center; + } +.footer-links .logo img{ + width: 50%; + max-width: 100px; + } +.footer-wrapper div{ + justify-content: left; + padding-top: 0; + border-left: 1px solid rgb(255,255,255,0.4); + padding: 0; + margin: 0; + width: 100%; + } +.footer-wrapper div:last-child{ + border-left: none; + align-self: center; + + } +.footer-links{ + display: flex; + justify-content: space-between; + padding-right: 2%; + padding-left: 2%; + padding-bottom: 10px; + padding-top: 10px; + } +.footer-wrapper{ + background-color: var(--footer-color); + color: #fff; + line-height: 1.5rem; + font-size: 0.8rem; + padding-top: 2%; + } +.footer-wrapper p{ + text-align: center; + color: rgb(255,255,255,0.4); + } +/*footer*//***************************************************************************/ + + +/*media queries*/ + +/*Large devices (desktops, less than 1200px)*/ + +@media (max-width: 1199.98px) { + +nav #logo{ + font-size: 1.2rem; + font-weight: bold; +} + } + +@media (min-width: 992px) { + .brand-custom { + font-size: 1rem; + font-weight: bold; + } + + .navbar-nav a{ + font-size: 0.8rem; + } + .applications-grid{ + grid-template-columns: repeat(3,1fr); + } + +.filter-jobfair .activities-event{ + display: grid; + grid-template-columns: 1fr 3fr; +} +.filter-internship .activities-event{ + display: grid; + grid-template-columns: 1fr 3fr; + } + .filter-workshop .activities-event{ + display: grid; + grid-template-columns: 1fr 1fr 3fr; + } + +.media-testimonials .media-wrapper{ + display: grid; + grid-template-columns: 1fr 1fr 1fr; + border:2px solid red; + grid-gap: 1rem; +} + +.media-testimonials1{ + display: grid; + grid-template-columns: 1fr 1fr 1fr; + grid-gap: 1rem; + padding:5% 10%; + background: var(--light); +} + +.media-testimonials1 .video-wrap{ + /*min-height: 40%;*/ + +} +.media-testimonials1 video{ + width: 100%; +} +.media-testimonials1 .item{ + box-shadow: var(--shadow); + padding:5% 5%; + border-radius: 10px; + background: #fff; +} +.media-testimonials1 .item h5{ + font-weight: bold; +} +.media-testimonials1 .item h6, h5{ + color: var(--dark); +} + +.video-testimonials{ + display: grid; + grid-template-columns: repeat(3,1fr); + grid-gap: 1rem; +} + +} + + +/*Medium devices (tablets, less than 992px)*/ +@media (max-width: 991.98px) { +.btn-info-spk{ + width: 90%; +} + + /*about*****************************************/ + .about{ + padding: 2%; + margin:5%; + } + + /*about*****************************************/ + .about{ + background-size: 100%; + grid-template-columns: 1fr; + margin-top:2rem; + display: grid; + grid-template-columns: 1fr; + justify-content: center; + } + .about .image{ + grid-row: 2/3; + width: 90%; + margin: auto; + } + .about .content { + grid-row: 1/2; + width: 90%; + margin: auto; + } + /*about*****************************************/ + + + .video-testimonials .content{ + padding: 20px 70px; +} + + /*contact*****************************************/ + .contact-wrapper{ + grid-template-columns: 1fr 1fr ; + grid-template-areas: + 'social details ' + 'form form '; + } + /*footer*****************************************/ + .footer-links{ + padding: 0; + } + .media-testimonials{ + padding:10px 10px; + } + + + .media-testimonials1{ + display: grid; + grid-template-columns: 1fr 1fr; + grid-gap: 1rem; + padding:5% 2%; + background: var(--light); +} + + } + +@media (max-width: 992px) and (min-width: 768px){ + + .applications-grid{ + grid-template-columns: 1fr 1fr; + } + + .video-testimonials{ + display: grid; + grid-template-columns:repeat(2,1fr); + + } + } + + /*Small devices (landscape phones, less than 768px)*/ +@media (max-width: 768px) { + .btn-info-spk{ + width: 90%; + font-size: 1rem; +} + nav{ + padding: 0; + } + /*nav*****************************************/ + .brand-custom { + font-size: 0.9rem; + font-weight: bold; + } + +/*quote*****************************************/ + .quote{ + grid-template-columns: 1fr; + } + .quote .image{ + display: flex; + align-items: stretch; + justify-content: center; + } + .quote img{ + max-width: 30%; + } + /*quote*****************************************/ + + /*about**********/ + .about{ + margin:5%; + } + .about .image{ + width:95%; + } + .about .content{ + width:95%; + } + + + /*about**********/ + + /*applications*****************************************/ + + .application{ + padding: 1%; + } + /*applications*****************************************/ + + /*activities*****************************************/ + .activities{ + grid-template-columns: 1fr; + } + .activities .v-image{ + display: block; + display: flex; + justify-content: center; + } + .activities .v-image img{ + max-width: 100%; + } + .activities .h-image{ + display: none; + } + /*collaboration*****************************************/ + + /*collaboration*****************************************/ + .collab { + display: flex; + flex-direction: column; + } + .collab .content{ + margin-left:0; + text-align: center; + align-self: center; + justify-content: center; + margin-left:10%; + margin-right:10%; + } + .collab a{ + margin: 0; + align-self:center; + } + + .collab .partners { + border-right: none; + margin-top: 2%; + } + .collab .partners img{ + width: 120px; + } + + .collab h2{ + margin-top: 2%; + } + + + + .video-testimonials .item{ +/*border:2px solid blue;*/ + } + /*INFO*/ + .info-wrapper{ + grid-template-columns: 1fr; + padding: 0 5%; + } + + /*footer*****************************************/ + .footer-links{ + flex-direction: column; + } + + #testimonialCarousel .testimonial-grid{ + grid-template-columns: repeat(2,1fr); + grid-template-rows: 1; +} + +.carousel{ + padding: 10px; + } + } + + +@media (max-width: 768px) and (min-width: 576px){ + + #products{ + margin:2%; + } + +} + + +@media (max-width: 575.98px) { + body{ + padding-top: 50%; + } + + nav #logo{ + font-size: 1rem; + color: var(--orange); + } + .navbar-toggler-icon{ + display: flex; + align-items: center; + justify-content: center; + } + nav img{ + width: 40px; + } + .about{ + margin:5%; + } + + .media-testimonials-grid{ + grid-template-columns: 1fr; + align-items: center; + align-content: center; + justify-content: center; + } + + .media-testimonials-grid video{ + max-width: 240px; + justify-self: stretch; + } + + .media-testimonial .content{ + justify-self: center; + } + .video-testimonials{ + display: grid; + grid-template-columns: 1fr; + padding: 5%; + } + + + .video-testimonials .content{ + /*border:2px solid green;*/ + padding: 2%;} + .carousel{ + + padding: 0; + } + + .info-wrapper .info-style{ + box-shadow: var(--shadow); + padding: 1rem; + border-left: 5px solid #004E95;*/ + +} + .info-wrapper .about_pi .bio{ + grid-template-columns: 1fr; + } + + + .info-wrapper .bio{ + grid-template-columns: 1fr; + + } + html *{ + padding: 0; + margin: 0; + } + /*nav*****************************************/ + + .brand-custom { + font-size: 0.7rem; + margin:2%; + } + nav span .navbar-toggler-icon{ + max-width: 25px; + max-height: 25px; + + } + .navbar .navbar-toggler { + margin:0 auto; + display: block; + text-align: center; +} + /*nav*****************************************/ + /*quote*****************************************/ + .quote{ + grid-template-columns: 1fr; + } + .quote .image{ + display: flex; + align-items: center; + justify-content: center; + } + .quote img{ + max-width: 50%; + margin: 0 auto; + } + /*quote*****************************************/ + + /*applications*****************************************/ + + .application .applications-grid{ + grid-template-columns: 1fr; + } + #products .box{ + width: 100%; + } + #products{ + margin-right: 5%; + margin-left: 5%; + } + /*applications*****************************************/ + + + /*contact*****************************************/ + .contact-wrapper{ + display: block; + } + .contact-wrapper .social-links{ + min-width: 100%; + + } + .contact-wrapper .contact-details{ + min-width: 100%; + } + /*collaboration*****************************************/ + .collab{ + padding-bottom: 0; + padding: 0; + } + .collab a{ + width: 100%; + margin: 0; + } + .collab .collab-nasscom{ + text-align: center; + padding-bottom: 4%; + } + + .testimonial-wrapper{ + margin-bottom: 2rem; + } + #side_bar{ + display: none; + } +} +@media (max-width: 375px) { + + nav #logo{ + font-size: 0.8rem; + color: var(--orange); + } + .navbar-toggler{ + padding: 0; + border:1px solid red; + display: flex; + align-content: center; + justify-content: center; + + } +} + +@media (min-width: 1199.98px) { +.navbar-nav a{ + font-size: 0.8rem; + } + } +/*media queries*/ + +/* login page */ +.login-help{ + color: var(--dark); + text-decoration: underline; +} + +.f-sm{ + font-size: .875rem; +} + +/* sidebar */ +.sb-icon{ + color: #013A6B!important; +} +body { + font-size: .875rem; + } + + .feather { + width: 16px; + height: 16px; + vertical-align: text-bottom; + } + + /* + * Sidebar + */ + + .sidebar { + position: fixed; + top: 0; + /* rtl:raw: + right: 0; + */ + bottom: 0; + /* rtl:remove */ + left: 0; + z-index: 100; /* Behind the navbar */ + padding: 48px 0 0; /* Height of navbar */ + box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1); + } + + @media (max-width: 767.98px) { + .sidebar { + top: 5rem; + } + } + + .sidebar-sticky { + position: relative; + top: 0; + height: calc(100vh - 48px); + padding-top: .5rem; + overflow-x: hidden; + overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */ + } + + .sidebar .nav-link { + font-weight: 500; + color: #333; + } + + .sidebar .nav-link .feather { + margin-right: 4px; + color: #727272; + } + + .sidebar .nav-link.active { + color: #2470dc; + } + + .sidebar .nav-link:hover .feather, + .sidebar .nav-link.active .feather { + color: inherit; + } + + .sidebar-heading { + font-size: .75rem; + text-transform: uppercase; + } + + /* + * Navbar + */ + + + .sidebar { + position: fixed; + top: 0; + /* rtl:raw: + right: 0; + */ + bottom: 0; + /* rtl:remove */ + left: 0; + z-index: 100; /* Behind the navbar */ + padding: 48px 0 0; /* Height of navbar */ + box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1); + } + + @media (max-width: 767.98px) { + .sidebar { + top: 5rem; + } + } + + .sidebar-sticky { + position: relative; + top: 0; + height: calc(100vh - 48px); + padding-top: .5rem; + overflow-x: hidden; + overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */ + } + + .sidebar .nav-link { + font-weight: 500; + color: #333; + } + + .sidebar .nav-link .feather { + margin-right: 4px; + color: #727272; + } + + .sidebar .nav-link.active { + color: #2470dc; + } + + .sidebar .nav-link:hover .feather, + .sidebar .nav-link.active .feather { + color: inherit; + } + + .sidebar-heading { + font-size: .75rem; + text-transform: uppercase; + } + + /* + * Navbar + */ + .feather { + width: 16px; + height: 16px; + vertical-align: text-bottom; + } + .navbar-brand { + padding-top: .75rem; + padding-bottom: .75rem; + font-size: 1rem; + background-color: rgba(0, 0, 0, .25); + box-shadow: inset -1px 0 0 rgba(0, 0, 0, .25); + } + + .navbar .navbar-toggler { + top: .25rem; + right: 1rem; + } + + .navbar .form-control { + padding: .75rem 1rem; + border-width: 0; + border-radius: 0; + } + + .form-control-dark { + color: #fff; + background-color: rgba(255, 255, 255, .1); + border-color: rgba(255, 255, 255, .1); + } + + .form-control-dark:focus { + border-color: transparent; + box-shadow: 0 0 0 3px rgba(255, 255, 255, .25); + } + .lock-scroll { + overflow: hidden; +} diff --git a/static/spoken/css/bootstrap.min.css b/static/spoken/css/bootstrap.min.css new file mode 100644 index 0000000..b6fe4e0 --- /dev/null +++ b/static/spoken/css/bootstrap.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v3.3.1 (http://getbootstrap.com) + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:before,:after{color:#000!important;text-shadow:none!important;background:transparent!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before,.glyphicon-eur:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:before,:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:hover,a:focus{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:400;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}mark,.mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=radio],input[type=checkbox]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px}input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.radio input[type=radio],.radio-inline input[type=radio],.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox]{position:absolute;margin-top:4px \9;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type=radio][disabled],input[type=checkbox][disabled],input[type=radio].disabled,input[type=checkbox].disabled,fieldset[disabled] input[type=radio],fieldset[disabled] input[type=checkbox]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm,.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm,select.form-group-sm .form-control{height:30px;line-height:30px}textarea.input-sm,textarea.form-group-sm .form-control,select[multiple].input-sm,select[multiple].form-group-sm .form-control{height:auto}.input-lg,.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg,select.form-group-lg .form-control{height:46px;line-height:46px}textarea.input-lg,textarea.form-group-lg .form-control,select[multiple].input-lg,select[multiple].form-group-lg .form-control{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type=radio],.form-inline .checkbox input[type=checkbox]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.3px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#333;text-decoration:none}.btn:active,.btn.active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default.focus,.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary:hover,.btn-primary:focus,.btn-primary.focus,.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success.focus,.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info.focus,.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning.focus,.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger.focus,.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=submit].btn-block,input[type=reset].btn-block,input[type=button].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none;visibility:hidden}.collapse.in{display:block;visibility:visible}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#777}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=radio],[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=radio],.input-group-addon input[type=checkbox]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none;visibility:hidden}.tab-content>.active{display:block;visibility:visible}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important;visibility:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type=radio],.navbar-form .checkbox input[type=checkbox]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#333}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#fff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:hover,.label-default[href]:focus{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px 15px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-right:auto;margin-left:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-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-image:-o-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-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);-webkit-background-size:40px 40px;background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-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-image:-o-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-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)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-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-image:-o-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-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)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-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-image:-o-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-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)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-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-image:-o-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-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)}.media{margin-top:15px}.media:first-child{margin-top:0}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-left,.media-right,.media-body{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,a.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,a.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:hover,a.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,a.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,a.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table caption,.panel>.table-responsive>.table caption,.panel>.panel-collapse>.table caption{padding-right:15px;padding-left:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body,.panel-group .panel-heading+.panel-collapse>.list-group{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:absolute;top:0;right:0;left:0;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-weight:400;line-height:1.4;visibility:visible;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.42857143;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;perspective:1000}.carousel-inner>.item.next,.carousel-inner>.item.active.right{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-footer:before,.modal-footer:after{display:table;content:" "}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-footer:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none!important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file diff --git a/static/spoken/css/font-awesome.min.css b/static/spoken/css/font-awesome.min.css new file mode 100644 index 0000000..ec53d4d --- /dev/null +++ b/static/spoken/css/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.2.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.2.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.2.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"} \ No newline at end of file diff --git a/static/spoken/css/main.css b/static/spoken/css/main.css new file mode 100644 index 0000000..5ed39c9 --- /dev/null +++ b/static/spoken/css/main.css @@ -0,0 +1,832 @@ +@media (min-width: 1200px) { + .col-lg-offset-6p5 { + margin-left: 54.12222223%; + } + .col-lg-offset-5p5 { + margin-left: 45.77777775%; + } + .col-lg-offset-4p5 { + margin-left: 37.44444445%; + } + .col-lg-offset-3p5 { + margin-left: 29.12222223%; + } + .col-lg-offset-2p5 { + margin-left: 20.77777778%; + } + .col-lg-offset-1p5 { + margin-left: 12.44444445%; + } + .col-lg-offset-0p5 { + margin-left: 4.12222223%; + } + .col-lg-shadow { + -webkit-box-shadow: 0px 0px 20px 0px rgba(84, 70, 70, 0.87); + -moz-box-shadow: 0px 0px 20px 0px rgba(84, 70, 70, 0.87); + box-shadow: 0px 0px 20px 0px rgba(84, 70, 70, 0.87); + margin-top: 20px; + margin-bottom: 20px; + } +} + +#testimonials { + color: black; + font-family: 'Josefin Sans', sans-serif; + line-height: 22px; +} +.comfortaa { + font-family: 'Comfortaa', cursive; +} +.sans-serif{ + font-family : sans-serif; +} +html,body +{ + /* font-family: 'Alegreya', serif; */ + height: 100%; + font-size: 15px; + font-size: 13px; +} +.mini-text{ + font-family: 'Ubuntu Mono'; +} +/* overwrite */ +.yamm .dropdown-menu { + left: 0px; +} +.yamm-content li ul li{ + margin: 5px 0; + padding: 0 5px; +} +.yamm .yamm-content { + padding: 10px; +} +.mseprator{ + border-right: 1px solid #e5e5e5; +} +.events .yamm-content .mseprator, .creation .yamm-content .mseprator{ + min-height: 170px; +} +.creation .yamm-content .mseprator{ + min-height: 110px; +} +.yamm-content li ul li a{ + padding: 4px 0; + text-decoration: none; + font-size: 12px; +} +.yamm-content li ul li:hover{ + background-color: #f5f5f5; +} +.yamm-content li ul li:hover a{ + color: #262626; +} +.navbar-nav>li>.dropdown-menu.events, .navbar-nav>li>.dropdown-menu.creation{ + left: auto; +} +.dropdown-menu.creation > li > a, .dropdown-menu.user-details > li > a{ + color: #428bca; + font-size: 12px; +} +.help-text{ + background-color: #D9EDF7; + border-color: #BCE8F1; + color: #31708F; + font-size: 12px; + padding:2px 10px; + margin-bottom: 0px; +} +/* overwrite end */ +.scroller{ + position: absolute; + top: 40%; + right: 10px; + width: 20px; + position: fixed; + z-index: 1000; +} +.scroller li{ + margin: 5px 0; +} +.scroller li a{ + display: block; + color: black; + width: 20px; + height: 20px; + background: gray; + outline: none; +} +.page4 h2.page-title{ + padding-bottom: 20px; +} +h1.page-title, h4.page-title { + font-size: 20px; + margin: 10px 0 20px 0; + font-family: 'Oswald'; +} +.spacer{ + height: 40px; +} +/* layout */ +#banner-wrapper, .container-inner{ + overflow: hidden; +} +.container-inner{ + padding: 25px 0 25px 0; +} +#header-wrapper{ + height: auto; + font-family: sans-serif; +} +#testimonials, #home-video-container{ + clear: both; +} +#header-wrapper .navbar-header a{ + color: white; +} +#header-wrapper .navbar-header a .title{ + color: orange; +} +.navbar-default .navbar-nav>li>a{ + color: #ffffff; +} +.navbar-default .navbar-nav>li>a:hover, .navbar-default .navbar-nav>li>a:focus{ + color: orange; +} +#header-inner, +#content-inner, +#footer-inner, .inner { + position: relative; + max-width: 1200px; + margin: 0 auto; +} +/* header styles */ +#header-wrapper nav{ + background: #555555; +} +#testimonials, #home-video-container{ + overflow: hidden; + padding-top: 20px; + padding-bottom: 20px; +} +#header-inner .navbar-header a{ + display: block; + font-size: 18px; + font-weight: bold; + margin-top: 3px; + text-decoration: none; + margin-right: 10px; +} +#header-inner .navbar-header a img{ + padding-right: 5px; +} + +#search-wrapper{ + border-bottom: 1px solid #e4e5e5; +} +#search-wrapper .common-search{ + margin: auto; + width: 67.77%; + width: 65%; + padding: 15px 0; + padding-bottom: 5px; +} + +.col-lg-12.col-md-12.col-sm-12.col-xs-12.banner-img{ + padding: 0px; +} +#banner-wrapper .banner-items{ + padding: 20px 0; +} +#banner-wrapper .banner-items div{ + text-align: center; +} +#content{ + padding-left: 0px; + padding-right: 0px; +} +.stay-middle{ + text-align: center; +} +.justify{ + text-align: justify; +} +.top-border{ + border-top: 1px solid orange; + padding: 20px 0; +} +/* home page testimonials */ + +#testimonials .testimonial-content{ + border: 1px solid #e5e5e5; + overflow: hidden; + padding: 10px; + min-height: 120px; + font-size: 14px; +} +#testimonials .caretr{ + position: absolute; + top: -1px; + left: 20px; + width: 34px; + height: 13px; + background:url('/static/spoken/images/caret.png'); + +} +#testimonials .user-details{ + padding: 20px; + position: relative; +} +#testimonials img, .testimonial-content img { + border-radius: 50%; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; +} + +#testimonials .testimonial-item{ + overflow: hidden; +} + +.forum-container img{ + width: 100%; +} + +/* home page testimonials end */ + +/* home-video-container */ +/*#home-video-container .big-video{ + background: black; + border: 5px solid black; +}*/ +.video-lists .video-item{ + margin: 20px 10px; + margin-top: 0px; + width: 160px; + float: left; +} +.video-lists .video-item .thump{ + position: relative; +} +.video-lists .video-item .video-item-playlist{ + display: none; +} +.video-lists .video-item .thump img{ + width: 100%; + border: 5px solid #e5e5e5; +} +.video-lists .video-item .thump .video-item-playlist{ + bottom: 0px; + position: absolute; + text-align: center; + background-color: black; + opacity: 0.7; + width: 100%; + color: white; +} +/* home-video-container end */ + +.support-us .collaborate { + line-height: 24px; +} +/* contact */ +.contact-container .contact div{ + padding: 4px 0; + font-size: 14px; +} +.contact-container .contact div span{ + padding-right: 20px; + font-size: 18px; +} +/* contact end */ + +/* footer */ +#footer-wrapper{ + background: #555555; +} +#footer-wrapper a, #footer-wrapper footer{ + color: white; +} +#footer-wrapper .footer-seperator{ + border-right: 1px solid #eee; + min-height: 130px; +} +.iitb-logo { + text-align: center; +} +#footer-wrapper .footer-links ul li{ + padding: 2px 0; +} +#footer-wrapper .license footer{ + padding-top: 10px; + font-size: 10px; +} +#footer-wrapper .container-inner sans-serif { + padding-bottom: 5px; +} +#footer-wrapper .container-inner.sans-serif { + padding-bottom: 2px; +} +/* footer end */ + +/* media secreen overwrite */ +media="screen" +@media (min-width: 768px) +.circular img{ + width: 100%; + height: 100%; +} + +/* media screen overwrite end */ + +@media (max-width: 767px) { + .navbar-nav .open .dropdown-menu { + background-color: white; + } +} +/* layout end */ + +/* video search page */ +.search-result { + +} +.search-result .result-record{ + margin: 25px 0px; +} +.search-result .result-record .thumb{ + min-width: 100px; +} +.search-result .result-record a img{ + min-width: 100px; + border: 5px solid #E5E5E5; +} +.search-result .result-record .thump{ +} +.search-result .result-record .info{ +} +.search-result .result-record .info h3{ + margin-top: 0px; +} +.Basic{ + +} +/* video search page end */ +.no-record{ + border: 1px solid #ddd; + padding: 8px; + text-align: center; +} +.no-record:hover{ + background-color: #f5f5f5; +} +.ajax-refresh, .ajax-search-refresh{ + padding: 0 5px; + display: none; + position: absolute; + left: 0; + top: 6px; +} +.ajax-search-refresh{ + left: 45%; + top: 11px; +} +.form-group .radio ul{ + list-style: none; +} +.form-group .radio ul li{ + float: left; +} +/* font awesome */ +.fa-1 { + font-size: 1.2em; +} + +.fa-2 { + font-size: 1.5em; +} + +.fa-3 { + font-size: 3.5em; +} + +.fa-4 { + font-size: 5.5em; +} + +.fa-5 { + font-size: 7em; +} + +.fa-6 { + font-size: 20em; +} + +/* font awesome end */ + +/* status icon color */ +.review-pending-upload { + color: #D9534F; +} + +.review-admin-review { + color: #D9534F; +} + +.review-domain-review { + color: #F0AD4E; +} + +.review-quality-review { + color: #5BC0DE; +} +.review-accepted { + color: #10a41e; +} +/* status icon color end */ + + +/* Navbar css */ + +a { + text-decoration: none !important; +} + +.navbar > .container .navbar-brand { + margin-left: 5px; + padding: 0px; + padding-top: 3px; +} + +.navbar > .container .navbar-brand img#logo { + width: 42px; + height: 43px; + margin-right: 5px; +} + +/* Navbar css end */ + +/* Content css */ + +#content-wrapper #content-inner div.container { + padding-left: 25px; +} +#content-wrapper{ + min-height: 400px; + margin-bottom: 10px; +} +/* Content css end */ + +/* Note box css */ + +.bs-callout { + border-left: 3px solid #EEEEEE; + margin: 20px 0; + padding: 20px; +} +.bs-callout-danger { + background-color: #FDF7F7; + border-color: #D9534F; +} +.bs-callout-info { + background-color: #F4F8FA; + border-color: #5BC0DE; +} +.bs-callout-warning { + background-color: #FCF8F2; + border-color: #F0AD4E; +} + +/* Note box css end */ + +/* upload page css */ + +.reviewers-feedback { + margin: 10px 10px 25px 10px; +} + +.review-user { + float: left; + margin: 5px; +} + +.review-date { + float: right; + margin: 5px; +} + +.review-data { + clear: both; +} + +a.btn-warning { + margin-left: 10px; + width: 48px; +} +a.twin-button { + width: 74px; +} +.col-center { + text-align: center; +} +.col-left { + text-align: left; +} +.col-right { + text-align: right; +} +.fancybox-title-float-wrap { + display: none; +} +/* upload page css end */ + +/* tabs */ +.tab-content{ + padding: 15px 0; +} +/* tabs end */ + +/* badge */ +.badge { + color: black; + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + line-height: 1; + background-color: white; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: 10px; + float: right; +} +.badge-none { + color: #fff; + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + line-height: 1; + background-color: orangered; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: 10px; + float: right; +} +/* badge end */ + +/* dashboard style */ +.panel-heading-notif { + padding: 5px 15px; +} +.panel-body-notif { + overflow-y: scroll; + max-height: 268px; +} +.notif { + position: relative; +} +.notif p { + padding-rignt: 15px; +} +.notif-del { + top: 0px; + right: 0px; + position: absolute; +} +.clear-all { + color: #777; + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + line-height: 1; + background-color: white; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: 10px; + float: right; +} +/* dashboard style end */ +.no-padding { + padding: 0px; +} +.no-padding-right { + padding-right: 0px; +} +.no-padding-left { + padding-left: 0px; +} +.ico-text { + font-size: 18px; +} +pre.custom-jumbotron { + padding: 10px 20px; + border-radius: 6px; + font-size: 14px; + min-height: 112px; + margin-bottom: 30px; + color: inherit; + background-color: #eee; +} +pre.custom-jumbotron b { + font-size: 18px; +} + +/* sortable header */ +.paleblue th { + padding: 2px 5px; + line-height: normal; +} + +.paleblue th a:link, .paleblue th a:visited { + color: #666; +} + +.paleblue th.sorted .text { + padding-right: 42px; +} + +.paleblue th .text span { + padding: 2px 5px; + display:block; +} + +.paleblue th .text a { + display: block; + cursor: pointer; + padding: 2px 5px; +} + +.paleblue th.sortable:hover { + background-color: #F4F8FA !important; +} + +.paleblue th.sorted a.sortremove { + visibility: hidden; +} + +.paleblue th.sorted:hover a.sortremove { + visibility: visible; +} + +.paleblue th.sorted .sortoptions { + display: block; + padding-top: 4px; + float: right; + text-align: right; +} + +.paleblue th.sorted .sortpriority { + font-size: .8em; + min-width: 12px; + text-align: center; + vertical-align: top; +} + +.paleblue th.sorted .sortoptions a { + width: 14px; + height: 13px; + display: inline-block; +} + +.paleblue th.sorted .sortoptions a.sortremove { + background: url(../images/sorting-icons.gif) -4px -5px no-repeat; +} + +.paleblue th.sorted .sortoptions a.sortremove:hover { + background: url(../images/sorting-icons.gif) -4px -27px no-repeat; +} + +.paleblue th.sorted .sortoptions a.ascending { + background: url(../images/sorting-icons.gif) -5px -50px no-repeat; +} + +.paleblue th.sorted .sortoptions a.ascending:hover { + background: url(../images/sorting-icons.gif) -5px -72px no-repeat; +} + +.paleblue th.sorted .sortoptions a.descending { + background: url(../images/sorting-icons.gif) -5px -94px no-repeat; +} + +.paleblue th.sorted .sortoptions a.descending:hover { + background: url(../images/sorting-icons.gif) -5px -115px no-repeat; +} +/* sortable header end */ + +#search-wrapper .form-group{ + margin-bottom: 2px; +} +.alternate-search-link { + margin-right:0; +} +#footer-wrapper a:hover { + color: #FFA500; +} +.cc-data { + color: #DEB887; + text-align: center; +} +.add-padding { + padding: 5px; +} +.st-statcounter-seperator { + border-top: 1px solid white; + margin-top: 20px;} +.st-statcounter { + color: white; +} +.st-statcounter p { + padding-top: 6px; + font-size: 12px; +} + +.announcement{ + font-size: 14px; + font-weight: bold; + color: white; + border-radius: 0px; + margin-bottom: 0px; + } +.text-container{ + text-align:center; + padding: 0 60px; +} +#nav-fdp{ + border: 1px solid #C9302C; + background: #C9302C; + color: #fff; + float: left; +} +.block-info{ + text-align: center; + overflow-x: hidden; + margin: auto; + width: 65%; +} +.block-info div{ + color: white; + background: rgba(0,0,0,0.5); + font-size: 1.1rem; + padding: 5px; + font-weight: 500; +} +.block-info span a{ + text-decoration: underline!important; + color: gold; +} +.search-wrap{ + display: flex; + width: 100%; + margin: 0!important; + margin-bottom: 2px!important; +} +.search-wrap div{ + width: 42%; + margin-right: 2%; +} + +.search-wrap .fl-search-btn{ + width: 10%; + margin-right: 0!important; + margin-left: 2%; +} +.search-wrap .fl-search-btn input{ + float: right!important; + width: 100%; + margin-right: 0!important; +} +@media (max-width: 767px) { + .block-info{ + width: 100%; + } + .block-info div{ + padding: 5px 10px; + } + .search-wrap{ + display: flex; + flex-direction: column; + } + .search-wrap div{ + width: 100%; + margin-bottom: 10px; + } + .search-wrap .fl-search-btn{ + width: 40%; + margin-left: 0!important; + } + .common-search{ + display: flex; + flex-direction: column; + } +} +@media (min-width: 768px) and (max-width: 991.98px) { + .search-wrap .fl-search-btn{ + width: 14%; + } +} \ No newline at end of file diff --git a/static/spoken/css/video-js.min.css b/static/spoken/css/video-js.min.css new file mode 100644 index 0000000..9753da1 --- /dev/null +++ b/static/spoken/css/video-js.min.css @@ -0,0 +1,5 @@ +/*! +Video.js Default Styles (http://videojs.com) +Version 4.4.3 +Create your own skin at http://designer.videojs.com +*/.vjs-default-skin{color:#ccc}@font-face{font-family:VideoJS;src:url(../fonts/vjs.eot);src:url(../fonts/vjs.eot?#iefix) format('embedded-opentype'),url(../fonts/vjs.woff) format('woff'),url(../fonts/vjs.ttf) format('truetype');font-weight:400;font-style:normal}.vjs-default-skin .vjs-slider{outline:0;position:relative;cursor:pointer;padding:0;background-color:#333;background-color:rgba(51,51,51,.9)}.vjs-default-skin .vjs-slider:focus{-webkit-box-shadow:0 0 2em #fff;-moz-box-shadow:0 0 2em #fff;box-shadow:0 0 2em #fff}.vjs-default-skin .vjs-slider-handle{position:absolute;left:0;top:0}.vjs-default-skin .vjs-slider-handle:before{content:"\e009";font-family:VideoJS;font-size:1em;line-height:1;text-align:center;text-shadow:0 0 1em #fff;position:absolute;top:0;left:0;-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-o-transform:rotate(-45deg);transform:rotate(-45deg)}.vjs-default-skin .vjs-control-bar{display:none;position:absolute;bottom:0;left:0;right:0;height:3em;background-color:#07141e;background-color:rgba(7,20,30,.7)}.vjs-default-skin.vjs-has-started .vjs-control-bar{display:block;visibility:visible;opacity:1;-webkit-transition:visibility .1s,opacity .1s;-moz-transition:visibility .1s,opacity .1s;-o-transition:visibility .1s,opacity .1s;transition:visibility .1s,opacity .1s}.vjs-default-skin.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{display:block;visibility:hidden;opacity:0;-webkit-transition:visibility 1s,opacity 1s;-moz-transition:visibility 1s,opacity 1s;-o-transition:visibility 1s,opacity 1s;transition:visibility 1s,opacity 1s}.vjs-default-skin.vjs-controls-disabled .vjs-control-bar{display:none}.vjs-default-skin.vjs-using-native-controls .vjs-control-bar{display:none}@media \0screen{.vjs-default-skin.vjs-user-inactive.vjs-playing .vjs-control-bar :before{content:""}}.vjs-default-skin .vjs-control{outline:0;position:relative;float:left;text-align:center;margin:0;padding:0;height:3em;width:4em}.vjs-default-skin .vjs-control:before{font-family:VideoJS;font-size:1.5em;line-height:2;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;text-shadow:1px 1px 1px rgba(0,0,0,.5)}.vjs-default-skin .vjs-control:focus:before,.vjs-default-skin .vjs-control:hover:before{text-shadow:0 0 1em #fff}.vjs-default-skin .vjs-control:focus{}.vjs-default-skin .vjs-control-text{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.vjs-default-skin .vjs-play-control{width:5em;cursor:pointer}.vjs-default-skin .vjs-play-control:before{content:"\e001"}.vjs-default-skin.vjs-playing .vjs-play-control:before{content:"\e002"}.vjs-default-skin .vjs-mute-control,.vjs-default-skin .vjs-volume-menu-button{cursor:pointer;float:right}.vjs-default-skin .vjs-mute-control:before,.vjs-default-skin .vjs-volume-menu-button:before{content:"\e006"}.vjs-default-skin .vjs-mute-control.vjs-vol-0:before,.vjs-default-skin .vjs-volume-menu-button.vjs-vol-0:before{content:"\e003"}.vjs-default-skin .vjs-mute-control.vjs-vol-1:before,.vjs-default-skin .vjs-volume-menu-button.vjs-vol-1:before{content:"\e004"}.vjs-default-skin .vjs-mute-control.vjs-vol-2:before,.vjs-default-skin .vjs-volume-menu-button.vjs-vol-2:before{content:"\e005"}.vjs-default-skin .vjs-volume-control{width:5em;float:right}.vjs-default-skin .vjs-volume-bar{width:5em;height:.6em;margin:1.1em auto 0}.vjs-default-skin .vjs-volume-menu-button .vjs-menu-content{height:2.9em}.vjs-default-skin .vjs-volume-level{position:absolute;top:0;left:0;height:.5em;background:#66a8cc url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAP0lEQVQIHWWMAQoAIAgDR/QJ/Ub//04+w7ZICBwcOg5FZi5iBB82AGzixEglJrd4TVK5XUJpskSTEvpdFzX9AB2pGziSQcvAAAAAAElFTkSuQmCC) -50% 0 repeat}.vjs-default-skin .vjs-volume-bar .vjs-volume-handle{width:.5em;height:.5em}.vjs-default-skin .vjs-volume-handle:before{font-size:.9em;top:-.2em;left:-.2em;width:1em;height:1em}.vjs-default-skin .vjs-volume-menu-button .vjs-menu .vjs-menu-content{width:6em;left:-4em}.vjs-default-skin .vjs-progress-control{position:absolute;left:0;right:0;width:auto;font-size:.3em;height:1em;top:-1em;-webkit-transition:all .4s;-moz-transition:all .4s;-o-transition:all .4s;transition:all .4s}.vjs-default-skin:hover .vjs-progress-control{font-size:.9em;-webkit-transition:all .2s;-moz-transition:all .2s;-o-transition:all .2s;transition:all .2s}.vjs-default-skin .vjs-progress-holder{height:100%}.vjs-default-skin .vjs-progress-holder .vjs-play-progress,.vjs-default-skin .vjs-progress-holder .vjs-load-progress{position:absolute;display:block;height:100%;margin:0;padding:0;left:0;top:0}.vjs-default-skin .vjs-play-progress{background:#66a8cc url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAP0lEQVQIHWWMAQoAIAgDR/QJ/Ub//04+w7ZICBwcOg5FZi5iBB82AGzixEglJrd4TVK5XUJpskSTEvpdFzX9AB2pGziSQcvAAAAAAElFTkSuQmCC) -50% 0 repeat}.vjs-default-skin .vjs-load-progress{background:#646464;background:rgba(255,255,255,.4)}.vjs-default-skin .vjs-seek-handle{width:1.5em;height:100%}.vjs-default-skin .vjs-seek-handle:before{padding-top:.1em}.vjs-default-skin .vjs-time-controls{font-size:1em;line-height:3em}.vjs-default-skin .vjs-current-time{float:left}.vjs-default-skin .vjs-duration{float:left}.vjs-default-skin .vjs-remaining-time{display:none;float:left}.vjs-time-divider{float:left;line-height:3em}.vjs-default-skin .vjs-fullscreen-control{width:3.8em;cursor:pointer;float:right}.vjs-default-skin .vjs-fullscreen-control:before{content:"\e000"}.vjs-default-skin.vjs-fullscreen .vjs-fullscreen-control:before{content:"\e00b"}.vjs-default-skin .vjs-big-play-button{left:.5em;top:.5em;font-size:3em;display:block;z-index:2;position:absolute;width:4em;height:2.6em;text-align:center;vertical-align:middle;cursor:pointer;opacity:1;background-color:#07141e;background-color:rgba(7,20,30,.7);border:.1em solid #3b4249;-webkit-border-radius:.8em;-moz-border-radius:.8em;border-radius:.8em;-webkit-box-shadow:0 0 1em rgba(255,255,255,.25);-moz-box-shadow:0 0 1em rgba(255,255,255,.25);box-shadow:0 0 1em rgba(255,255,255,.25);-webkit-transition:all .4s;-moz-transition:all .4s;-o-transition:all .4s;transition:all .4s}.vjs-default-skin.vjs-big-play-centered .vjs-big-play-button{left:50%;margin-left:-2.1em;top:50%;margin-top:-1.4000000000000001em}.vjs-default-skin.vjs-controls-disabled .vjs-big-play-button{display:none}.vjs-default-skin.vjs-has-started .vjs-big-play-button{display:none}.vjs-default-skin.vjs-using-native-controls .vjs-big-play-button{display:none}.vjs-default-skin:hover .vjs-big-play-button,.vjs-default-skin .vjs-big-play-button:focus{outline:0;border-color:#fff;background-color:#505050;background-color:rgba(50,50,50,.75);-webkit-box-shadow:0 0 3em #fff;-moz-box-shadow:0 0 3em #fff;box-shadow:0 0 3em #fff;-webkit-transition:all 0s;-moz-transition:all 0s;-o-transition:all 0s;transition:all 0s}.vjs-default-skin .vjs-big-play-button:before{content:"\e001";font-family:VideoJS;line-height:2.6em;text-shadow:.05em .05em .1em #000;text-align:center;position:absolute;left:0;width:100%;height:100%}.vjs-loading-spinner{display:none;position:absolute;top:50%;left:50%;font-size:4em;line-height:1;width:1em;height:1em;margin-left:-.5em;margin-top:-.5em;opacity:.75;-webkit-animation:spin 1.5s infinite linear;-moz-animation:spin 1.5s infinite linear;-o-animation:spin 1.5s infinite linear;animation:spin 1.5s infinite linear}.vjs-default-skin .vjs-loading-spinner:before{content:"\e01e";font-family:VideoJS;position:absolute;top:0;left:0;width:1em;height:1em;text-align:center;text-shadow:0 0 .1em #000}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}}.vjs-default-skin .vjs-menu-button{float:right;cursor:pointer}.vjs-default-skin .vjs-menu{display:none;position:absolute;bottom:0;left:0;width:0;height:0;margin-bottom:3em;border-left:2em solid transparent;border-right:2em solid transparent;border-top:1.55em solid #000;border-top-color:rgba(7,40,50,.5)}.vjs-default-skin .vjs-menu-button .vjs-menu .vjs-menu-content{display:block;padding:0;margin:0;position:absolute;width:10em;bottom:1.5em;max-height:15em;overflow:auto;left:-5em;background-color:#07141e;background-color:rgba(7,20,30,.7);-webkit-box-shadow:-.2em -.2em .3em rgba(255,255,255,.2);-moz-box-shadow:-.2em -.2em .3em rgba(255,255,255,.2);box-shadow:-.2em -.2em .3em rgba(255,255,255,.2)}.vjs-default-skin .vjs-menu-button:hover .vjs-menu{display:block}.vjs-default-skin .vjs-menu-button ul li{list-style:none;margin:0;padding:.3em 0;line-height:1.4em;font-size:1.2em;text-align:center;text-transform:lowercase}.vjs-default-skin .vjs-menu-button ul li.vjs-selected{background-color:#000}.vjs-default-skin .vjs-menu-button ul li:focus,.vjs-default-skin .vjs-menu-button ul li:hover,.vjs-default-skin .vjs-menu-button ul li.vjs-selected:focus,.vjs-default-skin .vjs-menu-button ul li.vjs-selected:hover{outline:0;color:#111;background-color:#fff;background-color:rgba(255,255,255,.75);-webkit-box-shadow:0 0 1em #fff;-moz-box-shadow:0 0 1em #fff;box-shadow:0 0 1em #fff}.vjs-default-skin .vjs-menu-button ul li.vjs-menu-title{text-align:center;text-transform:uppercase;font-size:1em;line-height:2em;padding:0;margin:0 0 .3em;font-weight:700;cursor:default}.vjs-default-skin .vjs-subtitles-button:before{content:"\e00c"}.vjs-default-skin .vjs-captions-button:before{content:"\e008"}.vjs-default-skin .vjs-captions-button:focus .vjs-control-content:before,.vjs-default-skin .vjs-captions-button:hover .vjs-control-content:before{-webkit-box-shadow:0 0 1em #fff;-moz-box-shadow:0 0 1em #fff;box-shadow:0 0 1em #fff}.video-js{background-color:#000;position:relative;padding:0;font-size:10px;vertical-align:middle;font-weight:400;font-style:normal;font-family:Arial,sans-serif;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.video-js:-moz-full-screen{position:absolute}body.vjs-full-window{padding:0;margin:0;height:100%;overflow-y:auto}.video-js.vjs-fullscreen{position:fixed;overflow:hidden;z-index:1000;left:0;top:0;bottom:0;right:0;width:100%!important;height:100%!important;_position:absolute}.video-js:-webkit-full-screen{width:100%!important;height:100%!important}.video-js.vjs-fullscreen.vjs-user-inactive{cursor:none}.vjs-poster{background-repeat:no-repeat;background-position:50% 50%;background-size:contain;cursor:pointer;height:100%;margin:0;padding:0;position:relative;width:100%}.vjs-poster img{display:block;margin:0 auto;max-height:100%;padding:0;width:100%}.video-js.vjs-using-native-controls .vjs-poster{display:none}.video-js .vjs-text-track-display{text-align:center;position:absolute;bottom:4em;left:1em;right:1em}.video-js .vjs-text-track{display:none;font-size:1.4em;text-align:center;margin-bottom:.1em;background-color:#000;background-color:rgba(0,0,0,.5)}.video-js .vjs-subtitles{color:#fff}.video-js .vjs-captions{color:#fc6}.vjs-tt-cue{display:block}.vjs-default-skin .vjs-hidden{display:none}.vjs-lock-showing{display:block!important;opacity:1;visibility:visible} diff --git a/static/spoken/images/Advanced.png b/static/spoken/images/Advanced.png new file mode 100644 index 0000000..e825322 Binary files /dev/null and b/static/spoken/images/Advanced.png differ diff --git a/static/spoken/images/Basic.png b/static/spoken/images/Basic.png new file mode 100644 index 0000000..6c1e4eb Binary files /dev/null and b/static/spoken/images/Basic.png differ diff --git a/static/spoken/images/Intermediate.png b/static/spoken/images/Intermediate.png new file mode 100644 index 0000000..dd03038 Binary files /dev/null and b/static/spoken/images/Intermediate.png differ diff --git a/static/spoken/images/csc1.png b/static/spoken/images/csc1.png new file mode 100644 index 0000000..f239c3b Binary files /dev/null and b/static/spoken/images/csc1.png differ diff --git a/static/spoken/images/thumb-even.png b/static/spoken/images/thumb-even.png new file mode 100644 index 0000000..dcba5cc Binary files /dev/null and b/static/spoken/images/thumb-even.png differ diff --git a/static/spoken/js/bootstrap.min.js b/static/spoken/js/bootstrap.min.js new file mode 100644 index 0000000..d839865 --- /dev/null +++ b/static/spoken/js/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.3.1 (http://getbootstrap.com) + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.1",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.1",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active"));a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.1",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c="prev"==a?-1:1,d=this.getItemIndex(b),e=(d+c)%this.$items.length;return this.$items.eq(e)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i="next"==b?"first":"last",j=this;if(!f.length){if(!this.options.wrap)return;f=this.$element.find(".item")[i]()}if(f.hasClass("active"))return this.sliding=!1;var k=f[0],l=a.Event("slide.bs.carousel",{relatedTarget:k,direction:h});if(this.$element.trigger(l),!l.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var m=a(this.$indicators.children()[this.getItemIndex(f)]);m&&m.addClass("active")}var n=a.Event("slid.bs.carousel",{relatedTarget:k,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),j.sliding=!1,setTimeout(function(){j.$element.trigger(n)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(n)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&"show"==b&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a(this.options.trigger).filter('[href="#'+b.id+'"], [data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.1",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0,trigger:'[data-toggle="collapse"]'},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.find("> .panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":a.extend({},e.data(),{trigger:this});c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=c(d),f={relatedTarget:this};e.hasClass("open")&&(e.trigger(b=a.Event("hide.bs.dropdown",f)),b.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f)))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.1",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('