commit e49f36eb14d3baf3e52b7ad632d1c0de5a6cf772 Author: fergal.moran Date: Thu Aug 9 11:02:18 2012 +0100 Initial commit after change to backbone/SPA diff --git a/README b/README new file mode 100644 index 0000000..56b130c --- /dev/null +++ b/README @@ -0,0 +1 @@ +Deep 'n Corky like.. diff --git a/core/__init__.py b/core/__init__.py new file mode 100644 index 0000000..8133f5e --- /dev/null +++ b/core/__init__.py @@ -0,0 +1 @@ +__author__ = 'fergalm' diff --git a/core/decorators.py b/core/decorators.py new file mode 100644 index 0000000..e803e25 --- /dev/null +++ b/core/decorators.py @@ -0,0 +1,26 @@ +from decorator import decorator +from django.http import HttpResponseRedirect +from django.shortcuts import render_to_response +from django.template.context import RequestContext + +@decorator +def render_template(func, *args, **kwargs): + """ + using example: + @render_template + def view(request, template='abc.html'): + slot = "this is a slot" + return template, {'slot' : slot} + """ + request = args[0] + _call = func(*args, **kwargs) + + if isinstance(_call, HttpResponseRedirect): + return _call + + if isinstance(_call, tuple): + template, context = _call + else: + template, context = _call, {} + + return render_to_response(template, context_instance=RequestContext(request, context)) diff --git a/core/tasks/__init__.py b/core/tasks/__init__.py new file mode 100644 index 0000000..8133f5e --- /dev/null +++ b/core/tasks/__init__.py @@ -0,0 +1 @@ +__author__ = 'fergalm' diff --git a/core/tasks/waveform.py b/core/tasks/waveform.py new file mode 100644 index 0000000..9696b7a --- /dev/null +++ b/core/tasks/waveform.py @@ -0,0 +1,8 @@ +from celery.task import task +from core.utils.waveform import generate_waveform + +@task(name='dss.create_waveform_task') +def create_waveform_task(in_file, out_file): + generate_waveform(in_file, out_file) + + diff --git a/core/utils/__init__.py b/core/utils/__init__.py new file mode 100644 index 0000000..8133f5e --- /dev/null +++ b/core/utils/__init__.py @@ -0,0 +1 @@ +__author__ = 'fergalm' diff --git a/core/utils/file.py b/core/utils/file.py new file mode 100644 index 0000000..f697da8 --- /dev/null +++ b/core/utils/file.py @@ -0,0 +1,5 @@ +import uuid + +__author__ = 'fergalm' +def generate_save_file_name(prefix, filename): + return '/'.join([prefix, str(uuid.uuid1()), filename]) diff --git a/core/utils/html.py b/core/utils/html.py new file mode 100644 index 0000000..2bf8848 --- /dev/null +++ b/core/utils/html.py @@ -0,0 +1,18 @@ +from HTMLParser import HTMLParser + +class HTMLStripper(HTMLParser): + """ + Class that cleans HTML, removing all tags and HTML entities. + """ + def __init__(self): + self.reset() + self.fed = [] + def handle_data(self, d): + self.fed.append(d) + def get_data(self): + return ''.join(self.fed) + def strip(self, d): + self.reset() + self.fed = [] + self.feed(d) + return self.get_data().strip() \ No newline at end of file diff --git a/core/utils/live.py b/core/utils/live.py new file mode 100644 index 0000000..e30d485 --- /dev/null +++ b/core/utils/live.py @@ -0,0 +1,35 @@ +import urllib2 +from bs4 import BeautifulSoup + +def get_server_details(server, port, mount): + server = "http://%s:%s/status.xsl?mount=/%s" % (server, port, mount) + print "Getting info for %s" % (server) + try: + response = urllib2.urlopen(server) + html = response.read() + if html: + soup = BeautifulSoup(html) + + info = {} + info['stream_title'] = soup.find(text="Stream Title:").findNext('td').contents[0] + info['stream_description'] = soup.find(text="Stream Description:").findNext('td').contents[0] + info['content_type'] = soup.find(text="Content Type:").findNext('td').contents[0] + info['mount_started'] = soup.find(text="Mount started:").findNext('td').contents[0] + info['quality'] = soup.find(text="Quality:").findNext('td').contents[0] + info['current_listeners'] = soup.find(text="Current Listeners:").findNext('td').contents[0] + info['peak_listeners'] = soup.find(text="Peak Listeners:").findNext('td').contents[0] + info['stream_genre'] = soup.find(text="Stream Genre:").findNext('td').contents[0] + info['stream_url'] = soup.find(text="Stream URL:").findNext('td').findNext('a').contents[0] + info['current_song'] = soup.find(text="Current Song:").findNext('td').contents[0] + + return info + else: + print "Invalid content found" + return None + + except urllib2.URLError: + print "Unable to read url, please check your parameters" + return None + +def get_now_playing(server, port, mount): + return get_server_details(server, port, mount)['current_song'] \ No newline at end of file diff --git a/core/utils/waveform.py b/core/utils/waveform.py new file mode 100644 index 0000000..b00b65f --- /dev/null +++ b/core/utils/waveform.py @@ -0,0 +1,36 @@ +import subprocess +import traceback +import uuid +import os +from dss import settings + +__author__ = 'fergalm' + +def generate_waveform(input_file, output_file): + print "Generating waveform" + try: + working_file = "%s%s.wav" % (settings.DSS_TEMP_PATH, uuid.uuid1()) + try: + print "Starting decode : %s\nInput File: %s\nOutput File: %s" % (settings.DSS_LAME_PATH, input_file, working_file) + p = subprocess.call([settings.DSS_LAME_PATH, "--decode", input_file, working_file]) + print "Finished decode" + if os.path.exists(working_file): + print "Starting waveform generation" + print "%s -m -l -i %s -o -b 000000 %s" % (settings.DSS_WAVE_PATH, working_file, output_file) + subprocess.call([settings.DSS_WAVE_PATH, "-t", "-m", "-l", "-i", working_file, "-o", output_file]) + + if os.path.isfile(output_file): + os.remove(working_file) + print "Generated waveform" + return output_file + else: + print "Failed generating waveform: %s" % output_file + else: + print "Unable to find working file, did LAME succeed?" + return "" + except Exception, ex: + print "Error generating waveform %s" % (ex) + + except: + print "Error generating waveform" + traceback.print_exc() diff --git a/dss/__init__.py b/dss/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dss/settings.py b/dss/settings.py new file mode 100644 index 0000000..2a5592f --- /dev/null +++ b/dss/settings.py @@ -0,0 +1,161 @@ +# Django settings for dss project. +from datetime import timedelta +from django.core.urlresolvers import reverse_lazy +import djcelery +import os +from utils import here +from django.conf import global_settings + +DEBUG = True +TEMPLATE_DEBUG = DEBUG + +ADMINS = ( +# ('Your Name', 'your_email@example.com'), +) + +MANAGERS = ADMINS +AUTH_PROFILE_MODULE = 'spa.UserProfile' + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': 'deepsouthsounds', + 'USER': 'deepsouthsounds', + 'PASSWORD': '', + 'HOST': '', + 'PORT': '', + } +} +ROOT_URLCONF = 'dss.urls' +TIME_ZONE = 'America/Chicago' +LANGUAGE_CODE = 'en-us' +SITE_ID = 1 +USE_I18N = False +USE_L10N = True +USE_TZ = False + +SITE_ROOT = here('') +MEDIA_ROOT = here('media') +MEDIA_URL = '/media/' + +STATIC_ROOT = '' +STATIC_URL = '/static/' + +STATICFILES_DIRS = ( + here('static'), + ) + +STATICFILES_FINDERS = ( + 'django.contrib.staticfiles.finders.FileSystemFinder', + 'django.contrib.staticfiles.finders.AppDirectoriesFinder', + ) + +SECRET_KEY = '8*&j)j4lnq*ft*=jhajvc7&upaifb2f2s5(v6i($$+3p(4^bvd' + +TEMPLATE_LOADERS = ( + 'django.template.loaders.filesystem.Loader', + 'django.template.loaders.app_directories.Loader', + 'django.template.loaders.eggs.Loader', + #'django.template.loaders.app_directories.load_template_source', + ) +TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + ( + 'django.core.context_processors.request', + 'django.contrib.auth.context_processors.auth', + "allauth.socialaccount.context_processors.socialaccount", + "allauth.account.context_processors.account" + ) +AUTHENTICATION_BACKENDS = global_settings.AUTHENTICATION_BACKENDS + ( + "allauth.account.auth_backends.AuthenticationBackend", + ) + +MIDDLEWARE_CLASSES = ( + 'django.middleware.common.CommonMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', + ) + +WSGI_APPLICATION = 'dss.wsgi.application' +TEMPLATE_DIRS = (here('templates'),) +INSTALLED_APPS = ( + 'grappelli', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.sites', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'django.contrib.admin', + 'django.contrib.admindocs', + 'djcelery', + 'avatar', + 'notification', + 'spa', + 'allauth', + 'allauth.account', + 'allauth.socialaccount', + 'allauth.socialaccount.providers.facebook', + 'allauth.socialaccount.providers.google', + 'allauth.socialaccount.providers.github', + 'allauth.socialaccount.providers.linkedin', + 'allauth.socialaccount.providers.openid', + 'allauth.socialaccount.providers.twitter', + 'emailconfirmation', + 'backbone_tastypie', + ) + +# where to redirect users to after logging in +LOGIN_REDIRECT_URL = reverse_lazy('home') +LOGOUT_URL = reverse_lazy('home') + +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'filters': { + 'require_debug_false': { + '()': 'django.utils.log.RequireDebugFalse' + } + }, + 'handlers': { + 'mail_admins': { + 'level': 'ERROR', + 'filters': ['require_debug_false'], + 'class': 'django.utils.log.AdminEmailHandler' + } + }, + 'loggers': { + 'django.request': { + 'handlers': ['mail_admins'], + 'level': 'ERROR', + 'propagate': True, + }, + } +} + +BROKER_HOST = "127.0.0.1" +BROKER_PORT = 5672 +BROKER_VHOST = "/" +BROKER_USER = "guest" +BROKER_PASSWORD = "guest" +CELERYBEAT_SCHEDULE = { + "runs-every-30-seconds": { + "task": "dss.generate_missing_waveforms_task", + "schedule": timedelta(seconds=30), + }, + } +djcelery.setup_loader() + +SOCIALACCOUNT_AVATAR_SUPPORT = True +AVATAR_STORAGE_DIR = MEDIA_ROOT + 'avatars/' + +if os.name == 'posix': + DSS_TEMP_PATH = "/tmp/" + DSS_LAME_PATH = "/usr/bin/lame" + DSS_WAVE_PATH = "/usr/local/bin/waveformgen" +else: + DSS_TEMP_PATH = "d:\\temp\\" + DSS_LAME_PATH = "D:\\Apps\\lame\\lame.exe" + DSS_WAVE_PATH = "d:\\Apps\\waveformgen.exe" \ No newline at end of file diff --git a/dss/urls.py b/dss/urls.py new file mode 100644 index 0000000..4d08f75 --- /dev/null +++ b/dss/urls.py @@ -0,0 +1,30 @@ +from django.conf.urls import patterns, include, url +from django.contrib import admin +from dss import settings + +admin.autodiscover() + +# Uncomment the next two lines to enable the admin: +# from django.contrib import admin +# admin.autodiscover() + +urlpatterns = patterns('', + url(r'^admin/', include(admin.site.urls)), + (r'^favicon\.ico$', 'django.views.generic.simple.redirect_to', {'url': '/static/img/favicon.ico'}), + url(r'^', include('spa.urls')), + (r'^grappelli/', include('grappelli.urls')), + url(r'^accounts/', include('allauth.urls')), + (r'^avatar/', include('avatar.urls')), +) + +if settings.DEBUG: + from django.views.static import serve + + _media_url = settings.MEDIA_URL + if _media_url.startswith('/'): + _media_url = _media_url[1:] + urlpatterns += patterns('', + (r'^%s(?P.*)$' % _media_url, + serve, + {'document_root': settings.MEDIA_ROOT})) + del(_media_url, serve) \ No newline at end of file diff --git a/dss/wsgi.py b/dss/wsgi.py new file mode 100644 index 0000000..8765705 --- /dev/null +++ b/dss/wsgi.py @@ -0,0 +1,28 @@ +""" +WSGI config for dss project. + +This module contains the WSGI application used by Django's development server +and any production WSGI deployments. It should expose a module-level variable +named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover +this application via the ``WSGI_APPLICATION`` setting. + +Usually you will have the standard Django WSGI application here, but it also +might make sense to replace the whole Django WSGI application with a custom one +that later delegates to the Django one. For example, you could introduce WSGI +middleware here, or combine a Django application with an application of another +framework. + +""" +import os + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dss.settings") + +# This application object is used by any WSGI server configured to use this +# file. This includes Django's development server, if the WSGI_APPLICATION +# setting points here. +from django.core.wsgi import get_wsgi_application +application = get_wsgi_application() + +# Apply WSGI middleware here. +# from helloworld.wsgi import HelloWorldApplication +# application = HelloWorldApplication(application) diff --git a/manage.py b/manage.py new file mode 100644 index 0000000..3de7571 --- /dev/null +++ b/manage.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python +import os +import sys + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dss.settings") + + from django.core.management import execute_from_command_line + + execute_from_command_line(sys.argv) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..0f0afcb --- /dev/null +++ b/requirements.txt @@ -0,0 +1,15 @@ +Django>=1.4 +MySQL-python>=1.2.3 +pillow>=1.7.7 +beautifulsoup4>=4.1.1 +decorator>=3.3.3 +django-allauth>=0.7.0 +django-annoying>=0.7.6 +django-celery>=3.0.4 +django-gravatar2>=1.0.6 +django-avatar>=1.0.5 +django-notification>=0.2 +django-socialauth>=0.1.2c +django-tastypie>=0.9.11 +django-grappelli +humanize diff --git a/spa/__init__.py b/spa/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/spa/admin.py b/spa/admin.py new file mode 100644 index 0000000..bd4bfbe --- /dev/null +++ b/spa/admin.py @@ -0,0 +1,16 @@ +from django.contrib import admin +from spa.models import Mix, Label, Release, ReleaseAudio, MixLike + +class DefaultAdmin(admin.ModelAdmin): + def save_model(self, request, obj, form, change): + obj.user = request.user.get_profile() + obj.save() + +#admin.site.register(Event, EventTestPageAdmin) +admin.site.register(Mix) +admin.site.register(MixLike) +#admin.site.register(Venue) +#admin.site.register(Genre) +admin.site.register(Label) +admin.site.register(Release, DefaultAdmin) +admin.site.register(ReleaseAudio) diff --git a/spa/ajax.py b/spa/ajax.py new file mode 100644 index 0000000..6274193 --- /dev/null +++ b/spa/ajax.py @@ -0,0 +1,111 @@ +from django.conf.urls import url +from django.contrib.auth.decorators import login_required +from django.http import HttpResponse +from annoying.decorators import render_to +from django.shortcuts import render_to_response +import json +from django.utils import simplejson +from core.utils import live +from spa.models import Mix, Comment, MixLike + +class AjaxHandler(object): + import logging + + # Get an instance of a logger + logger = logging.getLogger(__name__) + + def __init__(self, api_name="v1"): + self.api_name = api_name + + @property + def urls(self): + pattern_list = [ + url(r'^mix-description/(?P\d+)/$', 'spa.ajax.get_mix_description', name='ajax_mix-description'), + url(r'^mix/add_comment/$', 'spa.ajax.mix_add_comment', name='mix_add_comment'), + url(r'^mix/comments/(?P\d+)/$', 'spa.ajax.mix_comments', name='ajax_mix_comments'), + url(r'^header/$', 'spa.ajax.header', name='header'), + url(r'^mix_stream_url/(?P\d+)/$', 'spa.ajax.get_mix_stream_url'), + url(r'^release_player/(?P\d+)/$', 'spa.ajax.release_player'), + url(r'^live_now_playing/$', 'spa.ajax.live_now_playing'), + url(r'^like/$', 'spa.ajax.like', name='ajax_mix-description'), + ] + return pattern_list + + def wrap_view(self, view): + def wrapper(request, *args, **kwargs): + return getattr(self, view)(request, *args, **kwargs) + + return wrapper + + +def _get_json(payload, key='value'): + data = { + key: payload + } + return data + + +def get_mix_description(request, mix_id): + return HttpResponse(json.dumps(_get_json('ArgleBargle')), mimetype="application/json") + + +@render_to('inc/header.html') +def header(request): + return HttpResponse(render_to_response('inc/header.html')) + + +def get_mix_stream_url(request, mix_id): + try: + mix = Mix.objects.get(pk=mix_id) + mix.add_play(request.user) + data = { + 'stream_url': mix.get_stream_path(), + 'description': mix.description, + 'title': mix.title + } + return HttpResponse(json.dumps(data), mimetype="application/json") + except Exception, e: + self.logger.exception("Error getting mix stream url") + +def live_now_playing(request): + return HttpResponse( + json.dumps({ + 'stream_url': "radio.deepsouthsounds.com", + 'description': 'Description', + 'title': live.get_now_playing("radio.deepsouthsounds.com", "8000", "live") + }), mimetype="application/json") + + +@render_to('inc/release_player.html') +def release_player(request, release_id): + return HttpResponse('Hello Sailor') + +def mix_add_comment(request): + if request.POST: + comment = Comment() + comment.mix_id = request.POST['mixid'] + comment.user = request.user + comment.comment = request.POST['comment'] + comment.time_index = request.POST['position'] + comment.save() + + return HttpResponse(simplejson.dumps({'description': 'Hello Sailor'})) + else: + return HttpResponse(simplejson.dumps({'description': 'Error posting'})) + +@render_to('inc/comment_list.html') +def mix_comments(request, mix_id): + return { + "results": Comment.objects.filter(mix_id=mix_id), + } + +@login_required() +def like(request): + if request.is_ajax(): + if request.method == 'POST': + if request.POST['dataMode'] == 'mix': + mix = Mix.objects.get(pk = request.POST['dataId']) + if mix is not None: + mix.likes.add(MixLike(mix = mix, user = request.user)) + mix.save() + return HttpResponse(simplejson.dumps(request.raw_post_data)) diff --git a/spa/api/__init__.py b/spa/api/__init__.py new file mode 100644 index 0000000..8133f5e --- /dev/null +++ b/spa/api/__init__.py @@ -0,0 +1 @@ +__author__ = 'fergalm' diff --git a/spa/api/v1/BackboneCompatibleResource.py b/spa/api/v1/BackboneCompatibleResource.py new file mode 100644 index 0000000..4f4308b --- /dev/null +++ b/spa/api/v1/BackboneCompatibleResource.py @@ -0,0 +1,21 @@ +from django.conf.urls import url +from tastypie import fields +from tastypie.resources import ModelResource + +__author__ = 'fergalm' + +class BackboneCompatibleResource(ModelResource): + + def override_urls(self): + urls = [] + + for name, field in self.fields.items(): + if isinstance(field, fields.ToManyField): + resource = r"^(?P{resource_name})/(?P<{related_name}>.+)/{related_resource}/$".format( + resource_name=self._meta.resource_name, + related_name=field.related_name, + related_resource=field.attribute, + ) + resource = url(resource, field.to_class().wrap_view('get_list'), name="api_dispatch_detail") + urls.append(resource) + return urls \ No newline at end of file diff --git a/spa/api/v1/CommentResource.py b/spa/api/v1/CommentResource.py new file mode 100644 index 0000000..76450d3 --- /dev/null +++ b/spa/api/v1/CommentResource.py @@ -0,0 +1,36 @@ +import datetime +import humanize +from tastypie import fields +from tastypie.authentication import Authentication +from tastypie.authorization import Authorization +from spa.api.v1.BackboneCompatibleResource import BackboneCompatibleResource +from spa.models import Comment + +class CommentResource(BackboneCompatibleResource): + mix = fields.ToOneField('spa.api.v1.MixResource.MixResource', 'mix') + + class Meta: + queryset = Comment.objects.all().order_by('-date_created') + resource_name = 'comments' + filtering = { + "mix": ('exact',), + } + authorization = Authorization() + authentication = Authentication() + always_return_data = True + + def obj_create(self, bundle, request, **kwargs): + bundle.data['user'] = {'pk': request.user.pk} + return super(CommentResource, self).obj_create(bundle, request, user=request.user) + + def dehydrate_date_created(self, bundle): + if (datetime.datetime.now() - bundle.obj.date_created) <= datetime.timedelta(days=1): + return humanize.naturaltime(bundle.obj.date_created) + else: + return humanize.naturalday(bundle.obj.date_created) + + def dehydrate(self, bundle): + bundle.data['avatar_image'] = bundle.obj.user.get_profile().get_avatar_image(150) + bundle.data['user_url'] = bundle.obj.user.get_absolute_url() + bundle.data['user_name'] = bundle.obj.user.get_profile().nice_name() + return bundle \ No newline at end of file diff --git a/spa/api/v1/MixResource.py b/spa/api/v1/MixResource.py new file mode 100644 index 0000000..7a4e4e0 --- /dev/null +++ b/spa/api/v1/MixResource.py @@ -0,0 +1,43 @@ +from django.db.models.aggregates import Count +from tastypie import fields +from tastypie.authorization import Authorization +from tastypie.constants import ALL_WITH_RELATIONS +from spa.api.v1.BackboneCompatibleResource import BackboneCompatibleResource + +from spa.models import Mix + +class MixResource(BackboneCompatibleResource): + comments = fields.ToManyField('spa.api.v1.CommentResource.CommentResource', 'comments', 'mix') + + class Meta: + queryset = Mix.objects.filter(is_active=True) + excludes = ['download_url', 'is_active', 'local_file', 'upload_date'] + filtering = { + 'comments' : ALL_WITH_RELATIONS + } + authorization = Authorization() + + def obj_get_list(self, request=None, **kwargs): + sort = 'latest' + if 'sort' in request.GET and request.GET['sort']: + sort = request.GET['sort'] + + return Mix.get_listing(sort) + + def dehydrate_mix_image(self, bundle): + return bundle.obj.get_image() + + def dehydrate_description(self, bundle): + return bundle.obj.description.replace("\n", "
") + + def dehydrate(self, bundle): + bundle.data['waveform_url'] = bundle.obj.get_waveform_url() + bundle.data['user_name'] = bundle.obj.user.nice_name() + bundle.data['item_url'] = 'mix/%s' % bundle.obj.id + + bundle.data['play_count'] = bundle.obj.plays.count() + bundle.data['like_count'] = bundle.obj.likes.count() + bundle.data['mode'] = 'mix' + bundle.data['comment_count'] = bundle.obj.comments.count() + return bundle + diff --git a/spa/api/v1/ReleaseAudioResource.py b/spa/api/v1/ReleaseAudioResource.py new file mode 100644 index 0000000..1395311 --- /dev/null +++ b/spa/api/v1/ReleaseAudioResource.py @@ -0,0 +1,17 @@ +from tastypie import fields +from spa.api.v1.BackboneCompatibleResource import BackboneCompatibleResource +from spa.models import ReleaseAudio + +class ReleaseAudioResource(BackboneCompatibleResource): + release = fields.ToOneField('spa.api.v1.ReleaseResource.ReleaseResource', 'release') + + class Meta: + queryset = ReleaseAudio.objects.all() + resource_name = 'audio' + filtering = { + "release": ('exact',), + } + + def dehydrate(self, bundle): + bundle.data['waveform_url'] = bundle.obj.get_waveform_url() + return bundle \ No newline at end of file diff --git a/spa/api/v1/ReleaseResource.py b/spa/api/v1/ReleaseResource.py new file mode 100644 index 0000000..d4a5a22 --- /dev/null +++ b/spa/api/v1/ReleaseResource.py @@ -0,0 +1,24 @@ +import datetime +import humanize +from tastypie import fields +from tastypie.authorization import Authorization +from tastypie.constants import ALL_WITH_RELATIONS +from spa.api.v1.BackboneCompatibleResource import BackboneCompatibleResource +from spa.models import Release + +class ReleaseResource(BackboneCompatibleResource): + release_audio = fields.ToManyField('spa.api.v1.ReleaseAudioResource.ReleaseAudioResource', 'release_audio', 'release') + class Meta: + queryset = Release.objects.all() + filtering = { + 'release_audio' : ALL_WITH_RELATIONS + } + authorization = Authorization() + + def dehydrate(self, bundle): + bundle.data['item_url'] = 'release/%s' % bundle.obj.id + bundle.data['mode'] = 'release' + return bundle + + def dehydrate_release_date(self, bundle): + return humanize.naturalday(bundle.obj.release_date) \ No newline at end of file diff --git a/spa/api/v1/__init__.py b/spa/api/v1/__init__.py new file mode 100644 index 0000000..8133f5e --- /dev/null +++ b/spa/api/v1/__init__.py @@ -0,0 +1 @@ +__author__ = 'fergalm' diff --git a/spa/management/__init__.py b/spa/management/__init__.py new file mode 100644 index 0000000..8133f5e --- /dev/null +++ b/spa/management/__init__.py @@ -0,0 +1 @@ +__author__ = 'fergalm' diff --git a/spa/management/commands/__init__.py b/spa/management/commands/__init__.py new file mode 100644 index 0000000..8133f5e --- /dev/null +++ b/spa/management/commands/__init__.py @@ -0,0 +1 @@ +__author__ = 'fergalm' diff --git a/spa/management/commands/drop.py b/spa/management/commands/drop.py new file mode 100644 index 0000000..19fd4cf --- /dev/null +++ b/spa/management/commands/drop.py @@ -0,0 +1,21 @@ +from django.conf import settings + +from django.core.management.base import NoArgsCommand + +class Command(NoArgsCommand): + help = "Drop and re-create the database" + def handle_noargs(self, **options): + import MySQLdb + + print "Connecting..." + db = MySQLdb.connect( + host=settings.DATABASES['default']['HOST'] or "localhost", + user=settings.DATABASES['default']['USER'], + passwd=settings.DATABASES['default']['PASSWORD'], + port=int(settings.DATABASES['default']['PORT'] or 3306)) + + cursor = db.cursor() + print "Dropping database %s" % settings.DATABASES['default']['NAME'] + cursor.execute("drop database %s; create database %s;" % (settings.DATABASES['default']['NAME'], settings.DATABASES['default']['NAME'])) + print "Dropped" + diff --git a/spa/management/commands/generate_waveforms.py b/spa/management/commands/generate_waveforms.py new file mode 100644 index 0000000..df86985 --- /dev/null +++ b/spa/management/commands/generate_waveforms.py @@ -0,0 +1,29 @@ +import os +from dss import settings +from core.utils.waveform import generate_waveform +from spa.models import Mix, ReleaseAudio +from django.core.management.base import NoArgsCommand + +class Command(NoArgsCommand): + + help = "Generate all outstanding waveforms" + + def _check_file(self, local_file, output_file): + if os.path.isfile(os.path.join(settings.MEDIA_ROOT, local_file)): + file = os.path.join(settings.MEDIA_ROOT, output_file) + if not os.path.isfile(file): + print "Found missing waveform" + generate_waveform(local_file, file) + + def handle_noargs(self, **options): + print "Generating waveforms for mix" + objects = Mix.objects.all() + for object in objects: + output_file = 'waveforms/mix/%d.png' % object.pk + self._check_file(object.local_file.file.name, output_file) + + print "Generating waveforms for release" + objects = ReleaseAudio.objects.all() + for object in objects: + output_file = 'waveforms/release/%d.png' % object.pk + self._check_file(object.local_file.file.name, output_file) diff --git a/spa/models.py b/spa/models.py new file mode 100644 index 0000000..72e43ab --- /dev/null +++ b/spa/models.py @@ -0,0 +1,261 @@ +from datetime import datetime +import logging +import urlparse +from allauth.socialaccount.models import SocialAccount +from django.contrib.auth.models import User +from django.core.urlresolvers import reverse +from django.db import models +from django.db.models.aggregates import Count +from django.db.models.signals import post_save +from django_gravatar.helpers import has_gravatar, get_gravatar_url +import os +from core.utils.file import generate_save_file_name +from dss import settings +from tasks.waveform import create_waveform_task + +def mix_file_name(instance, filename): + return generate_save_file_name('mixes', filename) + + +def mix_image_name(instance, filename): + return generate_save_file_name('mix-images', filename) + + +def venue_image_name(instance, filename): + return generate_save_file_name('venue-images', filename) + + +def release_image_name(instance, filename): + return generate_save_file_name('release-images', filename) + + +def release_file_name(instance, filename): + return generate_save_file_name('release-audio', filename) + +class BaseModel(models.Model): + logger = logging.getLogger(__name__) + class Meta: + abstract = True + +class UserProfile(BaseModel): + class Meta: + db_table = 'www_userprofile' + + # This field is required. + user = models.ForeignKey(User, unique=True) + avatar_type = models.CharField(max_length=15) + avatar_image = models.ImageField(blank=True, upload_to='avatars/') + + def create_user_profile(sender, instance, created, **kwargs): + if created: + UserProfile.objects.create(user=instance) + post_save.connect(create_user_profile, sender=User) + + def get_username(self): + return self.user.username + username = property(get_username) + + def get_email(self): + return self.user.email + email = property(get_email) + + def get_first_name(self): + return self.user.first_name + first_name = property(get_first_name) + + def get_last_name(self): + return self.user.last_name + last_name = property(get_last_name) + + def get_absolute_url(self): + return reverse('user_details', kwargs={'user_name': self.user.username}) + + def nice_name(self): + return self.first_name + ' ' + self.last_name + + def get_avatar_image(self, size=150): + avatar_type = self.avatar_type + if avatar_type == 'gravatar': + gravatar_exists = has_gravatar(self.email) + if gravatar_exists: + return get_gravatar_url(self.email, size) + elif avatar_type == 'social': + try: + social_account = SocialAccount.objects.filter(user = self)[0] + if social_account: + provider = social_account.get_provider_account() + return provider.get_avatar_url() + except: + pass + elif avatar_type == 'custom': + return self.avatar_image.url + + return urlparse.urljoin(settings.STATIC_URL, "img/default-avatar-32.png") + +class Mix(BaseModel): + class Meta: + db_table = 'www_mix' + + title = models.CharField(max_length=50) + description = models.TextField() + upload_date = models.DateTimeField(default=datetime.now()) + mix_image = models.ImageField(blank=True, upload_to=mix_image_name) + local_file = models.FileField(upload_to=mix_file_name) + download_url = models.CharField(max_length=255) + stream_url = models.CharField(max_length=255) + is_active = models.BooleanField(default=True) + user = models.ForeignKey(UserProfile, editable=False) + + def __unicode__(self): + return self.title + + def save(self, force_insert=False, force_update=False, using=None): + super(Mix, self).save(force_insert, force_update, using) + if not os.path.exists(self.get_waveform_path()): + create_waveform_task.delay(id=self.id, in_file=self.local_file.file.name) + + def get_absolute_url(self): + return '/mix/%i' % self.id + + def get_waveform_path(self): + return os.path.join(settings.MEDIA_ROOT, "waveforms/mix/", "%d.%s" % (self.id, "png")) + + def get_waveform_url(self): + return settings.MEDIA_URL + 'waveforms/mix/%d.%s' % (self.id, "png") + + def get_image(self): + try: + if self.mix_image: + if os.path.exists(self.mix_image.file.name): + return self.mix_image.url + except Exception as ex: + pass + + return settings.STATIC_URL + 'img/default-track.png' + + def get_stream_path(self): + return settings.MEDIA_URL + self.local_file.name + + @classmethod + def get_listing(cls, listing_type): + queryset = None + if listing_type == 'latest': + queryset = Mix.objects.all().order_by( 'id') + elif listing_type == 'toprated': + queryset = Mix.objects.all()\ + .annotate(karma=Count('likes'))\ + .order_by('-karma') + elif listing_type == 'mostactive': + queryset = Mix.objects.all()\ + .annotate(karma=Count('comments'))\ + .order_by('-karma') + elif listing_type == 'mostplayed': + queryset = Mix.objects.all()\ + .annotate(karma=Count('likes'))\ + .order_by('-karma') + elif listing_type == 'recommended': + queryset = Mix.objects.all().order_by( '-id') + + return queryset + + @classmethod + def get_user_mixes(cls, user_name): + mixes = Mix.objects.filter(user__user__username=user_name) + if mixes.count(): + return { + "inline_play": False, + "heading": "Some mixes from " + mixes[0].user.user.get_full_name() or mixes[0].user.user.username, + "latest_mix_list": mixes, + } + + return { + "heading": "No mixes found for this user", + "latest_mix_list": None, + } + + def add_play(self, user): + try: + self.plays.add(MixPlay(user = user if user.is_authenticated() else None)) + except Exception, e: + self.logger.exception("Error getting mix stream url") + +class Comment(BaseModel): + class Meta: + db_table = 'www_comment' + + user = models.ForeignKey(User, editable=False) + mix = models.ForeignKey(Mix, editable=False, related_name='comments') + comment = models.CharField(max_length=1024) + date_created = models.DateTimeField(auto_now=True) + time_index = models.IntegerField() + + def get_absolute_url(self): + return '/comment/%i' % self.id + + def save(self, force_insert=False, force_update=False, using=None): + super(Comment, self).save(force_insert, force_update, using) + +class Label(BaseModel): + class Meta: + db_table = 'www_label' + + name = models.CharField(max_length=100) + + def __unicode__(self): + return self.name + +class Release(BaseModel): + class Meta: + db_table = 'www_release' + + release_artist = models.CharField(max_length=100) + release_title = models.CharField(max_length=100) + release_description = models.TextField() + release_image = models.ImageField(blank=True, upload_to=release_image_name) + release_label = models.ForeignKey(Label) + release_date = models.DateField(default=datetime.now()) + + is_active = models.BooleanField(default=True) + user = models.ForeignKey(UserProfile, editable=False) + + def __unicode__(self): + return self.release_title + + def save(self, force_insert=False, force_update=False, using=None): + super(Release, self).save(force_insert, force_update, using) + + def get_absolute_url(self): + return '/release/%i' % self.id + + @classmethod + def get_view_model(cls): + qs = cls.objects.get(is_active=True) + return qs + +class ReleaseAudio(BaseModel): + class Meta: + db_table = 'www_releaseaudio' + + def __unicode__(self): + return self.description + + def get_waveform_url(self): + return settings.MEDIA_URL + 'waveforms/release/%d.%s' % (self.id, "png") + + local_file = models.FileField(upload_to=release_file_name) + release = models.ForeignKey(Release, related_name='release_audio') + description = models.TextField() + +class __Like(BaseModel): + date = models.DateTimeField(auto_now=True) + user = models.ForeignKey(User, null=True ) + +class MixLike(__Like): + class Meta: + db_table = 'www_like' + mix = models.ForeignKey(Mix, related_name='likes') + +class MixPlay(__Like): + class Meta: + db_table = 'www_play' + mix = models.ForeignKey(Mix, related_name='plays') \ No newline at end of file diff --git a/spa/templates.py b/spa/templates.py new file mode 100644 index 0000000..6cb44c1 --- /dev/null +++ b/spa/templates.py @@ -0,0 +1,9 @@ +from django.shortcuts import render_to_response +from django.template.context import RequestContext + +__author__ = 'fergalm' + +def get_template(request, template_name): + return render_to_response( + 'views/%s.html' % (template_name), + context_instance=RequestContext(request)) \ No newline at end of file diff --git a/spa/templatetags/__init__.py b/spa/templatetags/__init__.py new file mode 100644 index 0000000..8133f5e --- /dev/null +++ b/spa/templatetags/__init__.py @@ -0,0 +1 @@ +__author__ = 'fergalm' diff --git a/spa/templatetags/spa_extras.py b/spa/templatetags/spa_extras.py new file mode 100644 index 0000000..344a86a --- /dev/null +++ b/spa/templatetags/spa_extras.py @@ -0,0 +1,40 @@ +from allauth.socialaccount.models import SocialAccount +from django import template +from django.contrib.auth.models import User +from django_gravatar.helpers import has_gravatar, get_gravatar_url +from dss import settings +from spa.models import UserProfile + +register = template.Library() + +@register.filter +def nice_name(user): + if user == "": + return "Unknown User" + + if type(user) is UserProfile: + return user.user.get_full_name() or user.user.username + elif type(user) is User: + return user.get_full_name() or user.username + +@register.filter +def avatar_image(user, size=150): + profile = user.get_profile() + avatar_type = profile.avatar_type + + if avatar_type == 'gravatar': + gravatar_exists = has_gravatar(user.email) + if gravatar_exists: + return get_gravatar_url(user.email, size) + elif avatar_type == 'social': + try: + social_account = SocialAccount.objects.filter(user = user)[0] + if social_account: + provider = social_account.get_provider_account() + return provider.get_avatar_url() + except: + pass + elif avatar_type == 'custom': + return profile.avatar_image.url + + return settings.STATIC_URL + "/images/default-avatar-32.png" diff --git a/spa/tests.py b/spa/tests.py new file mode 100644 index 0000000..178f860 --- /dev/null +++ b/spa/tests.py @@ -0,0 +1,16 @@ +""" +This file demonstrates writing tests using the unittest module. These will pass +when you run "manage.py test". + +Replace this with more appropriate tests for your application. +""" + +from django.test import TestCase + + +class SimpleTest(TestCase): + def test_basic_addition(self): + """ + Tests that 1 + 1 always equals 2. + """ + self.assertEqual(1 + 1, 2) diff --git a/spa/urls.py b/spa/urls.py new file mode 100644 index 0000000..b4c5a84 --- /dev/null +++ b/spa/urls.py @@ -0,0 +1,25 @@ +from django.conf.urls import patterns, url, include +import django.conf.urls +from tastypie.api import Api +from spa.ajax import AjaxHandler +from spa.api.v1.CommentResource import CommentResource +from spa.api.v1.MixResource import MixResource +from spa.api.v1.ReleaseAudioResource import ReleaseAudioResource +from spa.api.v1.ReleaseResource import ReleaseResource +import spa + +v1_api = Api(api_name='v1') +v1_api.register(MixResource()) +v1_api.register(CommentResource()) +v1_api.register(ReleaseResource()) +v1_api.register(ReleaseAudioResource()) + +ajax = AjaxHandler() + +urlpatterns = django.conf.urls.patterns( + '', + url(r'^$', 'spa.views.app', name='home'), + url(r'^tpl/(?P\w+)/$', 'spa.templates.get_template'), + (r'^ajax/', include(ajax.urls)), + (r'^api/', include(v1_api.urls)), +) \ No newline at end of file diff --git a/spa/views.py b/spa/views.py new file mode 100644 index 0000000..99e1742 --- /dev/null +++ b/spa/views.py @@ -0,0 +1,5 @@ +from core.decorators import render_template + +@render_template +def app(request): + return "inc/app.html" diff --git a/static/bin/sm/soundmanager2.swf b/static/bin/sm/soundmanager2.swf new file mode 100644 index 0000000..b74496c Binary files /dev/null and b/static/bin/sm/soundmanager2.swf differ diff --git a/static/bin/sm/soundmanager2_debug.swf b/static/bin/sm/soundmanager2_debug.swf new file mode 100644 index 0000000..d840f5f Binary files /dev/null and b/static/bin/sm/soundmanager2_debug.swf differ diff --git a/static/bin/sm/soundmanager2_flash9.swf b/static/bin/sm/soundmanager2_flash9.swf new file mode 100644 index 0000000..5eea89a Binary files /dev/null and b/static/bin/sm/soundmanager2_flash9.swf differ diff --git a/static/bin/sm/soundmanager2_flash9_debug.swf b/static/bin/sm/soundmanager2_flash9_debug.swf new file mode 100644 index 0000000..44f6075 Binary files /dev/null and b/static/bin/sm/soundmanager2_flash9_debug.swf differ diff --git a/static/bin/sm/soundmanager2_flash_xdomain.zip b/static/bin/sm/soundmanager2_flash_xdomain.zip new file mode 100644 index 0000000..034de77 Binary files /dev/null and b/static/bin/sm/soundmanager2_flash_xdomain.zip differ diff --git a/static/css/bootstrap-responsive.css b/static/css/bootstrap-responsive.css new file mode 100644 index 0000000..96b08cf --- /dev/null +++ b/static/css/bootstrap-responsive.css @@ -0,0 +1,808 @@ +/*! + * Bootstrap Responsive v2.0.3 + * + * Copyright 2012 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. + */ + +.clearfix { + *zoom: 1; +} + +.clearfix:before, +.clearfix:after { + display: table; + content: ""; +} + +.clearfix:after { + clear: both; +} + +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} + +.input-block-level { + display: block; + width: 100%; + min-height: 28px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; +} + +.hidden { + display: none; + visibility: hidden; +} + +.visible-phone { + display: none !important; +} + +.visible-tablet { + display: none !important; +} + +.hidden-desktop { + display: none !important; +} + +@media (max-width: 767px) { + .visible-phone { + display: inherit !important; + } + .hidden-phone { + display: none !important; + } + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important; + } +} + +@media (min-width: 768px) and (max-width: 979px) { + .visible-tablet { + display: inherit !important; + } + .hidden-tablet { + display: none !important; + } + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important ; + } +} + +@media (max-width: 480px) { + .nav-collapse { + -webkit-transform: translate3d(0, 0, 0); + } + .page-header h1 small { + display: block; + line-height: 18px; + } + input[type="checkbox"], + input[type="radio"] { + border: 1px solid #ccc; + } + .form-horizontal .control-group > label { + float: none; + width: auto; + padding-top: 0; + text-align: left; + } + .form-horizontal .controls { + margin-left: 0; + } + .form-horizontal .control-list { + padding-top: 0; + } + .form-horizontal .form-actions { + padding-right: 10px; + padding-left: 10px; + } + .modal { + position: absolute; + top: 10px; + right: 10px; + left: 10px; + width: auto; + margin: 0; + } + .modal.fade.in { + top: auto; + } + .modal-header .close { + padding: 10px; + margin: -10px; + } + .carousel-caption { + position: static; + } +} + +@media (max-width: 767px) { + body { + padding-right: 20px; + padding-left: 20px; + } + .navbar-fixed-top, + .navbar-fixed-bottom { + margin-right: -20px; + margin-left: -20px; + } + .container-fluid { + padding: 0; + } + .dl-horizontal dt { + float: none; + width: auto; + clear: none; + text-align: left; + } + .dl-horizontal dd { + margin-left: 0; + } + .container { + width: auto; + } + .row-fluid { + width: 100%; + } + .row, + .thumbnails { + margin-left: 0; + } + [class*="span"], + .row-fluid [class*="span"] { + display: block; + float: none; + width: auto; + margin-left: 0; + } + .input-large, + .input-xlarge, + .input-xxlarge, + input[class*="span"], + select[class*="span"], + textarea[class*="span"], + .uneditable-input { + display: block; + width: 100%; + min-height: 28px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + } + .input-prepend input, + .input-append input, + .input-prepend input[class*="span"], + .input-append input[class*="span"] { + display: inline-block; + width: auto; + } +} + +@media (min-width: 768px) and (max-width: 979px) { + .row { + margin-left: -20px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + content: ""; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + margin-left: 20px; + } + .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 724px; + } + .span12 { + width: 724px; + } + .span11 { + width: 662px; + } + .span10 { + width: 600px; + } + .span9 { + width: 538px; + } + .span8 { + width: 476px; + } + .span7 { + width: 414px; + } + .span6 { + width: 352px; + } + .span5 { + width: 290px; + } + .span4 { + width: 228px; + } + .span3 { + width: 166px; + } + .span2 { + width: 104px; + } + .span1 { + width: 42px; + } + .offset12 { + margin-left: 764px; + } + .offset11 { + margin-left: 702px; + } + .offset10 { + margin-left: 640px; + } + .offset9 { + margin-left: 578px; + } + .offset8 { + margin-left: 516px; + } + .offset7 { + margin-left: 454px; + } + .offset6 { + margin-left: 392px; + } + .offset5 { + margin-left: 330px; + } + .offset4 { + margin-left: 268px; + } + .offset3 { + margin-left: 206px; + } + .offset2 { + margin-left: 144px; + } + .offset1 { + margin-left: 82px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + content: ""; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + float: left; + width: 100%; + min-height: 28px; + margin-left: 2.762430939%; + *margin-left: 2.709239449638298%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .span12 { + width: 99.999999993%; + *width: 99.9468085036383%; + } + .row-fluid .span11 { + width: 91.436464082%; + *width: 91.38327259263829%; + } + .row-fluid .span10 { + width: 82.87292817100001%; + *width: 82.8197366816383%; + } + .row-fluid .span9 { + width: 74.30939226%; + *width: 74.25620077063829%; + } + .row-fluid .span8 { + width: 65.74585634900001%; + *width: 65.6926648596383%; + } + .row-fluid .span7 { + width: 57.182320438000005%; + *width: 57.129128948638304%; + } + .row-fluid .span6 { + width: 48.618784527%; + *width: 48.5655930376383%; + } + .row-fluid .span5 { + width: 40.055248616%; + *width: 40.0020571266383%; + } + .row-fluid .span4 { + width: 31.491712705%; + *width: 31.4385212156383%; + } + .row-fluid .span3 { + width: 22.928176794%; + *width: 22.874985304638297%; + } + .row-fluid .span2 { + width: 14.364640883%; + *width: 14.311449393638298%; + } + .row-fluid .span1 { + width: 5.801104972%; + *width: 5.747913482638298%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 714px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 652px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 590px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 528px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 466px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 404px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 342px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 280px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 218px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 156px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 94px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 32px; + } +} + +@media (min-width: 1200px) { + .row { + margin-left: -30px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + content: ""; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + margin-left: 30px; + } + .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 1170px; + } + .span12 { + width: 1170px; + } + .span11 { + width: 1070px; + } + .span10 { + width: 970px; + } + .span9 { + width: 870px; + } + .span8 { + width: 770px; + } + .span7 { + width: 670px; + } + .span6 { + width: 570px; + } + .span5 { + width: 470px; + } + .span4 { + width: 370px; + } + .span3 { + width: 270px; + } + .span2 { + width: 170px; + } + .span1 { + width: 70px; + } + .offset12 { + margin-left: 1230px; + } + .offset11 { + margin-left: 1130px; + } + .offset10 { + margin-left: 1030px; + } + .offset9 { + margin-left: 930px; + } + .offset8 { + margin-left: 830px; + } + .offset7 { + margin-left: 730px; + } + .offset6 { + margin-left: 630px; + } + .offset5 { + margin-left: 530px; + } + .offset4 { + margin-left: 430px; + } + .offset3 { + margin-left: 330px; + } + .offset2 { + margin-left: 230px; + } + .offset1 { + margin-left: 130px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + content: ""; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + float: left; + width: 100%; + min-height: 28px; + margin-left: 2.564102564%; + *margin-left: 2.510911074638298%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; + } + .row-fluid .span11 { + width: 91.45299145300001%; + *width: 91.3997999636383%; + } + .row-fluid .span10 { + width: 82.905982906%; + *width: 82.8527914166383%; + } + .row-fluid .span9 { + width: 74.358974359%; + *width: 74.30578286963829%; + } + .row-fluid .span8 { + width: 65.81196581200001%; + *width: 65.7587743226383%; + } + .row-fluid .span7 { + width: 57.264957265%; + *width: 57.2117657756383%; + } + .row-fluid .span6 { + width: 48.717948718%; + *width: 48.6647572286383%; + } + .row-fluid .span5 { + width: 40.170940171000005%; + *width: 40.117748681638304%; + } + .row-fluid .span4 { + width: 31.623931624%; + *width: 31.5707401346383%; + } + .row-fluid .span3 { + width: 23.076923077%; + *width: 23.0237315876383%; + } + .row-fluid .span2 { + width: 14.529914530000001%; + *width: 14.4767230406383%; + } + .row-fluid .span1 { + width: 5.982905983%; + *width: 5.929714493638298%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 1160px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 1060px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 960px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 860px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 760px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 660px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 560px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 460px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 360px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 260px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 160px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 60px; + } + .thumbnails { + margin-left: -30px; + } + .thumbnails > li { + margin-left: 30px; + } + .row-fluid .thumbnails { + margin-left: 0; + } +} + +@media (max-width: 979px) { + body { + padding-top: 0; + } + .navbar-fixed-top { + position: static; + margin-bottom: 18px; + } + .navbar-fixed-top .navbar-inner { + padding: 5px; + } + .navbar .container { + width: auto; + padding: 0; + } + .navbar .brand { + padding-right: 10px; + padding-left: 10px; + margin: 0 0 0 -5px; + } + .nav-collapse { + clear: both; + } + .nav-collapse .nav { + float: none; + margin: 0 0 9px; + } + .nav-collapse .nav > li { + float: none; + } + .nav-collapse .nav > li > a { + margin-bottom: 2px; + } + .nav-collapse .nav > .divider-vertical { + display: none; + } + .nav-collapse .nav .nav-header { + color: #999999; + text-shadow: none; + } + .nav-collapse .nav > li > a, + .nav-collapse .dropdown-menu a { + padding: 6px 15px; + font-weight: bold; + color: #999999; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + } + .nav-collapse .btn { + padding: 4px 10px 4px; + font-weight: normal; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + } + .nav-collapse .dropdown-menu li + li a { + margin-bottom: 2px; + } + .nav-collapse .nav > li > a:hover, + .nav-collapse .dropdown-menu a:hover { + background-color: #222222; + } + .nav-collapse.in .btn-group { + padding: 0; + margin-top: 5px; + } + .nav-collapse .dropdown-menu { + position: static; + top: auto; + left: auto; + display: block; + float: none; + max-width: none; + padding: 0; + margin: 0 15px; + background-color: transparent; + border: none; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + } + .nav-collapse .dropdown-menu:before, + .nav-collapse .dropdown-menu:after { + display: none; + } + .nav-collapse .dropdown-menu .divider { + display: none; + } + .nav-collapse .navbar-form, + .nav-collapse .navbar-search { + float: none; + padding: 9px 15px; + margin: 9px 0; + border-top: 1px solid #222222; + border-bottom: 1px solid #222222; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + } + .navbar .nav-collapse .nav.pull-right { + float: none; + margin-left: 0; + } + .nav-collapse, + .nav-collapse.collapse { + height: 0; + overflow: hidden; + } + .navbar .btn-navbar { + display: block; + } + .navbar-static .navbar-inner { + padding-right: 10px; + padding-left: 10px; + } +} + +@media (min-width: 980px) { + .nav-collapse.collapse { + height: auto !important; + overflow: visible !important; + } +} diff --git a/static/css/bootstrap.css b/static/css/bootstrap.css new file mode 100644 index 0000000..9ffe42b --- /dev/null +++ b/static/css/bootstrap.css @@ -0,0 +1,4326 @@ +@import url(https://fonts.googleapis.com/css?family=Ubuntu); +/*! + * Bootstrap v2.0.4 + * + * Copyright 2012 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. + */ +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; +} +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +a:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +a:hover, +a:active { + outline: 0; +} +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} +img { + max-width: 100%; + vertical-align: middle; + border: 0; + -ms-interpolation-mode: bicubic; +} +#map_canvas img { + max-width: none; +} +button, +input, +select, +textarea { + margin: 0; + font-size: 100%; + vertical-align: middle; +} +button, +input { + *overflow: visible; + line-height: normal; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} +button, +input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; +} +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} +textarea { + overflow: auto; + vertical-align: top; +} +.clearfix { + *zoom: 1; +} +.clearfix:before, +.clearfix:after { + display: table; + content: ""; +} +.clearfix:after { + clear: both; +} +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.input-block-level { + display: block; + width: 100%; + min-height: 28px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; +} +body { + margin: 0; + font-family: 'Ubuntu', Tahoma, sans-serif; + font-size: 13px; + line-height: 18px; + color: #333333; + background-color: #ffffff; +} +a { + color: #33332D; + text-decoration: none; +} +a:hover { + color: #9FB4CC; + text-decoration: underline; +} +.row { + margin-left: -20px; + *zoom: 1; +} +.row:before, +.row:after { + display: table; + content: ""; +} +.row:after { + clear: both; +} +[class*="span"] { + float: left; + margin-left: 20px; +} +.container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} +.span12 { + width: 940px; +} +.span11 { + width: 860px; +} +.span10 { + width: 780px; +} +.span9 { + width: 700px; +} +.span8 { + width: 620px; +} +.span7 { + width: 540px; +} +.span6 { + width: 460px; +} +.span5 { + width: 380px; +} +.span4 { + width: 300px; +} +.span3 { + width: 220px; +} +.span2 { + width: 140px; +} +.span1 { + width: 60px; +} +.offset12 { + margin-left: 980px; +} +.offset11 { + margin-left: 900px; +} +.offset10 { + margin-left: 820px; +} +.offset9 { + margin-left: 740px; +} +.offset8 { + margin-left: 660px; +} +.offset7 { + margin-left: 580px; +} +.offset6 { + margin-left: 500px; +} +.offset5 { + margin-left: 420px; +} +.offset4 { + margin-left: 340px; +} +.offset3 { + margin-left: 260px; +} +.offset2 { + margin-left: 180px; +} +.offset1 { + margin-left: 100px; +} +.row-fluid { + width: 100%; + *zoom: 1; +} +.row-fluid:before, +.row-fluid:after { + display: table; + content: ""; +} +.row-fluid:after { + clear: both; +} +.row-fluid [class*="span"] { + display: block; + width: 100%; + min-height: 28px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + float: left; + margin-left: 2.127659574%; + *margin-left: 2.0744680846382977%; +} +.row-fluid [class*="span"]:first-child { + margin-left: 0; +} +.row-fluid .span12 { + width: 99.99999998999999%; + *width: 99.94680850063828%; +} +.row-fluid .span11 { + width: 91.489361693%; + *width: 91.4361702036383%; +} +.row-fluid .span10 { + width: 82.97872339599999%; + *width: 82.92553190663828%; +} +.row-fluid .span9 { + width: 74.468085099%; + *width: 74.4148936096383%; +} +.row-fluid .span8 { + width: 65.95744680199999%; + *width: 65.90425531263828%; +} +.row-fluid .span7 { + width: 57.446808505%; + *width: 57.3936170156383%; +} +.row-fluid .span6 { + width: 48.93617020799999%; + *width: 48.88297871863829%; +} +.row-fluid .span5 { + width: 40.425531911%; + *width: 40.3723404216383%; +} +.row-fluid .span4 { + width: 31.914893614%; + *width: 31.8617021246383%; +} +.row-fluid .span3 { + width: 23.404255317%; + *width: 23.3510638276383%; +} +.row-fluid .span2 { + width: 14.89361702%; + *width: 14.8404255306383%; +} +.row-fluid .span1 { + width: 6.382978723%; + *width: 6.329787233638298%; +} +.container { + margin-right: auto; + margin-left: auto; + *zoom: 1; +} +.container:before, +.container:after { + display: table; + content: ""; +} +.container:after { + clear: both; +} +.container-fluid { + padding-right: 20px; + padding-left: 20px; + *zoom: 1; +} +.container-fluid:before, +.container-fluid:after { + display: table; + content: ""; +} +.container-fluid:after { + clear: both; +} +p { + margin: 0 0 9px; +} +p small { + font-size: 11px; + color: #999999; +} +.lead { + margin-bottom: 18px; + font-size: 20px; + font-weight: 200; + line-height: 27px; +} +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 0; + font-family: inherit; + font-weight: bold; + color: inherit; + text-rendering: optimizelegibility; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small { + font-weight: normal; + color: #999999; +} +h1 { + font-size: 30px; + line-height: 36px; +} +h1 small { + font-size: 18px; +} +h2 { + font-size: 24px; + line-height: 36px; +} +h2 small { + font-size: 18px; +} +h3 { + font-size: 18px; + line-height: 27px; +} +h3 small { + font-size: 14px; +} +h4, +h5, +h6 { + line-height: 18px; +} +h4 { + font-size: 14px; +} +h4 small { + font-size: 12px; +} +h5 { + font-size: 12px; +} +h6 { + font-size: 11px; + color: #999999; + text-transform: uppercase; +} +.page-header { + padding-bottom: 17px; + margin: 18px 0; + border-bottom: 1px solid #f5f5f5; +} +.page-header h1 { + line-height: 1; +} +ul, +ol { + padding: 0; + margin: 0 0 9px 25px; +} +ul ul, +ul ol, +ol ol, +ol ul { + margin-bottom: 0; +} +ul { + list-style: disc; +} +ol { + list-style: decimal; +} +li { + line-height: 18px; +} +ul.unstyled, +ol.unstyled { + margin-left: 0; + list-style: none; +} +dl { + margin-bottom: 18px; +} +dt, +dd { + line-height: 18px; +} +dt { + font-weight: bold; + line-height: 17px; +} +dd { + margin-left: 9px; +} +.dl-horizontal dt { + float: left; + width: 120px; + clear: left; + text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.dl-horizontal dd { + margin-left: 130px; +} +hr { + margin: 18px 0; + border: 0; + border-top: 1px solid #f5f5f5; + border-bottom: 1px solid #ffffff; +} +strong { + font-weight: bold; +} +em { + font-style: italic; +} +.muted { + color: #999999; +} +abbr[title] { + cursor: help; + border-bottom: 1px dotted #999999; +} +abbr.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 0 0 0 15px; + margin: 0 0 18px; + border-left: 5px solid #f5f5f5; +} +blockquote p { + margin-bottom: 0; + font-size: 16px; + font-weight: 300; + line-height: 22.5px; +} +blockquote small { + display: block; + line-height: 18px; + color: #999999; +} +blockquote small:before { + content: '\2014 \00A0'; +} +blockquote.pull-right { + float: right; + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #f5f5f5; + border-left: 0; +} +blockquote.pull-right p, +blockquote.pull-right small { + text-align: right; +} +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; +} +address { + display: block; + margin-bottom: 18px; + font-style: normal; + line-height: 18px; +} +small { + font-size: 100%; +} +cite { + font-style: normal; +} +code, +pre { + padding: 0 3px 2px; + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; + font-size: 12px; + color: #333333; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +code { + padding: 2px 4px; + color: #d14; + background-color: #f7f7f9; + border: 1px solid #e1e1e8; +} +pre { + display: block; + padding: 8.5px; + margin: 0 0 9px; + font-size: 12.025px; + line-height: 18px; + word-break: break-all; + word-wrap: break-word; + white-space: pre; + white-space: pre-wrap; + background-color: #f5f5f5; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.15); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +pre.prettyprint { + margin-bottom: 18px; +} +pre code { + padding: 0; + color: inherit; + background-color: transparent; + border: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +form { + margin: 0 0 18px; +} +fieldset { + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 27px; + font-size: 19.5px; + line-height: 36px; + color: #333333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +legend small { + font-size: 13.5px; + color: #999999; +} +label, +input, +button, +select, +textarea { + font-size: 13px; + font-weight: normal; + line-height: 18px; +} +input, +button, +select, +textarea { + font-family: 'Ubuntu', Tahoma, sans-serif; +} +label { + display: block; + margin-bottom: 5px; +} +select, +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + display: inline-block; + height: 18px; + padding: 4px; + margin-bottom: 9px; + font-size: 13px; + line-height: 18px; + color: #555555; +} +input, +textarea { + width: 210px; +} +textarea { + height: auto; +} +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + background-color: #ffffff; + border: 1px solid #cccccc; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border 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; +} +textarea:focus, +input[type="text"]:focus, +input[type="password"]:focus, +input[type="datetime"]:focus, +input[type="datetime-local"]:focus, +input[type="date"]:focus, +input[type="month"]:focus, +input[type="time"]:focus, +input[type="week"]:focus, +input[type="number"]:focus, +input[type="email"]:focus, +input[type="url"]:focus, +input[type="search"]:focus, +input[type="tel"]:focus, +input[type="color"]:focus, +.uneditable-input:focus { + border-color: rgba(82, 168, 236, 0.8); + outline: 0; + outline: thin dotted \9; + /* IE6-9 */ + + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); + -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); +} +input[type="radio"], +input[type="checkbox"] { + margin: 3px 0; + *margin-top: 0; + /* IE7 */ + + line-height: normal; + cursor: pointer; +} +input[type="submit"], +input[type="reset"], +input[type="button"], +input[type="radio"], +input[type="checkbox"] { + width: auto; +} +.uneditable-textarea { + width: auto; + height: auto; +} +select, +input[type="file"] { + height: 28px; + /* In IE7, the height of the select element cannot be changed by height, only font-size */ + + *margin-top: 4px; + /* For IE7, add top margin to align select with labels */ + + line-height: 28px; +} +select { + width: 220px; + border: 1px solid #bbb; +} +select[multiple], +select[size] { + height: auto; +} +select:focus, +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.radio, +.checkbox { + min-height: 18px; + padding-left: 18px; +} +.radio input[type="radio"], +.checkbox input[type="checkbox"] { + float: left; + margin-left: -18px; +} +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 5px; +} +.radio.inline, +.checkbox.inline { + display: inline-block; + padding-top: 5px; + margin-bottom: 0; + vertical-align: middle; +} +.radio.inline + .radio.inline, +.checkbox.inline + .checkbox.inline { + margin-left: 10px; +} +.input-mini { + width: 60px; +} +.input-small { + width: 90px; +} +.input-medium { + width: 150px; +} +.input-large { + width: 210px; +} +.input-xlarge { + width: 270px; +} +.input-xxlarge { + width: 530px; +} +input[class*="span"], +select[class*="span"], +textarea[class*="span"], +.uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"] { + float: none; + margin-left: 0; +} +.input-append input[class*="span"], +.input-append .uneditable-input[class*="span"], +.input-prepend input[class*="span"], +.input-prepend .uneditable-input[class*="span"], +.row-fluid .input-prepend [class*="span"], +.row-fluid .input-append [class*="span"] { + display: inline-block; +} +input, +textarea, +.uneditable-input { + margin-left: 0; +} +input.span12, textarea.span12, .uneditable-input.span12 { + width: 930px; +} +input.span11, textarea.span11, .uneditable-input.span11 { + width: 850px; +} +input.span10, textarea.span10, .uneditable-input.span10 { + width: 770px; +} +input.span9, textarea.span9, .uneditable-input.span9 { + width: 690px; +} +input.span8, textarea.span8, .uneditable-input.span8 { + width: 610px; +} +input.span7, textarea.span7, .uneditable-input.span7 { + width: 530px; +} +input.span6, textarea.span6, .uneditable-input.span6 { + width: 450px; +} +input.span5, textarea.span5, .uneditable-input.span5 { + width: 370px; +} +input.span4, textarea.span4, .uneditable-input.span4 { + width: 290px; +} +input.span3, textarea.span3, .uneditable-input.span3 { + width: 210px; +} +input.span2, textarea.span2, .uneditable-input.span2 { + width: 130px; +} +input.span1, textarea.span1, .uneditable-input.span1 { + width: 50px; +} +input[disabled], +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + cursor: not-allowed; + background-color: #f5f5f5; + border-color: #ddd; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"][readonly], +input[type="checkbox"][readonly] { + background-color: transparent; +} +.control-group.warning > label, +.control-group.warning .help-block, +.control-group.warning .help-inline { + color: #eca918; +} +.control-group.warning .checkbox, +.control-group.warning .radio, +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + color: #eca918; + border-color: #eca918; +} +.control-group.warning .checkbox:focus, +.control-group.warning .radio:focus, +.control-group.warning input:focus, +.control-group.warning select:focus, +.control-group.warning textarea:focus { + border-color: #c18910; + -webkit-box-shadow: 0 0 6px #f4cc76; + -moz-box-shadow: 0 0 6px #f4cc76; + box-shadow: 0 0 6px #f4cc76; +} +.control-group.warning .input-prepend .add-on, +.control-group.warning .input-append .add-on { + color: #eca918; + background-color: #fcefd4; + border-color: #eca918; +} +.control-group.error > label, +.control-group.error .help-block, +.control-group.error .help-inline { + color: #df382c; +} +.control-group.error .checkbox, +.control-group.error .radio, +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + color: #df382c; + border-color: #df382c; +} +.control-group.error .checkbox:focus, +.control-group.error .radio:focus, +.control-group.error input:focus, +.control-group.error select:focus, +.control-group.error textarea:focus { + border-color: #bc271c; + -webkit-box-shadow: 0 0 6px #ec8c85; + -moz-box-shadow: 0 0 6px #ec8c85; + box-shadow: 0 0 6px #ec8c85; +} +.control-group.error .input-prepend .add-on, +.control-group.error .input-append .add-on { + color: #df382c; + background-color: #fadfdd; + border-color: #df382c; +} +.control-group.success > label, +.control-group.success .help-block, +.control-group.success .help-inline { + color: #38b44a; +} +.control-group.success .checkbox, +.control-group.success .radio, +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + color: #38b44a; + border-color: #38b44a; +} +.control-group.success .checkbox:focus, +.control-group.success .radio:focus, +.control-group.success input:focus, +.control-group.success select:focus, +.control-group.success textarea:focus { + border-color: #2c8d3a; + -webkit-box-shadow: 0 0 6px #7cd689; + -moz-box-shadow: 0 0 6px #7cd689; + box-shadow: 0 0 6px #7cd689; +} +.control-group.success .input-prepend .add-on, +.control-group.success .input-append .add-on { + color: #38b44a; + background-color: #caeecf; + border-color: #38b44a; +} +input:focus:required:invalid, +textarea:focus:required:invalid, +select:focus:required:invalid { + color: #b94a48; + border-color: #ee5f5b; +} +input:focus:required:invalid:focus, +textarea:focus:required:invalid:focus, +select:focus:required:invalid: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-actions { + padding: 17px 20px 18px; + margin-top: 18px; + margin-bottom: 18px; + background-color: transparent; + border-top: 1px solid #e5e5e5; + *zoom: 1; +} +.form-actions:before, +.form-actions:after { + display: table; + content: ""; +} +.form-actions:after { + clear: both; +} +.uneditable-input { + overflow: hidden; + white-space: nowrap; + cursor: not-allowed; + background-color: #ffffff; + 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); +} +:-moz-placeholder { + color: #999999; +} +:-ms-input-placeholder { + color: #999999; +} +::-webkit-input-placeholder { + color: #999999; +} +.help-block, +.help-inline { + color: #555555; +} +.help-block { + display: block; + margin-bottom: 9px; +} +.help-inline { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + vertical-align: middle; + padding-left: 5px; +} +.input-prepend, +.input-append { + margin-bottom: 5px; +} +.input-prepend input, +.input-append input, +.input-prepend select, +.input-append select, +.input-prepend .uneditable-input, +.input-append .uneditable-input { + position: relative; + margin-bottom: 0; + *margin-left: 0; + vertical-align: middle; + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-prepend input:focus, +.input-append input:focus, +.input-prepend select:focus, +.input-append select:focus, +.input-prepend .uneditable-input:focus, +.input-append .uneditable-input:focus { + z-index: 2; +} +.input-prepend .uneditable-input, +.input-append .uneditable-input { + border-left-color: #ccc; +} +.input-prepend .add-on, +.input-append .add-on { + display: inline-block; + width: auto; + height: 18px; + min-width: 16px; + padding: 4px 5px; + font-weight: normal; + line-height: 18px; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + vertical-align: middle; + background-color: #f5f5f5; + border: 1px solid #ccc; +} +.input-prepend .add-on, +.input-append .add-on, +.input-prepend .btn, +.input-append .btn { + margin-left: -1px; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.input-prepend .active, +.input-append .active { + background-color: #a3e2ac; + border-color: #38b44a; +} +.input-prepend .add-on, +.input-prepend .btn { + margin-right: -1px; +} +.input-prepend .add-on:first-child, +.input-prepend .btn:first-child { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-append input, +.input-append select, +.input-append .uneditable-input { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-append .uneditable-input { + border-right-color: #ccc; + border-left-color: #eee; +} +.input-append .add-on:last-child, +.input-append .btn:last-child { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-prepend.input-append input, +.input-prepend.input-append select, +.input-prepend.input-append .uneditable-input { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.input-prepend.input-append .add-on:first-child, +.input-prepend.input-append .btn:first-child { + margin-right: -1px; + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-prepend.input-append .add-on:last-child, +.input-prepend.input-append .btn:last-child { + margin-left: -1px; + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.search-query { + padding-right: 14px; + padding-right: 4px \9; + padding-left: 14px; + padding-left: 4px \9; + /* IE7-8 doesn't have border-radius, so don't indent the padding */ + + margin-bottom: 0; + -webkit-border-radius: 14px; + -moz-border-radius: 14px; + border-radius: 14px; +} +.form-search input, +.form-inline input, +.form-horizontal input, +.form-search textarea, +.form-inline textarea, +.form-horizontal textarea, +.form-search select, +.form-inline select, +.form-horizontal select, +.form-search .help-inline, +.form-inline .help-inline, +.form-horizontal .help-inline, +.form-search .uneditable-input, +.form-inline .uneditable-input, +.form-horizontal .uneditable-input, +.form-search .input-prepend, +.form-inline .input-prepend, +.form-horizontal .input-prepend, +.form-search .input-append, +.form-inline .input-append, +.form-horizontal .input-append { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + margin-bottom: 0; +} +.form-search .hide, +.form-inline .hide, +.form-horizontal .hide { + display: none; +} +.form-search label, +.form-inline label { + display: inline-block; +} +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + margin-bottom: 0; +} +.form-search .radio, +.form-search .checkbox, +.form-inline .radio, +.form-inline .checkbox { + padding-left: 0; + margin-bottom: 0; + vertical-align: middle; +} +.form-search .radio input[type="radio"], +.form-search .checkbox input[type="checkbox"], +.form-inline .radio input[type="radio"], +.form-inline .checkbox input[type="checkbox"] { + float: left; + margin-right: 3px; + margin-left: 0; +} +.control-group { + margin-bottom: 9px; +} +legend + .control-group { + margin-top: 18px; + -webkit-margin-top-collapse: separate; +} +.form-horizontal .control-group { + margin-bottom: 18px; + *zoom: 1; +} +.form-horizontal .control-group:before, +.form-horizontal .control-group:after { + display: table; + content: ""; +} +.form-horizontal .control-group:after { + clear: both; +} +.form-horizontal .control-label { + float: left; + width: 140px; + padding-top: 5px; + text-align: right; +} +.form-horizontal .controls { + *display: inline-block; + *padding-left: 20px; + margin-left: 160px; + *margin-left: 0; +} +.form-horizontal .controls:first-child { + *padding-left: 160px; +} +.form-horizontal .help-block { + margin-top: 9px; + margin-bottom: 0; +} +.form-horizontal .form-actions { + padding-left: 160px; +} +table { + max-width: 100%; + background-color: transparent; + border-collapse: collapse; + border-spacing: 0; +} +.table { + width: 100%; + margin-bottom: 18px; +} +.table th, +.table td { + padding: 8px; + line-height: 18px; + text-align: left; + vertical-align: top; + border-top: 1px solid #dddddd; +} +.table th { + font-weight: bold; +} +.table thead th { + vertical-align: bottom; +} +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; +} +.table tbody + tbody { + border-top: 2px solid #dddddd; +} +.table-condensed th, +.table-condensed td { + padding: 4px 5px; +} +.table-bordered { + border: 1px solid #dddddd; + border-collapse: separate; + *border-collapse: collapsed; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.table-bordered th, +.table-bordered td { + border-left: 1px solid #dddddd; +} +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; +} +.table-bordered thead:first-child tr:first-child th:first-child, +.table-bordered tbody:first-child tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; +} +.table-bordered thead:first-child tr:first-child th:last-child, +.table-bordered tbody:first-child tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; +} +.table-bordered thead:last-child tr:last-child th:first-child, +.table-bordered tbody:last-child 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; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; +} +.table-bordered thead:last-child tr:last-child th:last-child, +.table-bordered tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; +} +.table-striped tbody tr:nth-child(odd) td, +.table-striped tbody tr:nth-child(odd) th { + background-color: #f9f9f9; +} +.table tbody tr:hover td, +.table tbody tr:hover th { + background-color: #f5f5f5; +} +table .span1 { + float: none; + width: 44px; + margin-left: 0; +} +table .span2 { + float: none; + width: 124px; + margin-left: 0; +} +table .span3 { + float: none; + width: 204px; + margin-left: 0; +} +table .span4 { + float: none; + width: 284px; + margin-left: 0; +} +table .span5 { + float: none; + width: 364px; + margin-left: 0; +} +table .span6 { + float: none; + width: 444px; + margin-left: 0; +} +table .span7 { + float: none; + width: 524px; + margin-left: 0; +} +table .span8 { + float: none; + width: 604px; + margin-left: 0; +} +table .span9 { + float: none; + width: 684px; + margin-left: 0; +} +table .span10 { + float: none; + width: 764px; + margin-left: 0; +} +table .span11 { + float: none; + width: 844px; + margin-left: 0; +} +table .span12 { + float: none; + width: 924px; + margin-left: 0; +} +table .span13 { + float: none; + width: 1004px; + margin-left: 0; +} +table .span14 { + float: none; + width: 1084px; + margin-left: 0; +} +table .span15 { + float: none; + width: 1164px; + margin-left: 0; +} +table .span16 { + float: none; + width: 1244px; + margin-left: 0; +} +table .span17 { + float: none; + width: 1324px; + margin-left: 0; +} +table .span18 { + float: none; + width: 1404px; + margin-left: 0; +} +table .span19 { + float: none; + width: 1484px; + margin-left: 0; +} +table .span20 { + float: none; + width: 1564px; + margin-left: 0; +} +table .span21 { + float: none; + width: 1644px; + margin-left: 0; +} +table .span22 { + float: none; + width: 1724px; + margin-left: 0; +} +table .span23 { + float: none; + width: 1804px; + margin-left: 0; +} +table .span24 { + float: none; + width: 1884px; + margin-left: 0; +} +[class^="icon-"], +[class*=" icon-"] { + display: inline-block; + width: 14px; + height: 14px; + *margin-right: .3em; + line-height: 14px; + vertical-align: text-top; + background-image: url("../img/glyphicons-halflings.png"); + background-position: 14px 14px; + background-repeat: no-repeat; +} +[class^="icon-"]:last-child, +[class*=" icon-"]:last-child { + *margin-left: 0; +} +.icon-white { + background-image: url("../img/glyphicons-halflings-white.png"); +} +.icon-glass { + background-position: 0 0; +} +.icon-music { + background-position: -24px 0; +} +.icon-search { + background-position: -48px 0; +} +.icon-envelope { + background-position: -72px 0; +} +.icon-heart { + background-position: -96px 0; +} +.icon-star { + background-position: -120px 0; +} +.icon-star-empty { + background-position: -144px 0; +} +.icon-user { + background-position: -168px 0; +} +.icon-film { + background-position: -192px 0; +} +.icon-th-large { + background-position: -216px 0; +} +.icon-th { + background-position: -240px 0; +} +.icon-th-list { + background-position: -264px 0; +} +.icon-ok { + background-position: -288px 0; +} +.icon-remove { + background-position: -312px 0; +} +.icon-zoom-in { + background-position: -336px 0; +} +.icon-zoom-out { + background-position: -360px 0; +} +.icon-off { + background-position: -384px 0; +} +.icon-signal { + background-position: -408px 0; +} +.icon-cog { + background-position: -432px 0; +} +.icon-trash { + background-position: -456px 0; +} +.icon-home { + background-position: 0 -24px; +} +.icon-file { + background-position: -24px -24px; +} +.icon-time { + background-position: -48px -24px; +} +.icon-road { + background-position: -72px -24px; +} +.icon-download-alt { + background-position: -96px -24px; +} +.icon-download { + background-position: -120px -24px; +} +.icon-upload { + background-position: -144px -24px; +} +.icon-inbox { + background-position: -168px -24px; +} +.icon-play-circle { + background-position: -192px -24px; +} +.icon-repeat { + background-position: -216px -24px; +} +.icon-refresh { + background-position: -240px -24px; +} +.icon-list-alt { + background-position: -264px -24px; +} +.icon-lock { + background-position: -287px -24px; +} +.icon-flag { + background-position: -312px -24px; +} +.icon-headphones { + background-position: -336px -24px; +} +.icon-volume-off { + background-position: -360px -24px; +} +.icon-volume-down { + background-position: -384px -24px; +} +.icon-volume-up { + background-position: -408px -24px; +} +.icon-qrcode { + background-position: -432px -24px; +} +.icon-barcode { + background-position: -456px -24px; +} +.icon-tag { + background-position: 0 -48px; +} +.icon-tags { + background-position: -25px -48px; +} +.icon-book { + background-position: -48px -48px; +} +.icon-bookmark { + background-position: -72px -48px; +} +.icon-print { + background-position: -96px -48px; +} +.icon-camera { + background-position: -120px -48px; +} +.icon-font { + background-position: -144px -48px; +} +.icon-bold { + background-position: -167px -48px; +} +.icon-italic { + background-position: -192px -48px; +} +.icon-text-height { + background-position: -216px -48px; +} +.icon-text-width { + background-position: -240px -48px; +} +.icon-align-left { + background-position: -264px -48px; +} +.icon-align-center { + background-position: -288px -48px; +} +.icon-align-right { + background-position: -312px -48px; +} +.icon-align-justify { + background-position: -336px -48px; +} +.icon-list { + background-position: -360px -48px; +} +.icon-indent-left { + background-position: -384px -48px; +} +.icon-indent-right { + background-position: -408px -48px; +} +.icon-facetime-video { + background-position: -432px -48px; +} +.icon-picture { + background-position: -456px -48px; +} +.icon-pencil { + background-position: 0 -72px; +} +.icon-map-marker { + background-position: -24px -72px; +} +.icon-adjust { + background-position: -48px -72px; +} +.icon-tint { + background-position: -72px -72px; +} +.icon-edit { + background-position: -96px -72px; +} +.icon-share { + background-position: -120px -72px; +} +.icon-check { + background-position: -144px -72px; +} +.icon-move { + background-position: -168px -72px; +} +.icon-step-backward { + background-position: -192px -72px; +} +.icon-fast-backward { + background-position: -216px -72px; +} +.icon-backward { + background-position: -240px -72px; +} +.icon-play { + background-position: -264px -72px; +} +.icon-pause { + background-position: -288px -72px; +} +.icon-stop { + background-position: -312px -72px; +} +.icon-forward { + background-position: -336px -72px; +} +.icon-fast-forward { + background-position: -360px -72px; +} +.icon-step-forward { + background-position: -384px -72px; +} +.icon-eject { + background-position: -408px -72px; +} +.icon-chevron-left { + background-position: -432px -72px; +} +.icon-chevron-right { + background-position: -456px -72px; +} +.icon-plus-sign { + background-position: 0 -96px; +} +.icon-minus-sign { + background-position: -24px -96px; +} +.icon-remove-sign { + background-position: -48px -96px; +} +.icon-ok-sign { + background-position: -72px -96px; +} +.icon-question-sign { + background-position: -96px -96px; +} +.icon-info-sign { + background-position: -120px -96px; +} +.icon-screenshot { + background-position: -144px -96px; +} +.icon-remove-circle { + background-position: -168px -96px; +} +.icon-ok-circle { + background-position: -192px -96px; +} +.icon-ban-circle { + background-position: -216px -96px; +} +.icon-arrow-left { + background-position: -240px -96px; +} +.icon-arrow-right { + background-position: -264px -96px; +} +.icon-arrow-up { + background-position: -289px -96px; +} +.icon-arrow-down { + background-position: -312px -96px; +} +.icon-share-alt { + background-position: -336px -96px; +} +.icon-resize-full { + background-position: -360px -96px; +} +.icon-resize-small { + background-position: -384px -96px; +} +.icon-plus { + background-position: -408px -96px; +} +.icon-minus { + background-position: -433px -96px; +} +.icon-asterisk { + background-position: -456px -96px; +} +.icon-exclamation-sign { + background-position: 0 -120px; +} +.icon-gift { + background-position: -24px -120px; +} +.icon-leaf { + background-position: -48px -120px; +} +.icon-fire { + background-position: -72px -120px; +} +.icon-eye-open { + background-position: -96px -120px; +} +.icon-eye-close { + background-position: -120px -120px; +} +.icon-warning-sign { + background-position: -144px -120px; +} +.icon-plane { + background-position: -168px -120px; +} +.icon-calendar { + background-position: -192px -120px; +} +.icon-random { + background-position: -216px -120px; +} +.icon-comment { + background-position: -240px -120px; +} +.icon-magnet { + background-position: -264px -120px; +} +.icon-chevron-up { + background-position: -288px -120px; +} +.icon-chevron-down { + background-position: -313px -119px; +} +.icon-retweet { + background-position: -336px -120px; +} +.icon-shopping-cart { + background-position: -360px -120px; +} +.icon-folder-close { + background-position: -384px -120px; +} +.icon-folder-open { + background-position: -408px -120px; +} +.icon-resize-vertical { + background-position: -432px -119px; +} +.icon-resize-horizontal { + background-position: -456px -118px; +} +.icon-hdd { + background-position: 0 -144px; +} +.icon-bullhorn { + background-position: -24px -144px; +} +.icon-bell { + background-position: -48px -144px; +} +.icon-certificate { + background-position: -72px -144px; +} +.icon-thumbs-up { + background-position: -96px -144px; +} +.icon-thumbs-down { + background-position: -120px -144px; +} +.icon-hand-right { + background-position: -144px -144px; +} +.icon-hand-left { + background-position: -168px -144px; +} +.icon-hand-up { + background-position: -192px -144px; +} +.icon-hand-down { + background-position: -216px -144px; +} +.icon-circle-arrow-right { + background-position: -240px -144px; +} +.icon-circle-arrow-left { + background-position: -264px -144px; +} +.icon-circle-arrow-up { + background-position: -288px -144px; +} +.icon-circle-arrow-down { + background-position: -312px -144px; +} +.icon-globe { + background-position: -336px -144px; +} +.icon-wrench { + background-position: -360px -144px; +} +.icon-tasks { + background-position: -384px -144px; +} +.icon-filter { + background-position: -408px -144px; +} +.icon-briefcase { + background-position: -432px -144px; +} +.icon-fullscreen { + background-position: -456px -144px; +} +.dropup, +.dropdown { + position: relative; +} +.dropdown-toggle { + *margin-bottom: -3px; +} +.dropdown-toggle:active, +.open .dropdown-toggle { + outline: 0; +} +.caret { + display: inline-block; + width: 0; + height: 0; + vertical-align: top; + border-top: 4px solid #000000; + border-right: 4px solid transparent; + border-left: 4px solid transparent; + content: ""; + opacity: 0.3; + filter: alpha(opacity=30); +} +.dropdown .caret { + margin-top: 8px; + margin-left: 2px; +} +.dropdown:hover .caret, +.open .caret { + opacity: 1; + filter: alpha(opacity=100); +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 4px 0; + margin: 1px 0 0; + list-style: none; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + *border-right-width: 2px; + *border-bottom-width: 2px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + *width: 100%; + height: 1px; + margin: 8px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} +.dropdown-menu a { + display: block; + padding: 3px 15px; + clear: both; + font-weight: normal; + line-height: 18px; + color: #33332D; + white-space: nowrap; +} +.dropdown-menu li > a:hover, +.dropdown-menu .active > a, +.dropdown-menu .active > a:hover { + color: #ffffff; + text-decoration: none; + background-color: #33332D; +} +.open { + *z-index: 1000; +} +.open > .dropdown-menu { + display: block; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px solid #000000; + content: "\2191"; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} +.typeahead { + margin-top: 2px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #eee; + border: 1px solid rgba(0, 0, 0, 0.05); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} +.well-large { + padding: 24px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.well-small { + padding: 9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.fade { + opacity: 0; + -webkit-transition: opacity 0.15s linear; + -moz-transition: opacity 0.15s linear; + -ms-transition: opacity 0.15s linear; + -o-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height 0.35s ease; + -moz-transition: height 0.35s ease; + -ms-transition: height 0.35s ease; + -o-transition: height 0.35s ease; + transition: height 0.35s ease; +} +.collapse.in { + height: auto; +} +.close { + float: right; + font-size: 20px; + font-weight: bold; + line-height: 18px; + color: #000000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} +.close:hover { + color: #000000; + text-decoration: none; + cursor: pointer; + opacity: 0.4; + filter: alpha(opacity=40); +} +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} +.btn { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + padding: 4px 10px 4px; + margin-bottom: 0; + font-size: 13px; + line-height: 18px; + *line-height: 20px; + color: #333333; + text-align: center; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); + vertical-align: middle; + cursor: pointer; + background-color: #f5f5f5; + background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -ms-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); + background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); + background-image: linear-gradient(top, #ffffff, #e6e6e6); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0); + border-color: #e6e6e6 #e6e6e6 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #e6e6e6; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + border: 1px solid #cccccc; + *border: 0; + border-bottom-color: #b3b3b3; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + *margin-left: .3em; + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); +} +.btn:hover, +.btn:active, +.btn.active, +.btn.disabled, +.btn[disabled] { + background-color: #e6e6e6; + *background-color: #d9d9d9; +} +.btn:active, +.btn.active { + background-color: #cccccc \9; +} +.btn:first-child { + *margin-left: 0; +} +.btn:hover { + color: #333333; + text-decoration: none; + background-color: #e6e6e6; + *background-color: #d9d9d9; + /* Buttons in IE7 don't get borders, so darken on hover */ + + background-position: 0 -15px; + -webkit-transition: background-position 0.1s linear; + -moz-transition: background-position 0.1s linear; + -ms-transition: background-position 0.1s linear; + -o-transition: background-position 0.1s linear; + transition: background-position 0.1s linear; +} +.btn:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn.active, +.btn:active { + background-color: #e6e6e6; + background-color: #d9d9d9 \9; + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); +} +.btn.disabled, +.btn[disabled] { + cursor: default; + background-color: #e6e6e6; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.btn-large { + padding: 9px 14px; + font-size: 15px; + line-height: normal; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +.btn-large [class^="icon-"] { + margin-top: 1px; +} +.btn-small { + padding: 5px 9px; + font-size: 11px; + line-height: 16px; +} +.btn-small [class^="icon-"] { + margin-top: -1px; +} +.btn-mini { + padding: 2px 6px; + font-size: 11px; + line-height: 14px; +} +.btn-primary, +.btn-primary:hover, +.btn-warning, +.btn-warning:hover, +.btn-danger, +.btn-danger:hover, +.btn-success, +.btn-success:hover, +.btn-info, +.btn-info:hover, +.btn-inverse, +.btn-inverse:hover { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.btn-primary.active, +.btn-warning.active, +.btn-danger.active, +.btn-success.active, +.btn-info.active, +.btn-inverse.active { + color: rgba(255, 255, 255, 0.75); +} +.btn { + border-color: #ccc; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); +} +.btn-primary { + background-color: #dd5c14; + background-image: -moz-linear-gradient(top, #33332D, #dd7a14); + background-image: -ms-linear-gradient(top, #33332D, #dd7a14); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#33332D), to(#dd7a14)); + background-image: -webkit-linear-gradient(top, #33332D, #dd7a14); + background-image: -o-linear-gradient(top, #33332D, #dd7a14); + background-image: linear-gradient(top, #33332D, #dd7a14); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#33332D', endColorstr='#dd7a14', GradientType=0); + border-color: #dd7a14 #dd7a14 #97530e; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #dd7a14; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-primary:hover, +.btn-primary:active, +.btn-primary.active, +.btn-primary.disabled, +.btn-primary[disabled] { + background-color: #dd7a14; + *background-color: #c66d12; +} +.btn-primary:active, +.btn-primary.active { + background-color: #ae6010 \9; +} +.btn-warning { + background-color: #e86537; + background-image: -moz-linear-gradient(top, #ef784e, #33332D); + background-image: -ms-linear-gradient(top, #ef784e, #33332D); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ef784e), to(#33332D)); + background-image: -webkit-linear-gradient(top, #ef784e, #33332D); + background-image: -o-linear-gradient(top, #ef784e, #33332D); + background-image: linear-gradient(top, #ef784e, #33332D); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ef784e', endColorstr='#33332D', GradientType=0); + border-color: #33332D #33332D #9FB4CC; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #33332D; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-warning:hover, +.btn-warning:active, +.btn-warning.active, +.btn-warning.disabled, +.btn-warning[disabled] { + background-color: #33332D; + *background-color: #c64012; +} +.btn-warning:active, +.btn-warning.active { + background-color: #ae3910 \9; +} +.btn-danger { + background-color: #da4f49; + background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -ms-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -o-linear-gradient(top, #ee5f5b, #bd362f); + background-image: linear-gradient(top, #ee5f5b, #bd362f); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#bd362f', GradientType=0); + border-color: #bd362f #bd362f #802420; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #bd362f; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-danger:hover, +.btn-danger:active, +.btn-danger.active, +.btn-danger.disabled, +.btn-danger[disabled] { + background-color: #bd362f; + *background-color: #a9302a; +} +.btn-danger:active, +.btn-danger.active { + background-color: #942a25 \9; +} +.btn-success { + background-color: #5bb75b; + background-image: -moz-linear-gradient(top, #62c462, #51a351); + background-image: -ms-linear-gradient(top, #62c462, #51a351); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351)); + background-image: -webkit-linear-gradient(top, #62c462, #51a351); + background-image: -o-linear-gradient(top, #62c462, #51a351); + background-image: linear-gradient(top, #62c462, #51a351); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#51a351', GradientType=0); + border-color: #51a351 #51a351 #387038; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #51a351; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-success:hover, +.btn-success:active, +.btn-success.active, +.btn-success.disabled, +.btn-success[disabled] { + background-color: #51a351; + *background-color: #499249; +} +.btn-success:active, +.btn-success.active { + background-color: #408140 \9; +} +.btn-info { + background-color: #99356b; + background-image: -moz-linear-gradient(top, #b03d7b, #772953); + background-image: -ms-linear-gradient(top, #b03d7b, #772953); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b03d7b), to(#772953)); + background-image: -webkit-linear-gradient(top, #b03d7b, #772953); + background-image: -o-linear-gradient(top, #b03d7b, #772953); + background-image: linear-gradient(top, #b03d7b, #772953); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b03d7b', endColorstr='#772953', GradientType=0); + border-color: #772953 #772953 #3e152b; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #772953; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-info:hover, +.btn-info:active, +.btn-info.active, +.btn-info.disabled, +.btn-info[disabled] { + background-color: #772953; + *background-color: #642246; +} +.btn-info:active, +.btn-info.active { + background-color: #511c39 \9; +} +.btn-inverse { + background-color: #414141; + background-image: -moz-linear-gradient(top, #555555, #222222); + background-image: -ms-linear-gradient(top, #555555, #222222); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#555555), to(#222222)); + background-image: -webkit-linear-gradient(top, #555555, #222222); + background-image: -o-linear-gradient(top, #555555, #222222); + background-image: linear-gradient(top, #555555, #222222); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#555555', endColorstr='#222222', GradientType=0); + border-color: #222222 #222222 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #222222; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-inverse:hover, +.btn-inverse:active, +.btn-inverse.active, +.btn-inverse.disabled, +.btn-inverse[disabled] { + background-color: #222222; + *background-color: #151515; +} +.btn-inverse:active, +.btn-inverse.active { + background-color: #080808 \9; +} +button.btn, +input[type="submit"].btn { + *padding-top: 2px; + *padding-bottom: 2px; +} +button.btn::-moz-focus-inner, +input[type="submit"].btn::-moz-focus-inner { + padding: 0; + border: 0; +} +button.btn.btn-large, +input[type="submit"].btn.btn-large { + *padding-top: 7px; + *padding-bottom: 7px; +} +button.btn.btn-small, +input[type="submit"].btn.btn-small { + *padding-top: 3px; + *padding-bottom: 3px; +} +button.btn.btn-mini, +input[type="submit"].btn.btn-mini { + *padding-top: 1px; + *padding-bottom: 1px; +} +.btn-group { + position: relative; + *zoom: 1; + *margin-left: .3em; +} +.btn-group:before, +.btn-group:after { + display: table; + content: ""; +} +.btn-group:after { + clear: both; +} +.btn-group:first-child { + *margin-left: 0; +} +.btn-group + .btn-group { + margin-left: 5px; +} +.btn-toolbar { + margin-top: 9px; + margin-bottom: 9px; +} +.btn-toolbar .btn-group { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; +} +.btn-group > .btn { + position: relative; + float: left; + margin-left: -1px; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.btn-group > .btn:first-child { + margin-left: 0; + -webkit-border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; + border-top-left-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + border-bottom-left-radius: 4px; +} +.btn-group > .btn:last-child, +.btn-group > .dropdown-toggle { + -webkit-border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; + border-bottom-right-radius: 4px; +} +.btn-group > .btn.large:first-child { + margin-left: 0; + -webkit-border-top-left-radius: 6px; + -moz-border-radius-topleft: 6px; + border-top-left-radius: 6px; + -webkit-border-bottom-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + border-bottom-left-radius: 6px; +} +.btn-group > .btn.large:last-child, +.btn-group > .large.dropdown-toggle { + -webkit-border-top-right-radius: 6px; + -moz-border-radius-topright: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + -moz-border-radius-bottomright: 6px; + border-bottom-right-radius: 6px; +} +.btn-group > .btn:hover, +.btn-group > .btn:focus, +.btn-group > .btn:active, +.btn-group > .btn.active { + z-index: 2; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; + -webkit-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + *padding-top: 4px; + *padding-bottom: 4px; +} +.btn-group > .btn-mini.dropdown-toggle { + padding-left: 5px; + padding-right: 5px; +} +.btn-group > .btn-small.dropdown-toggle { + *padding-top: 4px; + *padding-bottom: 4px; +} +.btn-group > .btn-large.dropdown-toggle { + padding-left: 12px; + padding-right: 12px; +} +.btn-group.open .dropdown-toggle { + background-image: none; + -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); +} +.btn-group.open .btn.dropdown-toggle { + background-color: #e6e6e6; +} +.btn-group.open .btn-primary.dropdown-toggle { + background-color: #dd7a14; +} +.btn-group.open .btn-warning.dropdown-toggle { + background-color: #33332D; +} +.btn-group.open .btn-danger.dropdown-toggle { + background-color: #bd362f; +} +.btn-group.open .btn-success.dropdown-toggle { + background-color: #51a351; +} +.btn-group.open .btn-info.dropdown-toggle { + background-color: #772953; +} +.btn-group.open .btn-inverse.dropdown-toggle { + background-color: #222222; +} +.btn .caret { + margin-top: 7px; + margin-left: 0; +} +.btn:hover .caret, +.open.btn-group .caret { + opacity: 1; + filter: alpha(opacity=100); +} +.btn-mini .caret { + margin-top: 5px; +} +.btn-small .caret { + margin-top: 6px; +} +.btn-large .caret { + margin-top: 6px; + border-left-width: 5px; + border-right-width: 5px; + border-top-width: 5px; +} +.dropup .btn-large .caret { + border-bottom: 5px solid #000000; + border-top: 0; +} +.btn-primary .caret, +.btn-warning .caret, +.btn-danger .caret, +.btn-info .caret, +.btn-success .caret, +.btn-inverse .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; + opacity: 0.75; + filter: alpha(opacity=75); +} +.alert { + padding: 8px 35px 8px 14px; + margin-bottom: 18px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + background-color: #fcefd4; + border: 1px solid #fae1c6; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + color: #eca918; +} +.alert-heading { + color: inherit; +} +.alert .close { + position: relative; + top: -2px; + right: -21px; + line-height: 18px; +} +.alert-success { + background-color: #caeecf; + border-color: #b7e8b6; + color: #38b44a; +} +.alert-danger, +.alert-error { + background-color: #fadfdd; + border-color: #f8d0d4; + color: #df382c; +} +.alert-info { + background-color: #e7b8d1; + border-color: #de9ecb; + color: #772953; +} +.alert-block { + padding-top: 14px; + padding-bottom: 14px; +} +.alert-block > p, +.alert-block > ul { + margin-bottom: 0; +} +.alert-block p + p { + margin-top: 5px; +} +.nav { + margin-left: 0; + margin-bottom: 18px; + list-style: none; +} +.nav > li > a { + display: block; +} +.nav > li > a:hover { + text-decoration: none; + background-color: #f5f5f5; +} +.nav > .pull-right { + float: right; +} +.nav .nav-header { + display: block; + padding: 3px 15px; + font-size: 11px; + font-weight: bold; + line-height: 18px; + color: #999999; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + text-transform: uppercase; +} +.nav li + .nav-header { + margin-top: 9px; +} +.nav-list { + padding-left: 15px; + padding-right: 15px; + margin-bottom: 0; +} +.nav-list > li > a, +.nav-list .nav-header { + margin-left: -15px; + margin-right: -15px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); +} +.nav-list > li > a { + padding: 3px 15px; +} +.nav-list > .active > a, +.nav-list > .active > a:hover { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); + background-color: #33332D; +} +.nav-list [class^="icon-"] { + margin-right: 2px; +} +.nav-list .divider { + *width: 100%; + height: 1px; + margin: 8px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} +.nav-tabs, +.nav-pills { + *zoom: 1; +} +.nav-tabs:before, +.nav-pills:before, +.nav-tabs:after, +.nav-pills:after { + display: table; + content: ""; +} +.nav-tabs:after, +.nav-pills:after { + clear: both; +} +.nav-tabs > li, +.nav-pills > li { + float: left; +} +.nav-tabs > li > a, +.nav-pills > li > a { + padding-right: 12px; + padding-left: 12px; + margin-right: 2px; + line-height: 14px; +} +.nav-tabs { + border-bottom: 1px solid #ddd; +} +.nav-tabs > li { + margin-bottom: -1px; +} +.nav-tabs > li > a { + padding-top: 8px; + padding-bottom: 8px; + line-height: 18px; + border: 1px solid transparent; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} +.nav-tabs > li > a:hover { + border-color: #f5f5f5 #f5f5f5 #dddddd; +} +.nav-tabs > .active > a, +.nav-tabs > .active > a:hover { + color: #555555; + background-color: #ffffff; + border: 1px solid #ddd; + border-bottom-color: transparent; + cursor: default; +} +.nav-pills > li > a { + padding-top: 8px; + padding-bottom: 8px; + margin-top: 2px; + margin-bottom: 2px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +.nav-pills > .active > a, +.nav-pills > .active > a:hover { + color: #ffffff; + background-color: #33332D; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li > a { + margin-right: 0; +} +.nav-tabs.nav-stacked { + border-bottom: 0; +} +.nav-tabs.nav-stacked > li > a { + border: 1px solid #ddd; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.nav-tabs.nav-stacked > li:first-child > a { + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} +.nav-tabs.nav-stacked > li:last-child > a { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} +.nav-tabs.nav-stacked > li > a:hover { + border-color: #ddd; + z-index: 2; +} +.nav-pills.nav-stacked > li > a { + margin-bottom: 3px; +} +.nav-pills.nav-stacked > li:last-child > a { + margin-bottom: 1px; +} +.nav-tabs .dropdown-menu { + -webkit-border-radius: 0 0 5px 5px; + -moz-border-radius: 0 0 5px 5px; + border-radius: 0 0 5px 5px; +} +.nav-pills .dropdown-menu { + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.nav-tabs .dropdown-toggle .caret, +.nav-pills .dropdown-toggle .caret { + border-top-color: #33332D; + border-bottom-color: #33332D; + margin-top: 6px; +} +.nav-tabs .dropdown-toggle:hover .caret, +.nav-pills .dropdown-toggle:hover .caret { + border-top-color: #9FB4CC; + border-bottom-color: #9FB4CC; +} +.nav-tabs .active .dropdown-toggle .caret, +.nav-pills .active .dropdown-toggle .caret { + border-top-color: #333333; + border-bottom-color: #333333; +} +.nav > .dropdown.active > a:hover { + color: #000000; + cursor: pointer; +} +.nav-tabs .open .dropdown-toggle, +.nav-pills .open .dropdown-toggle, +.nav > li.dropdown.open.active > a:hover { + color: #ffffff; + background-color: #999999; + border-color: #999999; +} +.nav li.dropdown.open .caret, +.nav li.dropdown.open.active .caret, +.nav li.dropdown.open a:hover .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; + opacity: 1; + filter: alpha(opacity=100); +} +.tabs-stacked .open > a:hover { + border-color: #999999; +} +.tabbable { + *zoom: 1; +} +.tabbable:before, +.tabbable:after { + display: table; + content: ""; +} +.tabbable:after { + clear: both; +} +.tab-content { + overflow: auto; +} +.tabs-below > .nav-tabs, +.tabs-right > .nav-tabs, +.tabs-left > .nav-tabs { + border-bottom: 0; +} +.tab-content > .tab-pane, +.pill-content > .pill-pane { + display: none; +} +.tab-content > .active, +.pill-content > .active { + display: block; +} +.tabs-below > .nav-tabs { + border-top: 1px solid #ddd; +} +.tabs-below > .nav-tabs > li { + margin-top: -1px; + margin-bottom: 0; +} +.tabs-below > .nav-tabs > li > a { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} +.tabs-below > .nav-tabs > li > a:hover { + border-bottom-color: transparent; + border-top-color: #ddd; +} +.tabs-below > .nav-tabs > .active > a, +.tabs-below > .nav-tabs > .active > a:hover { + border-color: transparent #ddd #ddd #ddd; +} +.tabs-left > .nav-tabs > li, +.tabs-right > .nav-tabs > li { + float: none; +} +.tabs-left > .nav-tabs > li > a, +.tabs-right > .nav-tabs > li > a { + min-width: 74px; + margin-right: 0; + margin-bottom: 3px; +} +.tabs-left > .nav-tabs { + float: left; + margin-right: 19px; + border-right: 1px solid #ddd; +} +.tabs-left > .nav-tabs > li > a { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} +.tabs-left > .nav-tabs > li > a:hover { + border-color: #f5f5f5 #dddddd #f5f5f5 #f5f5f5; +} +.tabs-left > .nav-tabs .active > a, +.tabs-left > .nav-tabs .active > a:hover { + border-color: #ddd transparent #ddd #ddd; + *border-right-color: #ffffff; +} +.tabs-right > .nav-tabs { + float: right; + margin-left: 19px; + border-left: 1px solid #ddd; +} +.tabs-right > .nav-tabs > li > a { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} +.tabs-right > .nav-tabs > li > a:hover { + border-color: #f5f5f5 #f5f5f5 #f5f5f5 #dddddd; +} +.tabs-right > .nav-tabs .active > a, +.tabs-right > .nav-tabs .active > a:hover { + border-color: #ddd #ddd #ddd transparent; + *border-left-color: #ffffff; +} +.navbar { + *position: relative; + *z-index: 2; + overflow: visible; + margin-bottom: 18px; +} +.navbar-inner { + min-height: 40px; + padding-left: 20px; + padding-right: 20px; + background-color: #33332D; + background-image: -moz-linear-gradient(top, #CCCC9F, #33332D); + background-image: -ms-linear-gradient(top, #CCCC9F, #33332D); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#CCCC9F), to(#33332D)); + background-image: -webkit-linear-gradient(top, #CCCC9F, #33332D); + background-image: -o-linear-gradient(top, #CCCC9F, #33332D); + background-image: linear-gradient(top, #CCCC9F, #33332D); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ce4213', endColorstr='#33332D', GradientType=0); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 3px rgba(0,0,0,.25), inset 0 -1px 0 rgba(0,0,0,.1); + -moz-box-shadow: 0 1px 3px rgba(0,0,0,.25), inset 0 -1px 0 rgba(0,0,0,.1); + box-shadow: 0 1px 3px rgba(0,0,0,.25), inset 0 -1px 0 rgba(0,0,0,.1); +} +.navbar .container { + width: auto; +} +.nav-collapse.collapse { + height: auto; +} +.navbar { + color: #ffffff; +} +.navbar .brand:hover { + text-decoration: none; +} +.navbar .brand { + float: left; + display: block; + padding: 8px 20px 12px; + margin-left: -20px; + font-size: 20px; + font-weight: 200; + line-height: 1; + color: #ffffff; +} +.navbar .navbar-text { + margin-bottom: 0; + line-height: 40px; +} +.navbar .navbar-link { + color: #ffffff; +} +.navbar .navbar-link:hover { + color: #ffffff; +} +.navbar .btn, +.navbar .btn-group { + margin-top: 5px; +} +.navbar .btn-group .btn { + margin: 0; +} +.navbar-form { + margin-bottom: 0; + *zoom: 1; +} +.navbar-form:before, +.navbar-form:after { + display: table; + content: ""; +} +.navbar-form:after { + clear: both; +} +.navbar-form input, +.navbar-form select, +.navbar-form .radio, +.navbar-form .checkbox { + margin-top: 5px; +} +.navbar-form input, +.navbar-form select { + display: inline-block; + margin-bottom: 0; +} +.navbar-form input[type="image"], +.navbar-form input[type="checkbox"], +.navbar-form input[type="radio"] { + margin-top: 3px; +} +.navbar-form .input-append, +.navbar-form .input-prepend { + margin-top: 6px; + white-space: nowrap; +} +.navbar-form .input-append input, +.navbar-form .input-prepend input { + margin-top: 0; +} +.navbar-search { + position: relative; + float: left; + margin-top: 6px; + margin-bottom: 0; +} +.navbar-search .search-query { + padding: 4px 9px; + font-family: 'Ubuntu', Tahoma, sans-serif; + font-size: 13px; + font-weight: normal; + line-height: 1; + color: #ffffff; + background-color: #f39c7d; + border: 1px solid #c64012; + -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + -webkit-transition: none; + -moz-transition: none; + -ms-transition: none; + -o-transition: none; + transition: none; +} +.navbar-search .search-query:-moz-placeholder { + color: #ffffff; +} +.navbar-search .search-query:-ms-input-placeholder { + color: #ffffff; +} +.navbar-search .search-query::-webkit-input-placeholder { + color: #ffffff; +} +.navbar-search .search-query:focus, +.navbar-search .search-query.focused { + padding: 5px 10px; + color: #333333; + text-shadow: 0 1px 0 #ffffff; + background-color: #ffffff; + border: 0; + -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); + outline: 0; +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; + margin-bottom: 0; +} +.navbar-fixed-top .navbar-inner, +.navbar-fixed-bottom .navbar-inner { + padding-left: 0; + padding-right: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} +.navbar-fixed-top { + top: 0; +} +.navbar-fixed-bottom { + bottom: 0; +} +.navbar .nav { + position: relative; + left: 0; + display: block; + float: left; + margin: 0 10px 0 0; +} +.navbar .nav.pull-right { + float: right; +} +.navbar .nav > li { + display: block; + float: left; +} +.navbar .nav > li > a { + float: none; + padding: 9px 10px 11px; + line-height: 19px; + color: #ffffff; + text-decoration: none; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.navbar .btn { + display: inline-block; + padding: 4px 10px 4px; + margin: 5px 5px 6px; + line-height: 18px; +} +.navbar .btn-group { + margin: 0; + padding: 5px 5px 6px; +} +.navbar .nav > li > a:hover { + background-color: transparent; + color: #ffffff; + text-decoration: none; +} +.navbar .nav .active > a, +.navbar .nav .active > a:hover { + color: #ffffff; + text-decoration: none; + background-color: #33332D; +} +.navbar .divider-vertical { + height: 40px; + width: 1px; + margin: 0 9px; + overflow: hidden; + background-color: #33332D; + border-right: 1px solid #ce4213; +} +.navbar .nav.pull-right { + margin-left: 10px; + margin-right: 0; +} +.navbar .btn-navbar { + display: none; + float: right; + padding: 7px 10px; + margin-left: 5px; + margin-right: 5px; + background-color: #d44413; + background-image: -moz-linear-gradient(top, #ce4213, #33332D); + background-image: -ms-linear-gradient(top, #ce4213, #33332D); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ce4213), to(#33332D)); + background-image: -webkit-linear-gradient(top, #ce4213, #33332D); + background-image: -o-linear-gradient(top, #ce4213, #33332D); + background-image: linear-gradient(top, #ce4213, #33332D); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ce4213', endColorstr='#33332D', GradientType=0); + border-color: #33332D #33332D #9FB4CC; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #33332D; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); + -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); + box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); +} +.navbar .btn-navbar:hover, +.navbar .btn-navbar:active, +.navbar .btn-navbar.active, +.navbar .btn-navbar.disabled, +.navbar .btn-navbar[disabled] { + background-color: #33332D; + *background-color: #c64012; +} +.navbar .btn-navbar:active, +.navbar .btn-navbar.active { + background-color: #ae3910 \9; +} +.navbar .btn-navbar .icon-bar { + display: block; + width: 18px; + height: 2px; + background-color: #f5f5f5; + -webkit-border-radius: 1px; + -moz-border-radius: 1px; + border-radius: 1px; + -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); +} +.btn-navbar .icon-bar + .icon-bar { + margin-top: 3px; +} +.navbar .dropdown-menu:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-bottom-color: rgba(0, 0, 0, 0.2); + position: absolute; + top: -7px; + left: 9px; +} +.navbar .dropdown-menu:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + position: absolute; + top: -6px; + left: 10px; +} +.navbar-fixed-bottom .dropdown-menu:before { + border-top: 7px solid #ccc; + border-top-color: rgba(0, 0, 0, 0.2); + border-bottom: 0; + bottom: -7px; + top: auto; +} +.navbar-fixed-bottom .dropdown-menu:after { + border-top: 6px solid #ffffff; + border-bottom: 0; + bottom: -6px; + top: auto; +} +.navbar .nav li.dropdown .dropdown-toggle .caret, +.navbar .nav li.dropdown.open .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} +.navbar .nav li.dropdown.active .caret { + opacity: 1; + filter: alpha(opacity=100); +} +.navbar .nav li.dropdown.open > .dropdown-toggle, +.navbar .nav li.dropdown.active > .dropdown-toggle, +.navbar .nav li.dropdown.open.active > .dropdown-toggle { + background-color: transparent; +} +.navbar .nav li.dropdown.active > .dropdown-toggle:hover { + color: #ffffff; +} +.navbar .pull-right .dropdown-menu, +.navbar .dropdown-menu.pull-right { + left: auto; + right: 0; +} +.navbar .pull-right .dropdown-menu:before, +.navbar .dropdown-menu.pull-right:before { + left: auto; + right: 12px; +} +.navbar .pull-right .dropdown-menu:after, +.navbar .dropdown-menu.pull-right:after { + left: auto; + right: 13px; +} +.breadcrumb { + padding: 7px 14px; + margin: 0 0 18px; + list-style: none; + background-color: #fbfbfb; + background-image: -moz-linear-gradient(top, #ffffff, #f5f5f5); + background-image: -ms-linear-gradient(top, #ffffff, #f5f5f5); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f5f5f5)); + background-image: -webkit-linear-gradient(top, #ffffff, #f5f5f5); + background-image: -o-linear-gradient(top, #ffffff, #f5f5f5); + background-image: linear-gradient(top, #ffffff, #f5f5f5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f5f5f5', GradientType=0); + border: 1px solid #ddd; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: inset 0 1px 0 #ffffff; + -moz-box-shadow: inset 0 1px 0 #ffffff; + box-shadow: inset 0 1px 0 #ffffff; +} +.breadcrumb li { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + text-shadow: 0 1px 0 #ffffff; +} +.breadcrumb .divider { + padding: 0 5px; + color: #999999; +} +.breadcrumb .active a { + color: #333333; +} +.pagination { + height: 36px; + margin: 18px 0; +} +.pagination ul { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + margin-left: 0; + margin-bottom: 0; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} +.pagination li { + display: inline; +} +.pagination a { + float: left; + padding: 0 14px; + line-height: 34px; + text-decoration: none; + border: 1px solid #ddd; + border-left-width: 0; +} +.pagination a:hover, +.pagination .active a { + background-color: #f5f5f5; +} +.pagination .active a { + color: #999999; + cursor: default; +} +.pagination .disabled span, +.pagination .disabled a, +.pagination .disabled a:hover { + color: #999999; + background-color: transparent; + cursor: default; +} +.pagination li:first-child a { + border-left-width: 1px; + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.pagination li:last-child a { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.pagination-centered { + text-align: center; +} +.pagination-right { + text-align: right; +} +.pager { + margin-left: 0; + margin-bottom: 18px; + list-style: none; + text-align: center; + *zoom: 1; +} +.pager:before, +.pager:after { + display: table; + content: ""; +} +.pager:after { + clear: both; +} +.pager li { + display: inline; +} +.pager a { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} +.pager a:hover { + text-decoration: none; + background-color: #f5f5f5; +} +.pager .next a { + float: right; +} +.pager .previous a { + float: left; +} +.pager .disabled a, +.pager .disabled a:hover { + color: #999999; + background-color: #fff; + cursor: default; +} +.modal-open .dropdown-menu { + z-index: 2050; +} +.modal-open .dropdown.open { + *z-index: 2050; +} +.modal-open .popover { + z-index: 2060; +} +.modal-open .tooltip { + z-index: 2070; +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000000; +} +.modal-backdrop.fade { + opacity: 0; +} +.modal-backdrop, +.modal-backdrop.fade.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +.modal { + position: fixed; + top: 50%; + left: 50%; + z-index: 1050; + overflow: auto; + width: 560px; + margin: -250px 0 0 -280px; + background-color: #ffffff; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, 0.3); + *border: 1px solid #999; + /* IE6-7 */ + + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; +} +.modal.fade { + -webkit-transition: opacity .3s linear, top .3s ease-out; + -moz-transition: opacity .3s linear, top .3s ease-out; + -ms-transition: opacity .3s linear, top .3s ease-out; + -o-transition: opacity .3s linear, top .3s ease-out; + transition: opacity .3s linear, top .3s ease-out; + top: -25%; +} +.modal.fade.in { + top: 50%; +} +.modal-header { + padding: 9px 15px; + border-bottom: 1px solid #eee; +} +.modal-header .close { + margin-top: 2px; +} +.modal-body { + overflow-y: auto; + max-height: 400px; + padding: 15px; +} +.modal-form { + margin-bottom: 0; +} +.modal-footer { + padding: 14px 15px 15px; + margin-bottom: 0; + text-align: right; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + -webkit-box-shadow: inset 0 1px 0 #ffffff; + -moz-box-shadow: inset 0 1px 0 #ffffff; + box-shadow: inset 0 1px 0 #ffffff; + *zoom: 1; +} +.modal-footer:before, +.modal-footer:after { + display: table; + content: ""; +} +.modal-footer:after { + clear: both; +} +.modal-footer .btn + .btn { + margin-left: 5px; + margin-bottom: 0; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.tooltip { + position: absolute; + z-index: 1020; + display: block; + visibility: visible; + padding: 5px; + font-size: 11px; + opacity: 0; + filter: alpha(opacity=0); +} +.tooltip.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +.tooltip.top { + margin-top: -2px; +} +.tooltip.right { + margin-left: 2px; +} +.tooltip.bottom { + margin-top: 2px; +} +.tooltip.left { + margin-left: -2px; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-top: 5px solid #000000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid #000000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-bottom: 5px solid #000000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-right: 5px solid #000000; +} +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + background-color: #000000; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + padding: 5px; +} +.popover.top { + margin-top: -5px; +} +.popover.right { + margin-left: 5px; +} +.popover.bottom { + margin-top: 5px; +} +.popover.left { + margin-left: -5px; +} +.popover.top .arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-top: 5px solid #000000; +} +.popover.right .arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-right: 5px solid #000000; +} +.popover.bottom .arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-bottom: 5px solid #000000; +} +.popover.left .arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid #000000; +} +.popover .arrow { + position: absolute; + width: 0; + height: 0; +} +.popover-inner { + padding: 3px; + width: 280px; + overflow: hidden; + background: #000000; + background: rgba(0, 0, 0, 0.8); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); +} +.popover-title { + padding: 9px 15px; + line-height: 1; + background-color: #f5f5f5; + border-bottom: 1px solid #eee; + -webkit-border-radius: 3px 3px 0 0; + -moz-border-radius: 3px 3px 0 0; + border-radius: 3px 3px 0 0; +} +.popover-content { + padding: 14px; + background-color: #ffffff; + -webkit-border-radius: 0 0 3px 3px; + -moz-border-radius: 0 0 3px 3px; + border-radius: 0 0 3px 3px; + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; +} +.popover-content p, +.popover-content ul, +.popover-content ol { + margin-bottom: 0; +} +.thumbnails { + margin-left: -20px; + list-style: none; + *zoom: 1; +} +.thumbnails:before, +.thumbnails:after { + display: table; + content: ""; +} +.thumbnails:after { + clear: both; +} +.row-fluid .thumbnails { + margin-left: 0; +} +.thumbnails > li { + float: left; + margin-bottom: 18px; + margin-left: 20px; +} +.thumbnail { + display: block; + padding: 4px; + line-height: 1; + border: 1px solid #ddd; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075); +} +a.thumbnail:hover { + border-color: #33332D; + -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); +} +.thumbnail > img { + display: block; + max-width: 100%; + margin-left: auto; + margin-right: auto; +} +.thumbnail .caption { + padding: 9px; +} +.label, +.badge { + font-size: 10.998px; + font-weight: bold; + line-height: 14px; + color: #ffffff; + vertical-align: baseline; + white-space: nowrap; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #999999; +} +.label { + padding: 1px 4px 2px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.badge { + padding: 1px 9px 2px; + -webkit-border-radius: 9px; + -moz-border-radius: 9px; + border-radius: 9px; +} +a.label:hover, +a.badge:hover { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} +.label-important, +.badge-important { + background-color: #df382c; +} +.label-important[href], +.badge-important[href] { + background-color: #bc271c; +} +.label-warning, +.badge-warning { + background-color: #33332D; +} +.label-warning[href], +.badge-warning[href] { + background-color: #ae3910; +} +.label-success, +.badge-success { + background-color: #38b44a; +} +.label-success[href], +.badge-success[href] { + background-color: #2c8d3a; +} +.label-info, +.badge-info { + background-color: #772953; +} +.label-info[href], +.badge-info[href] { + background-color: #511c39; +} +.label-inverse, +.badge-inverse { + background-color: #333333; +} +.label-inverse[href], +.badge-inverse[href] { + background-color: #1a1a1a; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-moz-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-ms-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-o-keyframes progress-bar-stripes { + from { + background-position: 0 0; + } + to { + background-position: 40px 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + overflow: hidden; + height: 18px; + margin-bottom: 18px; + background-color: #f7f7f7; + background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -ms-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9)); + background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: linear-gradient(top, #f5f5f5, #f9f9f9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f5f5f5', endColorstr='#f9f9f9', GradientType=0); + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.progress .bar { + width: 0%; + height: 18px; + color: #ffffff; + font-size: 12px; + text-align: center; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e90d2; + background-image: -moz-linear-gradient(top, #149bdf, #0480be); + background-image: -ms-linear-gradient(top, #149bdf, #0480be); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be)); + background-image: -webkit-linear-gradient(top, #149bdf, #0480be); + background-image: -o-linear-gradient(top, #149bdf, #0480be); + background-image: linear-gradient(top, #149bdf, #0480be); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#149bdf', endColorstr='#0480be', GradientType=0); + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition: width 0.6s ease; + -moz-transition: width 0.6s ease; + -ms-transition: width 0.6s ease; + -o-transition: width 0.6s ease; + transition: width 0.6s ease; +} +.progress-striped .bar { + background-color: #149bdf; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + -webkit-background-size: 40px 40px; + -moz-background-size: 40px 40px; + -o-background-size: 40px 40px; + background-size: 40px 40px; +} +.progress.active .bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -moz-animation: progress-bar-stripes 2s linear infinite; + -ms-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-danger .bar { + background-color: #dd514c; + background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); + background-image: linear-gradient(top, #ee5f5b, #c43c35); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0); +} +.progress-danger.progress-striped .bar { + background-color: #ee5f5b; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-success .bar { + background-color: #5eb95e; + background-image: -moz-linear-gradient(top, #62c462, #57a957); + background-image: -ms-linear-gradient(top, #62c462, #57a957); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957)); + background-image: -webkit-linear-gradient(top, #62c462, #57a957); + background-image: -o-linear-gradient(top, #62c462, #57a957); + background-image: linear-gradient(top, #62c462, #57a957); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0); +} +.progress-success.progress-striped .bar { + background-color: #62c462; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-info .bar { + background-color: #4bb1cf; + background-image: -moz-linear-gradient(top, #5bc0de, #339bb9); + background-image: -ms-linear-gradient(top, #5bc0de, #339bb9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9)); + background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); + background-image: -o-linear-gradient(top, #5bc0de, #339bb9); + background-image: linear-gradient(top, #5bc0de, #339bb9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0); +} +.progress-info.progress-striped .bar { + background-color: #5bc0de; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-warning .bar { + background-color: #e86537; + background-image: -moz-linear-gradient(top, #ef784e, #33332D); + background-image: -ms-linear-gradient(top, #ef784e, #33332D); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ef784e), to(#33332D)); + background-image: -webkit-linear-gradient(top, #ef784e, #33332D); + background-image: -o-linear-gradient(top, #ef784e, #33332D); + background-image: linear-gradient(top, #ef784e, #33332D); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ef784e', endColorstr='#33332D', GradientType=0); +} +.progress-warning.progress-striped .bar { + background-color: #ef784e; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.accordion { + margin-bottom: 18px; +} +.accordion-group { + margin-bottom: 2px; + border: 1px solid #e5e5e5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.accordion-heading { + border-bottom: 0; +} +.accordion-heading .accordion-toggle { + display: block; + padding: 8px 15px; +} +.accordion-toggle { + cursor: pointer; +} +.accordion-inner { + padding: 9px 15px; + border-top: 1px solid #e5e5e5; +} +.carousel { + position: relative; + margin-bottom: 18px; + line-height: 1; +} +.carousel-inner { + overflow: hidden; + width: 100%; + position: relative; +} +.carousel .item { + display: none; + position: relative; + -webkit-transition: 0.6s ease-in-out left; + -moz-transition: 0.6s ease-in-out left; + -ms-transition: 0.6s ease-in-out left; + -o-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} +.carousel .item > img { + display: block; + line-height: 1; +} +.carousel .active, +.carousel .next, +.carousel .prev { + display: block; +} +.carousel .active { + left: 0; +} +.carousel .next, +.carousel .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel .next { + left: 100%; +} +.carousel .prev { + left: -100%; +} +.carousel .next.left, +.carousel .prev.right { + left: 0; +} +.carousel .active.left { + left: -100%; +} +.carousel .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 40%; + left: 15px; + width: 40px; + height: 40px; + margin-top: -20px; + font-size: 60px; + font-weight: 100; + line-height: 30px; + color: #ffffff; + text-align: center; + background: #222222; + border: 3px solid #ffffff; + -webkit-border-radius: 23px; + -moz-border-radius: 23px; + border-radius: 23px; + opacity: 0.5; + filter: alpha(opacity=50); +} +.carousel-control.right { + left: auto; + right: 15px; +} +.carousel-control:hover { + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} +.carousel-caption { + position: absolute; + left: 0; + right: 0; + bottom: 0; + padding: 10px 15px 5px; + background: #333333; + background: rgba(0, 0, 0, 0.75); +} +.carousel-caption h4, +.carousel-caption p { + color: #ffffff; +} +.hero-unit { + padding: 60px; + margin-bottom: 30px; + background-color: #f5f5f5; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + color: inherit; + letter-spacing: -1px; +} +.hero-unit p { + font-size: 18px; + font-weight: 200; + line-height: 27px; + color: inherit; +} +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.hide { + display: none; +} +.show { + display: block; +} +.invisible { + visibility: hidden; +} +.navbar .nav > li > a { + border-right: 1px solid #FFF8E3; + border-left: 1px solid #CCCC9F; +} +.navbar .nav > li > a:hover { + background-color: #9FB4CC; +} +.navbar .nav .active > a, +.navbar .nav .active > a:hover { + background-color: rgba(0, 0, 0, 0.2); +} +.navbar .divider-vertical { + background-color: inherit; + border-right: 0px solid #CE4213; +} +.navbar .navbar-text { + padding: 9px 10px 11px; + line-height: 19px; + color: #ffffff; +} +.navbar .navbar-search .search-query { + margin-bottom: 3px; + border: 1px solid #9FB4CC; +} +.navbar .nav-collapse.in > .nav li > a { + color: #ffffff; + border-left: 0px solid #33332D; + border-right: 0px solid #33332D; +} +.navbar .nav-collapse.in > .nav li > a:hover { + background-color: #9FB4CC; +} +.navbar .nav-collapse.in .navbar-form, +.navbar .nav-collapse.in .navbar-search { + border-top: 0px solid #33332D; + border-bottom: 0px solid #33332D; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.btn-primary { + background-color: #e86537; + background-image: -moz-linear-gradient(top, #ef784e, #33332D); + background-image: -ms-linear-gradient(top, #ef784e, #33332D); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ef784e), to(#33332D)); + background-image: -webkit-linear-gradient(top, #ef784e, #33332D); + background-image: -o-linear-gradient(top, #ef784e, #33332D); + background-image: linear-gradient(top, #ef784e, #33332D); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ef784e', endColorstr='#33332D', GradientType=0); + border-color: #33332D #33332D #9FB4CC; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #33332D; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-primary:hover, +.btn-primary:active, +.btn-primary.active, +.btn-primary.disabled, +.btn-primary[disabled] { + background-color: #33332D; + *background-color: #c64012; +} +.btn-primary:active, +.btn-primary.active { + background-color: #ae3910 \9; +} +.btn-warning { + background-color: #f3c768; + background-image: -moz-linear-gradient(top, #f5d185, #efb73e); + background-image: -ms-linear-gradient(top, #f5d185, #efb73e); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5d185), to(#efb73e)); + background-image: -webkit-linear-gradient(top, #f5d185, #efb73e); + background-image: -o-linear-gradient(top, #f5d185, #efb73e); + background-image: linear-gradient(top, #f5d185, #efb73e); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f5d185', endColorstr='#efb73e', GradientType=0); + border-color: #efb73e #efb73e #cf9311; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #efb73e; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-warning:hover, +.btn-warning:active, +.btn-warning.active, +.btn-warning.disabled, +.btn-warning[disabled] { + background-color: #efb73e; + *background-color: #edae26; +} +.btn-warning:active, +.btn-warning.active { + background-color: #e7a413 \9; +} +.alert { + text-shadow: none; +} +.hero-unit { + border: 1px solid rgba(0, 0, 0, 0.05); + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} +.hero-unit h1 { + line-height: 1.6em; +} +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.hide { + display: none; +} +.show { + display: block; +} +.invisible { + visibility: hidden; +} \ No newline at end of file diff --git a/static/css/colorbox.css b/static/css/colorbox.css new file mode 100644 index 0000000..5ab7cd1 --- /dev/null +++ b/static/css/colorbox.css @@ -0,0 +1,52 @@ +/* + ColorBox Core Style: + The following CSS is consistent between example themes and should not be altered. +*/ +#colorbox, #cboxOverlay, #cboxWrapper{position:absolute; top:0; left:0; z-index:9999; overflow:hidden;} +#cboxOverlay{position:fixed; width:100%; height:100%;} +#cboxMiddleLeft, #cboxBottomLeft{clear:left;} +#cboxContent{position:relative;} +#cboxLoadedContent{overflow:auto;} +#cboxTitle{margin:0;} +#cboxLoadingOverlay, #cboxLoadingGraphic{position:absolute; top:0; left:0; width:100%; height:100%;} +#cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{cursor:pointer;} +.cboxPhoto{float:left; margin:auto; border:0; display:block; max-width:none;} +.cboxIframe{width:100%; height:100%; display:block; border:0;} +#colorbox, #cboxContent, #cboxLoadedContent{box-sizing:content-box;} + +/* + User Style: + Change the following styles to modify the appearance of ColorBox. They are + ordered & tabbed in a way that represents the nesting of the generated HTML. +*/ +#cboxOverlay{background:#000;} +#colorbox{} + #cboxTopLeft{width:14px; height:14px; background:url(../img/colorbox/controls.png) no-repeat 0 0;} + #cboxTopCenter{height:14px; background:url(../img/colorbox/border.png) repeat-x top left;} + #cboxTopRight{width:14px; height:14px; background:url(../img/colorbox/controls.png) no-repeat -36px 0;} + #cboxBottomLeft{width:14px; height:43px; background:url(../img/colorbox/controls.png) no-repeat 0 -32px;} + #cboxBottomCenter{height:43px; background:url(../img/colorbox/border.png) repeat-x bottom left;} + #cboxBottomRight{width:14px; height:43px; background:url(../img/colorbox/controls.png) no-repeat -36px -32px;} + #cboxMiddleLeft{width:14px; background:url(../img/colorbox/controls.png) repeat-y -175px 0;} + #cboxMiddleRight{width:14px; background:url(../img/colorbox/controls.png) repeat-y -211px 0;} + #cboxContent{background:#fff; overflow:visible;} + .cboxIframe{background:#fff;} + #cboxError{padding:50px; border:1px solid #ccc;} + #cboxLoadedContent{margin-bottom:5px;} + #cboxLoadingOverlay{background:url(../img/colorbox/loading_background.png) no-repeat center center;} + #cboxLoadingGraphic{background:url(../img/colorbox/loading.gif) no-repeat center center;} + #cboxTitle{position:absolute; bottom:-25px; left:0; text-align:center; width:100%; font-weight:bold; color:#7C7C7C;} + #cboxCurrent{position:absolute; bottom:-25px; left:58px; font-weight:bold; color:#7C7C7C;} + + #cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{position:absolute; bottom:-29px; background:url(../img/colorbox/controls.png) no-repeat 0px 0px; width:23px; height:23px; text-indent:-9999px;} + #cboxPrevious{left:0px; background-position: -51px -25px;} + #cboxPrevious:hover{background-position:-51px 0px;} + #cboxNext{left:27px; background-position:-75px -25px;} + #cboxNext:hover{background-position:-75px 0px;} + #cboxClose{right:0; background-position:-100px -25px;} + #cboxClose:hover{background-position:-100px 0px;} + + .cboxSlideshow_on #cboxSlideshow{background-position:-125px 0px; right:27px;} + .cboxSlideshow_on #cboxSlideshow:hover{background-position:-150px 0px;} + .cboxSlideshow_off #cboxSlideshow{background-position:-150px -25px; right:27px;} + .cboxSlideshow_off #cboxSlideshow:hover{background-position:-125px 0px;} \ No newline at end of file diff --git a/static/css/fmplayer.css b/static/css/fmplayer.css new file mode 100644 index 0000000..394f5c1 --- /dev/null +++ b/static/css/fmplayer.css @@ -0,0 +1,167 @@ +.player-wrapper { + margin-bottom: 3px; +} + +.player-header { + border: 1px #CCC solid; + border-bottom: 0; + padding: 0px 4px 0px 4px; + background: #C7BF9E; + position: relative; + height: 20px; + overflow: hidden; + -moz-border-radius-topleft: 4px; + border-top-left-radius: 4px; + -webkit-border-top-left-radius: 4px; + -moz-border-radius-topright: 4px; + border-top-right-radius: 4px; + -webkit-border-top-right-radius: 4px; +} + +.player-seekhead { + height: 100%; + position: absolute; + top: 0; + z-index: 1000; + background: none repeat scroll 0 0 #EB0C7A; + height: 92px; + position: absolute; + top: 0; + width: 1px; + z-index: 1001; +} + +.player-body { + height: 104px; + position: relative; + border: 1px #CCC solid; + background-color: #EEE; + -webkit-box-shadow: 0px 0px 7px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0px 0px 7px rgba(0, 0, 0, 0.1); +} + +div.player-body ul.player-controls a { + display: block; + overflow: hidden; + text-indent: -9999px; +} + +.player-title a { + text-decoration: none; + color: #3A1E20; +} + +.player-title li { + display: block; + text-decoration: none; +} + +.player-title li { + font-size: 10px; + line-height: 21px; + color: #C7BF9E; +} + +.cp_container { + border-right: 1px #CCC solid; + +} + +.player-progress { + margin-top: 2px; +} + +.bottom-wrapper { + z-index: 9999; +} + +.player-bottom { + border-top: 1px #CCC solid; + width: 100%; + height: 14px; + color: #423B35; + background-color: #283031; + font-size: 12px; + cursor: pointer; + top: 90px; + z-index: 9999; +} + +.waveform img { + width: 100%; + height: 90px; +} + +.download-progress-overlay { + + background-image: url('../img/download-progress-overlay.png'); + position: absolute; + width: 0px; + height: 81px; + display: block; + background-position: top right; + -webkit-box-shadow: 0px 0px 4px rgba(255, 0, 140, 0.2); +} + +.playhead { + background-image: url('../img/playhead.png'); + position: absolute; + top: 0; + width: 0px; + height: 81px; + display: block; + background-position: top right; + -webkit-box-shadow: 0px 0px 4px rgba(255, 0, 140, 0.2); +} + +/* Listing CSS */ +.audio-listing { + list-style: none; + margin: 0; +} + +.mix-image-image { + height: 100%; + width: 100%; + /* + width: 220px; + height: 120px; + */ + position: relative; + display: block; +} + +.audio-listing-item { + padding-bottom: 15px; +} + +.player-footer { + position: relative; + height: 25px; + padding-top: 12px; + border-bottom: 1px solid #F4F4F4; +} + +.play-button-small { + display: block; + width: 28px; + height: 28px; + border: none; +} + +.play-button-small-playing { + background: url(../img/play.png) no-repeat; +} + +.play-button-small-paused { + background: url(../img/pause.png) no-repeat; +} + +.footer-button { + float: left; + padding-right: 14px; +} + +.footer-button-right { + float: right; +} \ No newline at end of file diff --git a/static/css/style.css b/static/css/style.css new file mode 100644 index 0000000..bb6977c --- /dev/null +++ b/static/css/style.css @@ -0,0 +1,155 @@ +body { + /* background: url(../images/pattern1.jpg) repeat #ffffff;*/ + font-family: 'Lato', sans-serif; + font-size: 14px; + font-weight: 300; + line-height: 1.5em; + padding-top: 45px; + padding-bottom: 40px; + padding-right: 32px; +} + +#header { + margin-top: 20px; +} + +.nav-tabs { + margin-top: 10px; +} + +.bordered { + border-bottom: 3px solid #CEC3B3; +} + +#mix-comments-list ul { + list-style-type: none; +} + +ul.comment-listing .comment-entry { + border-bottom: 1px solid #D2D9E7; +} + +.comment-entry { + padding-top: 5px; +} + +.comment-details { + padding-top: 1px; + padding-left: 5px; + display: table-cell; + vertical-align: top; + width: 10000px; +} + +.image-avatar-small { + float: left; +} + +.image-avatar-small { + width: 32px; + height: 32px; +} + +.socialaccount_provider { + display: block; + height: 116px; + width: 250px; +} + +.signin_button { + display: block; + height: 22px; + width: 150px; + font-size: .1em; +} + +.social_login_providers { + display: inline; + list-style-type: none; +} + +.social_login_providers li { + padding: 7px; + float: left; +} + +#twitter_button { + background: transparent url(../img/signin_twitter.png) top left no-repeat; +} + +#facebook_button { + background: transparent url(../img/signin_facebook.png) top left no-repeat; +} + +#twitter_button:hover, #facebook_button:hover { + background-position: 0px -24px; +} + +#twitter_button:active, #facebook_button:active { + background-position: 0px -48px; +} + +.release-image { + max-width: 100%; + height: 200px; + width: 200px; /* ie8 */ +} + +#release-audio-slide-nav li { + display: inline; + list-style-type: none; + padding-right: 20px; +} + +.selector-button a.on { + background-position: 0 -24px; +} + +.selector-button a { + background-image: url(../img/slide-nav.png); + + float: left; + width: 24px; + height: 24px; + display: inline; + font-size: 11px; + margin: 0 5px 0 0; + line-height: 24px; + font-weight: bold; + text-align: center; + text-decoration: none; + background-position: 0 0; + background-repeat: no-repeat; +} + +.selector-button a:link, .selector-button a:visited { + color: white; + text-decoration: none; +} + +.list-nostyle { + list-style: none outside none; + margin: 0; +} + +.list-horiz li { + float: left; + position: relative; +} + +.bordered-right { + border-right: 1px solid #F2F2F2; +} + +.stats-item { + border-right-color: #E5E5E5; + margin-right: 7px; + padding-right: 7px; +} +.stats{ + border: 0; + font: 0/0 a; + text-shadow: none; + color: transparent; + background-color: transparent; +} \ No newline at end of file diff --git a/static/css/sup.css b/static/css/sup.css new file mode 100644 index 0000000..e69de29 diff --git a/static/img/colorbox/border.png b/static/img/colorbox/border.png new file mode 100644 index 0000000..df13bb6 Binary files /dev/null and b/static/img/colorbox/border.png differ diff --git a/static/img/colorbox/controls.png b/static/img/colorbox/controls.png new file mode 100644 index 0000000..65cfd1d Binary files /dev/null and b/static/img/colorbox/controls.png differ diff --git a/static/img/colorbox/loading.gif b/static/img/colorbox/loading.gif new file mode 100644 index 0000000..b4695d8 Binary files /dev/null and b/static/img/colorbox/loading.gif differ diff --git a/static/img/colorbox/loading_background.png b/static/img/colorbox/loading_background.png new file mode 100644 index 0000000..9de11f4 Binary files /dev/null and b/static/img/colorbox/loading_background.png differ diff --git a/static/img/default-avatar-32.png b/static/img/default-avatar-32.png new file mode 100644 index 0000000..402ced6 Binary files /dev/null and b/static/img/default-avatar-32.png differ diff --git a/static/img/default-avatar.png b/static/img/default-avatar.png new file mode 100644 index 0000000..f0082d1 Binary files /dev/null and b/static/img/default-avatar.png differ diff --git a/static/img/default-track.png b/static/img/default-track.png new file mode 100644 index 0000000..127c523 Binary files /dev/null and b/static/img/default-track.png differ diff --git a/static/img/download-progress-overlay.png b/static/img/download-progress-overlay.png new file mode 100644 index 0000000..23566c3 Binary files /dev/null and b/static/img/download-progress-overlay.png differ diff --git a/static/img/favicon.ico b/static/img/favicon.ico new file mode 100644 index 0000000..8c9109f Binary files /dev/null and b/static/img/favicon.ico differ diff --git a/static/img/glyphicons-halflings-white.png b/static/img/glyphicons-halflings-white.png new file mode 100644 index 0000000..a20760b Binary files /dev/null and b/static/img/glyphicons-halflings-white.png differ diff --git a/static/img/glyphicons-halflings.png b/static/img/glyphicons-halflings.png new file mode 100644 index 0000000..92d4445 Binary files /dev/null and b/static/img/glyphicons-halflings.png differ diff --git a/static/img/info.png b/static/img/info.png new file mode 100644 index 0000000..c315e6f Binary files /dev/null and b/static/img/info.png differ diff --git a/static/img/noise.png b/static/img/noise.png new file mode 100644 index 0000000..3117a83 Binary files /dev/null and b/static/img/noise.png differ diff --git a/static/img/pause.png b/static/img/pause.png new file mode 100644 index 0000000..e8bf675 Binary files /dev/null and b/static/img/pause.png differ diff --git a/static/img/play.png b/static/img/play.png new file mode 100644 index 0000000..0d5be48 Binary files /dev/null and b/static/img/play.png differ diff --git a/static/img/playhead.png b/static/img/playhead.png new file mode 100644 index 0000000..8104653 Binary files /dev/null and b/static/img/playhead.png differ diff --git a/static/img/sheen3.png b/static/img/sheen3.png new file mode 100644 index 0000000..eede1d0 Binary files /dev/null and b/static/img/sheen3.png differ diff --git a/static/img/signin_facebook.png b/static/img/signin_facebook.png new file mode 100644 index 0000000..b011037 Binary files /dev/null and b/static/img/signin_facebook.png differ diff --git a/static/img/signin_twitter.png b/static/img/signin_twitter.png new file mode 100644 index 0000000..2aa4eb5 Binary files /dev/null and b/static/img/signin_twitter.png differ diff --git a/static/img/site-logo-gr.png b/static/img/site-logo-gr.png new file mode 100644 index 0000000..c41539f Binary files /dev/null and b/static/img/site-logo-gr.png differ diff --git a/static/img/slide-nav.png b/static/img/slide-nav.png new file mode 100644 index 0000000..3469943 Binary files /dev/null and b/static/img/slide-nav.png differ diff --git a/static/img/variables.less b/static/img/variables.less new file mode 100644 index 0000000..2a1f7c1 --- /dev/null +++ b/static/img/variables.less @@ -0,0 +1,206 @@ +// Variables.less +// Variables to customize the look and feel of Bootstrap +// Swatch: United +// Version: 2.0.4 +// ----------------------------------------------------- + +// GLOBAL VALUES +// -------------------------------------------------- + + +// Grays +// ------------------------- +@black: #000; +@grayDarker: #222; +@grayDark: #333; +@gray: #555; +@grayLight: #999; +@grayLighter: #F5F5F5; +@white: #fff; + + +// Accent colors +// ------------------------- +@blue: #19B6EE; +@blueDark: #0064cd; +@green: #38B44A; +@red: #DF382C; +@yellow: #EFB73E; +@orange: #DD4814; +@pink: #c3325f; +@purple: #772953; + + +// Scaffolding +// ------------------------- +@bodyBackground: @white; +@textColor: @grayDark; + + +// Links +// ------------------------- +@linkColor: @orange; +@linkColorHover: darken(@linkColor, 15%); + + +// Typography +// ------------------------- +@sansFontFamily: 'Ubuntu', Tahoma, sans-serif; +@serifFontFamily: Georgia, "Times New Roman", Times, serif; +@monoFontFamily: Menlo, Monaco, Consolas, "Courier New", monospace; + +@baseFontSize: 13px; +@baseFontFamily: @sansFontFamily; +@baseLineHeight: 18px; +@altFontFamily: @serifFontFamily; + +@headingsFontFamily: inherit; // empty to use BS default, @baseFontFamily +@headingsFontWeight: bold; // instead of browser default, bold +@headingsColor: inherit; // empty to use BS default, @textColor + + +// Tables +// ------------------------- +@tableBackground: transparent; // overall background-color +@tableBackgroundAccent: #f9f9f9; // for striping +@tableBackgroundHover: #f5f5f5; // for hover +@tableBorder: #ddd; // table and cell border + + +// Buttons +// ------------------------- +@btnBackground: @white; +@btnBackgroundHighlight: darken(@white, 10%); +@btnBorder: darken(@white, 20%); + +@btnPrimaryBackground: @linkColor; +@btnPrimaryBackgroundHighlight: spin(@btnPrimaryBackground, 15%); + +@btnInfoBackground: lighten(@purple, 15%); +@btnInfoBackgroundHighlight: @purple; + +@btnSuccessBackground: #62c462; +@btnSuccessBackgroundHighlight: #51a351; + +@btnWarningBackground: lighten(@orange, 15%); +@btnWarningBackgroundHighlight: @orange; + +@btnDangerBackground: #ee5f5b; +@btnDangerBackgroundHighlight: #bd362f; + +@btnInverseBackground: @gray; +@btnInverseBackgroundHighlight: @grayDarker; + + +// Forms +// ------------------------- +@inputBackground: @white; +@inputBorder: #ccc; +@inputBorderRadius: 3px; +@inputDisabledBackground: @grayLighter; +@formActionsBackground: transparent; + +// Dropdowns +// ------------------------- +@dropdownBackground: @white; +@dropdownBorder: rgba(0,0,0,.2); +@dropdownLinkColor: @linkColor; +@dropdownLinkColorHover: @white; +@dropdownLinkBackgroundHover: @linkColor; +@dropdownDividerTop: #e5e5e5; +@dropdownDividerBottom: @white; + + + +// COMPONENT VARIABLES +// -------------------------------------------------- + +// Z-index master list +// ------------------------- +// Used for a bird's eye view of components dependent on the z-axis +// Try to avoid customizing these :) +@zindexDropdown: 1000; +@zindexPopover: 1010; +@zindexTooltip: 1020; +@zindexFixedNavbar: 1030; +@zindexModalBackdrop: 1040; +@zindexModal: 1050; + + +// Sprite icons path +// ------------------------- +@iconSpritePath: "../img/glyphicons-halflings.png"; +@iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; + + +// Input placeholder text color +// ------------------------- +@placeholderText: @grayLight; + + +// Hr border color +// ------------------------- +@hrBorder: @grayLighter; + + +// Navbar +// ------------------------- +@navbarHeight: 40px; +@navbarBackground: @orange; +@navbarBackgroundHighlight: #CE4213; + +@navbarText: @white; +@navbarLinkColor: @white; +@navbarLinkColorHover: @white; +@navbarLinkColorActive: @navbarLinkColorHover; +@navbarLinkBackgroundHover: transparent; +@navbarLinkBackgroundActive: @navbarBackground; + +@navbarSearchBackground: lighten(@navbarBackground, 25%); +@navbarSearchBackgroundFocus: @white; +@navbarSearchBorder: darken(@navbarSearchBackground, 30%); +@navbarSearchPlaceholderColor: @white; +@navbarBrandColor: @navbarLinkColor; + + +// Hero unit +// ------------------------- +@heroUnitBackground: @grayLighter; +@heroUnitHeadingColor: inherit; +@heroUnitLeadColor: inherit; + + +// Form states and alerts +// ------------------------- +@warningText: #ECA918; +@warningBackground: lighten(@warningText, 40%); +@warningBorder: darken(spin(@warningBackground, -10), 3%); + +@errorText: #DF382C; +@errorBackground: lighten(@errorText, 40%); +@errorBorder: darken(spin(@errorBackground, -10), 3%); + +@successText: #38B44A; +@successBackground: lighten(@successText, 40%); +@successBorder: darken(spin(@successBackground, -10), 5%); + +@infoText: @purple; +@infoBackground: lighten(@purple, 50%); +@infoBorder: darken(spin(@infoBackground, -10), 7%); + + + +// GRID +// -------------------------------------------------- + +// Default 940px grid +// ------------------------- +@gridColumns: 12; +@gridColumnWidth: 60px; +@gridGutterWidth: 20px; +@gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); + +// Fluid grid +// ------------------------- +@fluidGridColumnWidth: 6.382978723%; +@fluidGridGutterWidth: 2.127659574%; diff --git a/static/js/app/app.js b/static/js/app/app.js new file mode 100644 index 0000000..32f32bc --- /dev/null +++ b/static/js/app/app.js @@ -0,0 +1,92 @@ +var AppRouter = Backbone.Router.extend({ + routes:{ + "application/":"defaultRoute", + "/mixes":"mixList", + "/mixes/:type":"mixList", + "/mix/:id":"mixDetails", + "/releases":"releaseList", + "/release/:id":"releaseDetails", + "/accounts/login/":"login", + "/accounts/logout/":"logout" + }, + initialize:function () { + this.headerView = new HeaderView(); + $('#header').html(this.headerView.el); + this.sidebarView = new SidebarView(); + //$('#sidebar').html(this.sidebarView.el); + $('#site-content-fill').html(''); + }, + defaultRoute:function (path) { + if (path == "" || path == "/") + this.mixList(0); + }, + mixList:function (type) { + var mixList = new MixCollection(); + mixList.type = type || 'latest'; + $('#site-content-fill').html(''); + var data = type != undefined ? $.param({sort: type}) : null; + mixList.fetch({ + data: data, + success:function () { + var content = new MixListView({collection:mixList}).el; + $('#content').html(content); + } + }); + }, + mixDetails:function (id) { + var mix = new Mix({id:id}); + mix.fetch({success:function () { + var html = new MixView({model:mix}); + $('#content').html(html.el); + $('#site-content-fill').html(''); + var comments = new CommentCollection(); + comments.url = window.appSettings.urlRoot + mix.attributes.item_url + "/comments/"; + comments.mix_id = id; + comments.mix = mix.get("resource_uri"); + comments.fetch({success:function (data) { + var content = new CommentListView({collection:comments}).render(); + $('#site-content-fill').html(content.el); + }}); + }}); + }, + releaseList:function (page) { + + }, + releaseDetails:function (id) { + var release = new Release({id:id}); + $('#site-content-fill').html(''); + release.fetch({success:function () { + var content = new ReleaseView({model:release}).el; + $('#content').html(content); + var audio = new ReleaseAudioCollection(); + audio.url = window.appSettings.urlRoot + release.attributes.item_url + "/release_audio/"; + audio.audio_id = id; + audio.release = release.get("resource_uri"); + audio.fetch({success:function (data) { + var content = new ReleaseAudioListView({collection:audio}); + $('#release-description').html(content.el); + }}); + }}); + }, + login:function () { + $.colorbox({ + href:"/tpl/LoginView/", + onClosed:function () { + app.navigate('/'); + } + }) + }, + logout:function () { + window.utils.showAlert("Success", "You are now logged out", "alert-success"); + } +}); + +utils.loadTemplate([ + 'HeaderView', 'SidebarView', + 'MixListView', 'MixItemView', 'MixView', + 'CommentListView', 'CommentItemView', + 'ReleaseListView', 'ReleaseItemView', 'ReleaseView', 'ReleaseAudioListView', 'ReleaseAudioItemView'], function () { + window.app = new AppRouter(); + Backbone.history.start(); +}); +var _eventAggregator = _.extend({}, Backbone.Events); diff --git a/static/js/app/models/comment.js b/static/js/app/models/comment.js new file mode 100644 index 0000000..3784090 --- /dev/null +++ b/static/js/app/models/comment.js @@ -0,0 +1,10 @@ +var Comment = TastypieModel.extend({ + urlRoot:window.appSettings.urlRoot + "comments/" +}); + +var CommentCollection = TastypieCollection.extend({ + model:Comment, + comparator: function(comment){ + return -comment.get("id"); + } +}); \ No newline at end of file diff --git a/static/js/app/models/mix.js b/static/js/app/models/mix.js new file mode 100644 index 0000000..ccdad19 --- /dev/null +++ b/static/js/app/models/mix.js @@ -0,0 +1,7 @@ +window.Mix = TastypieModel.extend({ + urlRoot:window.appSettings.urlRoot + "mix/" +}); +window.MixCollection = TastypieCollection.extend({ + url:window.appSettings.urlRoot + "mix/", + model:Mix +}); diff --git a/static/js/app/models/release.js b/static/js/app/models/release.js new file mode 100644 index 0000000..c48e785 --- /dev/null +++ b/static/js/app/models/release.js @@ -0,0 +1,7 @@ +var Release = TastypieModel.extend({ + urlRoot:window.appSettings.urlRoot + "release/" +}); +var ReleaseCollection = TastypieCollection.extend({ + url:window.appSettings.urlRoot + "release/", + model:Release +}); diff --git a/static/js/app/models/release_audio.js b/static/js/app/models/release_audio.js new file mode 100644 index 0000000..4080ff7 --- /dev/null +++ b/static/js/app/models/release_audio.js @@ -0,0 +1,7 @@ +var ReleaseAudio = TastypieModel.extend({ + urlRoot:window.appSettings.urlRoot + "release_audio/" +}); + +var ReleaseAudioCollection = TastypieCollection.extend({ + model:ReleaseAudio +}); \ No newline at end of file diff --git a/static/js/app/settings.js b/static/js/app/settings.js new file mode 100644 index 0000000..2e97aa3 --- /dev/null +++ b/static/js/app/settings.js @@ -0,0 +1,4 @@ +if (!window.appSettings){ + window.appSettings = {}; + appSettings.urlRoot = "/api/v1/"; +} \ No newline at end of file diff --git a/static/js/app/site.js b/static/js/app/site.js new file mode 100644 index 0000000..fc68e28 --- /dev/null +++ b/static/js/app/site.js @@ -0,0 +1,38 @@ +$(document).ajaxSend(function (event, xhr, settings) { + function getCookie(name) { + var cookieValue = null; + if (document.cookie && document.cookie != '') { + var cookies = document.cookie.split(';'); + for (var i = 0; i < cookies.length; i++) { + var cookie = jQuery.trim(cookies[i]); + // Does this cookie string begin with the name we want? + if (cookie.substring(0, name.length + 1) == (name + '=')) { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; + } + + function sameOrigin(url) { + // url could be relative or scheme relative or absolute + var host = document.location.host; // host + port + var protocol = document.location.protocol; + var sr_origin = '//' + host; + var origin = protocol + sr_origin; + // Allow absolute or scheme relative URLs to same origin + return (url == origin || url.slice(0, origin.length + 1) == origin + '/') || + (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') || + // or any other URL that isn't scheme relative or absolute i.e relative. + !(/^(\/\/|http:|https:).*/.test(url)); + } + + function safeMethod(method) { + return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); + } + + if (!safeMethod(settings.type) && sameOrigin(settings.url)) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); + } +}); \ No newline at end of file diff --git a/static/js/app/utils.js b/static/js/app/utils.js new file mode 100644 index 0000000..47ff0a3 --- /dev/null +++ b/static/js/app/utils.js @@ -0,0 +1,90 @@ +window.utils = { + // Asynchronously load templates located in separate .html files + loadTemplate:function (views, callback) { + + var deferreds = []; + + $.each(views, function (index, view) { + if (window[view]) { + deferreds.push($.get('/tpl/' + view + '/', function (data) { + window[view].prototype.template = _.template(data); + })); + } else { + alert(view + " not found"); + } + }); + + $.when.apply(null, deferreds).done(callback); + }, + + uploadFile:function (file, callbackSuccess) { + var self = this; + var data = new FormData(); + data.append('file', file); + $.ajax({ + url:'api/upload.php', + type:'POST', + data:data, + processData:false, + cache:false, + contentType:false + }) + .done(function () { + console.log(file.name + " uploaded successfully"); + callbackSuccess(); + }) + .fail(function () { + self.showAlert('Error!', 'An error occurred while uploading ' + file.name, 'alert-error'); + }); + }, + + displayValidationErrors:function (messages) { + for (var key in messages) { + if (messages.hasOwnProperty(key)) { + this.addValidationError(key, messages[key]); + } + } + this.showAlert('Warning!', 'Fix validation errors and try again', 'alert-warning'); + }, + + addValidationError:function (field, message) { + var controlGroup = $('#' + field).parent().parent(); + controlGroup.addClass('error'); + $('.help-inline', controlGroup).html(message); + }, + + removeValidationError:function (field) { + var controlGroup = $('#' + field).parent().parent(); + controlGroup.removeClass('error'); + $('.help-inline', controlGroup).html(''); + }, + + showAlert:function (title, text, klass) { + $('.alert').removeClass("alert-error alert-warning alert-success alert-info"); + $('.alert').addClass(klass); + $('.alert').html('' + title + ' ' + text); + $('.alert').show(); + }, + + hideAlert:function () { + $('.alert').hide(); + } + +}; + +window.TastypieModel = Backbone.Model.extend({ + base_url:function () { + var temp_url = Backbone.Model.prototype.url.call(this); + return (temp_url.charAt(temp_url.length - 1) == '/' ? temp_url : temp_url + '/'); + }, + url:function () { + return this.base_url(); + } +}); + +window.TastypieCollection = Backbone.Collection.extend({ + parse:function (response) { + this.recent_meta = response.meta || {}; + return response.objects || response; + } +}); diff --git a/static/js/app/views/comment.js b/static/js/app/views/comment.js new file mode 100644 index 0000000..e75f17f --- /dev/null +++ b/static/js/app/views/comment.js @@ -0,0 +1,46 @@ +window.CommentItemView = Backbone.View.extend({ + tagName:"li", + initialize:function () { + $(this.el).data("id", this.model.get("id")); + $(this.el).addClass("comment-entry"); + }, + render:function () { + $(this.el).html(this.template({"item":this.model.toJSON()})); + return this; + } +}); +window.CommentListView = Backbone.View.extend({ + initialize:function () { + //this.collection.bind('add', this.render); + }, + events:{ + "click #id-btn-add-comment":"addComment" + }, + addComment:function (ev) { + var comment = $('textarea[name=new-comment]').val(); + var view = this; + if (comment) { + this.collection.create({ + mix:this.collection.mix, + comment:comment, + time_index:15 + }, { + success:function () { + view.collection.sort(); + view.render(); + }, + error:function () { + utils.showAlert("Error", "Unable to save comment", "alert-error"); + }}); + $('textarea[name=new-comment]').val(''); + } + return false; + }, + render:function () { + $(this.el).html(this.template()).append('
    '); + this.collection.each(function (item) { + $('.comment-listing', this.el).append(new CommentItemView({model:item}).render().el); + }, this); + return this; + } +}); diff --git a/static/js/app/views/header.js b/static/js/app/views/header.js new file mode 100644 index 0000000..d2172ac --- /dev/null +++ b/static/js/app/views/header.js @@ -0,0 +1,54 @@ +window.HeaderView = Backbone.View.extend({ + events:{ + "click #header-play-pause-button":"togglePlayState", + "click #header-live-button":"playLive" + }, + initialize:function () { + this.render(); + _.bindAll(this, "trackChanged"); + _.bindAll(this, "trackPlaying"); + _.bindAll(this, "trackPaused"); + _eventAggregator.bind("track_changed", this.trackChanged); + _eventAggregator.bind("track_playing", this.trackPlaying); + _eventAggregator.bind("track_paused", this.trackPaused); + }, + trackChanged:function (data) { + $(this.el).find('#track-description').text(data.title); + }, + trackPlaying:function (data) { + $(this.el).find('#header-play-button-icon').removeClass('icon-play'); + $(this.el).find('#header-play-button-icon').addClass('icon-pause'); + }, + trackPaused:function (data) { + $(this.el).find('#header-play-button-icon').removeClass('icon-pause'); + $(this.el).find('#header-play-button-icon').addClass('icon-play'); + }, + render:function () { + $(this.el).html(this.template()); + return this; + }, + playLive:function () { + dssSoundHandler.playLive(); + _eventAggregator.trigger("track_playing") + var button = $(this.el).find('#header-play-pause-button'); + button.data("mode", "pause"); + $.getJSON( + 'ajax/live_now_playing/', + function (data) { + _eventAggregator.trigger("track_changed", data); + }); + }, + togglePlayState:function () { + var button = $(this.el).find('#header-play-pause-button'); + var mode = button.data("mode"); + if (mode == "play") { + dssSoundHandler.resumeSound(); + _eventAggregator.trigger("track_playing"); + button.data("mode", "pause"); + } else { + dssSoundHandler.pauseSound(); + _eventAggregator.trigger("track_paused"); + button.data("mode", "play"); + } + } +}); \ No newline at end of file diff --git a/static/js/app/views/mix.js b/static/js/app/views/mix.js new file mode 100644 index 0000000..13f43bb --- /dev/null +++ b/static/js/app/views/mix.js @@ -0,0 +1,91 @@ +window.MixItemView = Backbone.View.extend({ + tagName:"li", + events:{ + "click .play-button-small":"playMix", + "click .like-button a":"likeMix", + "click .share-button a":"shareLink" + }, + initialize:function () { + $(this.el).attr("id", "mixitem-" + this.model.get("id")); + $(this.el).addClass("audio-listing-item"); + $(this.el).data("id", this.model.get("id")); + }, + render:function () { + $(this.el).html(this.template({"item":this.model.toJSON()})); + return this; + }, + shareLink:function (e) { + alert("Sharing"); + }, + likeMix:function (e) { + var id = $(e.currentTarget).data("id"); + var mode = $(e.currentTarget).data("mode"); + $.post( + "/ajax/like/", + { dataId:id, dataMode:mode }, + function (data) { + alert(data); + } + ); + }, + playMix:function () { + var id = $(this.el).data("id"); + var mode = "play"; + + //check if we're currently playing a sound + var playingId = dssSoundHandler.getPlayingId(); + if (playingId != -1 && dssSoundHandler.isPlaying()) { + var newMode = dssSoundHandler.togglePlaying(playingId); + //only set the mode if we're toggling an existing track + //otherwise default mode of "play" is what we want + if (playingId == id) + mode = newMode; + } + var button = $(this.el).find('#play-pause-button-small-' + id); + $(button).blur(); + if (mode == "play") { + dssSoundHandler.togglePlayVisual(id); + $.getJSON( + 'ajax/mix_stream_url/' + id + '/', + function (data) { + dssSoundHandler.playSound(id, data.stream_url); + _eventAggregator.trigger("track_changed", data); + _eventAggregator.trigger("track_playing"); + }); + } else if (mode == "resume") { + _eventAggregator.trigger("track_playing"); + } else { + _eventAggregator.trigger("track_paused"); + } + } +}); + +window.MixListView = Backbone.View.extend({ + initialize:function () { + this.render(); + }, + render:function () { + var mixes = this.collection; + var el = this.el; + $(this.el).html(this.template()).append('
      '); + this.collection.each(function (item) { + $('.mix-listing', el).append(new MixItemView({model:item}).render().el); + }); + var type = this.collection.type; + $('#' + type, this.el).parent().addClass('active'); + return this; + } +}); + +window.MixView = Backbone.View.extend({ + initialize:function () { + this.render(); + }, + render:function () { + $(this.el).html(this.template()); + var item = new MixItemView({model:this.model}).render(); + $('.mix-listing', this.el).append(item.el); + $('#mix-description', this.el).html(this.model.get("description")); + return this; + } +}); \ No newline at end of file diff --git a/static/js/app/views/release.js b/static/js/app/views/release.js new file mode 100644 index 0000000..1bd330c --- /dev/null +++ b/static/js/app/views/release.js @@ -0,0 +1,37 @@ +var ReleaseItemView = Backbone.View.extend({ + tagName:"li", + initialize:function () { + /*$(this.el).attr("id", "releaseitem-" + this.model.get("id")); + $(this.el).addClass("release-listing-item"); + $(this.el).data("id", this.model.get("id"));*/ + }, + render:function () { + $(this.el).html(this.template({"item":this.model.toJSON()})); + return this; + } +}); +var ReleaseListView = Backbone.View.extend({ + initialize:function () { + this.render(); + }, + render:function () { + $(this.el).html(this.template()).append('
        '); + var el = this.el; + this.collection.each(function (item) { + $('.release-listing', el).append(new ReleaseItemView({model:item}).render().el); + }); + return this; + } +}); +var ReleaseView = Backbone.View.extend({ + initialize:function () { + this.render(); + }, + render:function () { + $(this.el).html(this.template()); + var item = new ReleaseItemView({model:this.model}).render(); + $('.release-listing', this.el).append(item.el); + $('#release-description', this.el).html(this.model.get("description")); + return this; + } +}); \ No newline at end of file diff --git a/static/js/app/views/release_audio.js b/static/js/app/views/release_audio.js new file mode 100644 index 0000000..f03c2f1 --- /dev/null +++ b/static/js/app/views/release_audio.js @@ -0,0 +1,40 @@ +window.ReleaseAudioItemView = Backbone.View.extend({ + tagName:"li", + initialize:function () { + $(this.el).data("id", this.model.get("id")); + $(this.el).addClass("release-audio-entry"); + }, + render:function () { + $(this.el).html(this.template({"item":this.model.toJSON()})); + return this; + } +}); +window.ReleaseAudioListView = Backbone.View.extend({ + initialize:function () { + this.render(); + + }, + events: { + "click a": "clicked" + }, + clicked: function(e){ + e.preventDefault(); + this.renderItem($(e.currentTarget).attr("id")); + }, + render:function () { + $(this.el).html(this.template()).append('
          '); + var i=0; + this.collection.each(function (item) { + $('#release-audio-slide-nav', this.el).append('
        • ' + (i) + '
        • '); + }, this); + this.renderItem(0); + return this; + }, + renderItem: function(id){ + $('.release-audio-listing', this.el).empty(); + $('#' + id, this.el).blur(); + $('#' + id, this.el).addClass('on'); + $('a:not([id="' + id + '"]', this.el).removeClass('on'); + $('.release-audio-listing', this.el).append(new ReleaseAudioItemView({model:this.collection.models[id]}).render().el); + } +}); diff --git a/static/js/app/views/sidebar.js b/static/js/app/views/sidebar.js new file mode 100644 index 0000000..e7c144f --- /dev/null +++ b/static/js/app/views/sidebar.js @@ -0,0 +1,16 @@ +/** + * Created with PyCharm. + * User: fergalm + * Date: 08/08/12 + * Time: 22:10 + * To change this template use File | Settings | File Templates. + */ +window.SidebarView = Backbone.View.extend({ + initialize: function(){ + this.render(); + }, + render: function(){ + $(this.el).html(this.template()); + return this; + } +}); \ No newline at end of file diff --git a/static/js/dss_sound_handler.js b/static/js/dss_sound_handler.js new file mode 100644 index 0000000..518bc17 --- /dev/null +++ b/static/js/dss_sound_handler.js @@ -0,0 +1,137 @@ +$(document).ready(function () { + soundManager.url = '/static/bin/sm/'; + soundManager.flashVersion = 10; + soundManager.debugMode = false; + soundManager.useHTML5Audio = true; +}); + +function DssSoundHandler() { + var _currentSound = null; + var _currentId = -1; + this.stop_sound = function () { + if (_currentSound) { + this.togglePlaying(this.getPlayingId()); + _currentSound.stop(); + _currentId = -1; + } + }; + this.getPlayingId = function () { + return _currentId; + }; + this.isPlaying = function () { + if (_currentSound != null) + return _currentSound.playState == 1; + }; + + this.togglePlaying = function (id) { + this.togglePlayState(id); + return this.togglePlayVisual(id); + }; + + this.togglePlayVisual = function (id) { + var button = $('#play-pause-button-small-' + id); + var mode = button.data("mode"); + if (mode == "play" || mode == "resume") { + button.data('mode', 'pause'); + button.removeClass('play-button-small-playing'); + button.addClass('play-button-small-paused'); + } else { + button.data('mode', 'resume'); + button.removeClass('play-button-small-paused'); + button.addClass('play-button-small-playing'); + } + return mode; + }; + this.togglePlayState = function (id) { + var button = $('#play-pause-button-small-' + id); + var mode = button.data("mode"); + if (mode == 'pause') + this.pauseSound(); + else if (mode == 'resume') + this.resumeSound(); + }; + this.playSound = (function (itemId, stream_url) { + + _currentId = itemId; + var waveformTop = $('#waveform-' + _currentId).position().top; + var waveformWidth = $('#waveform-' + _currentId).width(); + + $('#player-seekhead').css('top', waveformTop); + if (_currentSound) _currentSound.stop(); + soundManager.destroySound('current_sound'); + _currentSound = soundManager.createSound({ + id:'current_sound', + url:stream_url, + volume:50, + stream:true, + whileloading:function () { + var percentageFinished = (_currentSound.bytesLoaded / _currentSound.bytesTotal) * 100; + var percentageWidth = (waveformWidth / 100) * percentageFinished; + $('#progress-player-' + _currentId).css('width', percentageWidth); + }, + whileplaying:function () { + /* Should move to an aggregator viewChanged callback */ + waveformTop = $('#waveform-' + _currentId).position().top; + waveformWidth = $('#waveform-' + _currentId).width(); + $('#playhead-player-' + _currentId).css('top', waveformTop); + $('#progress-player-' + _currentId).css('top', waveformTop); + $('#player-seekhead').css('top', waveformTop); + + var currentPosition = _currentSound.position; + var totalLength = _currentSound.duration; + var percentageFinished = (currentPosition / totalLength) * 100; + var percentageWidth = (waveformWidth / 100) * percentageFinished; + $('#playhead-player-' + _currentId).css('width', percentageWidth); + } + }); + _currentSound.loaded = false; + _currentSound.readyState = 0; + dssSoundHandler._setupEvents(_currentId, _currentSound); + _currentSound.play(); + }); + this.playLive = function () { + this.stop_sound(); + _currentSound = soundManager.createSound({ + id:'current_sound', + url:'http://streams.deepsouthsounds.com:8000/live', + volume:50, + type:'audio/mp3' + }); + _currentSound.play(); + }; + this.pauseSound = function () { + this.togglePlaying(); + if (_currentSound) { + _currentSound.pause(); + } + }; + this.resumeSound = function () { + this.togglePlaying(); + if (_currentSound) + _currentSound.resume(); + }; + this.getPosition = function () { + if (_currentSound) + return _currentSound.position; + }; + this._setupEvents = function (itemId, sound) { + $('#waveform-' + itemId).mousemove(function (event) { + $('#player-seekhead').show(); + $('#player-seekhead').css('left', (event.pageX) + 'px').fadeIn('fast'); + }); + $('#waveform-' + itemId).mousedown(function (event) { + var width = $('#waveform-image-' + itemId).width(); + if (sound != null) { + var fullLength = sound.duration; + var left = $('#waveform-image-' + itemId).offset().left; + var clickPerc = ((event.pageX - left) / width) * 100; + sound.setPosition((fullLength / 100) * clickPerc); + } + }); + $('#waveform-' + itemId).mouseleave(function (event) { + $('#player-seekhead').hide(); + }); + }; +} +dssSoundHandler = new DssSoundHandler(); +window.dssSoundHandler = dssSoundHandler; diff --git a/static/js/libs/ICanHaz.js b/static/js/libs/ICanHaz.js new file mode 100644 index 0000000..c131265 --- /dev/null +++ b/static/js/libs/ICanHaz.js @@ -0,0 +1,543 @@ +/*! + ICanHaz.js version 0.10 -- by @HenrikJoreteg + More info at: http://icanhazjs.com + */ +(function () { + /* + mustache.js — Logic-less templates in JavaScript + + See http://mustache.github.com/ for more info. + */ + + var Mustache = function () { + var _toString = Object.prototype.toString; + + Array.isArray = Array.isArray || function (obj) { + return _toString.call(obj) == "[object Array]"; + } + + var _trim = String.prototype.trim, trim; + + if (_trim) { + trim = function (text) { + return text == null ? "" : _trim.call(text); + } + } else { + var trimLeft, trimRight; + + // IE doesn't match non-breaking spaces with \s. + if ((/\S/).test("\xA0")) { + trimLeft = /^[\s\xA0]+/; + trimRight = /[\s\xA0]+$/; + } else { + trimLeft = /^\s+/; + trimRight = /\s+$/; + } + + trim = function (text) { + return text == null ? "" : + text.toString().replace(trimLeft, "").replace(trimRight, ""); + } + } + + var escapeMap = { + "&":"&", + "<":"<", + ">":">", + '"':'"', + "'":''' + }; + + function escapeHTML(string) { + return String(string).replace(/&(?!\w+;)|[<>"']/g, function (s) { + return escapeMap[s] || s; + }); + } + + var regexCache = {}; + var Renderer = function () { + }; + + Renderer.prototype = { + otag:"{{", + ctag:"}}", + pragmas:{}, + buffer:[], + pragmas_implemented:{ + "IMPLICIT-ITERATOR":true + }, + context:{}, + + render:function (template, context, partials, in_recursion) { + // reset buffer & set context + if (!in_recursion) { + this.context = context; + this.buffer = []; // TODO: make this non-lazy + } + + // fail fast + if (!this.includes("", template)) { + if (in_recursion) { + return template; + } else { + this.send(template); + return; + } + } + + // get the pragmas together + template = this.render_pragmas(template); + + // render the template + var html = this.render_section(template, context, partials); + + // render_section did not find any sections, we still need to render the tags + if (html === false) { + html = this.render_tags(template, context, partials, in_recursion); + } + + if (in_recursion) { + return html; + } else { + this.sendLines(html); + } + }, + + /* + Sends parsed lines + */ + send:function (line) { + if (line !== "") { + this.buffer.push(line); + } + }, + + sendLines:function (text) { + if (text) { + var lines = text.split("\n"); + for (var i = 0; i < lines.length; i++) { + this.send(lines[i]); + } + } + }, + + /* + Looks for %PRAGMAS + */ + render_pragmas:function (template) { + // no pragmas + if (!this.includes("%", template)) { + return template; + } + + var that = this; + var regex = this.getCachedRegex("render_pragmas", function (otag, ctag) { + return new RegExp(otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" + ctag, "g"); + }); + + return template.replace(regex, function (match, pragma, options) { + if (!that.pragmas_implemented[pragma]) { + throw({message:"This implementation of mustache doesn't understand the '" + + pragma + "' pragma"}); + } + that.pragmas[pragma] = {}; + if (options) { + var opts = options.split("="); + that.pragmas[pragma][opts[0]] = opts[1]; + } + return ""; + // ignore unknown pragmas silently + }); + }, + + /* + Tries to find a partial in the curent scope and render it + */ + render_partial:function (name, context, partials) { + name = trim(name); + if (!partials || partials[name] === undefined) { + throw({message:"unknown_partial '" + name + "'"}); + } + if (!context || typeof context[name] != "object") { + return this.render(partials[name], context, partials, true); + } + return this.render(partials[name], context[name], partials, true); + }, + + /* + Renders inverted (^) and normal (#) sections + */ + render_section:function (template, context, partials) { + if (!this.includes("#", template) && !this.includes("^", template)) { + // did not render anything, there were no sections + return false; + } + + var that = this; + + var regex = this.getCachedRegex("render_section", function (otag, ctag) { + // This regex matches _the first_ section ({{#foo}}{{/foo}}), and captures the remainder + return new RegExp( + "^([\\s\\S]*?)" + // all the crap at the beginning that is not {{*}} ($1) + + otag + // {{ + "(\\^|\\#)\\s*(.+)\\s*" + // #foo (# == $2, foo == $3) + ctag + // }} + + "\n*([\\s\\S]*?)" + // between the tag ($2). leading newlines are dropped + + otag + // {{ + "\\/\\s*\\3\\s*" + // /foo (backreference to the opening tag). + ctag + // }} + + "\\s*([\\s\\S]*)$", // everything else in the string ($4). leading whitespace is dropped. + + "g"); + }); + + + // for each {{#foo}}{{/foo}} section do... + return template.replace(regex, function (match, before, type, name, content, after) { + // before contains only tags, no sections + var renderedBefore = before ? that.render_tags(before, context, partials, true) : "", + + // after may contain both sections and tags, so use full rendering function + renderedAfter = after ? that.render(after, context, partials, true) : "", + + // will be computed below + renderedContent, + + value = that.find(name, context); + + if (type === "^") { // inverted section + if (!value || Array.isArray(value) && value.length === 0) { + // false or empty list, render it + renderedContent = that.render(content, context, partials, true); + } else { + renderedContent = ""; + } + } else if (type === "#") { // normal section + if (Array.isArray(value)) { // Enumerable, Let's loop! + renderedContent = that.map(value,function (row) { + return that.render(content, that.create_context(row), partials, true); + }).join(""); + } else if (that.is_object(value)) { // Object, Use it as subcontext! + renderedContent = that.render(content, that.create_context(value), + partials, true); + } else if (typeof value == "function") { + // higher order section + renderedContent = value.call(context, content, function (text) { + return that.render(text, context, partials, true); + }); + } else if (value) { // boolean section + renderedContent = that.render(content, context, partials, true); + } else { + renderedContent = ""; + } + } + + return renderedBefore + renderedContent + renderedAfter; + }); + }, + + /* + Replace {{foo}} and friends with values from our view + */ + render_tags:function (template, context, partials, in_recursion) { + // tit for tat + var that = this; + + var new_regex = function () { + return that.getCachedRegex("render_tags", function (otag, ctag) { + return new RegExp(otag + "(=|!|>|&|\\{|%)?([^#\\^]+?)\\1?" + ctag + "+", "g"); + }); + }; + + var regex = new_regex(); + var tag_replace_callback = function (match, operator, name) { + switch (operator) { + case "!": // ignore comments + return ""; + case "=": // set new delimiters, rebuild the replace regexp + that.set_delimiters(name); + regex = new_regex(); + return ""; + case ">": // render partial + return that.render_partial(name, context, partials); + case "{": // the triple mustache is unescaped + case "&": // & operator is an alternative unescape method + return that.find(name, context); + default: // escape the value + return escapeHTML(that.find(name, context)); + } + }; + var lines = template.split("\n"); + for (var i = 0; i < lines.length; i++) { + lines[i] = lines[i].replace(regex, tag_replace_callback, this); + if (!in_recursion) { + this.send(lines[i]); + } + } + + if (in_recursion) { + return lines.join("\n"); + } + }, + + set_delimiters:function (delimiters) { + var dels = delimiters.split(" "); + this.otag = this.escape_regex(dels[0]); + this.ctag = this.escape_regex(dels[1]); + }, + + escape_regex:function (text) { + // thank you Simon Willison + if (!arguments.callee.sRE) { + var specials = [ + '/', '.', '*', '+', '?', '|', + '(', ')', '[', ']', '{', '}', '\\' + ]; + arguments.callee.sRE = new RegExp( + '(\\' + specials.join('|\\') + ')', 'g' + ); + } + return text.replace(arguments.callee.sRE, '\\$1'); + }, + + /* + find `name` in current `context`. That is find me a value + from the view object + */ + find:function (name, context) { + name = trim(name); + + // Checks whether a value is thruthy or false or 0 + function is_kinda_truthy(bool) { + return bool === false || bool === 0 || bool; + } + + var value; + + // check for dot notation eg. foo.bar + if (name.match(/([a-z_]+)\./ig)) { + var childValue = this.walk_context(name, context); + if (is_kinda_truthy(childValue)) { + value = childValue; + } + } else { + if (is_kinda_truthy(context[name])) { + value = context[name]; + } else if (is_kinda_truthy(this.context[name])) { + value = this.context[name]; + } + } + + if (typeof value == "function") { + return value.apply(context); + } + if (value !== undefined) { + return value; + } + // silently ignore unkown variables + return ""; + }, + + walk_context:function (name, context) { + var path = name.split('.'); + // if the var doesn't exist in current context, check the top level context + var value_context = (context[path[0]] != undefined) ? context : this.context; + var value = value_context[path.shift()]; + while (value != undefined && path.length > 0) { + value_context = value; + value = value[path.shift()]; + } + // if the value is a function, call it, binding the correct context + if (typeof value == "function") { + return value.apply(value_context); + } + return value; + }, + + // Utility methods + + /* includes tag */ + includes:function (needle, haystack) { + return haystack.indexOf(this.otag + needle) != -1; + }, + + // by @langalex, support for arrays of strings + create_context:function (_context) { + if (this.is_object(_context)) { + return _context; + } else { + var iterator = "."; + if (this.pragmas["IMPLICIT-ITERATOR"]) { + iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator; + } + var ctx = {}; + ctx[iterator] = _context; + return ctx; + } + }, + + is_object:function (a) { + return a && typeof a == "object"; + }, + + /* + Why, why, why? Because IE. Cry, cry cry. + */ + map:function (array, fn) { + if (typeof array.map == "function") { + return array.map(fn); + } else { + var r = []; + var l = array.length; + for (var i = 0; i < l; i++) { + r.push(fn(array[i])); + } + return r; + } + }, + + getCachedRegex:function (name, generator) { + var byOtag = regexCache[this.otag]; + if (!byOtag) { + byOtag = regexCache[this.otag] = {}; + } + + var byCtag = byOtag[this.ctag]; + if (!byCtag) { + byCtag = byOtag[this.ctag] = {}; + } + + var regex = byCtag[name]; + if (!regex) { + regex = byCtag[name] = generator(this.otag, this.ctag); + } + + return regex; + } + }; + + return({ + name:"mustache.js", + version:"0.4.0", + + /* + Turns a template and view into HTML + */ + to_html:function (template, view, partials, send_fun) { + var renderer = new Renderer(); + if (send_fun) { + renderer.send = send_fun; + } + renderer.render(template, view || {}, partials); + if (!send_fun) { + return renderer.buffer.join("\n"); + } + } + }); + }(); + /*! + ICanHaz.js -- by @HenrikJoreteg + */ + /*global */ + (function () { + function trim(stuff) { + if (''.trim) return stuff.trim(); + else return stuff.replace(/^\s+/, '').replace(/\s+$/, ''); + } + + var ich = { + VERSION:"0.10", + templates:{}, + + // grab jquery or zepto if it's there + $:(typeof window !== 'undefined') ? window.jQuery || window.Zepto || null : null, + + // public function for adding templates + // can take a name and template string arguments + // or can take an object with name/template pairs + // We're enforcing uniqueness to avoid accidental template overwrites. + // If you want a different template, it should have a different name. + addTemplate:function (name, templateString) { + if (typeof name === 'object') { + for (var template in name) { + this.addTemplate(template, name[template]); + } + return; + } + if (ich[name]) { + console.error("Invalid name: " + name + "."); + } else if (ich.templates[name]) { + console.error("Template \"" + name + " \" exists"); + } else { + ich.templates[name] = templateString; + ich[name] = function (data, raw) { + data = data || {}; + var result = Mustache.to_html(ich.templates[name], data, ich.templates); + return (ich.$ && !raw) ? ich.$(result) : result; + }; + } + }, + + // clears all retrieval functions and empties cache + clearAll:function () { + for (var key in ich.templates) { + delete ich[key]; + } + ich.templates = {}; + }, + + // clears/grabs + refresh:function () { + ich.clearAll(); + ich.grabTemplates(); + }, + + // grabs templates from the DOM and caches them. + // Loop through and add templates. + // Whitespace at beginning and end of all templates inside +{% endblock %} diff --git a/templates/account/login.html b/templates/account/login.html new file mode 100644 index 0000000..38d51ee --- /dev/null +++ b/templates/account/login.html @@ -0,0 +1,53 @@ +{% extends "account/base.html" %} + +{% load i18n %} +{% load account_tags %} +{% load url from future %} + +{% block head_title %}{% trans "Sign In" %}{% endblock %} + + +{% block content %} + +

          {% trans "Sign In" %}

          + +{% if not user.is_authenticated %} + +{% if socialaccount.providers %} +

          {% blocktrans with site.name as site_name %}Please sign in with one +of your existing third party accounts. Or, sign up for a {{site_name}} account and sign in +below:{% endblocktrans %}

          + +
          + +
            +{% include "socialaccount/snippets/provider_list.html" %} +
          + + + +
          + +{% include "socialaccount/snippets/login_extra.html" %} + +{% endif %} +{% endif %} + + + +{% if user.is_authenticated %} +{% include "account/snippets/already_logged_in.html" %} +{% endif %} + + +{% endblock %} + diff --git a/templates/account/logout.html b/templates/account/logout.html new file mode 100644 index 0000000..da8f7a2 --- /dev/null +++ b/templates/account/logout.html @@ -0,0 +1,19 @@ +{% extends "account/base.html" %} + +{% load i18n %} + +{% block head_title %}{% trans "Signed Out" %}{% endblock %} + +{% block content %} +

          {% trans "Signed Out" %}

          + +

          {% trans "You have signed out." %}

          +{% endblock %} + +{% block footerscripts %} + +{% endblock %} \ No newline at end of file diff --git a/templates/account/password_change.html b/templates/account/password_change.html new file mode 100644 index 0000000..cf3d7b1 --- /dev/null +++ b/templates/account/password_change.html @@ -0,0 +1,14 @@ +{% extends "account/base.html" %} + +{% load i18n %} +{% block head_title %}{% trans "Change Password" %}{% endblock %} + +{% block content %} +

          {% trans "Change Password" %}

          + +
          + {% csrf_token %} + {{ password_change_form.as_p }} + +
          +{% endblock %} diff --git a/templates/account/password_delete.html b/templates/account/password_delete.html new file mode 100644 index 0000000..ade1c48 --- /dev/null +++ b/templates/account/password_delete.html @@ -0,0 +1,14 @@ +{% extends "account/base.html" %} + +{% load i18n %} + +{% block head_title %}{% trans "Delete Password" %}{% endblock %} + +{% block content %} +

          {% trans "Delete Password" %}

          +

          {% blocktrans %}You may delete your password since you are currently logged in using OpenID.{% endblocktrans %}

          +
          + {% csrf_token %} + +
          +{% endblock %} diff --git a/templates/account/password_delete_done.html b/templates/account/password_delete_done.html new file mode 100644 index 0000000..5b23700 --- /dev/null +++ b/templates/account/password_delete_done.html @@ -0,0 +1,10 @@ +{% extends "account/base.html" %} + +{% load i18n %} + +{% block head_title %}{% trans "Password Deleted" %}{% endblock %} + +{% block content %} +

          {% trans "Password Deleted" %}

          +

          {% blocktrans %}Your password has been deleted.{% endblocktrans %}

          +{% endblock %} diff --git a/templates/account/password_reset.html b/templates/account/password_reset.html new file mode 100644 index 0000000..92ac0d0 --- /dev/null +++ b/templates/account/password_reset.html @@ -0,0 +1,30 @@ +{% extends "account/base.html" %} + +{% load i18n %} +{% load account_tags %} + +{% block head_title %}{% trans "Password Reset" %}{% endblock %} + +{% block content %} + +

          {% trans "Password Reset" %}

          + {% if user.is_authenticated %} + {% include "account/snippets/already_logged_in.html" %} + {% endif %} + +

          {% trans "Forgotten your password? Enter your e-mail address below, and we'll send you an e-mail allowing you to reset it." %}

          + +
          + {% csrf_token %} + {{ password_reset_form.as_p }} + +
          + +

          {% blocktrans %}If you have any trouble resetting your password, contact us at {{ CONTACT_EMAIL }}.{% endblocktrans %}

          +{% endblock %} + +{% block extra_body %} + +{% endblock %} diff --git a/templates/account/password_reset_done.html b/templates/account/password_reset_done.html new file mode 100644 index 0000000..c9d946c --- /dev/null +++ b/templates/account/password_reset_done.html @@ -0,0 +1,16 @@ +{% extends "account/base.html" %} + +{% load i18n %} +{% load account_tags %} + +{% block head_title %}{% trans "Password Reset" %}{% endblock %} + +{% block content %} +

          {% trans "Password Reset" %}

          + + {% if user.is_authenticated %} + {% include "account/snippets/already_logged_in.html" %} + {% endif %} + +

          {% blocktrans %}We have sent you an e-mail. If you do not receive it within a few minutes, contact us at {{ CONTACT_EMAIL }}.{% endblocktrans %}

          +{% endblock %} diff --git a/templates/account/password_reset_from_key.html b/templates/account/password_reset_from_key.html new file mode 100644 index 0000000..1c93c40 --- /dev/null +++ b/templates/account/password_reset_from_key.html @@ -0,0 +1,24 @@ +{% extends "account/base.html" %} + +{% load url from future %} +{% load i18n %} +{% block head_title %}{% trans "Change Password" %}{% endblock %} + +{% block content %} +

          {% if token_fail %}{% trans "Bad Token" %}{% else %}{% trans "Change Password" %}{% endif %}

          + + {% if token_fail %} + {% url 'account_reset_password' as passwd_reset_url %} +

          {% blocktrans %}The password reset link was invalid, possibly because it has already been used. Please request a new password reset.{% endblocktrans %}

          + {% else %} + {% if form %} +
          + {% csrf_token %} + {{ form.as_p }} + +
          + {% else %} +

          {% trans 'Your password is now changed.' %}

          + {% endif %} + {% endif %} +{% endblock %} diff --git a/templates/account/password_reset_key_message.txt b/templates/account/password_reset_key_message.txt new file mode 100644 index 0000000..1a39222 --- /dev/null +++ b/templates/account/password_reset_key_message.txt @@ -0,0 +1,9 @@ +{% load i18n %}{% blocktrans with site.domain as site_domain and user.username as username %}You're receiving this e-mail because you or someone else has requested a password for your user account at {{site_domain}}. +It can be safely ignored if you did not request a password reset. Click the link below to reset your password. + +{{password_reset_url}} + +In case you forgot, your username is {{username}}. + +Thanks for using our site! +{% endblocktrans %} diff --git a/templates/account/password_set.html b/templates/account/password_set.html new file mode 100644 index 0000000..cf14619 --- /dev/null +++ b/templates/account/password_set.html @@ -0,0 +1,15 @@ +{% extends "account/base.html" %} + +{% load i18n %} + +{% block head_title %}{% trans "Set Password" %}{% endblock %} + +{% block content %} +

          {% trans "Set Password" %}

          + +
          + {% csrf_token %} + {{ password_set_form.as_p }} + +
          +{% endblock %} diff --git a/templates/account/registration_form.html b/templates/account/registration_form.html new file mode 100644 index 0000000..4390572 --- /dev/null +++ b/templates/account/registration_form.html @@ -0,0 +1,6 @@ +{%extends "base.html" %} +{% load crispy_forms_tags %} + +{% block content %} + {% crispy form %} +{% endblock %} \ No newline at end of file diff --git a/templates/account/signup.html b/templates/account/signup.html new file mode 100644 index 0000000..4b80968 --- /dev/null +++ b/templates/account/signup.html @@ -0,0 +1,28 @@ +{% extends "account/base.html" %} + +{% load url from future %} +{% load i18n %} + +{% block head_title %}{% trans "Signup" %}{% endblock %} + +{% block content %} +

          {% trans "Sign Up" %}

          + + {% if user.is_authenticated %} +{% include "account/snippets/already_logged_in.html" %} + {% else %} +

          {% blocktrans %}Already have an account? Then please sign in.{% endblocktrans %}

          + + + + {% endif %} +{% endblock %} + + diff --git a/templates/account/snippets/already_logged_in.html b/templates/account/snippets/already_logged_in.html new file mode 100644 index 0000000..d038ef5 --- /dev/null +++ b/templates/account/snippets/already_logged_in.html @@ -0,0 +1,5 @@ +{% load i18n %} +{% load account_tags %} + +{% user_display user as user_display %} +

          {% trans "Note" %}: {% blocktrans %}you are already logged in as {{ user_display }}.{% endblocktrans %}

          diff --git a/templates/account/user_details.html b/templates/account/user_details.html new file mode 100644 index 0000000..bc3a1da --- /dev/null +++ b/templates/account/user_details.html @@ -0,0 +1,22 @@ +{%extends "base.html" %} +{% load crispy_forms_tags %} +{% block scripts %} + + + +{% endblock %} +{% block content %} +{% crispy form form.helper %} +{% endblock %} \ No newline at end of file diff --git a/templates/account/verification_sent.html b/templates/account/verification_sent.html new file mode 100644 index 0000000..c59655c --- /dev/null +++ b/templates/account/verification_sent.html @@ -0,0 +1,12 @@ +{% extends "account/base.html" %} + +{% load i18n %} + +{% block head_title %}{% trans "Verify Your E-mail Address" %}{% endblock %} + +{% block content %} +

          {% trans "Verify Your E-mail Address" %}

          + +

          {% blocktrans %}We have sent you an e-mail to {{ email }} for verification. Follow the link provided to finalize the signup process. If you do not receive it within a few minutes, contact us at {{ CONTACT_EMAIL }}.{% endblocktrans %}

          + +{% endblock %} diff --git a/templates/account/verified_email_required.html b/templates/account/verified_email_required.html new file mode 100644 index 0000000..634355c --- /dev/null +++ b/templates/account/verified_email_required.html @@ -0,0 +1,26 @@ +{% extends "account/base.html" %} + +{% load url from future %} +{% load i18n %} + +{% block head_title %}{% trans "Verify Your E-mail Address" %}{% endblock %} + +{% block content %} +

          {% trans "Verify Your E-mail Address" %}

          + +{% url 'account_email' as email_url %} + +

          {% blocktrans %}This part of the site requires us to verify that +you are who you claim to be. For this purpose, we require that you +verify ownership of your e-mail address. {% endblocktrans %}

          + +

          {% blocktrans %}We have sent an e-mail to you for +verification. Please click on the link inside this +e-mail. If you do not receive it within a few minutes, contact us +at {{ CONTACT_EMAIL }}. +{% endblocktrans %}

          + +

          {% blocktrans %}Note: you can still change your e-mail address.{% endblocktrans %}

          + + +{% endblock %} diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..9fc0ed3 --- /dev/null +++ b/templates/base.html @@ -0,0 +1,87 @@ + + + + + + + + + + Deep South Sounds + + + + + + + + + + + + + + + + + + + +{% include 'inc/ancient_browser.html' %} +
          +
          + +
          +
          + +
          +
          +
          + {% block content %} + + {% endblock %} +
          +
          + {% block sidecontent %} + + {% endblock %} + +
          +
          + +
          +
          + + + + + + + + + + + + + + + + + + + + + + + + +{% block footerscripts %} +{% endblock %} + + + \ No newline at end of file diff --git a/templates/emailconfirmation/confirm_email.html b/templates/emailconfirmation/confirm_email.html new file mode 100644 index 0000000..f696e13 --- /dev/null +++ b/templates/emailconfirmation/confirm_email.html @@ -0,0 +1,20 @@ +{% extends "account/base.html" %} + +{% load i18n %} +{% load account_tags %} + +{% block head_title %}{% trans "E-mail Address Confirmation" %}{% endblock %} + + +{% block content %} + {% user_display email_address.user as user_display %} + +

          {% trans "E-mail Address Confirmation" %}

          + + {% if email_address %} + +

          {% blocktrans with email_address.email as email %}You have confirmed that {{ email }} is an e-mail address for user {{ user_display }}.{% endblocktrans %}

          + {% else %} +

          {% trans "Invalid confirmation key." %}

          + {% endif %} +{% endblock %} diff --git a/templates/emailconfirmation/email_confirmation_message.txt b/templates/emailconfirmation/email_confirmation_message.txt new file mode 100644 index 0000000..13b4257 --- /dev/null +++ b/templates/emailconfirmation/email_confirmation_message.txt @@ -0,0 +1,4 @@ +{% load account_tags %}{% user_display user as user_display %}{% load i18n %}{% autoescape off %}{% blocktrans with current_site.name as site_name %}User {{ user_display }} at {{ site_name }} has given this as an email address. + +To confirm this is correct, go to {{ activate_url }} +{% endblocktrans %}{% endautoescape %} diff --git a/templates/emailconfirmation/email_confirmation_subject.txt b/templates/emailconfirmation/email_confirmation_subject.txt new file mode 100644 index 0000000..605a924 --- /dev/null +++ b/templates/emailconfirmation/email_confirmation_subject.txt @@ -0,0 +1,5 @@ +{% load i18n %}{% autoescape off %}[{{current_site.name}}] {% blocktrans %}Confirm E-mail Address{% endblocktrans %}{% endautoescape %}{% comment %} +Local Variables: +require-final-newline: nil; +End: +{% endcomment %} \ No newline at end of file diff --git a/templates/inc/_MixItemInsert.html b/templates/inc/_MixItemInsert.html new file mode 100644 index 0000000..8333fa4 --- /dev/null +++ b/templates/inc/_MixItemInsert.html @@ -0,0 +1,69 @@ +
          + {% if model.has_image %} +
          +
          + mix-logo +
          +
          + {% endif %} +
          + +
          + +
          + Waveform generating... Stall the balls and check back later. + +
          +
          +
          +
          + +
          +
          diff --git a/templates/inc/ancient_browser.html b/templates/inc/ancient_browser.html new file mode 100644 index 0000000..8fa3cc2 --- /dev/null +++ b/templates/inc/ancient_browser.html @@ -0,0 +1,3 @@ + diff --git a/templates/inc/app.html b/templates/inc/app.html new file mode 100644 index 0000000..b32f008 --- /dev/null +++ b/templates/inc/app.html @@ -0,0 +1,17 @@ +{% extends 'base.html' %} +{% block footerscripts %} + +{% endblock %} + +{% block content %} +
          + +
          + +
          + +
          +{% endblock %} + +{% block sidecontent %} +{% endblock %} \ No newline at end of file diff --git a/templates/inc/comment_list.html b/templates/inc/comment_list.html new file mode 100644 index 0000000..cab47d3 --- /dev/null +++ b/templates/inc/comment_list.html @@ -0,0 +1,15 @@ +
          + + + + +
          + + <%= item.user_name %> + +
          +

          <%= item.comment %>

          + <%= item.date_created %> +
          +
          +
          diff --git a/templates/inc/mix_edit_toolbar.html b/templates/inc/mix_edit_toolbar.html new file mode 100644 index 0000000..b764f4a --- /dev/null +++ b/templates/inc/mix_edit_toolbar.html @@ -0,0 +1,74 @@ + + + +
          +
          + + Play + + {% if model.user.user == user %} + + + + {% endif %} +
          +
          diff --git a/templates/inc/track_player_ajax.html b/templates/inc/track_player_ajax.html new file mode 100644 index 0000000..e69de29 diff --git a/templates/inc/twitter.html b/templates/inc/twitter.html new file mode 100644 index 0000000..558ac47 --- /dev/null +++ b/templates/inc/twitter.html @@ -0,0 +1,41 @@ + + + + \ No newline at end of file diff --git a/templates/openid/base.html b/templates/openid/base.html new file mode 100644 index 0000000..7e8ac08 --- /dev/null +++ b/templates/openid/base.html @@ -0,0 +1 @@ +{% extends "socialaccount/base.html" %} diff --git a/templates/openid/login.html b/templates/openid/login.html new file mode 100644 index 0000000..e0900c7 --- /dev/null +++ b/templates/openid/login.html @@ -0,0 +1,19 @@ +{% extends "openid/base.html" %} + +{% load url from future %} +{% load i18n %} + +{% block head_title %}OpenID Sign In{% endblock %} + +{% block content %} + +

          {% trans 'OpenID Sign In' %}

          + + + + +{% endblock %} diff --git a/templates/socialaccount/account_inactive.html b/templates/socialaccount/account_inactive.html new file mode 100644 index 0000000..9d295e4 --- /dev/null +++ b/templates/socialaccount/account_inactive.html @@ -0,0 +1,11 @@ +{% extends "socialaccount/base.html" %} + +{% load i18n %} + +{% block head_title %}{% trans "Account Inactive" %}{% endblock %} + +{% block content %} +

          {% trans "Account Inactive" %}

          + +

          {% trans "This account is inactive." %}

          +{% endblock %} diff --git a/templates/socialaccount/authentication_error.html b/templates/socialaccount/authentication_error.html new file mode 100644 index 0000000..ae11a5e --- /dev/null +++ b/templates/socialaccount/authentication_error.html @@ -0,0 +1,11 @@ +{% extends "socialaccount/base.html" %} + +{% load i18n %} + +{% block head_title %}{% trans "Social Network Login Failure" %}{% endblock %} + +{% block content %} +

          {% trans "Social Network Login Failure" %}

          + +

          {% trans "An error occured while attempting to login via your social network account." %}

          +{% endblock %} diff --git a/templates/socialaccount/base.html b/templates/socialaccount/base.html new file mode 100644 index 0000000..0f400ed --- /dev/null +++ b/templates/socialaccount/base.html @@ -0,0 +1,2 @@ +{% extends "account/base.html" %} + diff --git a/templates/socialaccount/connections.html b/templates/socialaccount/connections.html new file mode 100644 index 0000000..9de05ac --- /dev/null +++ b/templates/socialaccount/connections.html @@ -0,0 +1,56 @@ +{% extends "socialaccount/base.html" %} + +{% load i18n %} + +{% block head_title %}{% trans "Account Connections" %}{% endblock %} + +{% block content %} +

          {% trans "Account Connections" %}

          + +{% if form.accounts %} +

          {% blocktrans %}You can sign in to your account using any of the following third party accounts:{% endblocktrans %}

          + + +
          +{% csrf_token %} + +
          +{% if form.non_field_errors %} +
          {{form.non_field_errors}}
          +{% endif %} + +{% for base_account in form.accounts %} +{% with base_account.get_provider_account as account %} +
          + +
          +{% endwith %} +{% endfor %} + +
          + +
          + +
          + +
          + +{% else %} +

          You currently have no social network accounts connected to this account.

          +{% endif %} + +

          {% trans 'Add a 3rd Party Account' %}

          + +
            +{% include "socialaccount/snippets/provider_list.html" %} +
          + +{% include "socialaccount/snippets/login_extra.html" %} + +{% endblock %} + + diff --git a/templates/socialaccount/login_cancelled.html b/templates/socialaccount/login_cancelled.html new file mode 100644 index 0000000..74be043 --- /dev/null +++ b/templates/socialaccount/login_cancelled.html @@ -0,0 +1,17 @@ +{% extends "socialaccount/base.html" %} + +{% load url from future %} +{% load i18n %} + +{% block head_title %}{% trans "Login Cancelled" %}{% endblock %} + +{% block content %} + +

          {% trans "Login Cancelled" %}

          + +{% url 'socialaccount_login' as login_url %} + +

          {% blocktrans %}You decided to cancel logging in to our site using one of your exisiting accounts. If this was a mistake, please proceed to sign in.{% endblocktrans %}

          + +{% endblock %} + diff --git a/templates/socialaccount/signup.html b/templates/socialaccount/signup.html new file mode 100644 index 0000000..b854ef9 --- /dev/null +++ b/templates/socialaccount/signup.html @@ -0,0 +1,25 @@ +{% extends "socialaccount/base.html" %} + +{% load i18n %} + +{% block head_title %}{% trans "Signup" %}{% endblock %} + +{% block content %} +

          {% trans "Sign Up" %}

          + +

          {% blocktrans with provider_name=account.get_provider.name site_name=site.name %}You are about to use your {{provider_name}} account to login to +{{site_name}}. As a final step, please complete the following form:{% endblocktrans %}

          + + + + +{% endblock %} + + diff --git a/templates/socialaccount/snippets/login_extra.html b/templates/socialaccount/snippets/login_extra.html new file mode 100644 index 0000000..4dfecaf --- /dev/null +++ b/templates/socialaccount/snippets/login_extra.html @@ -0,0 +1,4 @@ +{% load socialaccount_tags %} + +{% providers_media_js %} + diff --git a/templates/socialaccount/snippets/provider_list.html b/templates/socialaccount/snippets/provider_list.html new file mode 100644 index 0000000..ed637d1 --- /dev/null +++ b/templates/socialaccount/snippets/provider_list.html @@ -0,0 +1,19 @@ +{% load socialaccount_tags %} + +{% for provider in socialaccount.providers %} +{% if provider.id == "openid" %} +{% for brand in provider.get_brands %} +
        • + {{brand.name}} +
        • +{% endfor %} +{% endif %} +
        • + {{provider.name}} +
        • +{% endfor %} + diff --git a/templates/views/CommentItemView.html b/templates/views/CommentItemView.html new file mode 100644 index 0000000..cab47d3 --- /dev/null +++ b/templates/views/CommentItemView.html @@ -0,0 +1,15 @@ +
          + + + + +
          + + <%= item.user_name %> + +
          +

          <%= item.comment %>

          + <%= item.date_created %> +
          +
          +
          diff --git a/templates/views/CommentListView.html b/templates/views/CommentListView.html new file mode 100644 index 0000000..26781dd --- /dev/null +++ b/templates/views/CommentListView.html @@ -0,0 +1,12 @@ +
          + {% if request.user.is_authenticated %} +
          + + +
          + {% else %} +

          Please login to add comments

          + {% endif %} +
          +

          Comments

          +
          diff --git a/templates/views/HeaderView.html b/templates/views/HeaderView.html new file mode 100644 index 0000000..bd6f815 --- /dev/null +++ b/templates/views/HeaderView.html @@ -0,0 +1,47 @@ +{% load account_tags %} + diff --git a/templates/views/LoginView.html b/templates/views/LoginView.html new file mode 100644 index 0000000..1121141 --- /dev/null +++ b/templates/views/LoginView.html @@ -0,0 +1,46 @@ + + +{% load socialaccount_tags %} + +
          +

          Login to Deep South Sounds

          +
          + +
          +
          + + {% include "socialaccount/snippets/login_extra.html" %} +
          + {% csrf_token %} + {% if form.errors %} +

          Warning!

          + Unknown username or password. +
          + {% endif %} +
          +
          + + +
          + +
          + + +
          + +
          + +
          +
          +
          + Sign up +
          \ No newline at end of file diff --git a/templates/views/MixItemView.html b/templates/views/MixItemView.html new file mode 100644 index 0000000..9ff79b3 --- /dev/null +++ b/templates/views/MixItemView.html @@ -0,0 +1 @@ +{% include 'inc/_MixItemInsert.html' %} \ No newline at end of file diff --git a/templates/views/MixListView.html b/templates/views/MixListView.html new file mode 100644 index 0000000..571b63d --- /dev/null +++ b/templates/views/MixListView.html @@ -0,0 +1,8 @@ + +
          \ No newline at end of file diff --git a/templates/views/MixView.html b/templates/views/MixView.html new file mode 100644 index 0000000..48b8777 --- /dev/null +++ b/templates/views/MixView.html @@ -0,0 +1,4 @@ +
          +
            +
            +
            diff --git a/templates/views/ReleaseAudioItemView.html b/templates/views/ReleaseAudioItemView.html new file mode 100644 index 0000000..8ac6720 --- /dev/null +++ b/templates/views/ReleaseAudioItemView.html @@ -0,0 +1,2 @@ +{% include 'inc/_MixItemInsert.html' %} +
          • <%= item.description %>
          • diff --git a/templates/views/ReleaseAudioListView.html b/templates/views/ReleaseAudioListView.html new file mode 100644 index 0000000..d195fcd --- /dev/null +++ b/templates/views/ReleaseAudioListView.html @@ -0,0 +1,110 @@ + +
            +
              +
            +
            \ No newline at end of file diff --git a/templates/views/ReleaseItemView.html b/templates/views/ReleaseItemView.html new file mode 100644 index 0000000..b8a6a6e --- /dev/null +++ b/templates/views/ReleaseItemView.html @@ -0,0 +1,19 @@ +
            +
            +
            +

            + <%= item.release_date %> +  -  + <%= item.release_artist %>

            +
            +
            +
            +
            + +
            +
            + <%= item.release_description %> +
            +
            +
            +
            \ No newline at end of file diff --git a/templates/views/ReleaseListView.html b/templates/views/ReleaseListView.html new file mode 100644 index 0000000..20f84f0 --- /dev/null +++ b/templates/views/ReleaseListView.html @@ -0,0 +1 @@ +
            \ No newline at end of file diff --git a/templates/views/ReleaseView.html b/templates/views/ReleaseView.html new file mode 100644 index 0000000..84e4d9b --- /dev/null +++ b/templates/views/ReleaseView.html @@ -0,0 +1,5 @@ +
            +
              +
              + +
              \ No newline at end of file diff --git a/templates/views/SidebarView.html b/templates/views/SidebarView.html new file mode 100644 index 0000000..eec58de --- /dev/null +++ b/templates/views/SidebarView.html @@ -0,0 +1 @@ +{% include 'inc/twitter.html' %} \ No newline at end of file diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..12c335c --- /dev/null +++ b/utils.py @@ -0,0 +1,3 @@ +import os +def here(x): + return os.path.join(os.path.abspath(os.path.dirname(__file__)), x)