diff options
author | Prabhu Ramachandran | 2013-04-27 15:28:28 +0530 |
---|---|---|
committer | Prabhu Ramachandran | 2013-04-27 15:28:28 +0530 |
commit | 8b6ac259503323bc3d8333382d3769e5d10f162a (patch) | |
tree | 5d260a3db043492ef731b4241cf0f07563591743 | |
parent | fd044e4a9f08366c9425cb241b7452da2ba904e1 (diff) | |
parent | 5c7f66806e4be50985655b7c12bf3190ee91ae46 (diff) | |
download | online_test-8b6ac259503323bc3d8333382d3769e5d10f162a.tar.gz online_test-8b6ac259503323bc3d8333382d3769e5d10f162a.tar.bz2 online_test-8b6ac259503323bc3d8333382d3769e5d10f162a.zip |
Merge branch 'model_changes' of ...
https://github.com/hardythe1/online_test into master.
Conflicts:
production.cfg
testapp/production.py
57 files changed, 4655 insertions, 582 deletions
diff --git a/buildout.cfg b/buildout.cfg index c04ec59..486e68e 100644 --- a/buildout.cfg +++ b/buildout.cfg @@ -3,7 +3,11 @@ parts = django eggs = South + django-taggit + django-taggit-autocomplete-modified + django-debug-toolbar +versions = versions [versions] django = 1.3 @@ -17,3 +21,4 @@ eggs = ${buildout:eggs} extra-paths = testapp + diff --git a/initial_fixtures.json b/initial_fixtures.json new file mode 100644 index 0000000..f7cbceb --- /dev/null +++ b/initial_fixtures.json @@ -0,0 +1 @@ +[{"pk": 8, "model": "contenttypes.contenttype", "fields": {"model": "tag", "name": "Tag", "app_label": "taggit"}}, {"pk": 9, "model": "contenttypes.contenttype", "fields": {"model": "taggeditem", "name": "Tagged Item", "app_label": "taggit"}}, {"pk": 13, "model": "contenttypes.contenttype", "fields": {"model": "answer", "name": "answer", "app_label": "exam"}}, {"pk": 16, "model": "contenttypes.contenttype", "fields": {"model": "answerpaper", "name": "answer paper", "app_label": "exam"}}, {"pk": 4, "model": "contenttypes.contenttype", "fields": {"model": "contenttype", "name": "content type", "app_label": "contenttypes"}}, {"pk": 2, "model": "contenttypes.contenttype", "fields": {"model": "group", "name": "group", "app_label": "auth"}}, {"pk": 7, "model": "contenttypes.contenttype", "fields": {"model": "logentry", "name": "log entry", "app_label": "admin"}}, {"pk": 10, "model": "contenttypes.contenttype", "fields": {"model": "migrationhistory", "name": "migration history", "app_label": "south"}}, {"pk": 1, "model": "contenttypes.contenttype", "fields": {"model": "permission", "name": "permission", "app_label": "auth"}}, {"pk": 11, "model": "contenttypes.contenttype", "fields": {"model": "profile", "name": "profile", "app_label": "exam"}}, {"pk": 12, "model": "contenttypes.contenttype", "fields": {"model": "question", "name": "question", "app_label": "exam"}}, {"pk": 15, "model": "contenttypes.contenttype", "fields": {"model": "questionpaper", "name": "question paper", "app_label": "exam"}}, {"pk": 14, "model": "contenttypes.contenttype", "fields": {"model": "quiz", "name": "quiz", "app_label": "exam"}}, {"pk": 5, "model": "contenttypes.contenttype", "fields": {"model": "session", "name": "session", "app_label": "sessions"}}, {"pk": 6, "model": "contenttypes.contenttype", "fields": {"model": "site", "name": "site", "app_label": "sites"}}, {"pk": 3, "model": "contenttypes.contenttype", "fields": {"model": "user", "name": "user", "app_label": "auth"}}, {"pk": "b2f8681f9f910450d835f101d7bea258", "model": "sessions.session", "fields": {"expire_date": "2012-04-12T14:24:49.649", "session_data": "NDc2OTM3MDBkZDkwMDAyMGQ1NTZhNjAwZTJhMThmMzIyZGJmYjA5NzqAAn1xAS4=\n"}}, {"pk": 1, "model": "sites.site", "fields": {"domain": "example.com", "name": "example.com"}}, {"pk": 1, "model": "exam.question", "fields": {"description": "\nWrite a function called <code>fact</code> which takes a single integer argument\n(say <code>n</code>) and returns the factorial of the number. \nFor example:<br/>\n<code>fact(3) -> 6</code>\n", "summary": "Factorial", "active": true, "points": 2.0, "test": "\nassert fact(0) == 1\nassert fact(5) == 120\n", "type": "python", "options": ""}}, {"pk": 2, "model": "exam.question", "fields": {"description": "Create a simple function called <code>sqr</code> which takes a single \nargument and returns the square of the argument. For example: <br/>\n<code>sqr(3) -> 9</code>.", "summary": "Simple function", "active": true, "points": 1.0, "test": "\nimport math\nassert sqr(3) == 9\nassert abs(sqr(math.sqrt(2)) - 2.0) < 1e-14 \n ", "type": "python", "options": ""}}, {"pk": 3, "model": "exam.question", "fields": {"description": "Write a shell script which takes two arguments on the\n command line and prints the sum of the two on the output.", "summary": "Bash addition", "active": true, "points": 2.0, "test": "docs/sample.sh\ndocs/sample.args\n", "type": "bash", "options": ""}}, {"pk": 4, "model": "exam.question", "fields": {"description": "What is the largest integer value that can be represented\nin Python?", "summary": "Size of integer in Python", "active": true, "points": 0.5, "test": "No Limit", "type": "mcq", "options": "No Limit\n2**32\n2**32 - 1\nNone of the above\n"}}, {"pk": 1, "model": "exam.quiz", "fields": {"duration": 10, "active": true, "start_date": "2012-03-29", "description": "Basic Python Quiz 1"}}, {"pk": 19, "model": "auth.permission", "fields": {"codename": "add_logentry", "name": "Can add log entry", "content_type": 7}}, {"pk": 20, "model": "auth.permission", "fields": {"codename": "change_logentry", "name": "Can change log entry", "content_type": 7}}, {"pk": 21, "model": "auth.permission", "fields": {"codename": "delete_logentry", "name": "Can delete log entry", "content_type": 7}}, {"pk": 1, "model": "auth.permission", "fields": {"codename": "add_group", "name": "Can add group", "content_type": 2}}, {"pk": 4, "model": "auth.permission", "fields": {"codename": "change_group", "name": "Can change group", "content_type": 2}}, {"pk": 7, "model": "auth.permission", "fields": {"codename": "delete_group", "name": "Can delete group", "content_type": 2}}, {"pk": 2, "model": "auth.permission", "fields": {"codename": "add_permission", "name": "Can add permission", "content_type": 1}}, {"pk": 5, "model": "auth.permission", "fields": {"codename": "change_permission", "name": "Can change permission", "content_type": 1}}, {"pk": 8, "model": "auth.permission", "fields": {"codename": "delete_permission", "name": "Can delete permission", "content_type": 1}}, {"pk": 3, "model": "auth.permission", "fields": {"codename": "add_user", "name": "Can add user", "content_type": 3}}, {"pk": 6, "model": "auth.permission", "fields": {"codename": "change_user", "name": "Can change user", "content_type": 3}}, {"pk": 9, "model": "auth.permission", "fields": {"codename": "delete_user", "name": "Can delete user", "content_type": 3}}, {"pk": 10, "model": "auth.permission", "fields": {"codename": "add_contenttype", "name": "Can add content type", "content_type": 4}}, {"pk": 11, "model": "auth.permission", "fields": {"codename": "change_contenttype", "name": "Can change content type", "content_type": 4}}, {"pk": 12, "model": "auth.permission", "fields": {"codename": "delete_contenttype", "name": "Can delete content type", "content_type": 4}}, {"pk": 31, "model": "auth.permission", "fields": {"codename": "add_answer", "name": "Can add answer", "content_type": 13}}, {"pk": 37, "model": "auth.permission", "fields": {"codename": "change_answer", "name": "Can change answer", "content_type": 13}}, {"pk": 43, "model": "auth.permission", "fields": {"codename": "delete_answer", "name": "Can delete answer", "content_type": 13}}, {"pk": 32, "model": "auth.permission", "fields": {"codename": "add_answerpaper", "name": "Can add answer paper", "content_type": 16}}, {"pk": 38, "model": "auth.permission", "fields": {"codename": "change_answerpaper", "name": "Can change answer paper", "content_type": 16}}, {"pk": 44, "model": "auth.permission", "fields": {"codename": "delete_answerpaper", "name": "Can delete answer paper", "content_type": 16}}, {"pk": 33, "model": "auth.permission", "fields": {"codename": "add_profile", "name": "Can add profile", "content_type": 11}}, {"pk": 39, "model": "auth.permission", "fields": {"codename": "change_profile", "name": "Can change profile", "content_type": 11}}, {"pk": 45, "model": "auth.permission", "fields": {"codename": "delete_profile", "name": "Can delete profile", "content_type": 11}}, {"pk": 34, "model": "auth.permission", "fields": {"codename": "add_question", "name": "Can add question", "content_type": 12}}, {"pk": 40, "model": "auth.permission", "fields": {"codename": "change_question", "name": "Can change question", "content_type": 12}}, {"pk": 46, "model": "auth.permission", "fields": {"codename": "delete_question", "name": "Can delete question", "content_type": 12}}, {"pk": 35, "model": "auth.permission", "fields": {"codename": "add_questionpaper", "name": "Can add question paper", "content_type": 15}}, {"pk": 41, "model": "auth.permission", "fields": {"codename": "change_questionpaper", "name": "Can change question paper", "content_type": 15}}, {"pk": 47, "model": "auth.permission", "fields": {"codename": "delete_questionpaper", "name": "Can delete question paper", "content_type": 15}}, {"pk": 36, "model": "auth.permission", "fields": {"codename": "add_quiz", "name": "Can add quiz", "content_type": 14}}, {"pk": 42, "model": "auth.permission", "fields": {"codename": "change_quiz", "name": "Can change quiz", "content_type": 14}}, {"pk": 48, "model": "auth.permission", "fields": {"codename": "delete_quiz", "name": "Can delete quiz", "content_type": 14}}, {"pk": 13, "model": "auth.permission", "fields": {"codename": "add_session", "name": "Can add session", "content_type": 5}}, {"pk": 14, "model": "auth.permission", "fields": {"codename": "change_session", "name": "Can change session", "content_type": 5}}, {"pk": 15, "model": "auth.permission", "fields": {"codename": "delete_session", "name": "Can delete session", "content_type": 5}}, {"pk": 16, "model": "auth.permission", "fields": {"codename": "add_site", "name": "Can add site", "content_type": 6}}, {"pk": 17, "model": "auth.permission", "fields": {"codename": "change_site", "name": "Can change site", "content_type": 6}}, {"pk": 18, "model": "auth.permission", "fields": {"codename": "delete_site", "name": "Can delete site", "content_type": 6}}, {"pk": 28, "model": "auth.permission", "fields": {"codename": "add_migrationhistory", "name": "Can add migration history", "content_type": 10}}, {"pk": 29, "model": "auth.permission", "fields": {"codename": "change_migrationhistory", "name": "Can change migration history", "content_type": 10}}, {"pk": 30, "model": "auth.permission", "fields": {"codename": "delete_migrationhistory", "name": "Can delete migration history", "content_type": 10}}, {"pk": 22, "model": "auth.permission", "fields": {"codename": "add_tag", "name": "Can add Tag", "content_type": 8}}, {"pk": 24, "model": "auth.permission", "fields": {"codename": "change_tag", "name": "Can change Tag", "content_type": 8}}, {"pk": 26, "model": "auth.permission", "fields": {"codename": "delete_tag", "name": "Can delete Tag", "content_type": 8}}, {"pk": 23, "model": "auth.permission", "fields": {"codename": "add_taggeditem", "name": "Can add Tagged Item", "content_type": 9}}, {"pk": 25, "model": "auth.permission", "fields": {"codename": "change_taggeditem", "name": "Can change Tagged Item", "content_type": 9}}, {"pk": 27, "model": "auth.permission", "fields": {"codename": "delete_taggeditem", "name": "Can delete Tagged Item", "content_type": 9}}, {"pk": 1, "model": "auth.group", "fields": {"name": "moderator", "permissions": [31, 37, 43, 32, 38, 44, 33, 39, 45, 34, 40, 46, 35, 41, 47, 36, 42, 48]}}, {"pk": 1, "model": "auth.user", "fields": {"username": "hardik", "first_name": "", "last_name": "", "is_active": true, "is_superuser": true, "is_staff": true, "last_login": "2012-03-29T14:24:20.574", "groups": [], "user_permissions": [], "password": "pbkdf2_sha256$10000$lO6jpTBhhIwc$MxX0yI3Swtyzu33IWbxgRL64+pkuXN8F2Xf6kSzbTAI=", "email": "hardik@fossee.in", "date_joined": "2012-03-29T14:23:03.243"}}, {"pk": 2, "model": "auth.user", "fields": {"username": "hardy", "first_name": "", "last_name": "", "is_active": true, "is_superuser": false, "is_staff": false, "last_login": "2012-03-29T14:24:06", "groups": [1], "user_permissions": [], "password": "pbkdf2_sha256$10000$nrVGBlzheCeE$FHnLmLuY4ZoSwrW4y20d6ArwkLwmPteDbEr0fJhUmNs=", "email": "", "date_joined": "2012-03-29T14:24:06"}}, {"pk": 3, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2012-03-29T14:24:45.862", "object_repr": "hardy", "object_id": "2", "change_message": "Changed password and groups.", "user": 1, "content_type": 3}}, {"pk": 2, "model": "admin.logentry", "fields": {"action_flag": 1, "action_time": "2012-03-29T14:24:43.450", "object_repr": "moderator", "object_id": "1", "change_message": "", "user": 1, "content_type": 2}}, {"pk": 1, "model": "admin.logentry", "fields": {"action_flag": 1, "action_time": "2012-03-29T14:24:06.815", "object_repr": "hardy", "object_id": "2", "change_message": "", "user": 1, "content_type": 3}}]
\ No newline at end of file diff --git a/production.cfg b/production.cfg index 0e84b67..318fb12 100644 --- a/production.cfg +++ b/production.cfg @@ -3,9 +3,12 @@ parts = django eggs = South - MySQL-python + psycopg2 + django-taggit + django-taggit-autocomplete-modified + django-debug-toolbar -versions=versions +versions = versions [versions] django = 1.3 diff --git a/testapp/exam/forms.py b/testapp/exam/forms.py index a5ca26f..7bbf601 100644 --- a/testapp/exam/forms.py +++ b/testapp/exam/forms.py @@ -1,44 +1,57 @@ from django import forms -from exam.models import Profile +from exam.models import Profile,Quiz,Question from django.contrib.auth import authenticate from django.contrib.auth.models import User +from taggit.managers import TaggableManager +from taggit.forms import TagField +from taggit_autocomplete_modified.managers import TaggableManagerAutocomplete +from taggit_autocomplete_modified.widgets import TagAutocomplete +from taggit_autocomplete_modified import settings from string import letters, punctuation, digits +import datetime + +QUESTION_TYPE_CHOICES = ( + ("python", "Python"), + ("bash", "Bash"), + ("mcq", "MCQ"), + ) UNAME_CHARS = letters + "._" + digits PWD_CHARS = letters + punctuation + digits class UserRegisterForm(forms.Form): + """A Class to create new form for User's Registration. + It has the various fields and functions required to register + a new user to the system""" - username = forms.CharField(max_length=30, - help_text='Letters, digits, period and underscores only.') + username = forms.CharField\ + (max_length=30, help_text='Letters, digits,\ + period and underscores only.') email = forms.EmailField() - password = forms.CharField(max_length=30, - widget=forms.PasswordInput()) - confirm_password = forms.CharField(max_length=30, - widget=forms.PasswordInput()) + password = forms.CharField(max_length=30, widget=forms.PasswordInput()) + confirm_password = forms.CharField\ + (max_length=30, widget=forms.PasswordInput()) first_name = forms.CharField(max_length=30) last_name = forms.CharField(max_length=30) - roll_number = forms.CharField(max_length=30, - help_text="Use a dummy if you don't have one.") - institute = forms.CharField(max_length=128, - help_text='Institute/Organization') - department = forms.CharField(max_length=64, - help_text='Department you work/study at') - position = forms.CharField(max_length=64, - help_text='Student/Faculty/Researcher/Industry/etc.') + roll_number = forms.CharField\ + (max_length=30, help_text="Use a dummy if you don't have one.") + institute = forms.CharField\ + (max_length=128, help_text='Institute/Organization') + department = forms.CharField\ + (max_length=64, help_text='Department you work/study at') + position = forms.CharField\ + (max_length=64, help_text='Student/Faculty/Researcher/Industry/etc.') def clean_username(self): u_name = self.cleaned_data["username"] - if u_name.strip(UNAME_CHARS): msg = "Only letters, digits, period and underscore characters are "\ "allowed in username" raise forms.ValidationError(msg) - try: - User.objects.get(username__exact = u_name) + User.objects.get(username__exact=u_name) raise forms.ValidationError("Username already exists.") except User.DoesNotExist: return u_name @@ -46,8 +59,8 @@ class UserRegisterForm(forms.Form): def clean_password(self): pwd = self.cleaned_data['password'] if pwd.strip(PWD_CHARS): - raise forms.ValidationError("Only letters, digits and punctuation are \ - allowed in password") + raise forms.ValidationError("Only letters, digits and punctuation\ + are allowed in password") return pwd def clean_confirm_password(self): @@ -80,16 +93,83 @@ class UserRegisterForm(forms.Form): return u_name, pwd class UserLoginForm(forms.Form): - username = forms.CharField(max_length = 30) + """Creates a form which will allow the user to log into the system.""" + + username = forms.CharField(max_length=30) password = forms.CharField(max_length=30, widget=forms.PasswordInput()) def clean(self): super(UserLoginForm, self).clean() - u_name, pwd = self.cleaned_data["username"], self.cleaned_data["password"] - user = authenticate(username = u_name, password = pwd) - + try: + u_name, pwd = self.cleaned_data["username"],\ + self.cleaned_data["password"] + user = authenticate(username=u_name, password=pwd) + except Exception: + raise forms.ValidationError\ + ("Username and/or Password is not entered") if not user: raise forms.ValidationError("Invalid username/password") - return user +class QuizForm(forms.Form): + """Creates a form to add or edit a Quiz. + It has the related fields and functions required.""" + + start_date = forms.DateField(initial=datetime.date.today) + duration = forms.IntegerField() + active = forms.BooleanField(required = False) + tags = TagField(widget=TagAutocomplete()) + description = forms.CharField(max_length=256, widget=forms.Textarea\ + (attrs={'cols':20,'rows':1})) + + def save(self): + start_date = self.cleaned_data["start_date"] + duration = self.cleaned_data["duration"] + active = self.cleaned_data['active'] + description = self.cleaned_data["description"] + + new_quiz = Quiz() + new_quiz.start_date = start_date + new_quiz.duration = duration + new_quiz.active = active + new_quiz.description = description + new_quiz.save() + +class QuestionForm(forms.Form): + """Creates a form to add or edit a Question. + It has the related fields and functions required.""" + + summary = forms.CharField(widget=forms.Textarea\ + (attrs={'cols': 40, 'rows': 1})) + description = forms.CharField(widget=forms.Textarea\ + (attrs={'cols': 40, 'rows': 1})) + points = forms.FloatField() + test = forms.CharField(widget=forms.Textarea\ + (attrs={'cols': 40, 'rows': 1})) + options = forms.CharField(widget=forms.Textarea\ + (attrs={'cols': 40, 'rows': 1}),required=False) + type = forms.CharField(max_length=8, widget=forms.Select\ + (choices=QUESTION_TYPE_CHOICES)) + active = forms.BooleanField(required=False) + tags = TagField(widget=TagAutocomplete(),required=False) + snippet = forms.CharField(widget=forms.Textarea\ + (attrs={'cols': 40, 'rows': 1}),required=False) + + def save(self): + summary = self.cleaned_data["summary"] + description = self.cleaned_data["description"] + points = self.cleaned_data['points'] + test = self.cleaned_data["test"] + options = self.cleaned_data['options'] + type = self.cleaned_data["type"] + active = self.cleaned_data["active"] + + new_question = Question() + new_question.summary = summary + new_question.description = description + new_question.points = points + new_question.test = test + new_question.options = options + new_question.type = type + new_question.active = active + new_question.save() diff --git a/testapp/exam/migrations/0001_initial.py b/testapp/exam/migrations/0001_initial.py deleted file mode 100644 index 49048cc..0000000 --- a/testapp/exam/migrations/0001_initial.py +++ /dev/null @@ -1,193 +0,0 @@ -# encoding: utf-8 -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - -class Migration(SchemaMigration): - - def forwards(self, orm): - - # Adding model 'Profile' - db.create_table('exam_profile', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('user', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['auth.User'], unique=True)), - ('roll_number', self.gf('django.db.models.fields.CharField')(max_length=20)), - ('institute', self.gf('django.db.models.fields.CharField')(max_length=128)), - ('department', self.gf('django.db.models.fields.CharField')(max_length=64)), - ('position', self.gf('django.db.models.fields.CharField')(max_length=64)), - )) - db.send_create_signal('exam', ['Profile']) - - # Adding model 'Question' - db.create_table('exam_question', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('summary', self.gf('django.db.models.fields.CharField')(max_length=256)), - ('description', self.gf('django.db.models.fields.TextField')()), - ('points', self.gf('django.db.models.fields.FloatField')(default=1.0)), - ('test', self.gf('django.db.models.fields.TextField')(blank=True)), - ('options', self.gf('django.db.models.fields.TextField')(blank=True)), - ('type', self.gf('django.db.models.fields.CharField')(max_length=24)), - ('active', self.gf('django.db.models.fields.BooleanField')(default=True)), - )) - db.send_create_signal('exam', ['Question']) - - # Adding model 'Answer' - db.create_table('exam_answer', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('question', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['exam.Question'])), - ('answer', self.gf('django.db.models.fields.TextField')()), - ('error', self.gf('django.db.models.fields.TextField')()), - ('marks', self.gf('django.db.models.fields.FloatField')(default=0.0)), - ('correct', self.gf('django.db.models.fields.BooleanField')(default=False)), - )) - db.send_create_signal('exam', ['Answer']) - - # Adding model 'Quiz' - db.create_table('exam_quiz', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('start_date', self.gf('django.db.models.fields.DateField')()), - ('duration', self.gf('django.db.models.fields.IntegerField')(default=20)), - ('active', self.gf('django.db.models.fields.BooleanField')(default=True)), - ('description', self.gf('django.db.models.fields.CharField')(max_length=256)), - )) - db.send_create_signal('exam', ['Quiz']) - - # Adding model 'QuestionPaper' - db.create_table('exam_questionpaper', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])), - ('profile', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['exam.Profile'])), - ('quiz', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['exam.Quiz'])), - ('start_time', self.gf('django.db.models.fields.DateTimeField')()), - ('user_ip', self.gf('django.db.models.fields.CharField')(max_length=15)), - ('key', self.gf('django.db.models.fields.CharField')(max_length=10)), - ('active', self.gf('django.db.models.fields.BooleanField')(default=True)), - ('questions', self.gf('django.db.models.fields.CharField')(max_length=128)), - ('questions_answered', self.gf('django.db.models.fields.CharField')(max_length=128)), - ('comments', self.gf('django.db.models.fields.TextField')()), - )) - db.send_create_signal('exam', ['QuestionPaper']) - - # Adding M2M table for field answers on 'QuestionPaper' - db.create_table('exam_questionpaper_answers', ( - ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), - ('questionpaper', models.ForeignKey(orm['exam.questionpaper'], null=False)), - ('answer', models.ForeignKey(orm['exam.answer'], null=False)) - )) - db.create_unique('exam_questionpaper_answers', ['questionpaper_id', 'answer_id']) - - - def backwards(self, orm): - - # Deleting model 'Profile' - db.delete_table('exam_profile') - - # Deleting model 'Question' - db.delete_table('exam_question') - - # Deleting model 'Answer' - db.delete_table('exam_answer') - - # Deleting model 'Quiz' - db.delete_table('exam_quiz') - - # Deleting model 'QuestionPaper' - db.delete_table('exam_questionpaper') - - # Removing M2M table for field answers on 'QuestionPaper' - db.delete_table('exam_questionpaper_answers') - - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'exam.answer': { - 'Meta': {'object_name': 'Answer'}, - 'answer': ('django.db.models.fields.TextField', [], {}), - 'correct': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'error': ('django.db.models.fields.TextField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'marks': ('django.db.models.fields.FloatField', [], {'default': '0.0'}), - 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['exam.Question']"}) - }, - 'exam.profile': { - 'Meta': {'object_name': 'Profile'}, - 'department': ('django.db.models.fields.CharField', [], {'max_length': '64'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'institute': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'position': ('django.db.models.fields.CharField', [], {'max_length': '64'}), - 'roll_number': ('django.db.models.fields.CharField', [], {'max_length': '20'}), - 'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'}) - }, - 'exam.question': { - 'Meta': {'object_name': 'Question'}, - 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'description': ('django.db.models.fields.TextField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'options': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'points': ('django.db.models.fields.FloatField', [], {'default': '1.0'}), - 'summary': ('django.db.models.fields.CharField', [], {'max_length': '256'}), - 'test': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'type': ('django.db.models.fields.CharField', [], {'max_length': '24'}) - }, - 'exam.questionpaper': { - 'Meta': {'object_name': 'QuestionPaper'}, - 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'answers': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['exam.Answer']", 'symmetrical': 'False'}), - 'comments': ('django.db.models.fields.TextField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'key': ('django.db.models.fields.CharField', [], {'max_length': '10'}), - 'profile': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['exam.Profile']"}), - 'questions': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'questions_answered': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'quiz': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['exam.Quiz']"}), - 'start_time': ('django.db.models.fields.DateTimeField', [], {}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), - 'user_ip': ('django.db.models.fields.CharField', [], {'max_length': '15'}) - }, - 'exam.quiz': { - 'Meta': {'object_name': 'Quiz'}, - 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}), - 'duration': ('django.db.models.fields.IntegerField', [], {'default': '20'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {}) - } - } - - complete_apps = ['exam'] diff --git a/testapp/exam/migrations/__init__.py b/testapp/exam/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/testapp/exam/migrations/__init__.py +++ /dev/null diff --git a/testapp/exam/models.py b/testapp/exam/models.py index 717e02e..00d32e4 100644 --- a/testapp/exam/models.py +++ b/testapp/exam/models.py @@ -1,7 +1,9 @@ import datetime from django.db import models from django.contrib.auth.models import User - +from taggit_autocomplete_modified.managers import TaggableManagerAutocomplete\ +as TaggableManager +from django.http import HttpResponse ################################################################################ class Profile(models.Model): """Profile for a user to store roll number and other details.""" @@ -43,6 +45,12 @@ class Question(models.Model): # Is this question active or not. If it is inactive it will not be used # when creating a QuestionPaper. active = models.BooleanField(default=True) + + #Code Snippet + snippet = models.CharField(max_length=256) + + #Tags for the Question. + tags = TaggableManager() def __unicode__(self): return self.summary @@ -89,6 +97,10 @@ class Quiz(models.Model): # Description of quiz. description = models.CharField(max_length=256) + + #Tags for the Quiz. + tags = TaggableManager() + class Meta: verbose_name_plural = "Quizzes" @@ -97,9 +109,13 @@ class Quiz(models.Model): desc = self.description or 'Quiz' return '%s: on %s for %d minutes'%(desc, self.start_date, self.duration) - ################################################################################ class QuestionPaper(models.Model): + quiz = models.ForeignKey(Quiz) + questions = models.ManyToManyField(Question) + +################################################################################ +class AnswerPaper(models.Model): """A question paper for a student -- one per student typically. """ # The user taking this question paper. @@ -108,23 +124,22 @@ class QuestionPaper(models.Model): # The user's profile, we store a reference to make it easier to access the # data. profile = models.ForeignKey(Profile) - + + # All questions that remains to attempt to perticular Student + questions = models.CharField(max_length=128) + # The Quiz to which this question paper is attached to. - quiz = models.ForeignKey(Quiz) + question_paper = models.ForeignKey(QuestionPaper) # The time when this paper was started by the user. start_time = models.DateTimeField() + + # The time when this paper was ended by the user. + end_time = models.DateTimeField() # User's IP which is logged. user_ip = models.CharField(max_length=15) - # Unused currently. - key = models.CharField(max_length=10) - # used to allow/stop a user from retaking the question paper. - active = models.BooleanField(default = True) - - # The questions (a list of ids separated by '|') - questions = models.CharField(max_length=128) # The questions successfully answered (a list of ids separated by '|') questions_answered = models.CharField(max_length=128) @@ -152,7 +167,7 @@ class QuestionPaper(models.Model): def completed_question(self, question_id): """Removes the question from the list of questions and returns - the next.""" +the next.""" qa = self.questions_answered if len(qa) > 0: self.questions_answered = '|'.join([qa, str(question_id)]) @@ -188,7 +203,7 @@ class QuestionPaper(models.Model): except AttributeError: # total_seconds is new in Python 2.7. :( secs = dt.seconds + dt.days*24*3600 - total = self.quiz.duration*60.0 + total = self.question_paper.quiz.duration*60.0 remain = max(total - secs, 0) return int(remain) diff --git a/testapp/exam/urls.py b/testapp/exam/urls.py index 34e329f..b3cfceb 100644 --- a/testapp/exam/urls.py +++ b/testapp/exam/urls.py @@ -3,14 +3,44 @@ from django.conf.urls.defaults import patterns, include, url urlpatterns = patterns('exam.views', url(r'^$', 'index'), url(r'^login/$', 'user_login'), - url(r'^register/$', 'user_register'), + url(r'^quizzes/$','quizlist_user'), + url(r'^results/$','results_user'), url(r'^start/$', 'start'), - url(r'^quit/$', 'quit'), - url(r'^complete/$', 'complete'), - url(r'^monitor/$', 'monitor'), - url(r'^monitor/(?P<quiz_id>\d+)/$', 'monitor'), - url(r'^user_data/(?P<username>[a-zA-Z0-9_.]+)/$', 'user_data'), - url(r'^grade_user/(?P<username>[a-zA-Z0-9_.]+)/$', 'grade_user'), + url(r'^start/(?P<questionpaper_id>\d+)/$','start'), + url(r'^quit/(?P<answerpaper_id>\d+)/$', 'quit'), + url(r'^intro/$','start'), + url(r'^complete/$', 'complete'), + url(r'^complete/(?P<answerpaper_id>\d+)/$', 'complete'), + url(r'^register/$', 'user_register'), url(r'^(?P<q_id>\d+)/$', 'question'), url(r'^(?P<q_id>\d+)/check/$', 'check'), + url(r'^(?P<q_id>\d+)/check/(?P<questionpaper_id>\d+)/$', 'check'), + + + url(r'^manage/$', 'prof_manage'), + url(r'^manage/addquestion/$', 'add_question'), + url(r'^manage/addquestion/(?P<question_id>\d+)/$', 'add_question'), + url(r'^manage/addquiz/$', 'add_quiz'), + url(r'^manage/editquiz/$', 'edit_quiz'), + url(r'^manage/editquestion/$', 'edit_question'), + url(r'^manage/addquiz/(?P<quiz_id>\d+)/$', 'add_quiz'), + url(r'^manage/gradeuser/$', 'show_all_users'), + url(r'^manage/gradeuser/(?P<username>[a-zA-Z0-9_.]+)/$', 'grade_user'), + url(r'^manage/questions/$', 'show_all_questions'), + url(r'^manage/showquiz/$','show_all_quiz'), + url(r'^manage/monitor/$', 'monitor'), + url(r'^manage/showquestionpapers/$','show_all_questionpapers'), + url(r'^manage/showquestionpapers/(?P<questionpaper_id>\d+)/$',\ + 'show_all_questionpapers'), + url(r'^manage/monitor/(?P<quiz_id>\d+)/$', 'monitor'), + url(r'^manage/user_data/(?P<username>[a-zA-Z0-9_.]+)/$','user_data'), + url(r'^manage/designquestionpaper/$','design_questionpaper'), + url(r'^manage/designquestionpaper/(?P<questionpaper_id>\d+)/$',\ + 'design_questionpaper'), + url(r'^manage/designquestionpaper/automatic/(?P<questionpaper_id>\d+)/$',\ + 'automatic_questionpaper'), + url(r'^manage/designquestionpaper/automatic$','automatic_questionpaper'), + url(r'^manage/designquestionpaper/manual$','manual_questionpaper'), + url(r'^manage/designquestionpaper/manual/(?P<questionpaper_id>\d+)/$',\ + 'manual_questionpaper'), ) diff --git a/testapp/exam/views.py b/testapp/exam/views.py index c178a0b..5a5f5fe 100644 --- a/testapp/exam/views.py +++ b/testapp/exam/views.py @@ -5,15 +5,18 @@ import stat from os.path import dirname, pardir, abspath, join, exists import datetime +from django.http import HttpResponse from django.contrib.auth import login, logout, authenticate from django.shortcuts import render_to_response, get_object_or_404, redirect from django.template import RequestContext from django.http import Http404 from django.db.models import Sum - +from taggit.models import Tag +from itertools import chain # Local imports. -from exam.models import Quiz, Question, QuestionPaper, Profile, Answer, User -from exam.forms import UserRegisterForm, UserLoginForm +from exam.models import Quiz, Question, QuestionPaper +from exam.models import Profile, Answer, AnswerPaper, User +from exam.forms import UserRegisterForm, UserLoginForm, QuizForm, QuestionForm from exam.xmlrpc_clients import code_server from settings import URL_ROOT @@ -22,10 +25,11 @@ OUTPUT_DIR = abspath(join(dirname(__file__), pardir, 'output')) def my_redirect(url): - """An overridden redirect to deal with URL_ROOT-ing. See settings.py - for details.""" + """An overridden redirect to deal with URL_ROOT-ing. See settings.py +for details.""" return redirect(URL_ROOT + url) + def my_render_to_response(template, context=None, **kwargs): """Overridden render_to_response. """ @@ -33,34 +37,74 @@ def my_render_to_response(template, context=None, **kwargs): context = {'URL_ROOT': URL_ROOT} else: context['URL_ROOT'] = URL_ROOT - return render_to_response(template, context, **kwargs) + return render_to_response(template, context, **kwargs) def gen_key(no_of_chars): """Generate a random key of the number of characters.""" allowed_chars = string.digits+string.uppercase return ''.join([random.choice(allowed_chars) for i in range(no_of_chars)]) - + + def get_user_dir(user): """Return the output directory for the user.""" + user_dir = join(OUTPUT_DIR, str(user.username)) if not exists(user_dir): os.mkdir(user_dir) - # Make it rwx by others. - os.chmod(user_dir, stat.S_IROTH | stat.S_IWOTH | stat.S_IXOTH \ - | stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR \ + # Make it rwx by others. + os.chmod(user_dir, stat.S_IROTH | stat.S_IWOTH | stat.S_IXOTH\ + | stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR\ | stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP) return user_dir - + + +def is_moderator(user): + """Check if the user is having moderator rights""" + if user.groups.filter(name='moderator').count() == 1: + return True + + +def fetch_questions(request): + """Fetch questions from database based on the given search conditions & + tags""" + set1 = set() + set2 = set() + first_tag = request.POST.get('first_tag') + first_condition = request.POST.get('first_condition') + second_tag = request.POST.get('second_tag') + second_condition = request.POST.get('second_condition') + third_tag = request.POST.get('third_tag') + question1 = set(Question.objects.filter(tags__name__in=[first_tag])) + question2 = set(Question.objects.filter(tags__name__in=[second_tag])) + question3 = set(Question.objects.filter(tags__name__in=[third_tag])) + if first_condition == 'and': + set1 = question1.intersection(question2) + if second_condition == 'and': + set2 = set1.intersection(question3) + else: + set2 = set1.union(question3) + else: + set1 = question1.union(question2) + if second_condition == 'and': + set2 = set1.intersection(question3) + else: + set2 = set1.union(question3) + return set2 + + def index(request): """The start page. """ user = request.user if user.is_authenticated(): + if user.groups.filter(name='moderator').count() > 0: + return my_redirect('/exam/manage/') return my_redirect("/exam/start/") return my_redirect("/exam/login/") + def user_register(request): """ Register a new user. Create a user and corresponding profile and store roll_number also.""" @@ -74,34 +118,465 @@ def user_register(request): if form.is_valid(): data = form.cleaned_data u_name, pwd = form.save() - - new_user = authenticate(username = u_name, password = pwd) + new_user = authenticate(username=u_name, password=pwd) login(request, new_user) return my_redirect("/exam/start/") - else: return my_render_to_response('exam/register.html', - {'form':form}, + {'form': form}, context_instance=RequestContext(request)) else: form = UserRegisterForm() return my_render_to_response('exam/register.html', - {'form':form}, + {'form': form}, context_instance=RequestContext(request)) + + +def quizlist_user(request): + """Show All Quizzes that is available to logged-in user.""" + user = request.user + avail_quiz = list(QuestionPaper.objects.filter(quiz__active=True)) + user_answerpapers = AnswerPaper.objects.filter(user=user) + user_quiz = [] + + if user_answerpapers.count() == 0: + context = {'quizzes': avail_quiz} + return my_render_to_response("exam/quizzes_user.html", context) + + for paper in user_answerpapers: + for quiz in avail_quiz: + if paper.question_paper.id == quiz.id and \ + paper.end_time != paper.start_time: + avail_quiz.remove(quiz) + + context = {'quizzes': avail_quiz, 'user': user} + return my_render_to_response("exam/quizzes_user.html", context) + + +def results_user(request): + """Show list of Results of Quizzes that is taken by logged-in user.""" + user = request.user + papers = AnswerPaper.objects.filter(user=user) + quiz_marks = [] + for paper in papers: + temp = paper.question_paper.quiz.description, paper.get_total_marks() + quiz_marks.append(temp) + context = {'papers': quiz_marks} + return my_render_to_response("exam/results_user.html", context) + + +def edit_quiz(request): + """Edit the list of quizzes seleted by the user for editing.""" + + user = request.user + if not user.is_authenticated() or not is_moderator(user): + raise Http404('You are not allowed to view this page!') + quiz_list = request.POST.getlist('quizzes') + start_date = request.POST.getlist('start_date') + duration = request.POST.getlist('duration') + active = request.POST.getlist('active') + description = request.POST.getlist('description') + tags = request.POST.getlist('tags') + + for j, quiz_id in enumerate(quiz_list): + quiz = Quiz.objects.get(id=quiz_id) + quiz.start_date = start_date[j] + quiz.duration = duration[j] + quiz.active = active[j] + quiz.description = description[j] + quiz.save() + edit_tags = tags[j] + quiz.save() + for tag in quiz.tags.all(): + quiz.tags.remove(tag) + tags_split = edit_tags.split(', ') + for i in range(0, len(tags_split)-1): + tag = tags_split[i].strip() + quiz.tags.add(tag) + return my_redirect("/exam/manage/showquiz/") + + +def edit_question(request): + """Edit the list of questions seleted by the user for editing.""" + user = request.user + if not user.is_authenticated() or not is_moderator(user): + raise Http404('You are not allowed to view this page!') + + question_list = request.POST.getlist('questions') + summary = request.POST.getlist('summary') + description = request.POST.getlist('description') + points = request.POST.getlist('points') + test = request.POST.getlist('test') + options = request.POST.getlist('options') + type = request.POST.getlist('type') + active = request.POST.getlist('active') + snippet = request.POST.getlist('snippet') + tags = request.POST.getlist('tags') + for j, question_id in enumerate(question_list): + question = Question.objects.get(id=question_id) + question.summary = summary[j] + question.description = description[j] + question.points = points[j] + question.test = test[j] + question.options = options[j] + question.type = type[j] + edit_tags = tags[j] + question.active = active[j] + question.snippet = snippet[j] + question.save() + for tag in question.tags.all(): + question.tags.remove(tag) + tags_split = edit_tags.split(',') + for i in range(0, len(tags_split)-1): + tag = tags_split[i].strip() + question.tags.add(tag) + return my_redirect("/exam/manage/questions") + + +def add_question(request, question_id=None): + """To add a new question in the database. + Create a new question and store it.""" + user = request.user + if not user.is_authenticated() or not is_moderator(user): + raise Http404('You are not allowed to view this page!') + if request.method == "POST": + form = QuestionForm(request.POST) + if form.is_valid(): + data = form.cleaned_data + if question_id is None: + form.save() + question = Question.objects.order_by("-id")[0] + tags = form['tags'].data.split(',') + for i in range(0, len(tags)-1): + tag = tags[i].strip() + question.tags.add(tag) + return my_redirect("/exam/manage/questions") + else: + d = Question.objects.get(id=question_id) + d.summary = form['summary'].data + d.description = form['description'].data + d.points = form['points'].data + d.test = form['test'].data + d.options = form['options'].data + d.type = form['type'].data + d.active = form['active'].data + d.snippet = form['snippet'].data + d.save() + question = Question.objects.get(id=question_id) + for tag in question.tags.all(): + question.tags.remove(tag) + tags = form['tags'].data.split(', ') + for i in range(0, len(tags)-1): + tag = tags[i].strip() + question.tags.add(tag) + return my_redirect("/exam/manage/questions") + else: + return my_render_to_response('exam/add_question.html', + {'form': form}, context_instance=RequestContext(request)) + else: + if question_id is None: + form = QuestionForm() + return my_render_to_response('exam/add_question.html', + {'form': form}, context_instance=RequestContext(request)) + else: + d = Question.objects.get(id=question_id) + form = QuestionForm() + form.initial['summary'] = d.summary + form.initial['description'] = d.description + form.initial['points'] = d.points + form.initial['test'] = d.test + form.initial['options'] = d.options + form.initial['type'] = d.type + form.initial['active'] = d.active + form.initial['snippet'] = d.snippet + form_tags = d.tags.all() + form_tags_split = form_tags.values('name') + initial_tags = "" + for tag in form_tags_split: + initial_tags = initial_tags + str(tag['name']).strip() + "," + if (initial_tags == ","): + initial_tags = "" + form.initial['tags'] = initial_tags + return my_render_to_response('exam/add_question.html', + {'form': form}, + context_instance=RequestContext(request)) + + +def add_quiz(request, quiz_id=None): + """To add a new quiz in the database. + Create a new question and store it.""" + + user = request.user + if not user.is_authenticated() or not is_moderator(user): + raise Http404('You are not allowed to view this page!') + if request.method == "POST": + form = QuizForm(request.POST) + if form.is_valid(): + data = form.cleaned_data + if quiz_id is None: + form.save() + quiz = Quiz.objects.order_by("-id")[0] + tags = form['tags'].data.split(',') + for tag in tags: + tag = tag.strip() + quiz.tags.add(tag) + return my_redirect("/exam/manage/designquestionpaper") + else: + d = Quiz.objects.get(id=quiz_id) + d.start_date = form['start_date'].data + d.duration = form['duration'].data + d.active = form['active'].data + d.description = form['description'].data + d.save() + quiz = Quiz.objects.get(id=quiz_id) + for tag in quiz.tags.all(): + quiz.tags.remove(tag) + tags = form['tags'].data.split(',') + for i in range(0, len(tags)-1): + tag = tags[i].strip() + quiz.tags.add(tag) + return my_redirect("/exam/manage/showquiz") + else: + return my_render_to_response('exam/add_quiz.html', + {'form': form}, + context_instance=RequestContext(request)) + else: + if quiz_id is None: + form = QuizForm() + return my_render_to_response('exam/add_quiz.html', + {'form': form}, context_instance=RequestContext(request)) + else: + d = Quiz.objects.get(id=quiz_id) + form = QuizForm() + form.initial['start_date'] = d.start_date + form.initial['duration'] = d.duration + form.initial['description'] = d.description + form.initial['active'] = d.active + form_tags = d.tags.all() + form_tags_split = form_tags.values('name') + initial_tags = "" + for tag in form_tags_split: + initial_tags = initial_tags + str(tag['name']).strip() + "," + if (initial_tags == ","): + initial_tags = "" + form.initial['tags'] = initial_tags + return my_render_to_response('exam/add_quiz.html', + {'form': form}, + context_instance=RequestContext(request)) + + +def design_questionpaper(request, questionpaper_id=None): + user = request.user + if not user.is_authenticated() or not is_moderator(user): + raise Http404('You are not allowed to view this page!') + return my_render_to_response('exam/add_questionpaper.html', {}, + context_instance=RequestContext(request)) + + +def show_all_questionpapers(request, questionpaper_id=None): + user = request.user + if not user.is_authenticated() or not is_moderator(user): + raise Http404('You are not allowed to view this page!') + + if request.method == "POST" and request.POST.get('add') == "add": + return my_redirect("/exam/manage/designquestionpaper/" + \ + questionpaper_id) + + if request.method == "POST" and request.POST.get('delete') == "delete": + data = request.POST.getlist('papers') + q_paper = QuestionPaper.objects.get(id=questionpaper_id) + for i in data: + q_paper.questions.remove(Question.objects.get(id=i)) + question_paper = QuestionPaper.objects.all() + context = {'papers': question_paper} + return my_render_to_response('exam/showquestionpapers.html', context, + context_instance=RequestContext(request)) + if questionpaper_id is None: + qu_papers = QuestionPaper.objects.all() + context = {'papers': qu_papers} + return my_render_to_response('exam/showquestionpapers.html', context, + context_instance=RequestContext(request)) + else: + qu_papers = QuestionPaper.objects.get(id=questionpaper_id) + quiz = qu_papers.quiz + questions = qu_papers.questions.all() + context = {'papers': {'quiz': quiz, 'questions': questions}} + return my_render_to_response('exam/editquestionpaper.html', context, + context_instance=RequestContext(request)) + + +def automatic_questionpaper(request, questionpaper_id=None): + """Generate automatic question paper for a particular quiz""" + + user = request.user + if not user.is_authenticated() or not is_moderator(user): + raise Http404('You are not allowed to view this page!') + + if questionpaper_id is None: + if request.method == "POST": + if request.POST.get('save') == 'save': + quiz = Quiz.objects.order_by("-id")[0] + quest_paper = QuestionPaper() + quest_paper.quiz = quiz + quest_paper.save() + questions = request.POST.getlist('questions') + for i in questions: + if i.isdigit(): + q = Question.objects.get(id=i) + quest_paper.questions.add(q) + return my_redirect('/exam/manage/showquiz') + else: + no_questions = int(request.POST.get('questions')) + fetched_questions = fetch_questions(request) + n = len(fetched_questions) + msg = '' + if (no_questions < n): + i = n - no_questions + for i in range(0, i): + fetched_questions.pop() + elif (no_questions > n): + msg = 'The given Criteria does not satisfy the number\ + of Questions...' + tags = Tag.objects.all() + context = {'data': {'questions': fetched_questions, + 'tags': tags, + 'msg': msg}} + return my_render_to_response(\ + 'exam/automatic_questionpaper.html', context, + context_instance=RequestContext(request)) + else: + tags = Tag.objects.all() + context = {'data': {'tags': tags}} + return my_render_to_response('exam/automatic_questionpaper.html', + context, context_instance=RequestContext(request)) + + else: + if request.method == "POST": + if request.POST.get('save') == 'save': + quest_paper = QuestionPaper.objects.get(id=questionpaper_id) + questions = request.POST.getlist('questions') + for i in questions: + if i.isdigit(): + q = Question.objects.get(id=i) + quest_paper.questions.add(q) + return my_redirect('/exam/manage/showquiz') + else: + no_questions = int(request.POST.get('questions')) + fetched_questions = fetch_questions(request) + n = len(fetched_questions) + msg = '' + if(no_questions < n): + i = n - no_questions + for i in range(0, i): + fetched_questions.pop() + elif(no_questions > n): + msg = 'The given Criteria does not satisfy the number of \ + Questions...' + tags = Tag.objects.all() + context = {'data': {'questions': fetched_questions, + 'tags': tags, + 'msg': msg}} + return my_render_to_response\( + 'exam/automatic_questionpaper.html', context, + context_instance=RequestContext(request)) + else: + tags = Tag.objects.all() + context = {'data': {'tags': tags}} + return my_render_to_response('exam/automatic_questionpaper.html', + context, context_instance=RequestContext(request)) + + +def manual_questionpaper(request, questionpaper_id=None): + user = request.user + if not user.is_authenticated() or not is_moderator(user): + raise Http404('You are not allowed to view this page!') + + if questionpaper_id is None: + if request.method == "POST": + if request.POST.get('save') == 'save': + questions = request.POST.getlist('questions') + quiz = Quiz.objects.order_by("-id")[0] + quest_paper = QuestionPaper() + quest_paper.quiz = quiz + quest_paper.save() + for i in questions: + q = Question.objects.get(id=i) + quest_paper.questions.add(q) + return my_redirect('/exam/manage/showquiz') + else: + fetched_questions = fetch_questions(request) + n = len(fetched_questions) + msg = '' + if (n == 0): + msg = 'No matching Question found...' + tags = Tag.objects.all() + context = {'data': {'questions': fetched_questions,\ + 'tags': tags, 'msg': msg}} + return my_render_to_response('exam/manual_questionpaper.html', + context, + context_instance=RequestContext(request)) + else: + tags = Tag.objects.all() + context = {'data': {'tags': tags}} + return my_render_to_response('exam/manual_questionpaper.html', + context, context_instance=RequestContext(request)) + + else: + if request.method == "POST": + if request.POST.get('save') == 'save': + quest_paper = QuestionPaper.objects.get(id=questionpaper_id) + questions = request.POST.getlist('questions') + for i in questions: + q = Question.objects.get(id=i) + quest_paper.questions.add(q) + return my_redirect('/exam/manage/showquiz') + else: + fetched_questions = fetch_questions(request) + n = len(fetched_questions) + msg = '' + if (n == 0): + msg = 'No matching Question found...' + tags = Tag.objects.all() + context = {'data': {'questions': fetched_questions,\ + 'tags': tags, 'msg': msg}} + return my_render_to_response('exam/manual_questionpaper.html', + context, + context_instance=RequestContext(request)) + else: + tags = Tag.objects.all() + context = {'data': {'tags': tags}} + return my_render_to_response('exam/manual_questionpaper.html', + context, context_instance=RequestContext(request)) + + +def prof_manage(request): + """Take credentials of the user with professor/moderator + rights/permissions and log in.""" + user = request.user + if user.is_authenticated()\ + and user.groups.filter(name='moderator').count() > 0: + context = {'user': user} + return my_render_to_response('manage.html', context) + return my_redirect('/exam/login/') + def user_login(request): """Take the credentials of the user and log the user in.""" user = request.user if user.is_authenticated(): - return my_redirect("/exam/start/") + if user.groups.filter(name='moderator').count() > 0: + return my_redirect('/exam/manage/') + return my_redirect("/exam/intro/") if request.method == "POST": form = UserLoginForm(request.POST) if form.is_valid(): user = form.cleaned_data login(request, user) - return my_redirect("/exam/start/") + if user.groups.filter(name='moderator').count() > 0: + return my_redirect('/exam/manage/') + return my_redirect('/exam/login/') else: context = {"form": form} return my_render_to_response('exam/login.html', context, @@ -112,21 +587,28 @@ def user_login(request): return my_render_to_response('exam/login.html', context, context_instance=RequestContext(request)) -def start(request): + +def start(request, questionpaper_id=None): + """Check the user cedentials and if any quiz is available, + start the exam.""" user = request.user + if questionpaper_id is None: + return my_redirect('/exam/quizzes/') try: - # Right now the app is designed so there is only one active quiz - # at a particular time. - quiz = Quiz.objects.get(active=True) - except Quiz.DoesNotExist: - msg = 'No active quiz found, please contact your '\ - 'instructor/administrator. Please login again thereafter.' + """Right now the app is designed so there is only one active quiz + at a particular time.""" + questionpaper = QuestionPaper.objects.get(id=questionpaper_id) + except QuestionPaper.DoesNotExist: + msg = 'Quiz not found, please contact your '\ + 'instructor/administrator. Please login again thereafter.' return complete(request, reason=msg) + try: - old_paper = QuestionPaper.objects.get(user=user, quiz=quiz) + old_paper = AnswerPaper.objects.get(\ + question_paper=questionpaper, user=user) q = old_paper.current_question() - return show_question(request, q) - except QuestionPaper.DoesNotExist: + return show_question(request, q, questionpaper_id) + except AnswerPaper.DoesNotExist: ip = request.META['REMOTE_ADDR'] key = gen_key(10) try: @@ -135,68 +617,78 @@ def start(request): msg = 'You do not have a profile and cannot take the quiz!' raise Http404(msg) - new_paper = QuestionPaper(user=user, user_ip=ip, key=key, - quiz=quiz, profile=profile) + new_paper = AnswerPaper(user=user, user_ip=ip, + question_paper=questionpaper, profile=profile) new_paper.start_time = datetime.datetime.now() - + new_paper.end_time = datetime.datetime.now() # Make user directory. user_dir = get_user_dir(user) - questions = [ str(_.id) for _ in Question.objects.filter(active=True) ] + questions = [str(_.id) for _ in questionpaper.questions.all()] random.shuffle(questions) - + + #questions = questionpaper.questions + #random.shuffle(questions) new_paper.questions = "|".join(questions) new_paper.save() - - # Show the user the intro page. - context = {'user': user} + # Show the user the intro page. + context = {'user': user, 'paper_id': questionpaper_id} ci = RequestContext(request) - return my_render_to_response('exam/intro.html', context, - context_instance=ci) + return my_render_to_response('exam/intro.html', context, + context_instance=ci) + + +def question(request, q_id, questionpaper_id): + """Check the credentials of the user and start the exam.""" -def question(request, q_id): user = request.user if not user.is_authenticated(): return my_redirect('/exam/login/') q = get_object_or_404(Question, pk=q_id) try: - paper = QuestionPaper.objects.get(user=request.user, quiz__active=True) - except QuestionPaper.DoesNotExist: - return my_redirect('/exam/start') - if not paper.quiz.active: + q_paper = QuestionPaper.objects.get(id=questionpaper_id) + paper = AnswerPaper.objects.get(\ + user=request.user, question_paper=q_paper) + except AnswerPaper.DoesNotExist: + return my_redirect('/exam/start/') + if not paper.question_paper.quiz.active: return complete(request, reason='The quiz has been deactivated!') time_left = paper.time_left() if time_left == 0: return complete(request, reason='Your time is up!') - quiz_name = paper.quiz.description - context = {'question': q, 'paper': paper, 'user': user, - 'quiz_name': quiz_name, + quiz_name = paper.question_paper.quiz.description + context = {'question': q, 'paper': paper, 'user': user, + 'quiz_name': quiz_name, 'time_left': time_left} ci = RequestContext(request) return my_render_to_response('exam/question.html', context, - context_instance=ci) + context_instance=ci) + -def show_question(request, q_id): +def show_question(request, q_id, questionpaper_id): """Show a question if possible.""" if len(q_id) == 0: msg = 'Congratulations! You have successfully completed the quiz.' return complete(request, msg) else: - return question(request, q_id) + return question(request, q_id, questionpaper_id) + + +def check(request, q_id, questionpaper_id=None): + """Checks the answers of the user for particular question""" -def check(request, q_id): user = request.user if not user.is_authenticated(): return my_redirect('/exam/login/') question = get_object_or_404(Question, pk=q_id) - paper = QuestionPaper.objects.get(user=user, quiz__active=True) + q_paper = QuestionPaper.objects.get(id=questionpaper_id) + paper = AnswerPaper.objects.get(user=request.user, question_paper=q_paper) answer = request.POST.get('answer') skip = request.POST.get('skip', None) - if skip is not None: next_q = paper.skip() - return show_question(request, next_q) + return show_question(request, next_q, questionpaper_id) # Add the answer submitted, regardless of it being correct or not. new_answer = Answer(question=question, answer=answer, correct=False) @@ -207,7 +699,7 @@ def check(request, q_id): # questions, we obtain the results via XML-RPC with the code executed # safely in a separate process (the code_server.py) running as nobody. if question.type == 'mcq': - success = True # Only one attempt allowed for MCQ's. + success = True # Only one attempt allowed for MCQ's. if answer.strip() == question.test.strip(): new_answer.correct = True new_answer.marks = question.points @@ -226,16 +718,15 @@ def check(request, q_id): new_answer.save() - if not success: # Should only happen for non-mcq questions. + if not success: # Should only happen for non-mcq questions. time_left = paper.time_left() if time_left == 0: return complete(request, reason='Your time is up!') - if not paper.quiz.active: + if not paper.question_paper.quiz.active: return complete(request, reason='The quiz has been deactivated!') - context = {'question': question, 'error_message': err_msg, 'paper': paper, 'last_attempt': answer, - 'quiz_name': paper.quiz.description, + 'quiz_name': paper.question_paper.quiz.description, 'time_left': time_left} ci = RequestContext(request) @@ -243,60 +734,76 @@ def check(request, q_id): context_instance=ci) else: next_q = paper.completed_question(question.id) - return show_question(request, next_q) - -def quit(request): - return my_render_to_response('exam/quit.html', - context_instance=RequestContext(request)) + return show_question(request, next_q, questionpaper_id) + + +def quit(request, answerpaper_id=None): + """Show the quit page when the user logs out.""" + context = {'id': answerpaper_id} + return my_render_to_response('exam/quit.html', context, + context_instance=RequestContext(request)) + + +def complete(request, reason=None, answerpaper_id=None): + """Show a page to inform user that the quiz has been compeleted.""" -def complete(request, reason=None): user = request.user + + if answerpaper_id is None: + logout(request) + context = {'message': "You are successfully Logged out."} + return my_render_to_response('exam/complete.html', context) no = False message = reason or 'The quiz has been completed. Thank you.' + if user.groups.filter(name='moderator').count() > 0: + message = 'You are successfully Logged out.' if request.method == 'POST' and 'no' in request.POST: - no = request.POST.get('no', False) + no = True if not no: # Logout the user and quit with the message given. - logout(request) - context = {'message': message} - return my_render_to_response('exam/complete.html', context) + answer_paper = AnswerPaper.objects.get(id=answerpaper_id) + answer_paper.endtime = datetime.datetime.now() + answer_paper.save() + return my_redirect('/exam/quizzes/') else: return my_redirect('/exam/') def monitor(request, quiz_id=None): """Monitor the progress of the papers taken so far.""" + user = request.user - if not user.is_authenticated() and not user.is_staff: + if not user.is_authenticated() or not is_moderator(user): raise Http404('You are not allowed to view this page!') if quiz_id is None: - quizzes = Quiz.objects.all() + q_paper = QuestionPaper.objects.all() context = {'papers': [], 'quiz': None, - 'quizzes':quizzes} + 'quizzes': q_paper} return my_render_to_response('exam/monitor.html', context, context_instance=RequestContext(request)) # quiz_id is not None. try: - quiz = Quiz.objects.get(id=quiz_id) - except Quiz.DoesNotExist: + quiz = QuestionPaper.objects.get(id=quiz_id) + except QuestionPaper.DoesNotExist: papers = [] quiz = None else: - papers = QuestionPaper.objects.all().annotate( + papers = AnswerPaper.objects.all().annotate( total=Sum('answers__marks')).order_by('-total') context = {'papers': papers, 'quiz': quiz, 'quizzes': None} return my_render_to_response('exam/monitor.html', context, context_instance=RequestContext(request)) + def get_user_data(username): """For a given username, this returns a dictionary of important data related to the user including all the user's answers submitted. """ user = User.objects.get(username=username) - papers = QuestionPaper.objects.filter(user=user) + papers = AnswerPaper.objects.filter(user=user) data = {} try: @@ -309,10 +816,144 @@ def get_user_data(username): data['papers'] = papers return data + +def show_all_users(request): + """Shows all the users who have taken various exams/quiz.""" + + user = request.user + if not user.is_authenticated() or not is_moderator(user): + raise Http404('You are not allowed to view this page !') + user = User.objects.filter(username__contains="") + questionpaper = AnswerPaper.objects.all() + context = {'question': questionpaper} + return my_render_to_response('exam/showusers.html', context, + context_instance=RequestContext(request)) + + +def show_all_quiz(request): + """Generates a list of all the quizzes + that are currently in the database.""" + + user = request.user + if not user.is_authenticated() or not is_moderator(user): + raise Http404('You are not allowed to view this page !') + + if request.method == 'POST' and request.POST.get('delete') == 'delete': + data = request.POST.getlist('quiz') + + if data is None: + quizzes = Quiz.objects.all() + context = {'papers': [], + 'quiz': None, + 'quizzes': quizzes} + return my_render_to_response('exam/show_quiz.html', context, + context_instance=RequestContext(request)) + else: + for i in data: + quiz = Quiz.objects.get(id=i).delete() + quizzes = Quiz.objects.all() + context = {'papers': [], + 'quiz': None, + 'quizzes': quizzes} + return my_render_to_response('exam/show_quiz.html', context, + context_instance=RequestContext(request)) + + elif request.method == 'POST' and request.POST.get('edit') == 'edit': + data = request.POST.getlist('quiz') + forms = [] + for j in data: + d = Quiz.objects.get(id=j) + form = QuizForm() + form.initial['start_date'] = d.start_date + form.initial['duration'] = d.duration + form.initial['active'] = d.active + form.initial['description'] = d.description + form_tags = d.tags.all() + form_tags_split = form_tags.values('name') + initial_tags = "" + for tag in form_tags_split: + initial_tags = initial_tags + str(tag['name']).strip() + "," + if (initial_tags == ","): + initial_tags = "" + form.initial['tags'] = initial_tags + forms.append(form) + return my_render_to_response('exam/edit_quiz.html', + {'forms': forms, 'data': data}, + context_instance=RequestContext(request)) + else: + quizzes = Quiz.objects.all() + context = {'papers': [], + 'quiz': None, + 'quizzes': quizzes} + return my_render_to_response('exam/show_quiz.html', context, + context_instance=RequestContext(request)) + + +def show_all_questions(request): + """Show a list of all the questions currently in the databse.""" + + user = request.user + if not user.is_authenticated() or not is_moderator(user): + raise Http404("You are not allowed to view this page !") + + if request.method == 'POST' and request.POST.get('delete') == 'delete': + data = request.POST.getlist('question') + if data is None: + questions = Question.objects.all() + context = {'papers': [], + 'question': None, + 'questions': questions} + return my_render_to_response('exam/showquestions.html', context, + context_instance=RequestContext(request)) + else: + for i in data: + question = Question.objects.get(id=i).delete() + questions = Question.objects.all() + context = {'papers': [], + 'question': None, + 'questions': questions} + return my_render_to_response('exam/showquestions.html', context, + context_instance=RequestContext(request)) + elif request.method == 'POST' and request.POST.get('edit') == 'edit': + data = request.POST.getlist('question') + + forms = [] + for j in data: + d = Question.objects.get(id=j) + form = QuestionForm() + form.initial['summary'] = d.summary + form.initial['description'] = d.description + form.initial['points'] = d.points + form.initial['test'] = d.test + form.initial['options'] = d.options + form.initial['type'] = d.type + form.initial['active'] = d.active + form_tags = d.tags.all() + form_tags_split = form_tags.values('name') + initial_tags = "" + for tag in form_tags_split: + initial_tags = initial_tags + str(tag['name']).strip() + "," + if (initial_tags == ","): + initial_tags = "" + form.initial['tags'] = initial_tags + forms.append(form) + return my_render_to_response('exam/edit_question.html', + {'forms': forms, 'data': data}, + context_instance=RequestContext(request)) + else: + questions = Question.objects.all() + context = {'papers': [], + 'question': None, + 'questions': questions} + return my_render_to_response('exam/showquestions.html', context, + context_instance=RequestContext(request)) + + def user_data(request, username): """Render user data.""" + current_user = request.user - if not current_user.is_authenticated() and not current_user.is_staff: + if not current_user.is_authenticated() or not is_moderator(user): raise Http404('You are not allowed to view this page!') data = get_user_data(username) @@ -321,12 +962,13 @@ def user_data(request, username): return my_render_to_response('exam/user_data.html', context, context_instance=RequestContext(request)) + def grade_user(request, username): """Present an interface with which we can easily grade a user's papers and update all their marks and also give comments for each paper. """ current_user = request.user - if not current_user.is_authenticated() and not current_user.is_staff: + if not current_user.is_authenticated() or not is_moderator(current_user): raise Http404('You are not allowed to view this page!') data = get_user_data(username) @@ -334,11 +976,12 @@ def grade_user(request, username): papers = data['papers'] for paper in papers: for question, answers in paper.get_question_answers().iteritems(): - marks = float(request.POST.get('q%d_marks'%question.id)) + marks = float(request.POST.get('q%d_marks' % question.id)) last_ans = answers[-1] last_ans.marks = marks last_ans.save() - paper.comments = request.POST.get('comments_%d'%paper.quiz.id) + paper.comments = request.POST.get(\ + 'comments_%d' % paper.question_paper.id) paper.save() context = {'data': data} @@ -348,4 +991,3 @@ def grade_user(request, username): context = {'data': data} return my_render_to_response('exam/grade_user.html', context, context_instance=RequestContext(request)) - diff --git a/testapp/production.py b/testapp/production.py index f4d88e2..312e838 100644 --- a/testapp/production.py +++ b/testapp/production.py @@ -4,3 +4,8 @@ DEBUG=False TEMPLATE_DEBUG=DEBUG from testapp.local import * +DATABASE_ENGINE = 'django.db.backends.mysql' +DATABASE_NAME = 'online_test' +DATABASE_USER = 'online_test_user' +# Imports DATABASE_PASSWORD from testapp/local.py that is not part of git repo +from testapp.local import DATABASE_PASSWORD diff --git a/testapp/settings.py b/testapp/settings.py index f1c48b9..0002476 100644 --- a/testapp/settings.py +++ b/testapp/settings.py @@ -89,7 +89,7 @@ STATIC_URL = '/static/' # URL prefix for admin static files -- CSS, JavaScript and images. # Make sure to use a trailing slash. # Examples: "http://foo.com/static/admin/", "/static/admin/". -ADMIN_MEDIA_PREFIX = URL_ROOT + '/static/admin/' +ADMIN_MEDIA_PREFIX = '/static/admin/' # Additional locations of static files STATICFILES_DIRS = ( @@ -123,6 +123,8 @@ MIDDLEWARE_CLASSES = ( 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', + 'debug_toolbar.middleware.DebugToolbarMiddleware', + ) ROOT_URLCONF = '%s.urls'%(basename(CURDIR)) @@ -143,10 +145,12 @@ INSTALLED_APPS = ( 'django.contrib.staticfiles', # Uncomment the next line to enable the admin: 'django.contrib.admin', + 'taggit', # Uncomment the next line to enable admin documentation: # 'django.contrib.admindocs', - 'south', 'exam', + 'taggit_autocomplete_modified', + 'debug_toolbar', ) # A sample logging configuration. The only tangible logging diff --git a/testapp/static/exam/css/autotaggit.css b/testapp/static/exam/css/autotaggit.css new file mode 100644 index 0000000..ed856ce --- /dev/null +++ b/testapp/static/exam/css/autotaggit.css @@ -0,0 +1,48 @@ +.ac_results { + padding: 0px; + border: 1px solid #efefef; + background-color: white; + overflow: hidden; + z-index: 99999; +} + +.ac_results ul { + width: 100%; + list-style-position: outside; + list-style: none; + padding: 0; + margin: 0; +} + +.ac_results li { + margin: 0px; + padding: 2px 5px; + cursor: default; + display: block; + /* + if width will be 100% horizontal scrollbar will apear + when scroll mode will be used + */ + /*width: 100%;*/ + font: menu; + font-size: 12px; + /* + it is very important, if line-height not setted or setted + in relative units scroll will be broken in firefox + */ + line-height: 16px; + overflow: hidden; +} + +.ac_loading { + background: white url('indicator.gif') right center no-repeat; +} + +.ac_odd { + background-color: #CACACA; +} + +.ac_over { + background-color: #f5f5f5; + color: black; +} diff --git a/testapp/static/exam/css/base.css b/testapp/static/exam/css/base.css index 1323116..c822f4d 100644 --- a/testapp/static/exam/css/base.css +++ b/testapp/static/exam/css/base.css @@ -1,26 +1,2048 @@ -body { font-family: 'Georgia', serif; font-size: 17px; color: #000; background: #eee;} -h1, h2, h3, h4 { font-family: 'Garamond', 'Georgia', serif; font-weight: normal; } -h1 { margin: 0 0 30px 0; font-size: 36px;} -h1 span { display: none; } -h2 { font-size: 26px; margin: 15px 0 5px 0; } -h3 { font-size: 22px; margin: 15px 0 5px 0; } -h4 { font-size: 15px; margin: 15px 0 5px 0; } - -.box { width: 700px; margin: 10px auto ; } -.page { margin: 2em auto; width: 35em; border: 5px solid #ccc; - padding: 0.8em; background: white; } -.entries { list-style: none; margin: 0; padding: 0; } -.entries li { margin: 0.8em 1.2em; } -.entries li h2 { margin-left: -1em; } -.add-entry { font-size: 0.9em; border-bottom: 1px solid #ccc; } -.add-entry dl { font-weight: bold; } -.metanav { text-align: right; font-size: 0.8em; padding: 0.3em; - margin-bottom: 1em; background: #fafafa; } -.flash { background: #CEE5F5; padding: 0.5em; - border: 1px solid #AACBE2; } -.error { background: #F0D6D6; padding: 0.5em; } -textarea, code, -pre { font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', - monospace!important; font-size: 14px; background: #eee; } -pre { padding: 0px 30px; margin: 15px -30px; line-height: 1.3; } +/*! +Copyright 2012 Twitter, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with the License. You may obtain a copy of the License in the LICENSE file, or at: + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + + * Bootstrap v1.4.0 + * + * Copyright 2011 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + * Date: Sun Dec 25 20:18:31 PST 2011 + */ +/* Reset.less + * Props to Eric Meyer (meyerweb.com) for his CSS reset file. We're using an adapted version here that cuts out some of the reset HTML elements we will never need here (i.e., dfn, samp, etc). + * For Online Test Application, this CSS was changed as per the requirements wherever required. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */ + +html, body { + background-color: #eee; + margin: 0; + padding: 0; + +} +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +a, +abbr, +acronym, +address, +cite, +code, +del, +dfn, +em, +img, +q, +s, +samp, +small, +strike, +strong, +sub, +sup, +tt, +var, +dd, +dl, +dt, +li, +ol, +ul, +fieldset, +form, +label, +legend, +button, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td { + margin: 0; + padding: 0; + border: 0; + font-weight: normal; + font-style: normal; + font-size: 100%; + line-height: 1; + font-family: serif; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +ol, ul { + list-style: none; +} +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; +} +html { + overflow-y: scroll; + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +a:focus { + outline: thin dotted; +} +a:hover, a:active { + outline: 0; +} +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section { + display: block; +} +audio, canvas, video { + display: inline-block; + *display: inline; + *zoom: 1; +} +audio:not([controls]) { + display: none; +} +sub, sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} +img { + border: 0; + -ms-interpolation-mode: bicubic; +} +button, +input, +select, +textarea { + font-size: 100%; + margin: 0; + vertical-align: baseline; + *vertical-align: middle; +} +button, input { + line-height: normal; + *overflow: visible; +} +button::-moz-focus-inner, input::-moz-focus-inner { + border: 0; + padding: 0; +} +button, +input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; +} +input[type="search"] { + -webkit-appearance: textfield; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +textarea { + overflow: visible; + vertical-align: top; +} +/* Variables.less +* Variables to customize the look and feel of Bootstrap +* ----------------------------------------------------- */ +/* Mixins.less +* Snippets of reusable CSS to develop faster and keep code readable +* ----------------------------------------------------------------- */ +/* +* Scaffolding +* Basic and global styles for generating a grid system, structural layout, and page templates +* ------------------------------------------------------------------------------------------- */ +body { + padding-top : 10px; + background-color: #eee; + margin: 0; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: normal; + line-height: 18px; + color: #404040; + +} +.container { + width: 820px; + margin-left: auto; + margin-right: auto; + zoom: 1; +} +.container > footer p { + text-align: center; +} +.container > .content { + background-color: #fff; + padding: 20px; + margin: 0 -20px; + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.15); + -moz-box-shadow: 0 1px 2px rgba(0,0,0,.15); + box-shadow: 0 1px 2px rgba(0,0,0,.15); +} +.content .span10, +.content .span14 { + min-height: 475px; +} +.content .span4 { + margin-left: 0; + padding-left: 19px; + border-left: 1px solid #eee; +} +.topbar .btn { + border: 0; +} +.page-header { + background-color: #f5f5f5; + padding: 20px 20px 10px; + margin: -20px -20px 20px; +} +.container:before, .container:after { + display: table; + content: ""; + zoom: 1; +} +.container:after { + clear: both; +} + +a { + color: #0069d6; + text-decoration: none; + line-height: inherit; + font-weight: inherit; +} +a:hover { + color: #00438a; + text-decoration: underline; +} +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.hide { + display: none; +} +.show { + display: block; +} +.row { + zoom: 1; + margin-left: -20px; +} +.row:before, .row:after { + display: table; + content: ""; + zoom: 1; +} +.row:after { + clear: both; +} +.row > [class*="span"] { + display: inline; + float: left; + margin-left: 20px; +} +.span1 { + width: 40px; +} +.span2 { + width: 100px; +} +.span3 { + width: 160px; +} +.span4 { + min-height : 500px; + width: 220px; +} +.span5 { + width: 280px; +} +.span6 { + width: 340px; +} +.span7 { + width: 400px; +} +.span8 { + width: 460px; +} +.span9 { + width: 520px; +} +.span10 { + width: 560px; +} +.span11 { + width: 640px; +} +.span12 { + width: 700px; +} +.span13 { + width: 760px; +} +.span14 { + width: 820px; +} +.span15 { + width: 880px; +} +.span16 { + width: 940px; +} +.span17 { + width: 1000px; +} +.span18 { + width: 1060px; +} +.span19 { + width: 1120px; +} +.span20 { + width: 1180px; +} +.span21 { + width: 1240px; +} +.span22 { + width: 1300px; +} +.span23 { + width: 1360px; +} +.span24 { + width: 1420px; +} +.row > .offset1 { + margin-left: 80px; +} +.row > .offset2 { + margin-left: 140px; +} +.row > .offset3 { + margin-left: 200px; +} +.row > .offset4 { + margin-left: 260px; +} +.row > .offset5 { + margin-left: 320px; +} +.row > .offset6 { + margin-left: 380px; +} +.row > .offset7 { + margin-left: 440px; +} +.row > .offset8 { + margin-left: 500px; +} +.row > .offset9 { + margin-left: 560px; +} +.row > .offset10 { + margin-left: 620px; +} +.row > .offset11 { + margin-left: 680px; +} +.row > .offset12 { + margin-left: 740px; +} +.span-one-third { + width: 300px; +} +.span-two-thirds { + width: 620px; +} +.row > .offset-one-third { + margin-left: 340px; +} +.row > .offset-two-thirds { + margin-left: 660px; +} +/* Typography.less +* Headings, body text, lists, code, and more for a versatile and durable typography system +* ---------------------------------------------------------------------------------------- */ +p { + font-size: 13px; + font-weight: normal; + line-height: 18px; + margin-bottom: 9px; +} +p small { + font-size: 11px; + color: #bfbfbf; +} +h1, +h2, +h3, +h4, +h5, +h6 { + font-weight: bold; + color: #404040; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small { + color: #bfbfbf; +} +h1 { + margin-bottom: 18px; + font-size: 30px; + line-height: 36px; +} +h1 small { + font-size: 18px; +} +h2 { + font-size: 24px; + line-height: 36px; +} +h2 small { + font-size: 14px; +} +h3, +h4, +h5, +h6 { + line-height: 36px; +} +h3 { + font-size: 18px; +} +h3 small { + font-size: 14px; +} +h4 { + font-size: 16px; +} +h4 small { + font-size: 12px; +} +h5 { + font-size: 14px; +} +h6 { + font-size: 13px; + color: #bfbfbf; + text-transform: uppercase; +} +ul, ol { + margin: 0 0 18px 25px; +} +ul ul, +ul ol, +ol ol, +ol ul { + margin-bottom: 0; +} +ul { + list-style: disc; +} +ol { + list-style: decimal; +} +li { + line-height: 18px; + color: #808080; +} +ul.unstyled { + list-style: none; + margin-left: 0; +} +dl { + margin-bottom: 18px; +} +dl dt, dl dd { + line-height: 18px; +} +dl dt { + font-weight: bold; +} +dl dd { + margin-left: 9px; +} +hr { + margin: 20px 0 19px; + border: 0; + border-bottom: 1px solid; +} +strong { + font-style: inherit; + font-weight: bold; +} +em { + font-style: italic; + font-weight: inherit; + line-height: inherit; +} +.muted { + color: #bfbfbf; +} +blockquote { + margin-bottom: 18px; + border-left: 5px solid #eee; + padding-left: 15px; +} +blockquote p { + font-size: 14px; + font-weight: 300; + line-height: 18px; + margin-bottom: 0; +} +blockquote small { + display: block; + font-size: 12px; + font-weight: 300; + line-height: 18px; + color: #bfbfbf; +} +blockquote small:before { + content: '\2014 \00A0'; +} +address { + display: block; + line-height: 18px; + margin-bottom: 18px; +} +code, pre { + padding: 0 3px 2px; + font-family: Monaco, Andale Mono, Courier New, monospace; + font-size: 12px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +code { + background-color: #FDE8E8; + color: rgba(0, 0, 0, 0.75); + padding: 1px 3px; +} +pre { + background-color: #EAB9B9; + color:red; + display: block; + padding: 8.5px; + margin: 0 0 18px; + line-height: 18px; + font-size: 12px; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.15); + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + white-space: pre; + white-space: pre-wrap; + word-wrap: break-word; +} +/* Forms.less +* Base styles for various input types, form layouts, and states +* ------------------------------------------------------------- */ +form { + margin-bottom: 18px; +} +fieldset { + margin-bottom: 18px; + padding-top: 18px; +} +fieldset legend { + display: block; + padding-left: 150px; + font-size: 19.5px; + line-height: 1; + color: #404040; + *padding: 0 0 5px 145px; + /* IE6-7 */ + + *line-height: 1.5; + /* IE6-7 */ + +} +form .clearfix { + margin-bottom: 18px; + zoom: 1; +} +form .clearfix:before, form .clearfix:after { + display: table; + content: ""; + zoom: 1; +} +form .clearfix:after { + clear: both; +} +label, +input, +select, +textarea { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: normal; + line-height: normal; +} +select +{ + width : auto; +} +label { + padding-top: 6px; + font-size: 13px; + line-height: 18px; + float: left; + width: 130px; + text-align: left; + color: #404040; +} +form .input { + margin-left: 150px; +} +input[type=checkbox], input[type=radio] { + cursor: pointer; +} +input, +textarea, +select, +.uneditable-input { + display: inline-block; + width: 210px; + height: 18px; + padding: 4px; + font-size: 13px; + line-height: 18px; + color: #808080; + border: 1px solid #ccc; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +select { + padding: initial; +} +input[type=checkbox], input[type=radio] { + width: auto; + height: auto; + padding: 0; + margin: 3px 0; + *margin-top: 0; + /* IE6-7 */ + + line-height: normal; + border: none; +} +input[type=file] { + background-color: #ffffff; + padding: initial; + border: initial; + line-height: initial; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +input[type=button], input[type=reset], input[type=submit] { + width: auto; + height: auto; +} +select, input[type=file] { + height: 27px; + *height: auto; + line-height: 27px; + *margin-top: 4px; + /* For IE7, add top margin to align select with labels */ + +} +select[multiple] { + height: inherit; + background-color: #ffffff; +} +textarea { + height: auto; +} +.uneditable-input { + background-color: #ffffff; + display: block; + border-color: #eee; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + cursor: not-allowed; +} +:-moz-placeholder { + color: #bfbfbf; +} +::-webkit-input-placeholder { + color: #bfbfbf; +} +input, textarea { + -webkit-transition: border linear 0.2s, box-shadow linear 0.2s; + -moz-transition: border linear 0.2s, box-shadow linear 0.2s; + -ms-transition: border linear 0.2s, box-shadow linear 0.2s; + -o-transition: border linear 0.2s, box-shadow linear 0.2s; + transition: border linear 0.2s, box-shadow linear 0.2s; + -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1); +} +input:focus, textarea:focus { + outline: 0; + border-color: rgba(82, 168, 236, 0.8); + -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6); + -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6); + box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6); +} +input[type=file]:focus, input[type=checkbox]:focus, select:focus { + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + outline: 1px dotted #666; +} +form .clearfix.error > label, form .clearfix.error .help-block, form .clearfix.error .help-inline { + color: #b94a48; +} +form .clearfix.error input, form .clearfix.error textarea { + color: #b94a48; + border-color: #ee5f5b; +} +form .clearfix.error input:focus, form .clearfix.error textarea:focus { + border-color: #e9322d; + -webkit-box-shadow: 0 0 6px #f8b9b7; + -moz-box-shadow: 0 0 6px #f8b9b7; + box-shadow: 0 0 6px #f8b9b7; +} +form .clearfix.error .input-prepend .add-on, form .clearfix.error .input-append .add-on { + color: #b94a48; + background-color: #fce6e6; + border-color: #b94a48; +} +form .clearfix.warning > label, form .clearfix.warning .help-block, form .clearfix.warning .help-inline { + color: #c09853; +} +form .clearfix.warning input, form .clearfix.warning textarea { + color: #c09853; + border-color: #ccae64; +} +form .clearfix.warning input:focus, form .clearfix.warning textarea:focus { + border-color: #be9a3f; + -webkit-box-shadow: 0 0 6px #e5d6b1; + -moz-box-shadow: 0 0 6px #e5d6b1; + box-shadow: 0 0 6px #e5d6b1; +} +form .clearfix.warning .input-prepend .add-on, form .clearfix.warning .input-append .add-on { + color: #c09853; + background-color: #d2b877; + border-color: #c09853; +} +form .clearfix.success > label, form .clearfix.success .help-block, form .clearfix.success .help-inline { + color: #468847; +} +form .clearfix.success input, form .clearfix.success textarea { + color: #468847; + border-color: #57a957; +} +form .clearfix.success input:focus, form .clearfix.success textarea:focus { + border-color: #458845; + -webkit-box-shadow: 0 0 6px #9acc9a; + -moz-box-shadow: 0 0 6px #9acc9a; + box-shadow: 0 0 6px #9acc9a; +} +form .clearfix.success .input-prepend .add-on, form .clearfix.success .input-append .add-on { + color: #468847; + background-color: #bcddbc; + border-color: #468847; +} +textarea +{ + width : 290px; +} +.input-mini, +input.mini, +textarea.mini, +select.mini { + width: 60px; +} +.input-small, +input.small, +textarea.small, +select.small { + width: 90px; +} +.input-medium, +input.medium, +textarea.medium, +select.medium { + width: 150px; +} +.input-large, +input.large, +textarea.large, +select.large { + width: 210px; +} +.input-xlarge, +input.xlarge, +textarea.xlarge, +select.xlarge { + width: 270px; +} +.input-xxlarge, +input.xxlarge, +textarea.xxlarge, +select.xxlarge { + width: 530px; +} +textarea.xxlarge { + overflow-y: auto; +} +input.span1, textarea.span1 { + display: inline-block; + float: none; + width: 30px; + margin-left: 0; +} +input.span2, textarea.span2 { + display: inline-block; + float: none; + width: 90px; + margin-left: 0; +} +input.span3, textarea.span3 { + display: inline-block; + float: none; + width: 150px; + margin-left: 0; +} +input.span4, textarea.span4 { + display: inline-block; + float: none; + width: 210px; + margin-left: 0; +} +input.span5, textarea.span5 { + display: inline-block; + float: none; + width: 270px; + margin-left: 0; +} +input.span6, textarea.span6 { + display: inline-block; + float: none; + width: 330px; + margin-left: 0; +} +input.span7, textarea.span7 { + display: inline-block; + float: none; + width: 390px; + margin-left: 0; +} +input.span8, textarea.span8 { + display: inline-block; + float: none; + width: 450px; + margin-left: 0; +} +input.span9, textarea.span9 { + display: inline-block; + float: none; + width: 510px; + margin-left: 0; +} +input.span10, textarea.span10 { + display: inline-block; + float: none; + width: 570px; + margin-left: 0; +} +input.span11, textarea.span11 { + display: inline-block; + float: none; + width: 630px; + margin-left: 0; +} +input.span12, textarea.span12 { + display: inline-block; + float: none; + width: 690px; + margin-left: 0; +} +input.span13, textarea.span13 { + display: inline-block; + float: none; + width: 750px; + margin-left: 0; +} +input.span14, textarea.span14 { + display: inline-block; + float: none; + width: 810px; + margin-left: 0; +} +input.span15, textarea.span15 { + display: inline-block; + float: none; + width: 870px; + margin-left: 0; +} +input.span16, textarea.span16 { + display: inline-block; + float: none; + width: 930px; + margin-left: 0; +} +input[disabled], +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + background-color: #f5f5f5; + border-color: #ddd; + cursor: not-allowed; +} +.actions { + background: #f5f5f5; + margin-top: 18px; + margin-bottom: 18px; + padding: 17px 20px 18px 150px; + border-top: 1px solid #ddd; + -webkit-border-radius: 0 0 3px 3px; + -moz-border-radius: 0 0 3px 3px; + border-radius: 0 0 3px 3px; +} +.actions .secondary-action { + float: right; +} +.actions .secondary-action a { + line-height: 30px; +} +.actions .secondary-action a:hover { + text-decoration: underline; +} +.help-inline, .help-block { + font-size: 13px; + line-height: 18px; + color: #bfbfbf; +} +.help-inline { + padding-left: 5px; + *position: relative; + /* IE6-7 */ + + *top: -5px; + /* IE6-7 */ + +} +.help-block { + display: block; + max-width: 600px; +} +.inline-inputs { + color: #808080; +} +.inline-inputs span { + padding: 0 2px 0 1px; +} +.input-prepend input, .input-append input { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-prepend .add-on, .input-append .add-on { + position: relative; + background: #f5f5f5; + border: 1px solid #ccc; + z-index: 2; + float: left; + display: block; + width: auto; + min-width: 16px; + height: 18px; + padding: 4px 4px 4px 5px; + margin-right: -1px; + font-weight: normal; + line-height: 18px; + color: #bfbfbf; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-prepend .active, .input-append .active { + background: #a9dba9; + border-color: #46a546; +} +.input-prepend .add-on { + *margin-top: 1px; + /* IE6-7 */ + +} +.input-append input { + float: left; + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-append .add-on { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; + margin-right: 0; + margin-left: -1px; +} +.inputs-list { + margin: 0 0 5px; + width: 100%; +} +.inputs-list li { + display: block; + padding: 0; + width: 100%; +} +.inputs-list label { + display: block; + float: none; + width: auto; + padding: 0; + margin-left: 20px; + line-height: 18px; + text-align: left; + white-space: normal; +} +.inputs-list label strong { + color: #808080; +} +.inputs-list label small { + font-size: 11px; + font-weight: normal; +} +.inputs-list .inputs-list { + margin-left: 25px; + margin-bottom: 10px; + padding-top: 0; +} +.inputs-list:first-child { + padding-top: 6px; +} +.inputs-list li + li { + padding-top: 2px; +} +.inputs-list input[type=radio], .inputs-list input[type=checkbox] { + margin-bottom: 0; + margin-left: -20px; + float: left; +} +.form-stacked { + padding-left: 20px; +} +.form-stacked fieldset { + padding-top: 9px; +} +.form-stacked legend { + padding-left: 0; +} +.form-stacked label { + display: block; + float: none; + width: auto; + font-weight: bold; + text-align: left; + line-height: 20px; + padding-top: 0; +} +.form-stacked .clearfix { + margin-bottom: 9px; +} +.form-stacked .clearfix div.input { + margin-left: 0; +} +.form-stacked .inputs-list { + margin-bottom: 0; +} +.form-stacked .inputs-list li { + padding-top: 0; +} +.form-stacked .inputs-list li label { + font-weight: normal; + padding-top: 0; +} +.form-stacked div.clearfix.error { + padding-top: 10px; + padding-bottom: 10px; + padding-left: 10px; + margin-top: 0; + margin-left: -10px; +} +.form-stacked .actions { + margin-left: -20px; + padding-left: 20px; +} +/* +* Tables.less +* Tables for, you guessed it, tabular data +* ---------------------------------------- */ +table { + width: 100%; + margin-bottom: 18px; + padding: 0; + font-size: 13px; + border-collapse: collapse; +} +table th, table td { + padding: 10px 10px 9px; + line-height: 18px; + text-align: center; +} +table th { + padding-top: 9px; + font-weight: bold; + vertical-align: middle; +} +table td { + vertical-align: top; + /*border-top: 1px solid #ddd;*/ +} +table tbody th { +/* border-top: 1px solid #ddd;*/ + vertical-align: top; +} +.condensed-table th, .condensed-table td { + padding: 5px 5px 4px; +} +.bordered-table { + border: 1px solid #ddd; + border-collapse: separate; + *border-collapse: collapse; + /* IE7, collapse table to remove spacing */ + + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.bordered-table th + th, .bordered-table td + td, .bordered-table th + td { + border-left: 1px solid #ddd; +} +.bordered-table thead tr:first-child th:first-child, .bordered-table tbody tr:first-child td:first-child { + -webkit-border-radius: 4px 0 0 0; + -moz-border-radius: 4px 0 0 0; + border-radius: 4px 0 0 0; +} +.bordered-table thead tr:first-child th:last-child, .bordered-table tbody tr:first-child td:last-child { + -webkit-border-radius: 0 4px 0 0; + -moz-border-radius: 0 4px 0 0; + border-radius: 0 4px 0 0; +} +.bordered-table tbody tr:last-child td:first-child { + -webkit-border-radius: 0 0 0 4px; + -moz-border-radius: 0 0 0 4px; + border-radius: 0 0 0 4px; +} +.bordered-table tbody tr:last-child td:last-child { + -webkit-border-radius: 0 0 4px 0; + -moz-border-radius: 0 0 4px 0; + border-radius: 0 0 4px 0; +} +table .span1 { + width: 20px; +} +table .span2 { + width: 60px; +} +table .span3 { + width: 100px; +} +table .span4 { + width: 140px; +} +table .span5 { + width: 180px; +} +table .span6 { + width: 220px; +} +table .span7 { + width: 260px; +} +table .span8 { + width: 300px; +} +table .span9 { + width: 340px; +} +table .span10 { + width: 380px; +} +table .span11 { + width: 420px; +} +table .span12 { + width: 460px; +} +table .span13 { + width: 500px; +} +table .span14 { + width: 540px; +} +table .span15 { + width: 580px; +} +table .span16 { + width: 620px; +} +.zebra-striped tbody tr:nth-child(odd) td, .zebra-striped tbody tr:nth-child(odd) th { + background-color: #f9f9f9; +} +.zebra-striped tbody tr:hover td, .zebra-striped tbody tr:hover th { + background-color: #f5f5f5; +} +table .header { + cursor: pointer; +} +table .header:after { + content: ""; + float: right; + margin-top: 7px; + border-width: 0 4px 4px; + border-style: solid; + border-color: #000 transparent; + visibility: hidden; +} +table .headerSortUp, table .headerSortDown { + background-color: rgba(141, 192, 219, 0.25); + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); +} +table .header:hover:after { + visibility: visible; +} +table .headerSortDown:after, table .headerSortDown:hover:after { + visibility: visible; + filter: alpha(opacity=60); + -khtml-opacity: 0.6; + -moz-opacity: 0.6; + opacity: 0.6; +} +table .headerSortUp:after { + border-bottom: none; + border-left: 4px solid transparent; + border-right: 4px solid transparent; + border-top: 4px solid #000; + visibility: visible; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + filter: alpha(opacity=60); + -khtml-opacity: 0.6; + -moz-opacity: 0.6; + opacity: 0.6; +} +table .blue { + color: #049cdb; + border-bottom-color: #049cdb; +} +table .headerSortUp.blue, table .headerSortDown.blue { + background-color: #ade6fe; +} +table .green { + color: #46a546; + border-bottom-color: #46a546; +} +table .headerSortUp.green, table .headerSortDown.green { + background-color: #cdeacd; +} +table .red { + color: #9d261d; + border-bottom-color: #9d261d; +} +table .headerSortUp.red, table .headerSortDown.red { + background-color: #f4c8c5; +} +table .yellow { + color: #ffc40d; + border-bottom-color: #ffc40d; +} +table .headerSortUp.yellow, table .headerSortDown.yellow { + background-color: #fff6d9; +} +table .orange { + color: #f89406; + border-bottom-color: #f89406; +} +.center1 +{ +margin-left: auto; +margin-right: auto; +} +table .headerSortUp.orange, table .headerSortDown.orange { + background-color: #fee9cc; +} +table .purple { + color: #7a43b6; + border-bottom-color: #7a43b6; +} +table .headerSortUp.purple, table .headerSortDown.purple { + background-color: #e2d5f0; +} +/* Patterns.less +* Repeatable UI elements outside the base styles provided from the scaffolding +* ---------------------------------------------------------------------------- */ +.topbar { + height: 40px; + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 10000; + overflow: visible; +} +.topbar a { + color: #bfbfbf; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.topbar h3 a:hover, .topbar .brand:hover, .topbar ul .active > a { + background-color: #333; + background-color: rgba(255, 255, 255, 0.05); + color: #ffffff; + text-decoration: none; +} +.topbar h3 { + position: relative; +} +.topbar h3 a, .topbar .brand { + float: left; + display: block; + padding: 8px 20px 12px; + margin-left: -20px; + color: #ffffff; + font-size: 20px; + font-weight: 200; + line-height: 1; +} +.topbar p { + margin: 0; + line-height: 40px; +} +.topbar p a:hover { + background-color: transparent; + color: #ffffff; +} +.topbar form { + float: left; + margin: 5px 0 0 0; + position: relative; + filter: alpha(opacity=100); + -khtml-opacity: 1; + -moz-opacity: 1; + opacity: 1; +} +.topbar form.pull-right { + float: right; +} +.topbar input { + background-color: #444; + background-color: rgba(255, 255, 255, 0.3); + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: normal; + font-weight: 13px; + line-height: 1; + padding: 4px 9px; + color: #ffffff; + color: rgba(255, 255, 255, 0.75); + border: 1px solid #111; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.25); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.25); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.25); + -webkit-transition: none; + -moz-transition: none; + -ms-transition: none; + -o-transition: none; + transition: none; +} +.topbar input:-moz-placeholder { + color: #e6e6e6; +} +.topbar input::-webkit-input-placeholder { + color: #e6e6e6; +} +.topbar input:hover { + background-color: #bfbfbf; + background-color: rgba(255, 255, 255, 0.5); + color: #ffffff; +} +.topbar input:focus, .topbar input.focused { + outline: 0; + background-color: #ffffff; + color: #404040; + text-shadow: 0 1px 0 #ffffff; + border: 0; + padding: 5px 10px; + -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); +} +.topbar-inner, .topbar .fill { + background-color: #222; + background-color: #222222; + background-repeat: repeat-x; + background-image: -khtml-gradient(linear, left top, left bottom, from(#333333), to(#222222)); + background-image: -moz-linear-gradient(top, #333333, #222222); + background-image: -ms-linear-gradient(top, #333333, #222222); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #333333), color-stop(100%, #222222)); + background-image: -webkit-linear-gradient(top, #333333, #222222); + background-image: -o-linear-gradient(top, #333333, #222222); + background-image: linear-gradient(top, #333333, #222222); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); +} +.topbar div > ul, .nav { + display: block; + float: left; + margin: 0 10px 0 0; + position: relative; + left: 0; +} +.topbar div > ul > li, .nav > li { + display: block; + float: left; +} +.topbar div > ul a, .nav a { + display: block; + float: none; + padding: 10px 10px 11px; + line-height: 19px; + text-decoration: none; +} +.topbar div > ul a:hover, .nav a:hover { + color: #ffffff; + text-decoration: none; +} +.topbar div > ul .active > a, .nav .active > a { + background-color: #222; + background-color: rgba(0, 0, 0, 0.5); +} +.topbar div > ul.secondary-nav, .nav.secondary-nav { + float: right; + margin-left: 10px; + margin-right: 0; +} +.topbar div > ul.secondary-nav .menu-dropdown, +.nav.secondary-nav .menu-dropdown, +.topbar div > ul.secondary-nav .dropdown-menu, +.nav.secondary-nav .dropdown-menu { + right: 0; + border: 0; +} +.topbar div > ul a.menu:hover, +.nav a.menu:hover, +.topbar div > ul li.open .menu, +.nav li.open .menu, +.topbar div > ul .dropdown-toggle:hover, +.nav .dropdown-toggle:hover, +.topbar div > ul .dropdown.open .dropdown-toggle, +.nav .dropdown.open .dropdown-toggle { + background: #444; + background: rgba(255, 255, 255, 0.05); +} +.topbar div > ul .menu-dropdown, +.nav .menu-dropdown, +.topbar div > ul .dropdown-menu, +.nav .dropdown-menu { + background-color: #333; +} +.topbar div > ul .menu-dropdown a.menu, +.nav .menu-dropdown a.menu, +.topbar div > ul .dropdown-menu a.menu, +.nav .dropdown-menu a.menu, +.topbar div > ul .menu-dropdown .dropdown-toggle, +.nav .menu-dropdown .dropdown-toggle, +.topbar div > ul .dropdown-menu .dropdown-toggle, +.nav .dropdown-menu .dropdown-toggle { + color: #ffffff; +} +.topbar div > ul .menu-dropdown a.menu.open, +.nav .menu-dropdown a.menu.open, +.topbar div > ul .dropdown-menu a.menu.open, +.nav .dropdown-menu a.menu.open, +.topbar div > ul .menu-dropdown .dropdown-toggle.open, +.nav .menu-dropdown .dropdown-toggle.open, +.topbar div > ul .dropdown-menu .dropdown-toggle.open, +.nav .dropdown-menu .dropdown-toggle.open { + background: #444; + background: rgba(255, 255, 255, 0.05); +} +.topbar div > ul .menu-dropdown li a, +.nav .menu-dropdown li a, +.topbar div > ul .dropdown-menu li a, +.nav .dropdown-menu li a { + color: #999; + text-shadow: 0 1px 0 rgba(0, 0, 0, 0.5); +} +.topbar div > ul .menu-dropdown li a:hover, +.nav .menu-dropdown li a:hover, +.topbar div > ul .dropdown-menu li a:hover, +.nav .dropdown-menu li a:hover { + background-color: #191919; + background-repeat: repeat-x; + background-image: -khtml-gradient(linear, left top, left bottom, from(#292929), to(#191919)); + background-image: -moz-linear-gradient(top, #292929, #191919); + background-image: -ms-linear-gradient(top, #292929, #191919); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #292929), color-stop(100%, #191919)); + background-image: -webkit-linear-gradient(top, #292929, #191919); + background-image: -o-linear-gradient(top, #292929, #191919); + background-image: linear-gradient(top, #292929, #191919); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#292929', endColorstr='#191919', GradientType=0); + color: #ffffff; +} +.topbar div > ul .menu-dropdown .active a, +.nav .menu-dropdown .active a, +.topbar div > ul .dropdown-menu .active a, +.nav .dropdown-menu .active a { + color: #ffffff; +} +.topbar div > ul .menu-dropdown .divider, +.nav .menu-dropdown .divider, +.topbar div > ul .dropdown-menu .divider, +.nav .dropdown-menu .divider { + background-color: #222; + border-color: #444; +} +.topbar ul .menu-dropdown li a, .topbar ul .dropdown-menu li a { + padding: 4px 15px; +} +li.menu, .dropdown { + position: relative; +} +a.menu:after, .dropdown-toggle:after { + width: 0; + height: 0; + display: inline-block; + content: "↓"; + text-indent: -99999px; + vertical-align: top; + margin-top: 8px; + margin-left: 4px; + border-left: 4px solid transparent; + border-right: 4px solid transparent; + border-top: 4px solid #ffffff; + filter: alpha(opacity=50); + -khtml-opacity: 0.5; + -moz-opacity: 0.5; + opacity: 0.5; +} +.menu-dropdown, .dropdown-menu { + background-color: #ffffff; + float: left; + display: none; + position: absolute; + top: 40px; + z-index: 900; + min-width: 160px; + max-width: 220px; + _width: 160px; + margin-left: 0; + margin-right: 0; + padding: 6px 0; + zoom: 1; + border-color: #999; + border-color: rgba(0, 0, 0, 0.2); + border-style: solid; + border-width: 0 1px 1px; + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + -webkit-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; +} +.menu-dropdown li, .dropdown-menu li { + float: none; + display: block; + background-color: none; +} +.menu-dropdown .divider, .dropdown-menu .divider { + height: 1px; + margin: 5px 0; + overflow: hidden; + background-color: #eee; + border-bottom: 1px solid #ffffff; +} +.topbar .dropdown-menu a, .dropdown-menu a { + display: block; + padding: 4px 15px; + clear: both; + font-weight: normal; + line-height: 18px; + color: #808080; + text-shadow: 0 1px 0 #ffffff; +} +.topbar .dropdown-menu a:hover, +.dropdown-menu a:hover, +.topbar .dropdown-menu a.hover, +.dropdown-menu a.hover { + background-color: #dddddd; + background-repeat: repeat-x; + background-image: -khtml-gradient(linear, left top, left bottom, from(#eeeeee), to(#dddddd)); + background-image: -moz-linear-gradient(top, #eeeeee, #dddddd); + background-image: -ms-linear-gradient(top, #eeeeee, #dddddd); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #eeeeee), color-stop(100%, #dddddd)); + background-image: -webkit-linear-gradient(top, #eeeeee, #dddddd); + background-image: -o-linear-gradient(top, #eeeeee, #dddddd); + background-image: linear-gradient(top, #eeeeee, #dddddd); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#dddddd', GradientType=0); + color: #404040; + text-decoration: none; + -webkit-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.025), inset 0 -1px rgba(0, 0, 0, 0.025); + -moz-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.025), inset 0 -1px rgba(0, 0, 0, 0.025); + box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.025), inset 0 -1px rgba(0, 0, 0, 0.025); +} +footer { + margin-top: 17px; + padding-top: 17px; +} +.page-header { + margin-bottom: 17px; + border-bottom: 1px solid #ddd; + -webkit-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + -moz-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + box-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); +} +.page-header h3 { + margin-top: 20px; + margin-bottom : -17px; +} +.btn.danger, +.alert-message.danger, +.btn.danger:hover, +.alert-message.danger:hover, +.btn.error, +.alert-message.error, +.btn.error:hover, +.alert-message.error:hover, +.btn.success, +.alert-message.success, +.btn.success:hover, +.alert-message.success:hover, +.btn.info, +.alert-message.info, +.btn.info:hover, +.alert-message.info:hover { + color: #ffffff; +} +.btn .close, .alert-message .close { + font-family: Arial, sans-serif; + line-height: 18px; +} +.btn-mini { + padding: 2px 6px; + font-size: 15px; + line-height: 16px; +} +.btn.danger, +.alert-message.danger, +.btn.error, +.alert-message.error { + background-color: #c43c35; + background-repeat: repeat-x; + background-image: -khtml-gradient(linear, left top, left bottom, from(#ee5f5b), to(#c43c35)); + background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); + background-image: linear-gradient(top, #ee5f5b, #c43c35); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0); + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + border-color: #c43c35 #c43c35 #882a25; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); +} +.btn.success, .alert-message.success { + background-color: #57a957; + background-repeat: repeat-x; + background-image: -khtml-gradient(linear, left top, left bottom, from(#62c462), to(#57a957)); + background-image: -moz-linear-gradient(top, #62c462, #57a957); + background-image: -ms-linear-gradient(top, #62c462, #57a957); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462), color-stop(100%, #57a957)); + background-image: -webkit-linear-gradient(top, #62c462, #57a957); + background-image: -o-linear-gradient(top, #62c462, #57a957); + background-image: linear-gradient(top, #62c462, #57a957); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0); + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + border-color: #57a957 #57a957 #3d773d; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); +} +.btn.info, .alert-message.info { + background-color: #339bb9; + background-repeat: repeat-x; + background-image: -khtml-gradient(linear, left top, left bottom, from(#5bc0de), to(#339bb9)); + background-image: -moz-linear-gradient(top, #5bc0de, #339bb9); + background-image: -ms-linear-gradient(top, #5bc0de, #339bb9); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de), color-stop(100%, #339bb9)); + background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); + background-image: -o-linear-gradient(top, #5bc0de, #339bb9); + background-image: linear-gradient(top, #5bc0de, #339bb9); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0); + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + border-color: #339bb9 #339bb9 #22697d; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); +} +.btn { + cursor: pointer; + display: inline-block; + background-color: #e6e6e6; + background-repeat: no-repeat; + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), color-stop(25%, #ffffff), to(#e6e6e6)); + background-image: -webkit-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6); + background-image: -moz-linear-gradient(top, #ffffff, #ffffff 25%, #e6e6e6); + background-image: -ms-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6); + background-image: -o-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6); + background-image: linear-gradient(#ffffff, #ffffff 25%, #e6e6e6); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0); + padding: 5px 14px 6px; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); + color: #333; + font-size: 13px; + line-height: normal; + border: 1px solid #ccc; + border-bottom-color: #bbb; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -webkit-transition: 0.1s linear all; + -moz-transition: 0.1s linear all; + -ms-transition: 0.1s linear all; + -o-transition: 0.1s linear all; + transition: 0.1s linear all; +} +.btn:hover { + background-position: 0 -15px; + color: #333; + text-decoration: none; +} +.btn:focus { + outline: 1px dotted #666; +} +.btn.primary { + color: #ffffff; + background-color: #0064cd; + background-repeat: repeat-x; + background-image: -khtml-gradient(linear, left top, left bottom, from(#049cdb), to(#0064cd)); + background-image: -moz-linear-gradient(top, #049cdb, #0064cd); + background-image: -ms-linear-gradient(top, #049cdb, #0064cd); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #049cdb), color-stop(100%, #0064cd)); + background-image: -webkit-linear-gradient(top, #049cdb, #0064cd); + background-image: -o-linear-gradient(top, #049cdb, #0064cd); + background-image: linear-gradient(top, #049cdb, #0064cd); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#049cdb', endColorstr='#0064cd', GradientType=0); + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + border-color: #0064cd #0064cd #003f81; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); +} +.btn.active, .btn:active { + -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); +} +.btn.disabled { + cursor: default; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + filter: alpha(opacity=65); + -khtml-opacity: 0.65; + -moz-opacity: 0.65; + opacity: 0.65; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.btn[disabled] { + cursor: default; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + filter: alpha(opacity=65); + -khtml-opacity: 0.65; + -moz-opacity: 0.65; + opacity: 0.65; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.btn.large { + font-size: 15px; + line-height: normal; + padding: 9px 14px 9px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.btn.small { + padding: 7px 9px 7px; + font-size: 11px; +} +:root .alert-message, :root .btn { + border-radius: 0 \0; +} +.alert { + padding: 8px 35px 8px 14px; + margin-bottom: 18px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + background-color: #fcf8e3; + border: 1px solid #fbeed5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.alert, .alert-heading { + color: #c09853; +} +.alert .close { + position: relative; + top: -2px; + right: -21px; + line-height: 18px; +} +.alert-success { + background-color: #dff0d8; + border-color: #d6e9c6; +} +.alert-success, .alert-success .alert-heading { + color: #468847; +} +.alert-danger, .alert-error { + background-color: #f2dede; + border-color: #eed3d7; +} +.alert-danger, +.alert-error, +.alert-danger .alert-heading, +.alert-error .alert-heading { + color: #b94a48; +} +.alert-info { + background-color: #d9edf7; + border-color: #bce8f1; +} +.alert-info, .alert-info .alert-heading { + color: #3a87ad; +} +.alert-block { + padding-top: 14px; + padding-bottom: 14px; +} +.alert-block > p, .alert-block > ul { + margin-bottom: 0; +} +.alert-block p + p { + margin-top: 5px; +} + +button.btn::-moz-focus-inner, input[type=submit].btn::-moz-focus-inner { + padding: 0; + border: 0; +} +.close { + float: right; + color: #000000; + font-size: 20px; + font-weight: bold; + line-height: 13.5px; + text-shadow: 0 1px 0 #ffffff; + filter: alpha(opacity=25); + -khtml-opacity: 0.25; + -moz-opacity: 0.25; + opacity: 0.25; +} +.close:hover { + color: #000000; + text-decoration: none; + filter: alpha(opacity=40); + -khtml-opacity: 0.4; + -moz-opacity: 0.4; + opacity: 0.4; +} +.alert-message { + position: relative; + padding: 7px 15px; + margin-bottom: 18px; + color: #404040; + background-color: #eedc94; + background-repeat: repeat-x; + background-image: -khtml-gradient(linear, left top, left bottom, from(#fceec1), to(#eedc94)); + background-image: -moz-linear-gradient(top, #fceec1, #eedc94); + background-image: -ms-linear-gradient(top, #fceec1, #eedc94); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fceec1), color-stop(100%, #eedc94)); + background-image: -webkit-linear-gradient(top, #fceec1, #eedc94); + background-image: -o-linear-gradient(top, #fceec1, #eedc94); + background-image: linear-gradient(top, #fceec1, #eedc94); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fceec1', endColorstr='#eedc94', GradientType=0); + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + border-color: #eedc94 #eedc94 #e4c652; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + border-width: 1px; + border-style: solid; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); +} +.alert-message .close { + margin-top: 1px; + *margin-top: 0; +} +.alert-message a { + font-weight: bold; + color: #404040; +} +.alert-message.danger p a, +.alert-message.error p a, +.alert-message.success p a, +.alert-message.info p a { + color: #ffffff; +} +.alert-message h5 { + line-height: 18px; +} +.alert-message p { + margin-bottom: 0; +} +.alert-message div { + margin-top: 5px; + margin-bottom: 2px; + line-height: 28px; +} +.alert-message .btn { + -webkit-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.25); + -moz-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.25); + box-shadow: 0 1px 0 rgba(255, 255, 255, 0.25); +} +.alert-message.block-message { + background-image: none; + background-color: #fdf5d9; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + padding: 14px; + border-color: #fceec1; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.alert-message.block-message ul, .alert-message.block-message p { + margin-right: 30px; +} +.alert-message.block-message ul { + margin-bottom: 0; +} +.alert-message.block-message li { + color: #404040; +} +.alert-message.block-message .alert-actions { + margin-top: 5px; +} +.alert-message.block-message.error, .alert-message.block-message.success, .alert-message.block-message.info { + color: #404040; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); +} +.alert-message.block-message.error { + background-color: #fddfde; + border-color: #fbc7c6; +} +.alert-message.block-message.success { + background-color: #d1eed1; + border-color: #bfe7bf; +} +.alert-message.block-message.info { + background-color: #ddf4fb; + border-color: #c6edf9; +} +.alert-message.block-message.danger p a, +.alert-message.block-message.error p a, +.alert-message.block-message.success p a, +.alert-message.block-message.info p a { + color: #404040; +} +.label { + padding: 1px 3px 2px; + font-size: 9.75px; + font-weight: bold; + color: #ffffff; + text-transform: uppercase; + white-space: nowrap; + background-color: #bfbfbf; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + text-shadow: none; +} +.label.important { + background-color: #c43c35; +} +.label.warning { + background-color: #f89406; +} +.label.success { + background-color: #46a546; +} +.label.notice { + background-color: #62cffc; +} diff --git a/testapp/static/exam/css/gradeuser.css b/testapp/static/exam/css/gradeuser.css new file mode 100644 index 0000000..07b1079 --- /dev/null +++ b/testapp/static/exam/css/gradeuser.css @@ -0,0 +1,52 @@ +textarea +{ +width : 550px; +height : 200px; + +} + +.for-question{ + background: none repeat scroll 0 0 #F1F1F1; + border-radius: 6px 6px 6px 6px; + margin-bottom: 10px; + padding: 5px; +} + +#headerDiv, #contentDiv { +float: left; +} +#titleText { +float: left; +font-size: 1.1em; +font-weight: bold; +margin: 5px; +} +#myHeader { +font-size: 1.1em; +font-weight: bold; +margin: 5px; +} +#headerDiv { +background-color: #0037DB; +color: #9EB6FF; +} + +#contentDiv { + background-color:#F0F8FF; + border: 1px solid #C9C9C9; + border-radius: 5px 5px 5px 5px; + margin-bottom: 10px; + min-width: 805px; + +} + +#myContent { +margin: 5px 10px; + +} +#headerDiv a { +float: right; +margin: 10px 10px 5px 5px; +} +#headerDiv a:hover { +color: #FFFFFF; diff --git a/testapp/static/exam/css/login.css b/testapp/static/exam/css/login.css new file mode 100644 index 0000000..a10cbaa --- /dev/null +++ b/testapp/static/exam/css/login.css @@ -0,0 +1,10 @@ +label +{ + padding-top: 6px; + font-size: 15px; + line-height: 18px; + float: left; + width: 80px; + text-align: center; + color: #404040; + } diff --git a/testapp/static/exam/css/monitor.css b/testapp/static/exam/css/monitor.css new file mode 100644 index 0000000..b16c8b3 --- /dev/null +++ b/testapp/static/exam/css/monitor.css @@ -0,0 +1,11 @@ + table td + { + vertical-align: top; + border-top: 1px solid #ddd; + } + table tbody th + { + border-top: 1px solid #ddd; + vertical-align: top; + } + diff --git a/testapp/static/exam/css/question.css b/testapp/static/exam/css/question.css new file mode 100644 index 0000000..4bf5913 --- /dev/null +++ b/testapp/static/exam/css/question.css @@ -0,0 +1,42 @@ +.time-div +{ + background-color:black; + padding: 8px; + color: #5DFC0A; + vertical-align:middle; + width:150px; + float:right; + border-radius: 6px 6px 6px 6px; +} +.td1-class +{ + width:175px; +} +.td2-class +{ + width:50px; +} +.page-header { + height:50px; + text-align: center; + background-color: #f5f5f5; + padding: 35px 20px 10px; + margin: -20px -20px 20px; +} +#codeTextarea{ + + } + .textAreaWithLines{ + font-family:courier; + border:1px solid #eee; + + } + .textAreaWithLines textarea,.textAreaWithLines div{ + border:0px; + line-height:120%; + font-size:12px; + } + .lineObj{ + color: grey; + } + diff --git a/testapp/static/exam/css/question_quiz.css b/testapp/static/exam/css/question_quiz.css new file mode 100644 index 0000000..b702bd4 --- /dev/null +++ b/testapp/static/exam/css/question_quiz.css @@ -0,0 +1,18 @@ +table th, table td + { + text-align: left; + } + +.mini-text +{ + height : 9px; + width : 30px; +} +.select-type +{ + width : 80px; +} +.tag-text +{ + width : 290px; +} diff --git a/testapp/static/exam/css/showusers.css b/testapp/static/exam/css/showusers.css new file mode 100644 index 0000000..66a3746 --- /dev/null +++ b/testapp/static/exam/css/showusers.css @@ -0,0 +1,5 @@ +.table-class +{ + text-align:left; + width:60%; +} diff --git a/testapp/static/exam/js/add_question.js b/testapp/static/exam/js/add_question.js new file mode 100644 index 0000000..24af127 --- /dev/null +++ b/testapp/static/exam/js/add_question.js @@ -0,0 +1,109 @@ +function increase(frm) +{ + if(frm.points.value == "") + { + frm.points.value = "0.5"; + return; + } + frm.points.value = parseFloat(frm.points.value) + 0.5; +} + +function decrease(frm) +{ + if(frm.points.value > 0) + { + frm.points.value = parseFloat(frm.points.value) - 0.5; + } + else + { + frm.points.value=0; + } + + +} + +function textareaformat() +{ + + document.getElementById('id_type').setAttribute('class','select-type'); + + document.getElementById('id_points').setAttribute('class','mini-text'); + document.getElementById('id_tags').setAttribute('class','tag-text'); + + $('#id_description').bind('focus', function( event ){ + document.getElementById("id_description").rows=5; + document.getElementById("id_description").cols=40; + }); + + $('#id_description').bind('blur', function( event ){ + document.getElementById("id_description").rows=1; + document.getElementById("id_description").cols=40; + }); + + $('#id_description').bind('keypress', function (event){ + document.getElementById('my').innerHTML = document.getElementById('id_description').value ; + }); + + $('#id_test').bind('focus', function( event ){ + document.getElementById("id_test").rows=5; + document.getElementById("id_test").cols=40; + }); + + $('#id_test').bind('blur', function( event ){ + document.getElementById("id_test").rows=1; + document.getElementById("id_test").cols=40; + }); + $('#id_options').bind('focus', function( event ){ + document.getElementById("id_options").rows=5; + document.getElementById("id_options").cols=40; + }); + + $('#id_options').bind('blur', function( event ){ + document.getElementById("id_options").rows=1; + document.getElementById("id_options").cols=40; + }); + + $('#id_type').bind('change',function(event){ + var value = document.getElementById('id_type').value; + if(value == 'mcq') + { + document.getElementById('id_options').style.visibility='visible'; + document.getElementById('label_option').innerHTML="Options :" + + } + else + { + document.getElementById('id_options').style.visibility='hidden'; + document.getElementById('label_option').innerHTML = ""; + } + }); + + document.getElementById('my').innerHTML = document.getElementById('id_description').value ; + var value = document.getElementById('id_type').value; + if(value == 'mcq') + { + document.getElementById('id_options').style.visibility='visible'; + document.getElementById('label_option').innerHTML="Options :" + + } + else + { + document.getElementById('id_options').style.visibility='hidden'; + document.getElementById('label_option').innerHTML = ""; + } +} + +function autosubmit() +{ + if (document.getElementById('id_type').value == 'mcq') + { + var value = document.getElementById('id_options').value; + if(value.split('\n').length < 4) + { + alert("Please Enter 4 options. One option per line."); + return false; + } + return true; + } + +} diff --git a/testapp/static/exam/js/add_questionpaper.js b/testapp/static/exam/js/add_questionpaper.js new file mode 100644 index 0000000..6185dd5 --- /dev/null +++ b/testapp/static/exam/js/add_questionpaper.js @@ -0,0 +1,25 @@ +function load_data() +{ + var url_root = document.getElementById('url_root').value; + var value = document.getElementById('mode').value; + var pathArray = window.location.pathname.split( '/' ); + length = pathArray.length; + var digit = parseInt(pathArray[length-2]); + + if (! isNaN(digit) && value == 'Automatic') + { + window.location = url_root + "/exam/manage/designquestionpaper/automatic/" + digit; + } + else if(!isNaN(digit) && value == 'Manual') + { + window.location = url_root + "/exam/manage/designquestionpaper/manual/" + digit; + } + else if(value == 'Automatic') + { + window.location = window.location.pathname + "automatic"; + } + else if( value == 'Manual') + { + window.location = window.location.pathname + "manual"; + } +} diff --git a/testapp/static/exam/js/add_quiz.js b/testapp/static/exam/js/add_quiz.js new file mode 100644 index 0000000..56b0e95 --- /dev/null +++ b/testapp/static/exam/js/add_quiz.js @@ -0,0 +1,8 @@ +function test() +{ + if (document.getElementById("id_description").value != "") + { + alert("reached condition"); + document.getElementById("submit").innerHTML = "Save"; + } +} diff --git a/testapp/static/exam/js/edit_question.js b/testapp/static/exam/js/edit_question.js new file mode 100644 index 0000000..acba384 --- /dev/null +++ b/testapp/static/exam/js/edit_question.js @@ -0,0 +1,185 @@ +function render_question(frm) +{ + for(var i=1;i<=frm.description.length;i++) + { + document.getElementById('my'+i).innerHTML = frm.description[i-1].value; + } + +} + +function increase(frm,n) +{ + var newValue = document.getElementById('id_points'+ (n-1)).value ; + + if( newValue == "") + { + document.getElementById('id_points'+(n-1)).value = "0.5"; + return; + } + document.getElementById('id_points' + (n-1)).value = parseFloat(newValue) + 0.5; +} + +function decrease(frm,n) +{ + var newValue = document.getElementById('id_points'+ (n-1)).value ; + + if( newValue > 0) + { + document.getElementById('id_points' + (n-1)).value = parseFloat(newValue) - 0.5; + } + else + { + document.getElementById('id_points' + (n-1)).value = 0; + } +} + +function grade_data(showHideDiv) +{ + var ele=document.getElementById(showHideDiv); + if (ele.style.display=="block") + { + ele.style.display = "none"; + } + else + { + ele.style.display = "block"; + } +} + + +function data(showContent,showHideDiv,a,summary) +{ + var con = document.getElementById(showContent); + var ele=document.getElementById(showHideDiv); + var atag=document.getElementById(a); + if (ele.style.display=="block") + { + con.style.display = "none" + ele.style.display = "none"; + atag.text = summary; + } + else + { + con.style.display = "block"; + ele.style.display = "block"; + } +} + +function textareaformat() +{ + var point = document.getElementsByName('points'); + var test = document.getElementsByName('test'); + var option = document.getElementsByName('options'); + var descriptions = document.getElementsByName('description'); + var type = document.getElementsByName('type'); + var tags = document.getElementsByName('tags'); + + for (var i=0;i<point.length;i++) + { + point[i].id = point[i].id + i; + descriptions[i+1].id=descriptions[i+1].id + i; + test[i].id=test[i].id + i; + option[i].id=option[i].id + i; + type[i].id = type[i].id + i; + tags[i].id = tags[i].id + i; + } + + for(var i=0;i<point.length;i++) + { + var point_id = document.getElementById('id_points'+i); + point_id.setAttribute('class','mini-text'); + + var tags_id = document.getElementById('id_tags'+i); + tags_id.setAttribute('class','ac_input'); + tags_id.setAttribute('autocomplete','off'); + + jQuery().ready(function() + { + jQuery("#id_tags" + i).autocomplete("/taggit_autocomplete_modified/json", { multiple: true }); + }); + + var type_id = document.getElementById('id_type'+i); + type_id.setAttribute('class','select-type'); + type_id.onchange = showOptions; + var value = type_id.value; + + var desc_id = document.getElementById('id_description'+i); + desc_id.onfocus = gainfocus; + desc_id.onblur = lostfocus; + + var test_id = document.getElementById('id_test' + i); + test_id.onfocus = gainfocus; + test_id.onblur = lostfocus; + + var option_id = document.getElementById('id_options' + i); + option_id.onfocus = gainfocus; + option_id.onblur = lostfocus; + + if(value != 'mcq') + { + document.getElementById('id_options'+i).style.visibility='hidden'; + document.getElementById('label_option'+(i+1)).innerHTML = ""; + + } + + document.getElementById('my'+ (i+1)).innerHTML = desc_id.value; + } +} + +function showOptions(e) +{ + var value = this.value; + var no = parseInt(this.id.substring(this.id.length-1)); + if( value == 'mcq') + { + document.getElementById('id_options'+no).style.visibility = 'visible'; + document.getElementById('label_option'+ (no+1)).innerHTML = "Options : " + } + else + { + document.getElementById('id_options'+no).value = ""; + document.getElementById('id_options'+no).style.visibility = 'hidden'; + document.getElementById('label_option'+ (no+1)).innerHTML = ""; + } + + + +} + +function gainfocus(e) +{ + this.rows = 5; +} +function lostfocus(e) +{ + this.rows = 1; +} + +function autosubmit() +{ + var total_form = document.getElementsByName('summary').length; + var empty_options = 0 ; + var count_mcq = 0; + + for (var i=0;i<total_form;i++) + { + if (document.getElementById('id_type' + i).value != 'mcq') + { + continue; + } + else + { + count_mcq = count_mcq + 1; + var options = document.getElementById('id_options' + i).value; + var total_words = options.split("\n").length ; + if ( total_words < 4) + empty_options = empty_options + 1 ; + } + } + if (empty_options > 0) + { + alert('Enter 4 options. One option per line.'); + return false; + } + return true; +} diff --git a/testapp/static/exam/js/edit_quiz.js b/testapp/static/exam/js/edit_quiz.js new file mode 100644 index 0000000..610a438 --- /dev/null +++ b/testapp/static/exam/js/edit_quiz.js @@ -0,0 +1,21 @@ +function form_load() +{ + var tags = document.getElementsByName('tags'); + + for (var i=0;i<tags.length;i++) + { + tags[i].id = tags[i].id + i; + } + + for(var i=0;i<tags.length;i++) + { + var tags_id = document.getElementById('id_tags'+i); + tags_id.setAttribute('class','ac_input'); + tags_id.setAttribute('autocomplete','off'); + + jQuery().ready(function() + { + jQuery("#id_tags" + i).autocomplete("/taggit_autocomplete_modified/json", { multiple: true }); + }); + } +} diff --git a/testapp/static/exam/js/min.js b/testapp/static/exam/js/min.js new file mode 100644 index 0000000..b1ae21d --- /dev/null +++ b/testapp/static/exam/js/min.js @@ -0,0 +1,19 @@ +/* + * jQuery JavaScript Library v1.3.2 + * http://jquery.com/ + * + * Copyright (c) 2009 John Resig + * Dual licensed under the MIT and GPL licenses. + * http://docs.jquery.com/License + * + * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009) + * Revision: 6246 + */ +(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F<J;F++){var G=M[F];if(G.selected){K=o(G).val();if(H){return K}L.push(K)}}return L}return(E.value||"").replace(/\r/g,"")}return g}if(typeof K==="number"){K+=""}return this.each(function(){if(this.nodeType!=1){return}if(o.isArray(K)&&/radio|checkbox/.test(this.type)){this.checked=(o.inArray(this.value,K)>=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G<E;G++){L.call(K(this[G],H),this.length>1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H<I;H++){if((G=arguments[H])!=null){for(var F in G){var K=J[F],L=G[F];if(J===L){continue}if(E&&L&&typeof L==="object"&&!L.nodeType){J[F]=o.extend(E,K||(L.length!=null?[]:{}),L)}else{if(L!==g){J[F]=L}}}}}return J};var b=/z-?index|font-?weight|opacity|zoom|line-?height/i,q=document.defaultView||{},s=Object.prototype.toString;o.extend({noConflict:function(E){l.$=p;if(E){l.jQuery=y}return o},isFunction:function(E){return s.call(E)==="[object Function]"},isArray:function(E){return s.call(E)==="[object Array]"},isXMLDoc:function(E){return E.nodeType===9&&E.documentElement.nodeName!=="HTML"||!!E.ownerDocument&&o.isXMLDoc(E.ownerDocument)},globalEval:function(G){if(G&&/\S/.test(G)){var F=document.getElementsByTagName("head")[0]||document.documentElement,E=document.createElement("script");E.type="text/javascript";if(o.support.scriptEval){E.appendChild(document.createTextNode(G))}else{E.text=G}F.insertBefore(E,F.firstChild);F.removeChild(E)}},nodeName:function(F,E){return F.nodeName&&F.nodeName.toUpperCase()==E.toUpperCase()},each:function(G,K,F){var E,H=0,I=G.length;if(F){if(I===g){for(E in G){if(K.apply(G[E],F)===false){break}}}else{for(;H<I;){if(K.apply(G[H++],F)===false){break}}}}else{if(I===g){for(E in G){if(K.call(G[E],E,G[E])===false){break}}}else{for(var J=G[0];H<I&&K.call(J,H,J)!==false;J=G[++H]){}}}return G},prop:function(H,I,G,F,E){if(o.isFunction(I)){I=I.call(H,F)}return typeof I==="number"&&G=="curCSS"&&!b.test(E)?I+"px":I},className:{add:function(E,F){o.each((F||"").split(/\s+/),function(G,H){if(E.nodeType==1&&!o.className.has(E.className,H)){E.className+=(E.className?" ":"")+H}})},remove:function(E,F){if(E.nodeType==1){E.className=F!==g?o.grep(E.className.split(/\s+/),function(G){return !o.className.has(F,G)}).join(" "):""}},has:function(F,E){return F&&o.inArray(E,(F.className||F).toString().split(/\s+/))>-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+"></"+T+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!O.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!O.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!O.indexOf("<td")||!O.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!O.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||!o.support.htmlSerialize&&[1,"div<div>","</div>"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/<tbody/i.test(S),N=!O.indexOf("<table")&&!R?L.firstChild&&L.firstChild.childNodes:Q[1]=="<table>"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E<F;E++){if(H[E]===G){return E}}return -1},merge:function(H,E){var F=0,G,I=H.length;if(!o.support.getAll){while((G=E[F++])!=null){if(G.nodeType!=8){H[I++]=G}}}else{while((G=E[F++])!=null){H[I++]=G}}return H},unique:function(K){var F=[],E={};try{for(var G=0,H=K.length;G<H;G++){var J=o.data(K[G]);if(!E[J]){E[J]=true;F.push(K[G])}}}catch(I){F=K}return F},grep:function(F,J,E){var G=[];for(var H=0,I=F.length;H<I;H++){if(!E!=!J(F[H],H)){G.push(F[H])}}return G},map:function(E,J){var F=[];for(var G=0,H=E.length;G<H;G++){var I=J(E[G],G);if(I!=null){F[F.length]=I}}return F.concat.apply([],F)}});var C=navigator.userAgent.toLowerCase();o.browser={version:(C.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[0,"0"])[1],safari:/webkit/.test(C),opera:/opera/.test(C),msie:/msie/.test(C)&&!/opera/.test(C),mozilla:/mozilla/.test(C)&&!/(compatible|webkit)/.test(C)};o.each({parent:function(E){return E.parentNode},parents:function(E){return o.dir(E,"parentNode")},next:function(E){return o.nth(E,2,"nextSibling")},prev:function(E){return o.nth(E,2,"previousSibling")},nextAll:function(E){return o.dir(E,"nextSibling")},prevAll:function(E){return o.dir(E,"previousSibling")},siblings:function(E){return o.sibling(E.parentNode.firstChild,E)},children:function(E){return o.sibling(E.firstChild)},contents:function(E){return o.nodeName(E,"iframe")?E.contentDocument||E.contentWindow.document:o.makeArray(E.childNodes)}},function(E,F){o.fn[E]=function(G){var H=o.map(this,F);if(G&&typeof G=="string"){H=o.multiFilter(G,H)}return this.pushStack(o.unique(H),E,G)}});o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(E,F){o.fn[E]=function(G){var J=[],L=o(G);for(var K=0,H=L.length;K<H;K++){var I=(K>0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}}); +/* + * Sizzle CSS Selector Engine - v0.9.3 + * Copyright 2009, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa<ab.length;aa++){if(ab[aa]===ab[aa-1]){ab.splice(aa--,1)}}}}}return ab};F.matches=function(T,U){return F(T,null,null,U)};F.find=function(aa,T,ab){var Z,X;if(!aa){return[]}for(var W=0,V=I.order.length;W<V;W++){var Y=I.order[W],X;if((X=I.match[Y].exec(aa))){var U=RegExp.leftContext;if(U.substr(U.length-1)!=="\\"){X[1]=(X[1]||"").replace(/\\/g,"");Z=I.find[Y](X,T,ab);if(Z!=null){aa=aa.replace(I.match[Y],"");break}}}}if(!Z){Z=T.getElementsByTagName("*")}return{set:Z,expr:aa}};F.filter=function(ad,ac,ag,W){var V=ad,ai=[],aa=ac,Y,T,Z=ac&&ac[0]&&Q(ac[0]);while(ad&&ac.length){for(var ab in I.filter){if((Y=I.match[ab].exec(ad))!=null){var U=I.filter[ab],ah,af;T=false;if(aa==ai){ai=[]}if(I.preFilter[ab]){Y=I.preFilter[ab](Y,aa,ag,ai,W,Z);if(!Y){T=ah=true}else{if(Y===true){continue}}}if(Y){for(var X=0;(af=aa[X])!=null;X++){if(af){ah=U(af,Y,X,aa);var ae=W^!!ah;if(ag&&ah!=null){if(ae){T=true}else{aa[X]=false}}else{if(ae){ai.push(af);T=true}}}}}if(ah!==g){if(!ag){aa=ai}ad=ad.replace(I.match[ab],"");if(!T){return[]}break}}}if(ad==V){if(T==null){throw"Syntax error, unrecognized expression: "+ad}else{break}}V=ad}return aa};var I=F.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(T){return T.getAttribute("href")}},relative:{"+":function(aa,T,Z){var X=typeof T==="string",ab=X&&!/\W/.test(T),Y=X&&!ab;if(ab&&!Z){T=T.toUpperCase()}for(var W=0,V=aa.length,U;W<V;W++){if((U=aa[W])){while((U=U.previousSibling)&&U.nodeType!==1){}aa[W]=Y||U&&U.nodeName===T?U||false:U===T}}if(Y){F.filter(T,aa,true)}},">":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){var W=Y.parentNode;Z[V]=W.nodeName===U?W:false}}}else{for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){Z[V]=X?Y.parentNode:Y.parentNode===U}}if(X){F.filter(U,Z,true)}}},"":function(W,U,Y){var V=L++,T=S;if(!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("parentNode",U,V,W,X,Y)},"~":function(W,U,Y){var V=L++,T=S;if(typeof U==="string"&&!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("previousSibling",U,V,W,X,Y)}},find:{ID:function(U,V,W){if(typeof V.getElementById!=="undefined"&&!W){var T=V.getElementById(U[1]);return T?[T]:[]}},NAME:function(V,Y,Z){if(typeof Y.getElementsByName!=="undefined"){var U=[],X=Y.getElementsByName(V[1]);for(var W=0,T=X.length;W<T;W++){if(X[W].getAttribute("name")===V[1]){U.push(X[W])}}return U.length===0?null:U}},TAG:function(T,U){return U.getElementsByTagName(T[1])}},preFilter:{CLASS:function(W,U,V,T,Z,aa){W=" "+W[1].replace(/\\/g,"")+" ";if(aa){return W}for(var X=0,Y;(Y=U[X])!=null;X++){if(Y){if(Z^(Y.className&&(" "+Y.className+" ").indexOf(W)>=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return U<T[3]-0},gt:function(V,U,T){return U>T[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W<T;W++){if(Y[W]===Z){return false}}return true}}}},CHILD:function(T,W){var Z=W[1],U=T;switch(Z){case"only":case"first":while(U=U.previousSibling){if(U.nodeType===1){return false}}if(Z=="first"){return true}U=T;case"last":while(U=U.nextSibling){if(U.nodeType===1){return false}}return true;case"nth":var V=W[2],ac=W[3];if(V==1&&ac==0){return true}var Y=W[0],ab=T.parentNode;if(ab&&(ab.sizcache!==Y||!T.nodeIndex)){var X=0;for(U=ab.firstChild;U;U=U.nextSibling){if(U.nodeType===1){U.nodeIndex=++X}}ab.sizcache=Y}var aa=T.nodeIndex-ac;if(V==0){return aa==0}else{return(aa%V==0&&aa/V>=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V<T;V++){U.push(X[V])}}else{for(var V=0;X[V];V++){U.push(X[V])}}}return U}}var G;if(document.documentElement.compareDocumentPosition){G=function(U,T){var V=U.compareDocumentPosition(T)&4?-1:U===T?0:1;if(V===0){hasDuplicate=true}return V}}else{if("sourceIndex" in document.documentElement){G=function(U,T){var V=U.sourceIndex-T.sourceIndex;if(V===0){hasDuplicate=true}return V}}else{if(document.createRange){G=function(W,U){var V=W.ownerDocument.createRange(),T=U.ownerDocument.createRange();V.selectNode(W);V.collapse(true);T.selectNode(U);T.collapse(true);var X=V.compareBoundaryPoints(Range.START_TO_END,T);if(X===0){hasDuplicate=true}return X}}}}(function(){var U=document.createElement("form"),V="script"+(new Date).getTime();U.innerHTML="<input name='"+V+"'/>";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="<a href='#'></a>";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="<p class='TEST'></p>";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="<div class='test e'></div><div class='test'></div>";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1&&!ac){T.sizcache=Y;T.sizset=W}if(T.nodeName===Z){X=T;break}T=T[U]}ad[W]=X}}}function S(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1){if(!ac){T.sizcache=Y;T.sizset=W}if(typeof Z!=="string"){if(T===Z){X=true;break}}else{if(F.filter(Z,[T]).length>0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z<U;Z++){F(T,V[Z],W)}return F.filter(X,W)};o.find=F;o.filter=F.filter;o.expr=F.selectors;o.expr[":"]=o.expr.filters;F.selectors.filters.hidden=function(T){return T.offsetWidth===0||T.offsetHeight===0};F.selectors.filters.visible=function(T){return T.offsetWidth>0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F<E.length){o.event.proxy(G,E[F++])}return this.click(o.event.proxy(G,function(H){this.lastToggle=(this.lastToggle||0)%F;H.preventDefault();return E[this.lastToggle++].apply(this,arguments)||false}))},hover:function(E,F){return this.mouseenter(E).mouseleave(F)},ready:function(E){B();if(o.isReady){E.call(document,o)}else{o.readyList.push(E)}return this},live:function(G,F){var E=o.event.proxy(F);E.guid+=this.selector+G;o(document).bind(i(G,this.selector),this.selector,E);return this},die:function(F,E){o(document).unbind(i(F,this.selector),E?{guid:E.guid+this.selector+F}:null);return this}});function c(H){var E=RegExp("(^|\\.)"+H.type+"(\\.|$)"),G=true,F=[];o.each(o.data(this,"events").live||[],function(I,J){if(E.test(J.type)){var K=o(H.target).closest(J.data)[0];if(K){F.push({elem:K,fn:J})}}});F.sort(function(J,I){return o.data(J.elem,"closest")-o.data(I.elem,"closest")});o.each(F,function(){if(this.fn.call(this.elem,H,this.fn.data)===false){return(G=false)}});return G}function i(F,E){return["live",F,E.replace(/\./g,"`").replace(/ /g,"|")].join(".")}o.extend({isReady:false,readyList:[],ready:function(){if(!o.isReady){o.isReady=true;if(o.readyList){o.each(o.readyList,function(){this.call(document,o)});o.readyList=null}o(document).triggerHandler("ready")}}});var x=false;function B(){if(x){return}x=true;if(document.addEventListener){document.addEventListener("DOMContentLoaded",function(){document.removeEventListener("DOMContentLoaded",arguments.callee,false);o.ready()},false)}else{if(document.attachEvent){document.attachEvent("onreadystatechange",function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",arguments.callee);o.ready()}});if(document.documentElement.doScroll&&l==l.top){(function(){if(o.isReady){return}try{document.documentElement.doScroll("left")}catch(E){setTimeout(arguments.callee,0);return}o.ready()})()}}}o.event.add(l,"load",o.ready)}o.each(("blur,focus,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,change,select,submit,keydown,keypress,keyup,error").split(","),function(F,E){o.fn[E]=function(G){return G?this.bind(E,G):this.trigger(E)}});o(l).bind("unload",function(){for(var E in o.cache){if(E!=1&&o.cache[E].handle){o.event.remove(o.cache[E].handle.elem)}}});(function(){o.support={};var F=document.documentElement,G=document.createElement("script"),K=document.createElement("div"),J="script"+(new Date).getTime();K.style.display="none";K.innerHTML=' <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';var H=K.getElementsByTagName("*"),E=K.getElementsByTagName("a")[0];if(!H||!H.length||!E){return}o.support={leadingWhitespace:K.firstChild.nodeType==3,tbody:!K.getElementsByTagName("tbody").length,objectAll:!!K.getElementsByTagName("object")[0].getElementsByTagName("*").length,htmlSerialize:!!K.getElementsByTagName("link").length,style:/red/.test(E.getAttribute("style")),hrefNormalized:E.getAttribute("href")==="/a",opacity:E.style.opacity==="0.5",cssFloat:!!E.style.cssFloat,scriptEval:false,noCloneEvent:true,boxModel:null};G.type="text/javascript";try{G.appendChild(document.createTextNode("window."+J+"=1;"))}catch(I){}F.insertBefore(G,F.firstChild);if(l[J]){o.support.scriptEval=true;delete l[J]}F.removeChild(G);if(K.attachEvent&&K.fireEvent){K.attachEvent("onclick",function(){o.support.noCloneEvent=false;K.detachEvent("onclick",arguments.callee)});K.cloneNode(true).fireEvent("onclick")}o(function(){var L=document.createElement("div");L.style.width=L.style.paddingLeft="1px";document.body.appendChild(L);o.boxModel=o.support.boxModel=L.offsetWidth===2;document.body.removeChild(L).style.display="none"})})();var w=o.support.cssFloat?"cssFloat":"styleFloat";o.props={"for":"htmlFor","class":"className","float":w,cssFloat:w,styleFloat:w,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",tabindex:"tabIndex"};o.fn.extend({_load:o.fn.load,load:function(G,J,K){if(typeof G!=="string"){return this._load(G)}var I=G.indexOf(" ");if(I>=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("<div/>").append(M.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H<F;H++){var E=o.data(this[H],"olddisplay");this[H].style.display=E||"";if(o.css(this[H],"display")==="none"){var G=this[H].tagName,K;if(m[G]){K=m[G]}else{var I=o("<"+G+" />").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H<F;H++){this[H].style.display=o.data(this[H],"olddisplay")||""}return this}},hide:function(H,I){if(H){return this.animate(t("hide",3),H,I)}else{for(var G=0,F=this.length;G<F;G++){var E=o.data(this[G],"olddisplay");if(!E&&E!=="none"){o.data(this[G],"olddisplay",o.css(this[G],"display"))}}for(var G=0,F=this.length;G<F;G++){this[G].style.display="none"}return this}},_toggle:o.fn.toggle,toggle:function(G,F){var E=typeof G==="boolean";return o.isFunction(G)&&o.isFunction(F)?this._toggle.apply(this,arguments):G==null||E?this.each(function(){var H=E?G:o(this).is(":hidden");o(this)[H?"show":"hide"]()}):this.animate(t("toggle",3),G,F)},fadeTo:function(E,G,F){return this.animate({opacity:G},E,F)},animate:function(I,F,H,G){var E=o.speed(F,H,G);return this[E.queue===false?"each":"queue"](function(){var K=o.extend({},E),M,L=this.nodeType==1&&o(this).is(":hidden"),J=this;for(M in I){if(I[M]=="hide"&&L||I[M]=="show"&&!L){return K.complete.call(this)}if((M=="height"||M=="width")&&this.style){K.display=o.css(this,"display");K.overflow=this.style.overflow}}if(K.overflow!=null){this.style.overflow="hidden"}K.curAnim=o.extend({},I);o.each(I,function(O,S){var R=new o.fx(J,K,O);if(/toggle|show|hide/.test(S)){R[S=="toggle"?L?"show":"hide":S](I)}else{var Q=S.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),T=R.cur(true)||0;if(Q){var N=parseFloat(Q[2]),P=Q[3]||"px";if(P!="px"){J.style[O]=(N||1)+P;T=((N||1)/R.cur(true))*T;J.style[O]=T+P}if(Q[1]){N=((Q[1]=="-="?-1:1)*N)+T}R.custom(T,N,P)}else{R.custom(T,S,"")}}});return true})},stop:function(F,E){var G=o.timers;if(F){this.queue([])}this.each(function(){for(var H=G.length-1;H>=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J<K.length;J++){if(!K[J]()){K.splice(J--,1)}}if(!K.length){clearInterval(n);n=g}},13)}},show:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.show=true;this.custom(this.prop=="width"||this.prop=="height"?1:0,this.cur());o(this.elem).show()},hide:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(H){var G=e();if(H||G>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})();
\ No newline at end of file diff --git a/testapp/static/exam/js/question.js b/testapp/static/exam/js/question.js new file mode 100644 index 0000000..ba3f6d2 --- /dev/null +++ b/testapp/static/exam/js/question.js @@ -0,0 +1,122 @@ +function submitCode() +{ + document.forms["code"].submit(); + var x = document.getElementById("status"); + x.innerHTML = "<strong>Checking answer ...</strong>"; + x = document.getElementById("check"); + x.disabled = true; + x.value = "Checking Answer ..."; + document.getElementById("skip").disabled = true; +} + +function setSelectionRange(input, selectionStart, selectionEnd) +{ + if (input.setSelectionRange) + { + input.focus(); + input.setSelectionRange(selectionStart, selectionEnd); + } + else if (input.createTextRange) + { + var range = input.createTextRange(); + range.collapse(true); + range.moveEnd('character', selectionEnd); + range.moveStart('character', selectionStart); + range.select(); + } +} + +function replaceSelection (input, replaceString) +{ + if (input.setSelectionRange) + { + var selectionStart = input.selectionStart; + var selectionEnd = input.selectionEnd; + input.value = input.value.substring(0, selectionStart)+ replaceString + input.value.substring(selectionEnd); + if (selectionStart != selectionEnd) + { + setSelectionRange(input, selectionStart, selectionStart + replaceString.length); + } + else + { + setSelectionRange(input, selectionStart + replaceString.length, selectionStart + replaceString.length); + } + } + else if (document.selection) + { + var range = document.selection.createRange(); + if (range.parentElement() == input) + { + var isCollapsed = range.text == ''; + range.text = replaceString; + if (!isCollapsed) + { + range.moveStart('character', -replaceString.length); + range.select(); + } + } + } +} + +// We are going to catch the TAB key so that we can use it, Hooray! +function catchTab(item,e) +{ + if(navigator.userAgent.match("Gecko")) + { + c=e.which; + } + else + { + c=e.keyCode; + } + if(c==9) + { + replaceSelection(item,String.fromCharCode(9)); + setTimeout("document.getElementById('"+item.id+"').focus();",0); + return false; + } +} + +var lineObjOffsetTop = 2; + +function createTextAreaWithLines(id) +{ + var el = document.createElement('DIV'); + var ta = document.getElementById(id); + ta.parentNode.insertBefore(el,ta); + el.appendChild(ta); + el.className='textAreaWithLines'; + el.style.width = (ta.offsetWidth + 30) + 'px'; + ta.style.position = 'absolute'; + ta.style.left = '30px'; + el.style.height = (ta.offsetHeight + 2) + 'px'; + el.style.overflow='hidden'; + el.style.position = 'relative'; + el.style.width = (ta.offsetWidth + 30) + 'px'; + var lineObj = document.createElement('DIV'); + lineObj.style.position = 'absolute'; + lineObj.style.top = lineObjOffsetTop + 'px'; + lineObj.style.left = '0px'; + lineObj.style.width = '27px'; + el.insertBefore(lineObj,ta); + lineObj.style.textAlign = 'right'; + lineObj.className='lineObj'; + var string = ''; + for(var no=1;no<200;no++) + { + if(string.length>0)string = string + '<br>'; + string = string + no; + } + //ta.onkeydown = function() { positionLineObj(lineObj,ta); }; + ta.onmousedown = function() { positionLineObj(lineObj,ta); }; + ta.onscroll = function() { positionLineObj(lineObj,ta); }; + ta.onblur = function() { positionLineObj(lineObj,ta); }; + ta.onfocus = function() { positionLineObj(lineObj,ta); }; + ta.onmouseover = function() { positionLineObj(lineObj,ta); }; + lineObj.innerHTML = string; +} + +function positionLineObj(obj,ta) +{ + obj.style.top = (ta.scrollTop * -1 + lineObjOffsetTop) + 'px'; +} diff --git a/testapp/static/exam/js/show_question.js b/testapp/static/exam/js/show_question.js new file mode 100644 index 0000000..e3ed1cc --- /dev/null +++ b/testapp/static/exam/js/show_question.js @@ -0,0 +1,39 @@ +function confirm_delete(frm) +{ + var n=0; + for (var i =0;i<frm.question.length;i++) + { + if (frm.question[i].checked == false) + n = n + 1 ; + } + if(n==frm.question.length) + { + alert("Please Select at least one Question"); + return false; + } + var r = confirm("Are you Sure ?"); + if(r==false) + { + for(i=0;i<frm.question.length;i++) + { + frm.question[i].checked=false; + } + return false; + } +} +function confirm_edit(frm) +{ + var n = 0; + for (var i =0;i<frm.question.length;i++) + { + if (frm.question[i].checked == false) + n = n + 1 ; + } + if(n == frm.question.length) + { + alert("Please Select at least one Question"); + return false; + } + else + return true; +} diff --git a/testapp/static/exam/js/show_quiz.js b/testapp/static/exam/js/show_quiz.js new file mode 100644 index 0000000..2e6e2de --- /dev/null +++ b/testapp/static/exam/js/show_quiz.js @@ -0,0 +1,43 @@ +function confirm_delete(frm) +{ + var n=0; + quiz = document.getElementsByName('quiz'); + for (var i =0;i<quiz.length;i++) + { + if (quiz[i].checked == false) + n = n + 1 ; + } + if(n==quiz.length) + { + alert("Please Select at least one Quiz"); + return false; + } + var r = confirm("Are you Sure ?"); + if(r==false) + { + for(i=0;i<quiz.length;i++) + { + quiz[i].checked=false; + } + return false; + } +} +function confirm_edit(frm) +{ + var n = 0; + quiz = document.getElementsByName('quiz'); + for (var i =0;i<quiz.length;i++) + { + if (quiz[i].checked == false) + n = n + 1 ; + } + if(n == quiz.length) + { + alert("Please Select at least one Question"); + return false; + } + else + return true; + + +} diff --git a/testapp/templates/base.html b/testapp/templates/base.html index c2bbabb..3dfbe10 100644 --- a/testapp/templates/base.html +++ b/testapp/templates/base.html @@ -1,25 +1,46 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> + <head> + <title> + {% block title %} + {% endblock %} + </title> + + {% block meta %} + <meta charset="utf-8"> + <meta name="description" content=""> + <meta name="author" content=""> + {% endblock %} + + <link rel="stylesheet" href="{{ URL_ROOT }}/static/exam/css/base.css" type="text/css" /> + {% block css %} + {% endblock %} -<head> -<title> -{% block title %} -{% endblock %} -</title> -{% block meta %} -{% endblock %} -<link rel="stylesheet" href="{{ URL_ROOT }}/static/exam/css/base.css" type="text/css" /> -{% block css %} -{% endblock %} -{% block script %} -{% endblock %} -</head> + {% block script %} + {% endblock %} + </head> <body {% block onload %}{% endblock %}> - <div class=box> -{% block content %} -{% endblock %} - </div> + <div class="container"> + <div class="content"> + <div class="page-header"> + <h1><Strong><center>{% block pagetitle %} {% endblock pagetitle %}</center></strong></h1> + </div> + <div class=row> + <div class=span14> + <h3><center>{% block formtitle %} {% endblock formtitle %}</center></h3><br> + {% block content %} + {% endblock %} + </div> + </div> + </div> + <footer> + <p>© FOSSEE group, IIT Bombay</p> + </footer> + </div> + </body> </html> + diff --git a/testapp/templates/exam/add_question.html b/testapp/templates/exam/add_question.html new file mode 100644 index 0000000..e3ba17a --- /dev/null +++ b/testapp/templates/exam/add_question.html @@ -0,0 +1,39 @@ +{% extends "manage.html" %} + + +{% block subtitle %}Add Question{% endblock %} + +{% block css %} +<link rel="stylesheet" href="{{ URL_ROOT }}/static/exam/css/question_quiz.css" type="text/css" /> +<link rel="stylesheet" media="all" type="text/css" href="{{ URL_ROOT }}/static/exam/css/autotaggit.css" /> +{% endblock %} + +{% block script %} +<script type="text/javascript" src="{{ URL_ROOT }}/static/exam/js/min.js"></script> +<script src="/static/taggit_autocomplete_modified/jquery.min.js" type="text/javascript"></script> +<script src="/static/taggit_autocomplete_modified/jquery.autocomplete.js" type="text/javascript"></script> +<script src="{{ URL_ROOT }}/static/exam/js/add_question.js"></script> +{% endblock %} + +{% block onload %} onload='javascript:textareaformat();' {% endblock %} + +{% block manage %} +<form action="" method="post" name=frm onSubmit="return autosubmit();"> + {% csrf_token %} + <center><table class=span1> + <tr><td>Summary: <td>{{ form.summary }}{{ form.summary.errors }} + <tr><td>Points:<td><button class="btn-mini" type="button" onClick="increase(frm);">+</button>{{ form.points }}<button class="btn-mini" type="button" onClick="decrease(frm);"">-</button>{{ form.points.errors }} Active: {{ form.active }}{{form.active.errors}} Type: {{ form.type }}{{form.type.errors}} + <tr><td><strong>Rendered: </strong><td><p id='my'></p> + <tr><td>Description: <td>{{ form.description}} {{form.description.errors}} + <tr><td>Test: <td>{{ form.test }}{{form.test.errors}} + <tr><td>Snippet: <td>{{ form.snippet }}{{ form.snippet.errors }}</td></tD></td></tr> + <tr><td>Tags: <td>{{ form.tags }} + <tr><td id='label_option'>Options: <td>{{ form.options }} {{form.options.errors}} + + + </table></center> + <center><button class="btn" type="submit" name="savequestion">Save</button> + <button class="btn" type="button" name="button" onClick='location.replace("{{URL_ROOT}}/exam/manage/questions/");'>Cancel</button> </center> +</form> +{% endblock %} + diff --git a/testapp/templates/exam/add_questionpaper.html b/testapp/templates/exam/add_questionpaper.html new file mode 100644 index 0000000..4cce8a9 --- /dev/null +++ b/testapp/templates/exam/add_questionpaper.html @@ -0,0 +1,28 @@ +{% extends "manage.html" %} + + +{% block subtitle %}Design Question Paper{% endblock %} + +{% block css %} +<link rel="stylesheet" href="{{ URL_ROOT }}/static/exam/css/question_quiz.css" type="text/css" /> +<link rel="stylesheet" media="all" type="text/css" href="{{ URL_ROOT }}/static/exam/css/autotaggit.css" /> +{% endblock %} +{% block script %} +<script src="/static/taggit_autocomplete_modified/jquery.min.js" type="text/javascript"></script> +<script src="/static/taggit_autocomplete_modified/jquery.autocomplete.js" type="text/javascript"></script> +<script src="{{ URL_ROOT }}/static/exam/js/add_questionpaper.js"></script> +{% endblock %} + +{% block manage %} +<input type=hidden id="url_root" value={{ URL_ROOT }}> +<form> +{% csrf_token %} +Select mode to design Question Paper: +<select name='mode' id='mode' onChange='javascript:load_data();'> + <option>---------</option> + <option>Automatic</option> + <option>Manual</option> +</select> +</form> + +{% endblock %} diff --git a/testapp/templates/exam/add_quiz.html b/testapp/templates/exam/add_quiz.html new file mode 100644 index 0000000..9851584 --- /dev/null +++ b/testapp/templates/exam/add_quiz.html @@ -0,0 +1,28 @@ +{% extends "manage.html" %} + + +{% block subtitle %}Add Quiz{% endblock %} + +{% block css %} +<link rel="stylesheet" href="{{ URL_ROOT }}/static/exam/css/question_quiz.css" type="text/css" /> +<link rel="stylesheet" media="all" type="text/css" href="{{ URL_ROOT }}/static/exam/css/autotaggit.css" /> +{% endblock %} +{% block script %} +<script src="/static/taggit_autocomplete_modified/jquery.min.js" type="text/javascript"></script> +<script src="/static/taggit_autocomplete_modified/jquery.autocomplete.js" type="text/javascript"></script> +<script src="{{ URL_ROOT }}/static/exam/js/add_quiz.js"></script> +{% endblock %} +{% block onload %} onload="javascript:test();" {% endblock %} +{% block manage %} +<form name=frm id=frm action="" method="post" > + {% csrf_token %} + <center> + <table class=span1> + {{ form.as_table }} + </table> + </center> + + <center><button class="btn" type="submit" id="submit" name="questionpaper">Design Question Paper</button> + <button class="btn" type="button" name="button" onClick='location.replace("{{URL_ROOT}}/exam/manage/showquiz/");'>Cancel</button> </center> +</form> +{% endblock %} diff --git a/testapp/templates/exam/automatic_questionpaper.html b/testapp/templates/exam/automatic_questionpaper.html new file mode 100644 index 0000000..1175f55 --- /dev/null +++ b/testapp/templates/exam/automatic_questionpaper.html @@ -0,0 +1,88 @@ +{% extends "manage.html" %} + + +{% block subtitle %}Design Question Paper{% endblock %} + +{% block css %} +<link rel="stylesheet" href="{{ URL_ROOT }}/static/exam/css/question_quiz.css" type="text/css" /> +<link rel="stylesheet" media="all" type="text/css" href="{{ URL_ROOT }}/static/exam/css/autotaggit.css" /> +<style> +select +{ + width:auto; +} +</style> +{% endblock %} +{% block script %} +<script src="/static/taggit_autocomplete_modified/jquery.min.js" type="text/javascript"></script> +<script src="/static/taggit_autocomplete_modified/jquery.autocomplete.js" type="text/javascript"></script> +<script src="{{ URL_ROOT }}/static/exam/js/add_questionpaper.js"></script> +{% endblock %} + +{% block manage %} +<input type=hidden id="url_root" value={{ URL_ROOT }}> +<center><b>Automatic mode to design the Question Paper</center><br> +<form action="" method="post" name=frm> + {% csrf_token %} + <center> + Tag Conditions: + <select name='first_tag'> + <option value="">Select Tag </option> + {% for tag in data.tags %} + <option value={{tag}}>{{tag}}</option> + {% endfor %} + </select> + + <select name='first_condition'> + <option value="or">OR</option> + <option value="and">AND</option> + </select> + + <select name='second_tag'> + <option value="">Select Tag </option> + {% for tag in data.tags %} + <option value={{tag}}>{{tag}}</option> + {% endfor %} + </select> + + <select name='second_condition'> + <option value="or">OR</option> + <option value="and">AND</option> + </select> + + <select name='third_tag'> + <option value="null">Select Tag </option> + {% for tag in data.tags %} + <option value={{tag}}>{{tag}}</option> + {% endfor %} + </select> + </center> + + <br> + + <center>Number of question: <input type=text id=questions name='questions' style="width:25px;"> <button class=btn type=submit name='fetch' value='fetch'>Fetch Questions</button><br></center> + + <br> + <br> + <p><b>Below is the list of Questions fetched according to the given tag conditions</p> + <hr> + <center><table class=span10> + <th>Summary + <th>Type + <th>Points + <th>Tags + {% for question in data.questions %} + <input type=hidden name='questions' value={{ question.id }} /> + <tr><td>{{ question.summary }} <td>{{ question.type }} <td>{{ question.points }} <td> + {% for tag in question.tags.all %} + {{ tag }} + {% endfor %} + </tr> + <br> + {% endfor %} + </table> + {% if data.msg %}<div class="alert alert-error">{{ data.msg }}</div>{% endif %} + <center><button class=btn type=submit name='save' value='save'>Save Question Paper</button></center> +</form> + +{% endblock %} diff --git a/testapp/templates/exam/complete.html b/testapp/templates/exam/complete.html index 4c3f3d5..1d5df3c 100644 --- a/testapp/templates/exam/complete.html +++ b/testapp/templates/exam/complete.html @@ -2,11 +2,11 @@ {% block title %}Good bye!{% endblock %} +{% block pagetitle %}Online Test{% endblock %} {% block content %} -<h2> Good bye! </h2> - -<p> {{message}} </p> -<br /> -<p>You may now close the browser.</p> - +{% csrf_token %} + <center><h2> Good bye! </h2></center> + <center><h4> {{message}} </h4></center> + <center><h4>You may now close the browser.</h4></center><br> + <center><a href="{{URL_ROOT}}/exam/"> Login Again </a></center> {% endblock content %} diff --git a/testapp/templates/exam/edit_question.html b/testapp/templates/exam/edit_question.html new file mode 100644 index 0000000..96502f1 --- /dev/null +++ b/testapp/templates/exam/edit_question.html @@ -0,0 +1,54 @@ +{% extends "manage.html" %} + +{% block subtitle %}Edit Question{% endblock %} + +{% block css %} +<link rel="stylesheet" href="{{ URL_ROOT }}/static/exam/css/question_quiz.css" type="text/css" /> +<link rel="stylesheet" media="all" type="text/css" href="{{ URL_ROOT }}/static/exam/css/autotaggit.css" /> +{% endblock %} +{% block script %} +<script src="{{ URL_ROOT }}/static/exam/js/edit_question.js"></script> +<script src="/static/taggit_autocomplete_modified/jquery.min.js" type="text/javascript"></script> +<script src="/static/taggit_autocomplete_modified/jquery.autocomplete.js" type="text/javascript"></script> +{% endblock %} + +{% block onload %} onload = 'javascript:textareaformat();' {% endblock %} + +{% block manage %} +<form name='frm' action="{{URL_ROOT}}/exam/manage/editquestion/" method="post" onSubmit="return autosubmit()" onKeyPress='javascript:render_question(frm);'> + {% csrf_token %} +<center><p>Click on the Question links to edit the question.</p></center> + +<table> + + {% for form in forms %} + + <tr><td height=10><a id='a{{forloop.counter}}' onClick="data('contentDiv{{forloop.counter}}','myContent{{forloop.counter}}','a{{forloop.counter}}','{{form.summary.value}}');" style='cursor:pointer;'>{{form.summary.value}}</a> + + <div id="contentDiv{{forloop.counter}}" style="display:none;"> + <div id="myContent{{forloop.counter}}" style="display: none;"> + + <center><table class=span1> + <tr><td><b>Summary:</b> <td>{{ form.summary }}{{ form.summary.errors }} + + <tr><td><b>Points:<td><button class="btn-mini" name={{forloop.counter}} type="button" onClick="increase(frm,{{forloop.counter}});">+</button>{{ form.points }}<button class="btn-mini" type="button" onClick="decrease(frm,{{forloop.counter}});"">-</button>{{ form.points.errors }} Active: {{ form.active }}{{form.active.errors}} Type: {{ form.type }}{{form.type.errors}} + + <tr><td><strong>Rendered: </strong><td><p id='my{{forloop.counter}}'></p> + <tr><td><b>Description: <td>{{ form.description }} {{form.description.errors}} + <tr><td><b>Test: <td>{{ form.test }}{{form.test.errors}} + <tr><td><b>Snippet: <td>{{ form.snippet }}{{ form.snippet.errors }}</td></b></td></tr> + <tr><td>Tags: <td>{{ form.tags }} + <tr><td id='label_option{{forloop.counter}}'><b>Options: <td>{{ form.options }} {{form.options.errors}} {{form.options.helptext}} + </table></center> + </div> + </div> + {% endfor %} +</table></center> +{% for i in data %} + <input type=hidden name='questions' value="{{ i }}" /> +{% endfor %} + + <center><button class="btn" type="submit" name="savequestion">Save</button> + <button class="btn" type="button" name="button" onClick='location.replace("{{URL_ROOT}}/exam/manage/questions/");'>Cancel</button> </center> +</form> +{% endblock %} diff --git a/testapp/templates/exam/edit_quiz.html b/testapp/templates/exam/edit_quiz.html new file mode 100644 index 0000000..0ea4aae --- /dev/null +++ b/testapp/templates/exam/edit_quiz.html @@ -0,0 +1,40 @@ +{% extends "manage.html" %} + + +{% block subtitle %}Edit Quiz(zes){% endblock %} + +{% block css %} +<link rel="stylesheet" href="{{ URL_ROOT }}/static/exam/css/question_quiz.css" type="text/css" /> +<link rel="stylesheet" media="all" type="text/css" href="{{ URL_ROOT }}/static/exam/css/autotaggit.css" /> +{% endblock %} + +{% block script %} +<script src="{{ URL_ROOT }}/static/exam/js/edit_quiz.js"></script> +<script src="/static/taggit_autocomplete_modified/jquery.min.js" type="text/javascript"></script> +<script src="/static/taggit_autocomplete_modified/jquery.autocomplete.js" type="text/javascript"></script> +{% endblock %} + +{% block onload %} onload = 'javascript:form_load();' {% endblock %} + +{% block manage %} +<form name=frm action="{{URL_ROOT}}/exam/manage/editquiz/" method="post"> + {% csrf_token %} + <center> + <table class=span1> + {% for form in forms %} + <tr><td><b>Start Date: <td>{{ form.start_date}} + <tr><td><b>Duration: <td> {{ form.duration }} + <tr><td><b>Active: <td> {{ form.active }} + <tr><td><b>Tags: <td> {{ form.tags }} + <tr><td><b>Description: <td> {{ form.description }} + <hr> + {% endfor %} + </table> + </center> +{% for i in data %} + <input type=hidden name='quizzes' value="{{ i }}" /> +{% endfor %} + <center><button class="btn" type="submit" name="save">Save</button> + <button class="btn" type="button" name="button" onClick='location.replace("{{URL_ROOT}}/exam/manage/showquiz/");'>Cancel</button> </center> +</form> +{% endblock %} diff --git a/testapp/templates/exam/editquestionpaper.html b/testapp/templates/exam/editquestionpaper.html new file mode 100644 index 0000000..819ff06 --- /dev/null +++ b/testapp/templates/exam/editquestionpaper.html @@ -0,0 +1,21 @@ +{% extends "manage.html" %} + + +{% block subtitle %}Questions in "{{ papers.quiz.description }}"{% endblock %} + +{% block script %} +<script src="{{ URL_ROOT }}/static/exam/js/show_question.js"></script> +{% endblock %} + +{% block manage %} +<form name=frm action="" method="post"> +{% csrf_token %} + +{% for i in papers.questions %} +<input type="checkbox" name="papers" value="{{ i.id }}"> <a href="{{URL_ROOT}}/exam/manage/addquestion/{{ i.id }}">{{ i.summary}}</a><br> +{% endfor %} +<br> +<button class="btn" type="submit" name='add' value=add>Add Question</button> +<button class="btn" type="submit" onClick="return confirm_delete(frm);" name='delete' value='delete'>Delete Selected</button> +</form> +{% endblock %} diff --git a/testapp/templates/exam/grade_user.html b/testapp/templates/exam/grade_user.html index 75ed2e0..ae9274e 100644 --- a/testapp/templates/exam/grade_user.html +++ b/testapp/templates/exam/grade_user.html @@ -1,10 +1,17 @@ -{% extends "base.html" %} +{% extends "manage.html" %} {% block title %} Grading papers for {{ data.user.get_full_name.title }} {% endblock title %} -{% block content %} +{% block subtitle %}Grading papers for {{ data.user.get_full_name.title }}{% endblock %} + +{% block css %} + <link rel="stylesheet" href="{{ URL_ROOT }}/static/exam/css/gradeuser.css" type="text/css" /> +{% endblock %} -<h1> Grading papers for {{ data.user.get_full_name.title }} </h1> +{% block script %} +<script src= "{{ URL_ROOT }}/static/exam/js/edit_question.js"></script> +{% endblock %} +{% block manage %} <p> Name: {{ data.user.get_full_name.title }} @@ -30,16 +37,26 @@ Start time: {{ paper.start_time }} <br/> </p> {% if paper.answers.count %} -<h3> Answers </h3> -<form id="q{{ paper.quiz.id }}_form" - action="{{URL_ROOT}}/exam/grade_user/{{data.user.username}}/" method="post"> +<h3> Answers </h3><br> +<form name=frm id="q{{ paper.quiz.id }}_form" + action="{{URL_ROOT}}/exam/manage/gradeuser/{{data.user.username}}/" method="post"> {% csrf_token %} {% for question, answers in paper.get_question_answers.items %} +<div class="for-question"> <p><strong> - <a href="{{URL_ROOT}}/admin/exam/question/{{question.id}}"> - Question: {{ question.id }}. {{ question.summary }} </a> - (Points: {{ question.points }})</strong> </p> + Question: {{ question.id }}. {{ question.summary }} (Points: {{ question.points }}) +</strong> +<strong><a href="" onClick="grade_data('myContent{{question.id}}'); return false;" style="cursor:pointer;" />Details</strong></p></a> +<div id="contentDiv"> + <div id="myContent{{question.id}}" style="padding:5px; display:none;"> + <p> Description : {{ question.description }} </p> + <p> Test : {{ question.test }} </p> + </div> +</div> +<div class="question-form"> + {% if question.type == "mcq" %} +<br> <p> Choices: {% for option in question.options.strip.splitlines %} {{option}}, {% endfor %} </p> @@ -54,14 +71,19 @@ Start time: {{ paper.start_time }} <br/> {% with answers|last as answer %} Marks: <input id="q{{ question.id }}" type="text" name="q{{ question.id }}_marks" size="4" - value="{{ answer.marks }}" /> + value="{{ answer.marks }}"><br><br> {% endwith %} +</div> +</div> {% endfor %} {# for question, answers ... #} + + <h3>Teacher comments: </h3> -<textarea id="comments_{{paper.quiz.id}}" rows="10" cols="80" - name="comments_{{ paper.quiz.id }}">{{ paper.comments }}</textarea> -<br/> -<input type="submit" name="submit_{{paper.quiz.id}}" value="Save marks" /> +<textarea id="comments_{{paper.question_paper.id}}" rows="10" cols="80" + name="comments_{{ paper.question_paper.id }}">{{ paper.comments }}</textarea> +<br> +<br><button class="btn" type="submit" name="submit_{{paper.quiz.id}}">Save Marks</button> + </form> {% endif %} {# if paper.answers.count #} @@ -69,15 +91,4 @@ Marks: <input id="q{{ question.id }}" type="text" {% endif %} {# if data.papers #} -{% if data.papers.count > 1 %} -<a href="{{URL_ROOT}}/exam/monitor/"> - Monitor quiz</a> -{% else %} -{% with data.papers.0 as paper %} -<a href="{{URL_ROOT}}/exam/monitor/{{paper.quiz.id}}/"> - Monitor quiz</a> -{% endwith %} -{% endif %} -<br /> -<a href="{{URL_ROOT}}/admin/">Admin</a> -{% endblock content %} +{% endblock%} diff --git a/testapp/templates/exam/intro.html b/testapp/templates/exam/intro.html index 1d3e5de..ec1888a 100644 --- a/testapp/templates/exam/intro.html +++ b/testapp/templates/exam/intro.html @@ -1,53 +1,34 @@ {% extends "base.html" %} {% block title %}Instructions and Rules {% endblock %} - +{% block pagetitle %}Online Test {% endblock %} +{% block formtitle %}Important instructions & rules {% endblock %} {% block content %} -<h2>Important rules and instructions</h2> - -<p> Welcome <strong>{{user.first_name.title}} {{user.last_name.title}}</strong>, -to the programming quiz! </p> - -<p> -This examination system has been developed with the intention of making you -learn programming and be assessed in an interactive and fun manner. -You will be presented with a series of programming questions and problems that -you will answer online and get immediate feedback for. -</p> - -<p> Here are some important instructions and rules that you should understand -carefully. -</p> - -<ul> - - <li>For any programming questions, you can submit solutions as many times as - you want without a penalty. You may skip questions and solve them later. - </li> - - <li> You <strong>may</strong> use your computer's Python/IPython shell or - an editor to solve - the problem and cut/paste the solution to the web interface. - </li> - - <li> <strong>You are <strong>not allowed</strong> to use any internet - resources, i.e. no google etc.</strong> </li> - - <li> Do not copy or share the questions or answers with anyone until the - exam is complete <strong>for everyone</strong>.</li> - - <li> <strong>All</strong> your attempts at the questions are logged. - Do not try to outsmart and break the testing system. If you do, we know - who you are and we will expell you from the course. You have been warned. - </li> - -</ul> -<p> We hope you enjoy taking this exam.</p> -<form action="{{URL_ROOT}}/exam/start/" method="post" align="center"> -{% csrf_token %} -<input type="submit" name="start" value="Start Exam!"> -</form> -{% endblock content %}
\ No newline at end of file + <p> Welcome <strong>{{user.first_name.title}} {{user.last_name.title}}</strong>, to the programming quiz! </p> + <p> + This examination system has been developed with the intention of making you + learn programming and be assessed in an interactive and fun manner. + You will be presented with a series of programming questions and problems that + you will answer online and get immediate feedback for. + </p> + <p> Here are some important instructions and rules that you should understand carefully.</p> + <ul> + <li>For any programming questions, you can submit solutions as many times as you want without a penalty. You may skip questions and solve them later. + </li> + <li> You <strong>may</strong> use your computer's Python/IPython shell or an editor to solve the problem and cut/paste the solution to the web interface. + </li> + <li> <strong>You are <strong>not allowed</strong> to use any internet resources, i.e. no google etc.</strong> </li> + <li> Do not copy or share the questions or answers with anyone until the exam is complete <strong>for everyone</strong>.</li> + <li> <strong>All</strong> your attempts at the questions are logged. Do not try to outsmart and break the testing system. If you do, we know who you are and we will expell you from the course. You have been warned. + </li> + </ul> + <p> We hope you enjoy taking this exam !!!</p> + + <form action="{{URL_ROOT}}/exam/start/{{ paper_id }}/" method="post" align="center"> + {% csrf_token %} + <center><button class="btn" type="submit" name="start">Start Exam!</button></center> + </form> +{% endblock content %} diff --git a/testapp/templates/exam/login.html b/testapp/templates/exam/login.html index 8e6352e..078e7a7 100644 --- a/testapp/templates/exam/login.html +++ b/testapp/templates/exam/login.html @@ -1,20 +1,22 @@ {% extends "base.html" %} {% block title %}Login{% endblock title %} - +{% block pagetitle %} Online Test {% endblock %} +{% block formtitle %}Login{% endblock %} +{% block css %} +<link rel="stylesheet" href="{{ URL_ROOT }}/static/exam/css/login.css" type="text/css" /> +{% endblock %} {% block content %} -<p> Welcome to the Examination. -Please login to proceed.</p> - -<form action="" method="post"> -{% csrf_token %} - -<table> -{{ form.as_table }} -</table> -<input type="submit" value="Login" /> -</form> -<!-- <a href="{{URL_ROOT}}/exam/forgotpassword/">Forgot Password</a> <br /> --> -<a href="{{URL_ROOT}}/exam/register/">New User Registration</a> -{% endblock content %}
\ No newline at end of file + <form action="" method="post"> + {% csrf_token %} + + <center><table class=span1> + {{ form.as_table }} + </table></center> + <center><button class="btn" type="submit">Login</button> <button class="btn" type="reset">Cancel</button></center> + <br><center><a href="{{URL_ROOT}}/exam/forgotpassword/">Forgot Password?</a></center><br> + <center><a href="{{URL_ROOT}}/exam/register/">New User? Sign-Up </a></center> + </form> + +{% endblock content %} diff --git a/testapp/templates/exam/manual_questionpaper.html b/testapp/templates/exam/manual_questionpaper.html new file mode 100644 index 0000000..1a1f95c --- /dev/null +++ b/testapp/templates/exam/manual_questionpaper.html @@ -0,0 +1,81 @@ +{% extends "manage.html" %} + + +{% block subtitle %}Design Question Paper{% endblock %} + +{% block css %} +<link rel="stylesheet" href="{{ URL_ROOT }}/static/exam/css/question_quiz.css" type="text/css" /> +<link rel="stylesheet" media="all" type="text/css" href="{{ URL_ROOT }}/static/exam/css/autotaggit.css" /> +<style> +select +{ + width:auto; +} +</style> +{% endblock %} +{% block script %} +<script src="/static/taggit_autocomplete_modified/jquery.min.js" type="text/javascript"></script> +<script src="/static/taggit_autocomplete_modified/jquery.autocomplete.js" type="text/javascript"></script> + +<script src="{{ URL_ROOT }}/static/exam/js/add_questionpaper.js"></script> +{% endblock %} + +{% block manage %} +<input type=hidden id="url_root" value={{ URL_ROOT }}> +<center><b>Manual mode to design the Question Paper</center><br> + +<form action="" method="post" name=frm> + {% csrf_token %} + <center> + Tag Conditions: + <select name='first_tag'> + <option value="">Select Tag </option> + {% for tag in data.tags %} + <option value={{tag}}>{{tag}}</option> + {% endfor %} + </select> + <select name='first_condition'> + <option value="or">OR</option> + <option value="and">AND</option> + </select> + <select name='second_tag'> + <option value="">Select Tag </option> + {% for tag in data.tags %} + <option value={{tag}}>{{tag}}</option> + {% endfor %} + </select> + <select name='second_condition'> + <option value="or">OR</option> + <option value="and">AND</option> + </select> + <select name='third_tag'> + <option value="null">Select Tag </option> + {% for tag in data.tags %} + <option value={{tag}}>{{tag}}</option> + {% endfor %} + </select> + </center> + <br> + <center><button class=btn type=submit name='fetch' value='fetch'>Fetch Questions</button> + <br><br><b>Below is the list of Questions fetched according to the given tag conditions</b></center> + <hr> + <center><table class=span10> + <th> + <th>Summary + <th>Type + <th>Points + <th>Tags + {% for question in data.questions %} + <tr><td><input type=checkbox name=questions value={{question.id}}> <td> {{ question.summary }} <td>{{ question.type }} <td>{{ question.points }} <td> + {% for tag in question.tags.all %} + {{ tag }} + {% endfor %} + </tr> + <br> + {% endfor %} + </table> + {% if data.msg %}<div class="alert alert-error">{{ data.msg }}</div>{% endif %} + <center><button class=btn type=submit name='save' value='save'>Save Question Paper</button></center> +</form> + +{% endblock %} diff --git a/testapp/templates/exam/monitor.html b/testapp/templates/exam/monitor.html index fb6cb58..aa8b678 100644 --- a/testapp/templates/exam/monitor.html +++ b/testapp/templates/exam/monitor.html @@ -1,26 +1,34 @@ -{% extends "base.html" %} +{% extends "manage.html" %} {% block title %} Quiz results {% endblock title %} {% block meta %} <meta http-equiv="refresh" content="30"/> {% endblock meta %} -{% block content %} - -{% if not quizzes and not quiz %} -<h1> Quiz results </h1> - -<p> No quizzes available. </p> - -{% endif %} +{% block css %} +<link rel="stylesheet" href="{{ URL_ROOT }}/static/exam/css/question_quiz.css" type="text/css" /> +{% endblock %} +{% block subtitle %} + {% if not quizzes and not quiz %} + Quiz Results + {% endif %} + {% if quizzes %} + Available Quizzes + {% endif %} + {% if quiz %} + {{ quiz.description }} Results + {% endif %} +{% endblock %} +{% block manage %} + {% if not quizzes and not quiz %} + <center><h5> No quizzes available. </h5></center> + {% endif %} {# ############################################################### #} {# This is rendered when we are just viewing exam/monitor #} {% if quizzes %} -<h1> Available quizzes </h1> - <ul> -{% for quiz in quizzes %} -<li><a href="{{URL_ROOT}}/exam/monitor/{{quiz.id}}/">{{ quiz.description }}</a></li> +{% for q in quizzes %} +<li><a href="{{URL_ROOT}}/exam/manage/monitor/{{q.id}}/">{{ q.quiz.description }}</a></li> {% endfor %} </ul> {% endif %} @@ -28,27 +36,24 @@ {# ############################################################### #} {# This is rendered when we are just viewing exam/monitor/quiz_num #} {% if quiz %} -<h1> {{ quiz.description }} results </h1> + {% if papers %} {# <p> Quiz: {{ quiz_name }}</p> #} <p>Number of papers: {{ papers|length }} </p> - <table border="1" cellpadding="3"> <tr> - <th> Name </th> - <th> Username </th> - <th> Roll number </th> - <th> Institute </th> - <th> Questions answered </th> - <th> Total marks </th> - <th> Attempts </th> + <th> Name </th> + <th> Username </th> + <th> Roll number </th> + <th> Institute </th> + <th> Questions answered </th> + <th> Total marks </th> + <th> Attempts </th> </tr> {% for paper in papers %} <tr> - <td> <a href="{{URL_ROOT}}/exam/user_data/{{paper.user.username}}"> - {{ paper.user.get_full_name.title }}</a> </td> - <td> <a href="{{URL_ROOT}}/exam/user_data/{{paper.user.username}}"> - {{ paper.user.username }}</a> </td> + <td> <a href="{{URL_ROOT}}/exam/manage/user_data/{{paper.user.username}}">{{ paper.user.get_full_name.title }}</a> </td> + <td> <a href="{{URL_ROOT}}/exam/manage/user_data/{{paper.user.username}}">{{ paper.user.username }}</a> </td> <td> {{ paper.profile.roll_number }} </td> <td> {{ paper.profile.institute }} </td> <td> {{ paper.get_answered_str }} </td> @@ -61,7 +66,4 @@ <p> No answer papers so far. </p> {% endif %} {# if papers #} {% endif %} - -<a href="{{URL_ROOT}}/admin/">Admin</a> - -{% endblock content %} +{% endblock %} diff --git a/testapp/templates/exam/question.html b/testapp/templates/exam/question.html index 8b589b6..4f65b64 100644 --- a/testapp/templates/exam/question.html +++ b/testapp/templates/exam/question.html @@ -1,23 +1,19 @@ {% extends "base.html" %} +<!DOCTYPE html> + {% block title %} Answer question {% endblock %} -{% block script %} -<script type="text/javascript"> -<!-- -var time_left = {{ time_left }}; +{% block css %} +<link rel="stylesheet" href="{{ URL_ROOT }}/static/exam/css/question.css" type="text/css" /> -function submitCode() -{ - document.forms["code"].submit(); - var x = document.getElementById("status"); - x.innerHTML = "<strong>Checking answer ...</strong>"; - x = document.getElementById("check"); - x.disabled = true; - x.value = "Checking Answer ..."; - document.getElementById("skip").disabled = true; -} +{% endblock %} +{% block script %} +<script src="{{ URL_ROOT }}/static/exam/js/question.js"></script> + +<script> +var time_left = {{ time_left }} function secs_to_time(secs) { var h = Math.floor(secs/3600); @@ -31,61 +27,81 @@ function secs_to_time(secs) function update_time() { time_left -= 1; - if (time_left) { - var elem = document.getElementById("time_left"); - var t_str = secs_to_time(time_left); - elem.innerHTML = "<strong> Time left: " + t_str + "</strong>"; - setTimeout("update_time()", 1000); - } - else { - document.forms["code"].submit(); + if (time_left) + { + var elem = document.getElementById("time_left"); + var t_str = secs_to_time(time_left); + elem.innerHTML = "<strong>" + t_str + "</strong>"; + setTimeout("update_time()", 1000); } + else + { + document.forms["code"].submit(); + } } -//--> </script> {% endblock script %} + + {% block onload %} onload="update_time()" {% endblock %} +{% block pagetitle %} + +<table><h6><div> + <tr><td class=td1-class><h5>You have {{ paper.questions_left }} question(s) left in {{ quiz_name }} </h5> + <td class=td2-class><div class=time-div id="time_left"> + </div> +</div></h6></table> + +{% endblock %} + {% block content %} -<h3> {{ question.summary }} </h3> - -<p>{{ question.description|safe }} -<br/> -(Marks: {{ question.points }}) </p> - -{% if error_message %}<p><strong>ERROR:</strong></p><pre>{{ error_message }}</pre>{% endif %} - -<p id="status"></p> - -<form id="code" action="{{URL_ROOT}}/exam/{{ question.id }}/check/" method="post"> -{% csrf_token %} -{% if question.type == "mcq" %} -{% for option in question.options.strip.splitlines %} -<input name="answer" type="radio" value="{{option}}" />{{option}} <br/> -{% endfor %} -{% else %} -<textarea rows="20" cols="100" name="answer">{% if last_attempt %}{{last_attempt.strip}}{% else %}{% if question.type == "bash" %}#!/bin/bash{% else %}# Enter your answer here.{% endif %}{% endif %}</textarea> -{% endif %} -<br/> -{% if question.type == "mcq" %} -<input id="check" type="submit" name="check" value="Submit answer"/> -{% else %} -<input id="check" type="submit" name="check" value="Check Answer" -onclick="submitCode();"/> -{% endif %} -<input id="skip" type="submit" name="skip" value="Skip question" /> -</form> - -<p> {{ user.first_name.title }} {{ user.last_name.title }}, -you have {{ paper.questions_left }} question(s) left in {{ quiz_name }}.</p> - -<p id="time_left"> <strong> Time left: </strong> </p> - -<hr/> -<form id="logout" action="{{URL_ROOT}}/exam/quit/" method="post"> -{% csrf_token %} -<input type="submit" name="quit" value="Quit exam and logout" /> -</form> +<div class="topbar"> + <div class="fill"> + <div class="container"> + <h3 class="brand"><strong>Online Test</h3></strong> + <ul> + <li> <h5><a> Hi {{user.first_name.title}} {{user.last_name.title}} </a></h5> + </ul> + <form id="logout" action="{{URL_ROOT}}/exam/quit/{{ paper.question_paper.id }}/" method="post" class="pull-right"> + {% csrf_token %} + <button class="btn" type="submit" name="quit">Quit Exam</button> </li> + + </form> + </div> + </div> +</div> + + + <h4><u> {{ question.summary }} </u><font class=pull-right>(Marks : {{ question.points }}) </font></h4><br> + <font size=3 face=arial> {{ question.description|safe }} </font> + + {% if error_message %}<h5>ERROR:</h5><div class="alert alert-error">{{ error_message }}</div>{% endif %} + <p id="status"></p> + <form id="code" action="{{URL_ROOT}}/exam/{{ question.id }}/check/{{ paper.question_paper.id }}/" method="post"> + {% csrf_token %} + {% if question.type == "mcq" %} + {% for option in question.options.strip.splitlines %} + <input name="answer" type="radio" value="{{option}}" />{{option}} <br/> + {% endfor %} + {% else %} + + <textarea tabindex=1 rows="15" style="width:750px;margin-bottom:10px;" name="answer" id="answer" wrap="off" onkeydown="return catchTab(this,event)">{% if last_attempt %}{{last_attempt.strip}}{% else %}{% if question.type == "bash" %} #!/bin/bash{% else %}{{ question.snippet }}{% endif %}{% endif %}</textarea> +<br> + + <script type="text/javascript"> + createTextAreaWithLines('answer'); + </script> + {% endif %} + {% if question.type == "mcq" %} + <br><button class="btn" type="submit" name="check" id="check">Submit Answer</button> + {% else %} + <button class="btn" type="submit" name="check" id="check" onClick="submitCode();">Check Answer</button> + {% endif %} + <button class="btn" type="submit" name="skip" id="skip">Skip Question</button> + </form> + + {% endblock content %} diff --git a/testapp/templates/exam/quit.html b/testapp/templates/exam/quit.html index 37b5c08..fee11ed 100644 --- a/testapp/templates/exam/quit.html +++ b/testapp/templates/exam/quit.html @@ -1,14 +1,14 @@ {% extends "base.html" %} {% block title %}Quit exam {% endblock %} - +{% block pagetitle %}Online Test {% endblock %} {% block content %} -<p>Your current answers are saved.</p> -<p> Are you sure you wish to quit the exam?</p> -<form action="{{URL_ROOT}}/exam/complete/" method="post"> -{% csrf_token %} -<input type="submit" name="yes" value="Yes!" /> -<input type="submit" name="no" value="No!" /> -</form> -{% endblock content %}
\ No newline at end of file + <center><h4>Your current answers are saved.</h4></center> + <center><h4> Are you sure you wish to quit the exam?</h4></center> + <center><h4> Be sure, as you won't be able to restart this exam.</h4></center> + <form action="{{URL_ROOT}}/exam/complete/{{ id }}/" method="post"> + {% csrf_token %} + <center><button class="btn" type="submit" name="yes">Yes!</button> <button class="btn" type="button" name="no" onClick="window.location='{{ URL_ROOT }}/exam/start/{{ id }}/'">No!</button></center> + </form> +{% endblock content %} diff --git a/testapp/templates/exam/quizlist.html b/testapp/templates/exam/quizlist.html new file mode 100644 index 0000000..9b1fd73 --- /dev/null +++ b/testapp/templates/exam/quizlist.html @@ -0,0 +1,24 @@ +{% extends "base.html" %} + +{% block title %} Quiz List {% endblock title %} + +{% block formtitle %} Quiz List {% endblock %} + +{% block pagetitle %} Online Test {% endblock %} + +{% block content %} +{% if not quizzes and not quiz %} +<center><h5> No quizzes available. </h5></center> +{% endif %} + +{% if quizzes %} +<form method="post" action="" name='frm'> +{% csrf_token %} + +{% for quiz in quizzes %} +<a href="{{URL_ROOT}}/exam/start/{{quiz.id}}/">{{ quiz.description }}</a><br> +{% endfor %} +</form> +{% endif %} + +{% endblock %} diff --git a/testapp/templates/exam/quizzes_user.html b/testapp/templates/exam/quizzes_user.html new file mode 100644 index 0000000..af2d98a --- /dev/null +++ b/testapp/templates/exam/quizzes_user.html @@ -0,0 +1,18 @@ +{% extends "user.html" %} + + +{% block subtitle %}Available Quizzes{% endblock %} + +{% block css %} +<link rel="stylesheet" href="{{ URL_ROOT }}/static/exam/css/question_quiz.css" type="text/css" /> +{% endblock %} + +{% block manage %} + {% if not quizzes %} + <center><h4>No active quizzes for you</h4></center> + {% endif %} + {% for paper in quizzes %} + <a href="{{ URL_ROOT }}/exam/start/{{paper.id}}">{{ paper.quiz.description }}</a><br> + {% endfor %} +{% endblock %} + diff --git a/testapp/templates/exam/register.html b/testapp/templates/exam/register.html index 921e7b5..5ff79cc 100644 --- a/testapp/templates/exam/register.html +++ b/testapp/templates/exam/register.html @@ -2,16 +2,19 @@ {% block title %}Registration form {% endblock %} +{% block pagetitle %}Online Test {% endblock %} +{% block formtitle %}Please fill in the following details {% endblock %} + {% block content %} -Please provide the following details. -<form action="" method="post"> -{% csrf_token %} -<table> -{{ form.as_table }} -</table> -<input type="submit" value="Register" /> + +<form action="" method="post"> + {% csrf_token %} + <center><table class=span1> + {{ form.as_table }} + </table></center> + <center><button class="btn" type="submit">Register</button> <button class="btn" type="reset">Cancel</button></center> </form> -{% endblock content %}
\ No newline at end of file +{% endblock content %} diff --git a/testapp/templates/exam/results_user.html b/testapp/templates/exam/results_user.html new file mode 100644 index 0000000..bf847c0 --- /dev/null +++ b/testapp/templates/exam/results_user.html @@ -0,0 +1,26 @@ +{% extends "user.html" %} + + +{% block subtitle %}Results{% endblock %} + +{% block css %} +<link rel="stylesheet" href="{{ URL_ROOT }}/static/exam/css/question_quiz.css" type="text/css" /> +{% endblock %} + +{% block manage %} +<form action="" method="post" name=frm> + {% csrf_token %} + <center><table class="span6"> + <th>Quiz Description + <th>Obtained Marks + {% for paper in papers %} + <tr> + {% for i in paper %} + <td>{{ i }} + {% endfor %} + <br> + {% endfor %} + </table></center> +</form> +{% endblock %} + diff --git a/testapp/templates/exam/show_quiz.html b/testapp/templates/exam/show_quiz.html new file mode 100644 index 0000000..886a696 --- /dev/null +++ b/testapp/templates/exam/show_quiz.html @@ -0,0 +1,32 @@ +{% extends "manage.html" %} + +{% block title %} Quiz List {% endblock title %} + +{% block script %} +<script src="{{ URL_ROOT }}/static/exam/js/show_quiz.js"></script> +{% endblock %} + +{% block subtitle %} Quiz List {% endblock %} +{% block manage %} +{% if not quizzes and not quiz %} +<center><h5> No quizzes available. </h5></center> +{% endif %} + +{# ############################################################### #} +{# This is rendered when we are just viewing exam/monitor #} +{% if quizzes %} +<form method="post" action="" name='frm'> +{% csrf_token %} + +{% for quiz in quizzes %} +<input type=checkbox name='quiz' value={{quiz.id}} /> <a href="{{URL_ROOT}}/exam/manage/addquiz/{{quiz.id}}/">{{ quiz.description }}</a><br> +{% endfor %} + +<br><br> +<button class="btn" type="button" onClick='location.replace("{{URL_ROOT}}/exam/manage/addquiz");'>Add New Quiz</button> +<button class="btn" type="submit" name='edit' value='edit' onClick="return confirm_edit(frm);" >Edit Selected</button> +<button class="btn" type="submit" name="delete" value='delete' onClick="return confirm_delete(frm);">Delete Selected</button> +</form> +{% endif %} + +{% endblock %} diff --git a/testapp/templates/exam/showquestionpapers.html b/testapp/templates/exam/showquestionpapers.html new file mode 100644 index 0000000..26b756d --- /dev/null +++ b/testapp/templates/exam/showquestionpapers.html @@ -0,0 +1,19 @@ +{% extends "manage.html" %} + + +{% block subtitle %}List of Question Papers {% endblock %} + +{% block script %} +<script src="{{ URL_ROOT }}/static/exam/js/show_question.js"></script> +{% endblock %} + +{% block manage %} +<form name=frm action="" method="post"> +{% csrf_token %} +{% for i in papers %} +<input type="checkbox" name="papers" value="{{ i.id }}"> <a href="{{URL_ROOT}}/exam/manage/showquestionpapers/{{ i.id }}">{{ i.quiz.description }}</a><br> +{% endfor %} +<br> +<button class="btn" type="submit" onClick="return confirm_delete(frm);" name='delete' value='delete'>Delete Selected</button> +</form> +{% endblock %} diff --git a/testapp/templates/exam/showquestions.html b/testapp/templates/exam/showquestions.html new file mode 100644 index 0000000..62b40e4 --- /dev/null +++ b/testapp/templates/exam/showquestions.html @@ -0,0 +1,21 @@ +{% extends "manage.html" %} + + +{% block subtitle %}List of Questions {% endblock %} + +{% block script %} +<script src="{{ URL_ROOT }}/static/exam/js/show_question.js"></script> +{% endblock %} + +{% block manage %} +<form name=frm action="" method="post"> +{% csrf_token %} +{% for i in questions %} +<input type="checkbox" name="question" value="{{ i.id }}"> <a href="{{URL_ROOT}}/exam/manage/addquestion/{{ i.id }}">{{ i }}</a><br> +{% endfor %} +<br> +<button class="btn" type="button" onclick='location.replace("{{URL_ROOT}}/exam/manage/addquestion/");'>Add Question</button> +<button class="btn" type="submit" name='edit' value='edit' onClick="return confirm_edit(frm);">Edit Selected</button> +<button class="btn" type="submit" onClick="return confirm_delete(frm);" name='delete' value='delete'>Delete Selected</button> +</form> +{% endblock %} diff --git a/testapp/templates/exam/showusers.html b/testapp/templates/exam/showusers.html new file mode 100644 index 0000000..01ecc37 --- /dev/null +++ b/testapp/templates/exam/showusers.html @@ -0,0 +1,26 @@ +{% extends "manage.html" %} + + +{% block subtitle %} +List of Users +{% endblock %} + +{% block css %} +<link rel="stylesheet" href="{{ URL_ROOT }}/static/exam/css/showusers.css" type="text/css" /> +{% endblock css %} + + +{% block manage %} +<center><table style="text-align:left;" class=table-class border=3> +<th>Username +<th>First Name +<th>Last Name +<th>Quiz Description +{% for papers in question %} +<tr><td><a href="{{URL_ROOT}}/exam/manage/gradeuser/{{ papers.user.username }}">{{ papers.user.username }}</a><br> + <td >{{ papers.user.first_name.title }} + <td>{{ papers.user.last_name.title }} + <td>{{ papers.question_paper.quiz.description }} +{% endfor %} +</table></center> +{% endblock %} diff --git a/testapp/templates/exam/user_data.html b/testapp/templates/exam/user_data.html index 9fb442a..61a3a97 100644 --- a/testapp/templates/exam/user_data.html +++ b/testapp/templates/exam/user_data.html @@ -1,11 +1,11 @@ -{% extends "base.html" %} +{% extends "manage.html" %} {% block title %} Data for user {{ data.user.get_full_name.title }} {% endblock title %} -{% block content %} - -<h1> Data for user {{ data.user.get_full_name.title }} </h1> +{% block manage %} +{% block subtitle %}Data for user {{ data.user.get_full_name.title }}{% endblock %} +<form action="" method="post"> <p> Name: {{ data.user.get_full_name.title }} <br/> Username: {{ data.user.username }} <br/> @@ -21,7 +21,7 @@ Last login: {{ data.user.last_login }} </p> {% if data.papers %} -<p><a href="{{URL_ROOT}}/exam/grade_user/{{ data.user.username }}/"> +<p><a href="{{URL_ROOT}}/exam/manage/gradeuser/{{ data.user.username }}/"> Grade/correct paper</a> </p> @@ -66,19 +66,15 @@ User IP address: {{ paper.user_ip }} {% endif %} {# if data.papers #} <br /> <hr /> -<a href="{{URL_ROOT}}/exam/grade_user/{{ data.user.username }}/"> +<a href="{{URL_ROOT}}/exam/manage/gradeuser/{{ data.user.username }}/"> Grade/correct paper</a> <br/> {% if data.papers.count > 1 %} -<a href="{{URL_ROOT}}/exam/monitor/"> - Monitor quiz</a> +<a href="{{URL_ROOT}}/exam/manage/monitor/">Monitor quiz</a> {% else %} {% with data.papers.0 as paper %} -<a href="{{URL_ROOT}}/exam/monitor/{{paper.quiz.id}}/"> - Monitor quiz</a> +<a href="{{URL_ROOT}}/exam/manage/monitor/{{paper.quiz.id}}/">Monitor quiz</a> {% endwith %} {% endif %} -<br /> -<a href="{{URL_ROOT}}/admin/">Admin</a> -{% endblock content %} +{% endblock %} diff --git a/testapp/templates/manage.html b/testapp/templates/manage.html new file mode 100644 index 0000000..0f122b0 --- /dev/null +++ b/testapp/templates/manage.html @@ -0,0 +1,61 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> + <head> + <title> + {% block title %} + {% endblock %} + </title> + + {% block meta %} + <meta charset="utf-8"> + <meta name="description" content=""> + <meta name="author" content=""> + {% endblock %} + + <link rel="stylesheet" href="{{ URL_ROOT }}/static/exam/css/base.css" type="text/css" /> + {% block css %} + {% endblock %} + + {% block script %} + {% endblock %} + </head> + +<body {% block onload %}{% endblock %}> +<div class="topbar"> + <div class="fill"> + <div class="container"> + <h3 class="brand"><strong>Online Test</h3></strong> + <ul> + <li><a href="{{ URL_ROOT }}/exam/manage/questions">Questions</a></li> + <li><a href="{{ URL_ROOT }}/exam/manage/showquiz">Quizzes</a></li> + <li><a href="{{ URL_ROOT }}/exam/manage/showquestionpapers">Question Papers</a></li> + <li><a href="{{ URL_ROOT }}/exam/manage/gradeuser">Grade User</a></li> + <li><a href="{{ URL_ROOT }}/exam/manage/monitor">Monitor</a></li> + </ul> + <ul style="float:right;"> + <li><strong><a style='cursor:pointer' onClick='location.replace("{{URL_ROOT}}/exam/complete/");'>Log out</a></strong></li> + </ul> + </div> + </div> +</div> + <div class="container"> + <div class="content"> + <div class="page-header"> + <h3><center>{% block subtitle %}Welcome {{ user.first_name.title }} {{user.last_name.title}} {% endblock %}</center></h3><br> + </div> + <div class=row> + <div class=span14> + {% block manage %} + {% endblock %} + </div> + </div> + </div> + <footer> + <p>© FOSSEE group, IIT Bombay</p> + </footer> + </div> + +</body> +</html> diff --git a/testapp/templates/user.html b/testapp/templates/user.html new file mode 100644 index 0000000..22a9fac --- /dev/null +++ b/testapp/templates/user.html @@ -0,0 +1,58 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> + <head> + <title> + {% block title %} + {% endblock %} + </title> + + {% block meta %} + <meta charset="utf-8"> + <meta name="description" content=""> + <meta name="author" content=""> + {% endblock %} + + <link rel="stylesheet" href="{{ URL_ROOT }}/static/exam/css/base.css" type="text/css" /> + {% block css %} + {% endblock %} + + {% block script %} + {% endblock %} + </head> + +<body {% block onload %}{% endblock %}> +<div class="topbar"> + <div class="fill"> + <div class="container"> + <h3 class="brand"><strong>Online Test</h3></strong> + <ul> + <li><a href="{{ URL_ROOT }}/exam/quizzes">Quizzes</a></li> + <li><a href="{{ URL_ROOT }}/exam/results">Results</a></li> + </ul> + <ul style="float:right;"> + <li><strong><a style='cursor:pointer' onClick='location.replace("{{URL_ROOT}}/exam/complete/");'>Log out</a></strong></li> + </ul> + </div> + </div> +</div> + <div class="container"> + <div class="content"> + <div class="page-header"> + <h3><center>{% block subtitle %}Welcome {{ user.first_name.title }} {{user.last_name.title}} {% endblock %}</center></h3><br> + </div> + <div class=row> + <div class=span14> + {% block manage %} + {% endblock %} + </div> + </div> + </div> + <footer> + <p>© FOSSEE group, IIT Bombay</p> + </footer> + </div> + +</body> +</html> diff --git a/testapp/test_server.py b/testapp/test_server.py index be9f876..0790816 100644 --- a/testapp/test_server.py +++ b/testapp/test_server.py @@ -80,4 +80,4 @@ def test_bash(): if __name__ == '__main__': test_python() test_bash() - + test_c() diff --git a/testapp/urls.py b/testapp/urls.py index d956bfc..c82ecb6 100644 --- a/testapp/urls.py +++ b/testapp/urls.py @@ -15,9 +15,15 @@ else: urlpatterns = patterns('', url(URL_BASE, include('exam.urls')), - + #url(r'^admin/', include(admin.site.urls)), # Uncomment the admin/doc line below to enable admin documentation: # url(r'^admin/doc/', include('django.contrib.admindocs.urls')), # Uncomment the next line to enable the admin: url(ADMIN_BASE, include(admin.site.urls)), + +) + +urlpatterns += patterns('', + url(r'^taggit_autocomplete_modified/', include\ + ('taggit_autocomplete_modified.urls')), ) |