diff --git a/.gitignore b/.gitignore index 27fc33727..96186b465 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,7 @@ html/ coverage/ build/ dist/ -djangorestframework.egg-info/ +rest_framework.egg-info/ MANIFEST !.gitignore diff --git a/MANIFEST.in b/MANIFEST.in index 5c6a1c578..00e450866 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,2 @@ -recursive-include djangorestframework/static *.ico *.txt *.css -recursive-include djangorestframework/templates *.txt *.html -recursive-include examples .keep *.py *.txt -recursive-include docs *.py *.rst *.html *.txt -include AUTHORS LICENSE CHANGELOG.rst requirements.txt tox.ini +recursive-include rest_framework/static *.js *.css *.png +recursive-include rest_framework/templates *.txt *.html diff --git a/README.md b/README.md index 314500520..92490bd47 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,6 @@ For more information, check out [the documentation][docs], in particular, the tu * Python (2.6, 2.7) * Django (1.3, 1.4, 1.5) -* [URLObject][urlobject] (2.0.0+) **Optional:** @@ -29,7 +28,7 @@ For more information, check out [the documentation][docs], in particular, the tu Install using `pip`... - pip install djangorestframework + pip install rest_framework ...or clone the project from github. @@ -48,7 +47,7 @@ To build the docs. To run the tests. - ./djangorestframework/runtests/runtests.py + ./rest_framework/runtests/runtests.py # Changelog diff --git a/djangorestframework/response.py b/djangorestframework/response.py deleted file mode 100644 index e1366bdb7..000000000 --- a/djangorestframework/response.py +++ /dev/null @@ -1,173 +0,0 @@ -""" -The :mod:`response` module provides :class:`Response` and :class:`ImmediateResponse` classes. - -`Response` is a subclass of `HttpResponse`, and can be similarly instantiated and returned -from any view. It is a bit smarter than Django's `HttpResponse`, for it renders automatically -its content to a serial format by using a list of :mod:`renderers`. - -To determine the content type to which it must render, default behaviour is to use standard -HTTP Accept header content negotiation. But `Response` also supports overriding the content type -by specifying an ``_accept=`` parameter in the URL. Also, `Response` will ignore `Accept` headers -from Internet Explorer user agents and use a sensible browser `Accept` header instead. -""" - - -import re -from django.template.response import SimpleTemplateResponse -from django.core.handlers.wsgi import STATUS_CODE_TEXT -from djangorestframework.settings import api_settings -from djangorestframework.utils.mediatypes import order_by_precedence -from djangorestframework import status - - -MSIE_USER_AGENT_REGEX = re.compile(r'^Mozilla/[0-9]+\.[0-9]+ \([^)]*; MSIE [0-9]+\.[0-9]+[a-z]?;[^)]*\)(?!.* Opera )') - - -class NotAcceptable(Exception): - pass - - -class Response(SimpleTemplateResponse): - """ - An HttpResponse that may include content that hasn't yet been serialized. - - Kwargs: - - content(object). The raw content, not yet serialized. - This must be native Python data that renderers can handle. - (e.g.: `dict`, `str`, ...) - - renderer_classes(list/tuple). The renderers to use for rendering the response content. - """ - - _ACCEPT_QUERY_PARAM = api_settings.URL_ACCEPT_OVERRIDE - _IGNORE_IE_ACCEPT_HEADER = True - - def __init__(self, content=None, status=None, headers=None, view=None, - request=None, renderer_classes=None, format=None): - # First argument taken by `SimpleTemplateResponse.__init__` is template_name, - # which we don't need - super(Response, self).__init__(None, status=status) - - self.raw_content = content - self.has_content_body = content is not None - self.headers = headers and headers[:] or [] - self.view = view - self.request = request - self.renderer_classes = renderer_classes - self.format = format - - def get_renderers(self): - """ - Instantiates and returns the list of renderers the response will use. - """ - if self.renderer_classes is None: - renderer_classes = api_settings.DEFAULT_RENDERERS - else: - renderer_classes = self.renderer_classes - - if self.format: - return [cls(self.view) for cls in renderer_classes - if cls.format == self.format] - return [cls(self.view) for cls in renderer_classes] - - @property - def rendered_content(self): - """ - The final rendered content. Accessing this attribute triggers the - complete rendering cycle: selecting suitable renderer, setting - response's actual content type, rendering data. - """ - renderer, media_type = self._determine_renderer() - - # Set the media type of the response - self['Content-Type'] = renderer.media_type - - # Render the response content - if self.has_content_body: - return renderer.render(self.raw_content, media_type) - return renderer.render() - - def render(self): - try: - return super(Response, self).render() - except NotAcceptable: - response = self._get_406_response() - return response.render() - - @property - def status_text(self): - """ - Returns reason text corresponding to our HTTP response status code. - Provided for convenience. - """ - return STATUS_CODE_TEXT.get(self.status_code, '') - - def _determine_accept_list(self): - """ - Returns a list of accepted media types. This list is determined from : - - 1. overload with `_ACCEPT_QUERY_PARAM` - 2. `Accept` header of the request - - If those are useless, a default value is returned instead. - """ - request = self.request - - if (self._ACCEPT_QUERY_PARAM and - request.GET.get(self._ACCEPT_QUERY_PARAM, None)): - # Use _accept parameter override - return [request.GET.get(self._ACCEPT_QUERY_PARAM)] - elif (self._IGNORE_IE_ACCEPT_HEADER and - 'HTTP_USER_AGENT' in request.META and - MSIE_USER_AGENT_REGEX.match(request.META['HTTP_USER_AGENT']) and - request.META.get('HTTP_X_REQUESTED_WITH', '') != 'XMLHttpRequest'): - # Ignore MSIE's broken accept behavior except for AJAX requests - # and do something sensible instead - return ['text/html', '*/*'] - elif 'HTTP_ACCEPT' in request.META: - # Use standard HTTP Accept negotiation - return [token.strip() for token in request.META['HTTP_ACCEPT'].split(',')] - else: - # No accept header specified - return ['*/*'] - - def _determine_renderer(self): - """ - Determines the appropriate renderer for the output, given the list of - accepted media types, and the :attr:`renderer_classes` set on this class. - - Returns a 2-tuple of `(renderer, media_type)` - - See: RFC 2616, Section 14 - http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html - """ - - renderers = self.get_renderers() - accepts = self._determine_accept_list() - - # Not acceptable response - Ignore accept header. - if self.status_code == 406: - return (renderers[0], renderers[0].media_type) - - # Check the acceptable media types against each renderer, - # attempting more specific media types first - # NB. The inner loop here isn't as bad as it first looks :) - # Worst case is we're looping over len(accept_list) * len(self.renderers) - for media_type_set in order_by_precedence(accepts): - for renderer in renderers: - for media_type in media_type_set: - if renderer.can_handle_response(media_type): - return renderer, media_type - - # No acceptable renderers were found - raise NotAcceptable - - def _get_406_response(self): - renderer = self.renderer_classes[0] - return Response( - { - 'detail': 'Could not satisfy the client\'s Accept header', - 'available_types': [renderer.media_type - for renderer in self.renderer_classes] - }, - status=status.HTTP_406_NOT_ACCEPTABLE, - view=self.view, request=self.request, renderer_classes=[renderer]) diff --git a/djangorestframework/static/djangorestframework/css/style.css b/djangorestframework/static/djangorestframework/css/style.css deleted file mode 100644 index d47aa16ac..000000000 --- a/djangorestframework/static/djangorestframework/css/style.css +++ /dev/null @@ -1,1209 +0,0 @@ -/********************** admin 'base.css' ************************/ - -body { - margin: 0; - padding: 0; - font-size: 12px; - font-family: "Lucida Grande","DejaVu Sans","Bitstream Vera Sans",Verdana,Arial,sans-serif; - color: #333; - background: #fff; -} - -/* LINKS */ - -a:link, a:visited { - color: #5b80b2; - text-decoration: none; -} - -a:hover { - color: #036; -} - -a img { - border: none; -} - -a.section:link, a.section:visited { - color: white; - text-decoration: none; -} - -/* GLOBAL DEFAULTS */ - -p, ol, ul, dl { - margin: .2em 0 .8em 0; -} - -p { - padding: 0; - line-height: 140%; -} - -h1,h2,h3,h4,h5 { - font-weight: bold; -} - -h1 { - font-size: 18px; - color: #666; - padding: 0 6px 0 0; - margin: 0 0 .2em 0; -} - -h2 { - font-size: 16px; - margin: 1em 0 .5em 0; -} - -h2.subhead { - font-weight: normal; - margin-top: 0; -} - -h3 { - font-size: 14px; - margin: .8em 0 .3em 0; - color: #666; - font-weight: bold; -} - -h4 { - font-size: 12px; - margin: 1em 0 .8em 0; - padding-bottom: 3px; -} - -h5 { - font-size: 10px; - margin: 1.5em 0 .5em 0; - color: #666; - text-transform: uppercase; - letter-spacing: 1px; -} - -ul li { - list-style-type: square; - padding: 1px 0; -} - -ul.plainlist { - margin-left: 0 !important; -} - -ul.plainlist li { - list-style-type: none; -} - -li ul { - margin-bottom: 0; -} - -li, dt, dd { - font-size: 11px; - line-height: 14px; -} - -dt { - font-weight: bold; - margin-top: 4px; -} - -dd { - margin-left: 0; -} - -form { - margin: 0; - padding: 0; -} - -fieldset { - margin: 0; - padding: 0; -} - -blockquote { - font-size: 11px; - color: #777; - margin-left: 2px; - padding-left: 10px; - border-left: 5px solid #ddd; -} - -code, pre { - font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace; - background: inherit; - color: #666; - font-size: 11px; -} - -pre.literal-block { - margin: 10px; - background: #eee; - padding: 6px 8px; -} - -code strong { - color: #930; -} - -hr { - clear: both; - color: #eee; - background-color: #eee; - height: 1px; - border: none; - margin: 0; - padding: 0; - font-size: 1px; - line-height: 1px; -} - -/* TEXT STYLES & MODIFIERS */ - -.small { - font-size: 11px; -} - -.tiny { - font-size: 10px; -} - -p.tiny { - margin-top: -2px; -} - -.mini { - font-size: 9px; -} - -p.mini { - margin-top: -3px; -} - -.help, p.help { - font-size: 10px !important; - color: #999; -} - -p img, h1 img, h2 img, h3 img, h4 img, td img { - vertical-align: middle; -} - -.quiet, a.quiet:link, a.quiet:visited { - color: #999 !important; - font-weight: normal !important; -} - -.quiet strong { - font-weight: bold !important; -} - -.float-right { - float: right; -} - -.float-left { - float: left; -} - -.clear { - clear: both; -} - -.align-left { - text-align: left; -} - -.align-right { - text-align: right; -} - -.example { - margin: 10px 0; - padding: 5px 10px; - background: #efefef; -} - -.nowrap { - white-space: nowrap; -} - -/* TABLES */ - -table { - border-collapse: collapse; - border-color: #ccc; -} - -td, th { - font-size: 11px; - line-height: 13px; - border-bottom: 1px solid #eee; - vertical-align: top; - padding: 5px; - font-family: "Lucida Grande", Verdana, Arial, sans-serif; -} - -th { - text-align: left; - font-size: 12px; - font-weight: bold; -} - -thead th, -tfoot td { - color: #666; - padding: 2px 5px; - font-size: 11px; - background: #e1e1e1 url(../../admin/img/admin/nav-bg.gif) top left repeat-x; - border-left: 1px solid #ddd; - border-bottom: 1px solid #ddd; -} - -tfoot td { - border-bottom: none; - border-top: 1px solid #ddd; -} - -thead th:first-child, -tfoot td:first-child { - border-left: none !important; -} - -thead th.optional { - font-weight: normal !important; -} - -fieldset table { - border-right: 1px solid #eee; -} - -tr.row-label td { - font-size: 9px; - padding-top: 2px; - padding-bottom: 0; - border-bottom: none; - color: #666; - margin-top: -1px; -} - -tr.alt { - background: #f6f6f6; -} - -.row1 { - background: #EDF3FE; -} - -.row2 { - background: white; -} - -/* SORTABLE TABLES */ - -thead th a:link, thead th a:visited { - color: #666; - display: block; -} - -table thead th.sorted { - background-position: bottom left !important; -} - -table thead th.sorted a { - padding-right: 13px; -} - -table thead th.ascending a { - background: url(../../admin/img/admin/arrow-up.gif) right .4em no-repeat; -} - -table thead th.descending a { - background: url(../../admin/img/admin/arrow-down.gif) right .4em no-repeat; -} - -/* ORDERABLE TABLES */ - -table.orderable tbody tr td:hover { - cursor: move; -} - -table.orderable tbody tr td:first-child { - padding-left: 14px; - background-image: url(../../admin/img/admin/nav-bg-grabber.gif); - background-repeat: repeat-y; -} - -table.orderable-initalized .order-cell, body>tr>td.order-cell { - display: none; -} - -/* FORM DEFAULTS */ - -input, textarea, select, .form-row p { - margin: 2px 0; - padding: 2px 3px; - vertical-align: middle; - font-family: "Lucida Grande", Verdana, Arial, sans-serif; - font-weight: normal; - font-size: 11px; -} - -textarea { - vertical-align: top !important; -} - -input[type=text], input[type=password], textarea, select, .vTextField { - border: 1px solid #ccc; -} - -/* FORM BUTTONS */ - -.button, input[type=submit], input[type=button], .submit-row input { - background: white url(../../admin/img/admin/nav-bg.gif) bottom repeat-x; - padding: 3px 5px; - color: black; - border: 1px solid #bbb; - border-color: #ddd #aaa #aaa #ddd; -} - -.button:active, input[type=submit]:active, input[type=button]:active { - background-image: url(../../admin/img/admin/nav-bg-reverse.gif); - background-position: top; -} - -.button[disabled], input[type=submit][disabled], input[type=button][disabled] { - background-image: url(../../admin/img/admin/nav-bg.gif); - background-position: bottom; - opacity: 0.4; -} - -.button.default, input[type=submit].default, .submit-row input.default { - border: 2px solid #5b80b2; - background: #7CA0C7 url(../../admin/img/admin/default-bg.gif) bottom repeat-x; - font-weight: bold; - color: white; - float: right; -} - -.button.default:active, input[type=submit].default:active { - background-image: url(../../admin/img/admin/default-bg-reverse.gif); - background-position: top; -} - -.button[disabled].default, input[type=submit][disabled].default, input[type=button][disabled].default { - background-image: url(../../admin/img/admin/default-bg.gif); - background-position: bottom; - opacity: 0.4; -} - - -/* MODULES */ - -.module { - border: 1px solid #ccc; - margin-bottom: 5px; - background: white; -} - -.module p, .module ul, .module h3, .module h4, .module dl, .module pre { - padding-left: 10px; - padding-right: 10px; -} - -.module blockquote { - margin-left: 12px; -} - -.module ul, .module ol { - margin-left: 1.5em; -} - -.module h3 { - margin-top: .6em; -} - -.module h2, .module caption, .inline-group h2 { - margin: 0; - padding: 2px 5px 3px 5px; - font-size: 11px; - text-align: left; - font-weight: bold; - background: #7CA0C7 url(../../admin/img/admin/default-bg.gif) top left repeat-x; - color: white; -} - -.module table { - border-collapse: collapse; -} - -/* MESSAGES & ERRORS */ - -ul.messagelist { - padding: 0 0 5px 0; - margin: 0; -} - -ul.messagelist li { - font-size: 12px; - display: block; - padding: 4px 5px 4px 25px; - margin: 0 0 3px 0; - border-bottom: 1px solid #ddd; - color: #666; - background: #ffc url(../../admin/img/admin/icon_success.gif) 5px .3em no-repeat; -} - -ul.messagelist li.warning{ - background-image: url(../../admin/img/admin/icon_alert.gif); -} - -ul.messagelist li.error{ - background-image: url(../../admin/img/admin/icon_error.gif); -} - -.errornote { - font-size: 12px !important; - display: block; - padding: 4px 5px 4px 25px; - margin: 0 0 3px 0; - border: 1px solid red; - color: red; - background: #ffc url(../../admin/img/admin/icon_error.gif) 5px .3em no-repeat; -} - -ul.errorlist { - margin: 0 !important; - padding: 0 !important; -} - -.errorlist li { - font-size: 12px !important; - display: block; - padding: 4px 5px 4px 25px; - margin: 0 0 3px 0; - border: 1px solid red; - color: white; - background: red url(../../admin/img/admin/icon_alert.gif) 5px .3em no-repeat; -} - -.errorlist li a { - color: white; - text-decoration: underline; -} - -td ul.errorlist { - margin: 0 !important; - padding: 0 !important; -} - -td ul.errorlist li { - margin: 0 !important; -} - -.errors { - background: #ffc; -} - -.errors input, .errors select, .errors textarea { - border: 1px solid red; -} - -div.system-message { - background: #ffc; - margin: 10px; - padding: 6px 8px; - font-size: .8em; -} - -div.system-message p.system-message-title { - padding: 4px 5px 4px 25px; - margin: 0; - color: red; - background: #ffc url(../../admin/img/admin/icon_error.gif) 5px .3em no-repeat; -} - -.description { - font-size: 12px; - padding: 5px 0 0 12px; -} - -/* BREADCRUMBS */ - -div.breadcrumbs { - background: white url(../../admin/img/admin/nav-bg-reverse.gif) 0 -10px repeat-x; - padding: 2px 8px 3px 8px; - font-size: 11px; - color: #999; - border-top: 1px solid white; - border-bottom: 1px solid #ccc; - text-align: left; -} - -/* ACTION ICONS */ - -.addlink { - padding-left: 12px; - background: url(../../admin/img/admin/icon_addlink.gif) 0 .2em no-repeat; -} - -.changelink { - padding-left: 12px; - background: url(../../admin/img/admin/icon_changelink.gif) 0 .2em no-repeat; -} - -.deletelink { - padding-left: 12px; - background: url(../../admin/img/admin/icon_deletelink.gif) 0 .25em no-repeat; -} - -a.deletelink:link, a.deletelink:visited { - color: #CC3434; -} - -a.deletelink:hover { - color: #993333; -} - -/* OBJECT TOOLS */ - -.object-tools { - font-size: 10px; - font-weight: bold; - font-family: Arial,Helvetica,sans-serif; - padding-left: 0; - float: right; - position: relative; - margin-top: -2.4em; - margin-bottom: -2em; -} - -.form-row .object-tools { - margin-top: 5px; - margin-bottom: 5px; - float: none; - height: 2em; - padding-left: 3.5em; -} - -.object-tools li { - display: block; - float: left; - background: url(../../admin/img/admin/tool-left.gif) 0 0 no-repeat; - padding: 0 0 0 8px; - margin-left: 2px; - height: 16px; -} - -.object-tools li:hover { - background: url(../../admin/img/admin/tool-left_over.gif) 0 0 no-repeat; -} - -.object-tools a:link, .object-tools a:visited { - display: block; - float: left; - color: white; - padding: .1em 14px .1em 8px; - height: 14px; - background: #999 url(../../admin/img/admin/tool-right.gif) 100% 0 no-repeat; -} - -.object-tools a:hover, .object-tools li:hover a { - background: #5b80b2 url(../../admin/img/admin/tool-right_over.gif) 100% 0 no-repeat; -} - -.object-tools a.viewsitelink, .object-tools a.golink { - background: #999 url(../../admin/img/admin/tooltag-arrowright.gif) top right no-repeat; - padding-right: 28px; -} - -.object-tools a.viewsitelink:hover, .object-tools a.golink:hover { - background: #5b80b2 url(../../admin/img/admin/tooltag-arrowright_over.gif) top right no-repeat; -} - -.object-tools a.addlink { - background: #999 url(../../admin/img/admin/tooltag-add.gif) top right no-repeat; - padding-right: 28px; -} - -.object-tools a.addlink:hover { - background: #5b80b2 url(../../admin/img/admin/tooltag-add_over.gif) top right no-repeat; -} - -/* OBJECT HISTORY */ - -table#change-history { - width: 100%; -} - -table#change-history tbody th { - width: 16em; -} - -/* PAGE STRUCTURE */ - -#container { - position: relative; - width: 100%; - min-width: 760px; - padding: 0; -} - -#content { - margin: 10px 15px; -} - -#header { - width: 100%; -} - -#content-main { - float: left; - width: 100%; -} - -#content-related { - float: right; - width: 18em; - position: relative; - margin-right: -19em; -} - -#footer { - clear: both; - padding: 10px; -} - -/* COLUMN TYPES */ - -.colMS { - margin-right: 20em !important; -} - -.colSM { - margin-left: 20em !important; -} - -.colSM #content-related { - float: left; - margin-right: 0; - margin-left: -19em; -} - -.colSM #content-main { - float: right; -} - -.popup .colM { - width: 95%; -} - -.subcol { - float: left; - width: 46%; - margin-right: 15px; -} - -.dashboard #content { - width: 500px; -} - -/* HEADER */ - -#header { - background: #417690; - color: #ffc; - overflow: hidden; -} - -#header a:link, #header a:visited { - color: white; -} - -#header a:hover { - text-decoration: underline; -} - -#branding h1 { - padding: 0 10px; - font-size: 18px; - margin: 8px 0; - font-weight: normal; - color: #f4f379; -} - -#branding h2 { - padding: 0 10px; - font-size: 14px; - margin: -8px 0 8px 0; - font-weight: normal; - color: #ffc; -} - -#user-tools { - position: absolute; - top: 0; - right: 0; - padding: 1.2em 10px; - font-size: 11px; - text-align: right; -} - -/* SIDEBAR */ - -#content-related h3 { - font-size: 12px; - color: #666; - margin-bottom: 3px; -} - -#content-related h4 { - font-size: 11px; -} - -#content-related .module h2 { - background: #eee url(../../admin/img/admin/nav-bg.gif) bottom left repeat-x; - color: #666; -} - -/********************** admin 'forms.css' ************************/ - -/* FORM ROWS */ - -.form-row { - overflow: hidden; - padding: 8px 12px; - font-size: 11px; - border-bottom: 1px solid #eee; -} - -.form-row img, .form-row input { - vertical-align: middle; -} - -form .form-row p { - padding-left: 0; - font-size: 11px; -} - -/* FORM LABELS */ - -form h4 { - margin: 0 !important; - padding: 0 !important; - border: none !important; -} - -label { - font-weight: normal !important; - color: #666; - font-size: 12px; -} - -.required label, label.required { - font-weight: bold !important; - color: #333 !important; -} - -/* RADIO BUTTONS */ - -form ul.radiolist li { - list-style-type: none; -} - -form ul.radiolist label { - float: none; - display: inline; -} - -form ul.inline { - margin-left: 0; - padding: 0; -} - -form ul.inline li { - float: left; - padding-right: 7px; -} - -/* ALIGNED FIELDSETS */ - -.aligned label { - display: block; - padding: 3px 10px 0 0; - float: left; - width: 8em; -} - -.aligned ul label { - display: inline; - float: none; - width: auto; -} - -.colMS .aligned .vLargeTextField, .colMS .aligned .vXMLLargeTextField { - width: 350px; -} - -form .aligned p, form .aligned ul { - margin-left: 7em; - padding-left: 30px; -} - -form .aligned table p { - margin-left: 0; - padding-left: 0; -} - -form .aligned p.help { - padding-left: 38px; -} - -.aligned .vCheckboxLabel { - float: none !important; - display: inline; - padding-left: 4px; -} - -.colM .aligned .vLargeTextField, .colM .aligned .vXMLLargeTextField { - width: 610px; -} - -.checkbox-row p.help { - margin-left: 0; - padding-left: 0 !important; -} - -fieldset .field-box { - float: left; - margin-right: 20px; -} - -/* WIDE FIELDSETS */ - -.wide label { - width: 15em !important; -} - -form .wide p { - margin-left: 15em; -} - -form .wide p.help { - padding-left: 38px; -} - -.colM fieldset.wide .vLargeTextField, .colM fieldset.wide .vXMLLargeTextField { - width: 450px; -} - -/* COLLAPSED FIELDSETS */ - -fieldset.collapsed * { - display: none; -} - -fieldset.collapsed h2, fieldset.collapsed { - display: block !important; -} - -fieldset.collapsed h2 { - background-image: url(../../admin/img/admin/nav-bg.gif); - background-position: bottom left; - color: #999; -} - -fieldset.collapsed .collapse-toggle { - background: transparent; - display: inline !important; -} - -/* MONOSPACE TEXTAREAS */ - -fieldset.monospace textarea { - font-family: "Bitstream Vera Sans Mono",Monaco,"Courier New",Courier,monospace; -} - -/* SUBMIT ROW */ - -.submit-row { - padding: 5px 7px; - text-align: right; - background: white url(../../admin/img/admin/nav-bg.gif) 0 100% repeat-x; - border: 1px solid #ccc; - margin: 5px 0; - overflow: hidden; -} - -.submit-row input { - margin: 0 0 0 5px; -} - -.submit-row p { - margin: 0.3em; -} - -.submit-row p.deletelink-box { - float: left; -} - -.submit-row .deletelink { - background: url(../../admin/img/admin/icon_deletelink.gif) 0 50% no-repeat; - padding-left: 14px; -} - -/* CUSTOM FORM FIELDS */ - -.vSelectMultipleField { - vertical-align: top !important; -} - -.vCheckboxField { - border: none; -} - -.vDateField, .vTimeField { - margin-right: 2px; -} - -.vURLField { - width: 30em; -} - -.vLargeTextField, .vXMLLargeTextField { - width: 48em; -} - -.flatpages-flatpage #id_content { - height: 40.2em; -} - -.module table .vPositiveSmallIntegerField { - width: 2.2em; -} - -.vTextField { - width: 20em; -} - -.vIntegerField { - width: 5em; -} - -.vForeignKeyRawIdAdminField { - width: 5em; -} - -/* INLINES */ - -.inline-group { - padding: 0; - border: 1px solid #ccc; - margin: 10px 0; -} - -.inline-group .aligned label { - width: 8em; -} - -.inline-related { - position: relative; -} - -.inline-related h3 { - margin: 0; - color: #666; - padding: 3px 5px; - font-size: 11px; - background: #e1e1e1 url(../../admin/img/admin/nav-bg.gif) top left repeat-x; - border-bottom: 1px solid #ddd; -} - -.inline-related h3 span.delete { - float: right; -} - -.inline-related h3 span.delete label { - margin-left: 2px; - font-size: 11px; -} - -.inline-related fieldset { - margin: 0; - background: #fff; - border: none; -} - -.inline-related fieldset.module h3 { - margin: 0; - padding: 2px 5px 3px 5px; - font-size: 11px; - text-align: left; - font-weight: bold; - background: #bcd; - color: #fff; -} - -.inline-group .tabular fieldset.module { - border: none; - border-bottom: 1px solid #ddd; -} - -.inline-related.tabular fieldset.module table { - width: 100%; -} - -.last-related fieldset { - border: none; -} - -.inline-group .tabular tr.has_original td { - padding-top: 2em; -} - -.inline-group .tabular tr td.original { - padding: 2px 0 0 0; - width: 0; - _position: relative; -} - -.inline-group .tabular th.original { - width: 0px; - padding: 0; -} - -.inline-group .tabular td.original p { - position: absolute; - left: 0; - height: 1.1em; - padding: 2px 7px; - overflow: hidden; - font-size: 9px; - font-weight: bold; - color: #666; - _width: 700px; -} - -.inline-group ul.tools { - padding: 0; - margin: 0; - list-style: none; -} - -.inline-group ul.tools li { - display: inline; - padding: 0 5px; -} - -.inline-group div.add-row, -.inline-group .tabular tr.add-row td { - color: #666; - padding: 3px 5px; - border-bottom: 1px solid #ddd; - background: #e1e1e1 url(../../admin/img/admin/nav-bg.gif) top left repeat-x; -} - -.inline-group .tabular tr.add-row td { - padding: 4px 5px 3px; - border-bottom: none; -} - -.inline-group ul.tools a.add, -.inline-group div.add-row a, -.inline-group .tabular tr.add-row td a { - background: url(../../admin/img/admin/icon_addlink.gif) 0 50% no-repeat; - padding-left: 14px; - font-size: 11px; - outline: 0; /* Remove dotted border around link */ -} - -.empty-form { - display: none; -} - -/* IE7 specific bug fixes */ - -.submit-row input { - float: right; -} - -body.login { - background: #eee; -} - -.login #container { - background: white; - border: 1px solid #ccc; - width: 28em; - min-width: 300px; - margin-left: auto; - margin-right: auto; - margin-top: 100px; -} - -.login #content-main { - width: 100%; -} - -.login form { - margin-top: 1em; -} - -.login .form-row { - padding: 4px 0; - float: left; - width: 100%; -} - -.login .form-row label { - float: left; - width: 9em; - padding-right: 0.5em; - line-height: 2em; - text-align: right; - font-size: 1em; - color: #333; -} - -.login .form-row #id_username, .login .form-row #id_password { - width: 14em; -} - -.login span.help { - font-size: 10px; - display: block; -} - -.login .submit-row { - clear: both; - padding: 1em 0 0 9.4em; -} - -/* Overrides specific to REST framework */ - -#site-name a { - color: #F4F379 !important; -} - -.errorlist { - display: inline !important; -} - -.errorlist li { - display: inline !important; - background: white !important; - color: black !important; - border: 0 !important; -} - -/* Custom styles */ - -.version { - font-size: 8px; -} - -.form-row { - border-bottom: 0.25em !important; -} diff --git a/djangorestframework/templates/djangorestframework/api.txt b/djangorestframework/templates/djangorestframework/api.txt deleted file mode 100644 index b2f071d64..000000000 --- a/djangorestframework/templates/djangorestframework/api.txt +++ /dev/null @@ -1,8 +0,0 @@ -{% autoescape off %}{{ name }} - -{{ description }} - -HTTP {{ response.status }} {{ response.status_text }} -{% for key, val in response.headers.items %}{{ key }}: {{ val }} -{% endfor %} -{{ content }}{% endautoescape %} diff --git a/djangorestframework/templates/djangorestframework/base.html b/djangorestframework/templates/djangorestframework/base.html deleted file mode 100644 index 97e81bbed..000000000 --- a/djangorestframework/templates/djangorestframework/base.html +++ /dev/null @@ -1,151 +0,0 @@ -{% load url from future %} -{% load urlize_quoted_links %} -{% load add_query_param %} -{% load optional_login %} -{% load static %} - - - - - - {% block extrastyle %}{% endblock %} - {% block title %}Django REST framework - {{ name }}{% endblock %} - {% block extrahead %}{% endblock %} - {% block blockbots %}{% endblock %} - - -
- - - - - - -
- - {% if 'OPTIONS' in allowed_methods and api_settings.FORM_METHOD_OVERRIDE %} -
- {% csrf_token %} - - -
- {% endif %} - -
-

{{ name }}

-

{{ description }}

-
-
HTTP {{ response.status_code }} {{ response.status_text }}{% autoescape off %}
-{% for key, val in response.items %}{{ key }}: {{ val|urlize_quoted_links }}
-{% endfor %}
-{{ content|urlize_quoted_links }}
{% endautoescape %}
- - {% if 'GET' in allowed_methods %} -
-
-

GET {{ name }}

-
- GET - {% for format in available_formats %} - {% with FORMAT_PARAM|add:"="|add:format as param %} - [{{ format }}] - {% endwith %} - {% endfor %} -
-
-
- {% endif %} - - - {# Only display the POST/PUT/DELETE forms if method tunneling via POST forms is enabled and the user has permissions on this view. #} - {% if response.status_code != 403 %} - - {% if 'POST' in allowed_methods %} -
-
-

POST {{ name }}

- {% csrf_token %} - {{ post_form.non_field_errors }} - {% for field in post_form %} -
- {{ field.label_tag }} - {{ field }} - {{ field.help_text }} - {{ field.errors }} -
- {% endfor %} -
- -
-
-
- {% endif %} - - {% if 'PUT' in allowed_methods and api_settings.FORM_METHOD_OVERRIDE %} -
-
-

PUT {{ name }}

- - {% csrf_token %} - {{ put_form.non_field_errors }} - {% for field in put_form %} -
- {{ field.label_tag }} - {{ field }} - {{ field.help_text }} - {{ field.errors }} -
- {% endfor %} -
- -
-
-
- {% endif %} - - {% if 'DELETE' in allowed_methods and api_settings.FORM_METHOD_OVERRIDE %} -
-
-

DELETE {{ name }}

- {% csrf_token %} - -
- -
-
-
- {% endif %} - - {% endif %} -
- - -
- - - {% block footer %}{% endblock %} -
- - diff --git a/djangorestframework/templatetags/add_query_param.py b/djangorestframework/templatetags/add_query_param.py deleted file mode 100644 index 4cf0133be..000000000 --- a/djangorestframework/templatetags/add_query_param.py +++ /dev/null @@ -1,10 +0,0 @@ -from django.template import Library -from urlobject import URLObject -register = Library() - - -def add_query_param(url, param): - return unicode(URLObject(url).with_query(param)) - - -register.filter('add_query_param', add_query_param) diff --git a/djangorestframework/templatetags/optional_login.py b/djangorestframework/templatetags/optional_login.py deleted file mode 100644 index c448c142b..000000000 --- a/djangorestframework/templatetags/optional_login.py +++ /dev/null @@ -1,32 +0,0 @@ -""" -Tags to optionally include the login and logout links, depending on if the -login and logout views are in the urlconf. -""" -from django import template -from django.core.urlresolvers import reverse, NoReverseMatch - -register = template.Library() - - -@register.simple_tag(takes_context=True) -def optional_login(context): - try: - login_url = reverse('djangorestframework:login') - except NoReverseMatch: - return '' - - request = context['request'] - snippet = "Log in" % (login_url, request.path) - return snippet - - -@register.simple_tag(takes_context=True) -def optional_logout(context): - try: - logout_url = reverse('djangorestframework:logout') - except NoReverseMatch: - return '' - - request = context['request'] - snippet = "Log out" % (logout_url, request.path) - return snippet diff --git a/djangorestframework/tests/accept.py b/djangorestframework/tests/accept.py deleted file mode 100644 index 7258f4613..000000000 --- a/djangorestframework/tests/accept.py +++ /dev/null @@ -1,83 +0,0 @@ -from django.conf.urls.defaults import patterns, url, include -from django.test import TestCase - -from djangorestframework.compat import RequestFactory -from djangorestframework.views import APIView -from djangorestframework.response import Response - - -# See: http://www.useragentstring.com/ -MSIE_9_USER_AGENT = 'Mozilla/5.0 (Windows; U; MSIE 9.0; WIndows NT 9.0; en-US))' -MSIE_8_USER_AGENT = 'Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; Media Center PC 4.0; SLCC1; .NET CLR 3.0.04320)' -MSIE_7_USER_AGENT = 'Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; en-US)' -FIREFOX_4_0_USER_AGENT = 'Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/4.0 (.NET CLR 3.5.30729)' -CHROME_11_0_USER_AGENT = 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.17 (KHTML, like Gecko) Chrome/11.0.655.0 Safari/534.17' -SAFARI_5_0_USER_AGENT = 'Mozilla/5.0 (X11; U; Linux x86_64; en-ca) AppleWebKit/531.2+ (KHTML, like Gecko) Version/5.0 Safari/531.2+' -OPERA_11_0_MSIE_USER_AGENT = 'Mozilla/4.0 (compatible; MSIE 8.0; X11; Linux x86_64; pl) Opera 11.00' -OPERA_11_0_OPERA_USER_AGENT = 'Opera/9.80 (X11; Linux x86_64; U; pl) Presto/2.7.62 Version/11.00' - - -urlpatterns = patterns('', - url(r'^api', include('djangorestframework.urls', namespace='djangorestframework')) -) - - -class UserAgentMungingTest(TestCase): - """ - We need to fake up the accept headers when we deal with MSIE. Blergh. - http://www.gethifi.com/blog/browser-rest-http-accept-headers - """ - - urls = 'djangorestframework.tests.accept' - - def setUp(self): - - class MockView(APIView): - permissions = () - response_class = Response - - def get(self, request): - return self.response_class({'a': 1, 'b': 2, 'c': 3}) - - self.req = RequestFactory() - self.MockView = MockView - self.view = MockView.as_view() - - def test_munge_msie_accept_header(self): - """Send MSIE user agent strings and ensure that we get an HTML response, - even if we set a */* accept header.""" - for user_agent in (MSIE_9_USER_AGENT, - MSIE_8_USER_AGENT, - MSIE_7_USER_AGENT): - req = self.req.get('/', HTTP_ACCEPT='*/*', HTTP_USER_AGENT=user_agent) - resp = self.view(req) - resp.render() - self.assertEqual(resp['Content-Type'], 'text/html') - - def test_dont_rewrite_msie_accept_header(self): - """Turn off _IGNORE_IE_ACCEPT_HEADER, send MSIE user agent strings and ensure - that we get a JSON response if we set a */* accept header.""" - class IgnoreIEAcceptResponse(Response): - _IGNORE_IE_ACCEPT_HEADER = False - view = self.MockView.as_view(response_class=IgnoreIEAcceptResponse) - - for user_agent in (MSIE_9_USER_AGENT, - MSIE_8_USER_AGENT, - MSIE_7_USER_AGENT): - req = self.req.get('/', HTTP_ACCEPT='*/*', HTTP_USER_AGENT=user_agent) - resp = view(req) - resp.render() - self.assertEqual(resp['Content-Type'], 'application/json') - - def test_dont_munge_nice_browsers_accept_header(self): - """Send Non-MSIE user agent strings and ensure that we get a JSON response, - if we set a */* Accept header. (Other browsers will correctly set the Accept header)""" - for user_agent in (FIREFOX_4_0_USER_AGENT, - CHROME_11_0_USER_AGENT, - SAFARI_5_0_USER_AGENT, - OPERA_11_0_MSIE_USER_AGENT, - OPERA_11_0_OPERA_USER_AGENT): - req = self.req.get('/', HTTP_ACCEPT='*/*', HTTP_USER_AGENT=user_agent) - resp = self.view(req) - resp.render() - self.assertEqual(resp['Content-Type'], 'application/json') diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md index 799509466..f24c6a81b 100644 --- a/docs/api-guide/authentication.md +++ b/docs/api-guide/authentication.md @@ -28,10 +28,10 @@ The value of `request.user` and `request.auth` for unauthenticated requests can The default authentication policy may be set globally, using the `DEFAULT_AUTHENTICATION` setting. For example. - API_SETTINGS = { + REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION': ( - 'djangorestframework.authentication.UserBasicAuthentication', - 'djangorestframework.authentication.SessionAuthentication', + 'rest_framework.authentication.UserBasicAuthentication', + 'rest_framework.authentication.SessionAuthentication', ) } @@ -75,11 +75,11 @@ If successfully authenticated, `BasicAuthentication` provides the following cred This policy uses a simple token-based HTTP Authentication scheme. Token authentication is appropriate for client-server setups, such as native desktop and mobile clients. -To use the `TokenAuthentication` policy, include `djangorestframework.authtoken` in your `INSTALLED_APPS` setting. +To use the `TokenAuthentication` policy, include `rest_framework.authtoken` in your `INSTALLED_APPS` setting. You'll also need to create tokens for your users. - from djangorestframework.authtoken.models import Token + from rest_framework.authtoken.models import Token token = Token.objects.create(user=...) print token.key @@ -91,7 +91,7 @@ For clients to authenticate, the token key should be included in the `Authorizat If successfully authenticated, `TokenAuthentication` provides the following credentials. * `request.user` will be a `django.contrib.auth.models.User` instance. -* `request.auth` will be a `djangorestframework.tokenauth.models.BasicToken` instance. +* `request.auth` will be a `rest_framework.tokenauth.models.BasicToken` instance. **Note:** If you use `TokenAuthentication` in production you must ensure that your API is only available over `https` only. @@ -102,7 +102,7 @@ This policy uses the [OAuth 2.0][oauth] protocol to authenticate requests. OAut If successfully authenticated, `OAuthAuthentication` provides the following credentials. * `request.user` will be a `django.contrib.auth.models.User` instance. -* `request.auth` will be a `djangorestframework.models.OAuthToken` instance. +* `request.auth` will be a `rest_framework.models.OAuthToken` instance. ## SessionAuthentication diff --git a/docs/api-guide/content-negotiation.md b/docs/api-guide/content-negotiation.md index 01895a4b0..ad98de3b9 100644 --- a/docs/api-guide/content-negotiation.md +++ b/docs/api-guide/content-negotiation.md @@ -1,3 +1,5 @@ + + # Content negotiation > HTTP has provisions for several mechanisms for "content negotiation" - the process of selecting the best representation for a given response when there are multiple representations available. diff --git a/docs/api-guide/permissions.md b/docs/api-guide/permissions.md index fafef3054..e0ceb1eac 100644 --- a/docs/api-guide/permissions.md +++ b/docs/api-guide/permissions.md @@ -27,9 +27,9 @@ Object level permissions are run by REST framework's generic views when `.get_ob The default permission policy may be set globally, using the `DEFAULT_PERMISSIONS` setting. For example. - API_SETTINGS = { + REST_FRAMEWORK = { 'DEFAULT_PERMISSIONS': ( - 'djangorestframework.permissions.IsAuthenticated', + 'rest_framework.permissions.IsAuthenticated', ) } @@ -97,4 +97,4 @@ The method should return `True` if the request should be granted access, and `Fa [authentication]: authentication.md [throttling]: throttling.md [contribauth]: https://docs.djangoproject.com/en/1.0/topics/auth/#permissions -[guardian]: https://github.com/lukaszb/django-guardian \ No newline at end of file +[guardian]: https://github.com/lukaszb/django-guardian diff --git a/docs/api-guide/requests.md b/docs/api-guide/requests.md index 6746bb20d..b223da80f 100644 --- a/docs/api-guide/requests.md +++ b/docs/api-guide/requests.md @@ -49,7 +49,7 @@ This allows you to support file uploads from multiple content-types. For exampl `request.parsers` may no longer be altered once `request.DATA`, `request.FILES` or `request.POST` have been accessed. -If you're using the `djangorestframework.views.View` class... **[TODO]** +If you're using the `rest_framework.views.View` class... **[TODO]** ## .stream @@ -63,6 +63,6 @@ You will not typically need to access `request.stream`, unless you're writing a `request.authentication` may no longer be altered once `request.user` or `request.auth` have been accessed. -If you're using the `djangorestframework.views.View` class... **[TODO]** +If you're using the `rest_framework.views.View` class... **[TODO]** -[cite]: https://groups.google.com/d/topic/django-developers/dxI4qVzrBY4/discussion \ No newline at end of file +[cite]: https://groups.google.com/d/topic/django-developers/dxI4qVzrBY4/discussion diff --git a/docs/api-guide/reverse.md b/docs/api-guide/reverse.md index f3cb0c642..3fa654c09 100644 --- a/docs/api-guide/reverse.md +++ b/docs/api-guide/reverse.md @@ -23,8 +23,8 @@ There's no requirement for you to use them, but if you do then the self-describi Has the same behavior as [`django.core.urlresolvers.reverse`][reverse], except that it returns a fully qualified URL, using the request to determine the host and port. - from djangorestframework.utils import reverse - from djangorestframework.views import APIView + from rest_framework.utils import reverse + from rest_framework.views import APIView class MyView(APIView): def get(self, request): @@ -40,4 +40,4 @@ Has the same behavior as [`django.core.urlresolvers.reverse_lazy`][reverse-lazy] [cite]: http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_1_5 [reverse]: https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse -[reverse-lazy]: https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse-lazy \ No newline at end of file +[reverse-lazy]: https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse-lazy diff --git a/docs/api-guide/settings.md b/docs/api-guide/settings.md index 2513928c5..0f66e85ec 100644 --- a/docs/api-guide/settings.md +++ b/docs/api-guide/settings.md @@ -6,16 +6,16 @@ > > — [The Zen of Python][cite] -Configuration for REST framework is all namespaced inside a single Django setting, named `API_SETTINGS`. +Configuration for REST framework is all namespaced inside a single Django setting, named `REST_FRAMEWORK`. For example your project's `settings.py` file might include something like this: - API_SETTINGS = { + REST_FRAMEWORK = { 'DEFAULT_RENDERERS': ( - 'djangorestframework.renderers.YAMLRenderer', + 'rest_framework.renderers.YAMLRenderer', ) 'DEFAULT_PARSERS': ( - 'djangorestframework.parsers.YAMLParser', + 'rest_framework.parsers.YAMLParser', ) } @@ -24,7 +24,7 @@ For example your project's `settings.py` file might include something like this: If you need to access the values of REST framework's API settings in your project, you should use the `api_settings` object. For example. - from djangorestframework.settings import api_settings + from rest_framework.settings import api_settings print api_settings.DEFAULT_AUTHENTICATION @@ -37,9 +37,9 @@ A list or tuple of renderer classes, that determines the default set of renderer Default: ( - 'djangorestframework.renderers.JSONRenderer', - 'djangorestframework.renderers.DocumentingHTMLRenderer' - 'djangorestframework.renderers.TemplateHTMLRenderer' + 'rest_framework.renderers.JSONRenderer', + 'rest_framework.renderers.DocumentingHTMLRenderer' + 'rest_framework.renderers.TemplateHTMLRenderer' ) ## DEFAULT_PARSERS @@ -49,8 +49,8 @@ A list or tuple of parser classes, that determines the default set of parsers us Default: ( - 'djangorestframework.parsers.JSONParser', - 'djangorestframework.parsers.FormParser' + 'rest_framework.parsers.JSONParser', + 'rest_framework.parsers.FormParser' ) ## DEFAULT_AUTHENTICATION @@ -60,8 +60,8 @@ A list or tuple of authentication classes, that determines the default set of au Default: ( - 'djangorestframework.authentication.SessionAuthentication', - 'djangorestframework.authentication.UserBasicAuthentication' + 'rest_framework.authentication.SessionAuthentication', + 'rest_framework.authentication.UserBasicAuthentication' ) ## DEFAULT_PERMISSIONS @@ -80,13 +80,13 @@ Default: `()` **TODO** -Default: `djangorestframework.serializers.ModelSerializer` +Default: `rest_framework.serializers.ModelSerializer` ## DEFAULT_PAGINATION_SERIALIZER **TODO** -Default: `djangorestframework.pagination.PaginationSerializer` +Default: `rest_framework.pagination.PaginationSerializer` ## FORMAT_SUFFIX_KWARG diff --git a/docs/api-guide/status-codes.md b/docs/api-guide/status-codes.md index 6693c79f5..401f45ce0 100644 --- a/docs/api-guide/status-codes.md +++ b/docs/api-guide/status-codes.md @@ -8,7 +8,7 @@ Using bare status codes in your responses isn't recommended. REST framework includes a set of named constants that you can use to make more code more obvious and readable. - from djangorestframework import status + from rest_framework import status def empty_view(self): content = {'please move along': 'nothing to see here'} diff --git a/docs/api-guide/throttling.md b/docs/api-guide/throttling.md index d1e34dcda..7861e9baa 100644 --- a/docs/api-guide/throttling.md +++ b/docs/api-guide/throttling.md @@ -29,10 +29,10 @@ If any throttle check fails an `exceptions.Throttled` exception will be raised, The default throttling policy may be set globally, using the `DEFAULT_THROTTLES` and `DEFAULT_THROTTLE_RATES` settings. For example. - API_SETTINGS = { + REST_FRAMEWORK = { 'DEFAULT_THROTTLES': ( - 'djangorestframework.throttles.AnonThrottle', - 'djangorestframework.throttles.UserThrottle', + 'rest_framework.throttles.AnonThrottle', + 'rest_framework.throttles.UserThrottle', ) 'DEFAULT_THROTTLE_RATES': { 'anon': '100/day', @@ -76,7 +76,7 @@ The allowed request rate is determined from one of the following (in order of pr ## UserRateThrottle -The `UserThrottle` will throttle users to a given rate of requests across the API. The user id is used to generate a unique key to throttle against. Unauthenticted requests will fall back to using the IP address of the incoming request is used to generate a unique key to throttle against. +The `UserThrottle` will throttle users to a given rate of requests across the API. The user id is used to generate a unique key to throttle against. Unauthenticted requests will fall back to using the IP address of the incoming request to generate a unique key to throttle against. The allowed request rate is determined from one of the following (in order of preference). @@ -95,7 +95,7 @@ For example, multiple user throttle rates could be implemented by using the foll ...and the following settings. - API_SETTINGS = { + REST_FRAMEWORK = { 'DEFAULT_THROTTLES': ( 'example.throttles.BurstRateThrottle', 'example.throttles.SustainedRateThrottle', @@ -106,7 +106,7 @@ For example, multiple user throttle rates could be implemented by using the foll } } -`UserThrottle` is suitable if you want a simple global rate restriction per-user. +`UserThrottle` is suitable if you want simple global rate restrictions per-user. ## ScopedRateThrottle @@ -124,16 +124,15 @@ For example, given the following views... throttle_scope = 'contacts' ... - class UploadView(APIView): throttle_scope = 'uploads' ... ...and the following settings. - API_SETTINGS = { + REST_FRAMEWORK = { 'DEFAULT_THROTTLES': ( - 'djangorestframework.throttles.ScopedRateThrottle', + 'rest_framework.throttles.ScopedRateThrottle', ) 'DEFAULT_THROTTLE_RATES': { 'contacts': '1000/day', @@ -149,4 +148,4 @@ To create a custom throttle, override `BaseThrottle` and implement `.allow_reque Optionally you may also override the `.wait()` method. If implemented, `.wait()` should return a recomended number of seconds to wait before attempting the next request, or `None`. The `.wait()` method will only be called if `.check_throttle()` has previously returned `False`. -[permissions]: permissions.md \ No newline at end of file +[permissions]: permissions.md diff --git a/docs/index.md b/docs/index.md index 78f4674f7..e7db5dbc7 100644 --- a/docs/index.md +++ b/docs/index.md @@ -17,7 +17,6 @@ REST framework requires the following: * Python (2.6, 2.7) * Django (1.3, 1.4, 1.5) -* [URLObject][urlobject] (2.0.0+) The following packages are optional: @@ -41,20 +40,22 @@ Install using `pip`, including any optional packages you want... pip install -r requirements.txt pip install -r optionals.txt -Add `djangorestframework` to your `INSTALLED_APPS`. +Add `rest_framework` to your `INSTALLED_APPS`. INSTALLED_APPS = ( ... - 'djangorestframework', + 'rest_framework', ) If you're intending to use the browserable API you'll want to add REST framework's login and logout views. Add the following to your root `urls.py` file. urlpatterns = patterns('', ... - url(r'^api-auth/', include('djangorestframework.urls', namespace='djangorestframework')) + url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')) ) - + +Note that the base URL can be whatever you want, but you must include `rest_framework.urls` with the `rest_framework` namespace. + ## Quickstart **TODO** @@ -97,6 +98,7 @@ General guides to using REST framework. * [CSRF][csrf] * [Form overloading][formoverloading] +* [Working with the Browsable API][browsableapi] * [Contributing to REST framework][contributing] * [Credits][credits] @@ -110,7 +112,7 @@ Build the docs: Run the tests: - ./djangorestframework/runtests/runtests.py + ./rest_framework/runtests/runtests.py ## License @@ -168,5 +170,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [csrf]: topics/csrf.md [formoverloading]: topics/formoverloading.md +[browsableapi]: topics/browsable-api.md [contributing]: topics/contributing.md [credits]: topics/credits.md diff --git a/docs/template.html b/docs/template.html index e6c9078a7..4ac94f404 100644 --- a/docs/template.html +++ b/docs/template.html @@ -68,6 +68,7 @@ @@ -117,7 +118,7 @@ if (location.hash) shiftWindow(); window.addEventListener("hashchange", shiftWindow); - $('.dropdown-menu').click(function(event) { + $('.dropdown-menu').on('click touchstart', function(event) { event.stopPropagation(); }); diff --git a/docs/topics/browsable-api.md b/docs/topics/browsable-api.md new file mode 100644 index 000000000..ed27752f8 --- /dev/null +++ b/docs/topics/browsable-api.md @@ -0,0 +1,97 @@ +# Working with the Browsable API + +API may stand for Application *Programming* Interface, but humans have to be able to read the APIs, too; someone has to do the programming. Django REST Framework supports generating human-friendly HTML output for each resource when the `HTML` format is requested. These pages allow for easy browsing of resources, as well as forms for submitting data to the resources using `POST`, `PUT`, and `DELETE`. + +## URLs + +If you include fully-qualified URLs in your resource output, they will be 'urlized' and made clickable for easy browsing by humans. The `rest_framework` package includes a [`reverse`][drfreverse] helper for this purpose. + + +## Formats + +By default, the API will return the format specified by the headers, which in the case of the browser is HTML. The format can be specified using `?format=` in the request, so you can look at the raw JSON response in a browser by adding `?format=json` to the URL. There are helpful extensions for viewing JSON in [Firefox][ffjsonview] and [Chrome][chromejsonview]. + + +## Customizing + +To customize the look-and-feel, create a template called `api.html` and add it to your project, eg: `templates/rest_framework/api.html`, that extends the `rest_framework/base.html` template. + +The included browsable API template is built with [Bootstrap (2.1.1)][bootstrap], making it easy to customize the look-and-feel. + +### Theme + +To replace the theme wholesale, add a `bootstrap_theme` block to your `api.html` and insert a `link` to the desired Bootstrap theme css file. This will completely replace the included theme. + + {% block bootstrap_theme %} + + {% endblock %} + +A suitable replacement theme can be generated using Bootstrap's [Customize Tool][bcustomize]. Also, there are pre-made themes available at [Bootswatch][bswatch]. To use any of the Bootswatch themes, simply download the theme's `bootstrap.min.css` file, add it to your project, and replace the default one as described above. + +You can also change the navbar variant, which by default is `navbar-inverse`, using the `bootstrap_navbar_variant` block. The empty `{% block bootstrap_navbar_variant %}{% endblock %}` will use the original Bootstrap navbar style. + +For more specific CSS tweaks, use the `extra_style` block instead. + + +### Blocks + +All of the blocks available in the browsable API base template that can be used in your `api.html`. + +* `blockbots` - `` tag that blocks crawlers +* `bodyclass` - (empty) class attribute for the `` +* `bootstrap_theme` - CSS for the Bootstrap theme +* `bootstrap_navbar_variant` - CSS class for the navbar +* `branding` - section of the navbar, see [Bootstrap components][bcomponentsnav] +* `breadcrumbs` - Links showing resource nesting, allowing the user to go back up the resources. It's recommended to preserve these, but they can be overridden using the breadcrumbs block. +* `extrastyle` - (empty) extra CSS for the page +* `extrahead` - (empty) extra markup for the page `` +* `footer` - Any copyright notices or similar footer materials can go here (by default right-aligned) +* `global_heading` - (empty) Use to insert content below the header but before the breadcrumbs. +* `title` - title of the page +* `userlinks` - This is a list of links on the right of the header, by default containing login/logout links. To add links instead of replace, use {{ block.super }} to preserve the authentication links. + +#### Components + +All of the [Bootstrap components][bcomponents] are available. + +##### Tooltips + +The browsable API makes use of the Bootstrap tooltips component. Any element with the `js-tooltip` class and a `title` attribute has that title content displayed in a tooltip on hover after a 1000ms delay. + + +### Advanced Customization + +#### Context + +The context that's available to the template: + +* `allowed_methods` : A list of methods allowed by the resource +* `api_settings` : The API settings +* `available_formats` : A list of formats allowed by the resource +* `breadcrumblist` : The list of links following the chain of nested resources +* `content` : The content of the API response +* `description` : The description of the resource, generated from its docstring +* `name` : The name of the resource +* `post_form` : A form instance for use by the POST form (if allowed) +* `put_form` : A form instance for use by the PUT form (if allowed) +* `request` : The request object +* `response` : The response object +* `version` : The version of Django REST Framework +* `view` : The view handling the request +* `FORMAT_PARAM` : The view can accept a format override +* `METHOD_PARAM` : The view can accept a method override + +#### Not using base.html + +For more advanced customization, such as not having a Bootstrap basis or tighter integration with the rest of your site, you can simply choose not to have `api.html` extend `base.html`. Then the page content and capabilities are entirely up to you. + + +[drfreverse]: ../api-guide/reverse.md +[ffjsonview]: https://addons.mozilla.org/en-US/firefox/addon/jsonview/ +[chromejsonview]: https://chrome.google.com/webstore/detail/chklaanhfefbnpoihckbnefhakgolnmc +[bootstrap]: http://getbootstrap.com +[bcustomize]: http://twitter.github.com/bootstrap/customize.html#variables +[bswatch]: http://bootswatch.com/ +[bcomponents]: http://twitter.github.com/bootstrap/components.html +[bcomponentsnav]: http://twitter.github.com/bootstrap/components.html#navbar + diff --git a/docs/topics/changelog.md b/docs/topics/changelog.md new file mode 100644 index 000000000..a4fd39e29 --- /dev/null +++ b/docs/topics/changelog.md @@ -0,0 +1,107 @@ +# Release Notes + +## 2.0.0 + +**TODO:** Explain REST framework 2.0 + +## 0.4.0 + +* Supports Django 1.5. +* Fixes issues with 'HEAD' method. +* Allow views to specify template used by TemplateRenderer +* More consistent error responses +* Some serializer fixes +* Fix internet explorer ajax behaviour +* Minor xml and yaml fixes +* Improve setup (eg use staticfiles, not the defunct ADMIN_MEDIA_PREFIX) +* Sensible absolute URL generation, not using hacky set_script_prefix + +## 0.3.3 + +* Added DjangoModelPermissions class to support `django.contrib.auth` style permissions. +* Use `staticfiles` for css files. + - Easier to override. Won't conflict with customised admin styles (eg grappelli) +* Templates are now nicely namespaced. + - Allows easier overriding. +* Drop implied 'pk' filter if last arg in urlconf is unnamed. + - Too magical. Explict is better than implicit. +* Saner template variable autoescaping. +* Tider setup.py +* Updated for URLObject 2.0 +* Bugfixes: + - Bug with PerUserThrottling when user contains unicode chars. + +## 0.3.2 + +* Bugfixes: + * Fix 403 for POST and PUT from the UI with UserLoggedInAuthentication (#115) + * serialize_model method in serializer.py may cause wrong value (#73) + * Fix Error when clicking OPTIONS button (#146) + * And many other fixes +* Remove short status codes + - Zen of Python: "There should be one-- and preferably only one --obvious way to do it." +* get_name, get_description become methods on the view - makes them overridable. +* Improved model mixin API - Hooks for build_query, get_instance_data, get_model, get_queryset, get_ordering + +## 0.3.1 + +* [not documented] + +## 0.3.0 + +* JSONP Support +* Bugfixes, including support for latest markdown release + +## 0.2.4 + +* Fix broken IsAdminUser permission. +* OPTIONS support. +* XMLParser. +* Drop mentions of Blog, BitBucket. + +## 0.2.3 + +* Fix some throttling bugs. +* ``X-Throttle`` header on throttling. +* Support for nesting resources on related models. + +## 0.2.2 + +* Throttling support complete. + +## 0.2.1 + +* Couple of simple bugfixes over 0.2.0 + +## 0.2.0 + +* Big refactoring changes since 0.1.0, ask on the discussion group if anything isn't clear. + The public API has been massively cleaned up. Expect it to be fairly stable from here on in. + +* ``Resource`` becomes decoupled into ``View`` and ``Resource``, your views should now inherit from ``View``, not ``Resource``. + +* The handler functions on views ``.get() .put() .post()`` etc, no longer have the ``content`` and ``auth`` args. + Use ``self.CONTENT`` inside a view to access the deserialized, validated content. + Use ``self.user`` inside a view to access the authenticated user. + +* ``allowed_methods`` and ``anon_allowed_methods`` are now defunct. if a method is defined, it's available. + The ``permissions`` attribute on a ``View`` is now used to provide generic permissions checking. + Use permission classes such as ``FullAnonAccess``, ``IsAuthenticated`` or ``IsUserOrIsAnonReadOnly`` to set the permissions. + +* The ``authenticators`` class becomes ``authentication``. Class names change to ``Authentication``. + +* The ``emitters`` class becomes ``renderers``. Class names change to ``Renderers``. + +* ``ResponseException`` becomes ``ErrorResponse``. + +* The mixin classes have been nicely refactored, the basic mixins are now ``RequestMixin``, ``ResponseMixin``, ``AuthMixin``, and ``ResourceMixin`` + You can reuse these mixin classes individually without using the ``View`` class. + +## 0.1.1 + +* Final build before pulling in all the refactoring changes for 0.2, in case anyone needs to hang on to 0.1. + +## 0.1.0 + +* Initial release. + diff --git a/docs/topics/credits.md b/docs/topics/credits.md index c20f52461..e54fd4bf7 100644 --- a/docs/topics/credits.md +++ b/docs/topics/credits.md @@ -40,6 +40,7 @@ The following people have helped make REST framework great. * Can Yavuz - [tschan] * Shawn Lewis - [shawnlewis] * Alec Perkins - [alecperkins] +* Michael Barrett - [phobologic] Many thanks to everyone who's contributed to the project. @@ -102,3 +103,4 @@ To contact the author directly: [tschan]: https://github.com/tschan [shawnlewis]: https://github.com/shawnlewis [alecperkins]: https://github.com/alecperkins +[phobologic]: https://github.com/phobologic diff --git a/docs/topics/rest-hypermedia-hateoas.md b/docs/topics/rest-hypermedia-hateoas.md new file mode 100644 index 000000000..46a4c9d72 --- /dev/null +++ b/docs/topics/rest-hypermedia-hateoas.md @@ -0,0 +1,52 @@ +# REST, Hypermedia & HATEOAS + +> You keep using that word "REST". I do not think it means what you think it means. +> +> — Mike Amundsen, [REST fest 2012 keynote][cite]. + +First off, the disclaimer. The name "Django REST framework" was choosen with a view to making sure the project would be easily found by developers. Throughout the documentation we try to use the more simple and technically correct terminology of "Web APIs". + +If you are serious about designing a Hypermedia APIs, you should look to resources outside of this documentation to help inform your design choices. + +The following fall into the "required reading" category. + +* Fielding's dissertation - [Architectural Styles and +the Design of Network-based Software Architectures][dissertation]. +* Fielding's "[REST APIs must be hypertext-driven][hypertext-driven]" blog post. +* Leonard Richardson & Sam Ruby's [RESTful Web Services][restful-web-services]. +* Mike Amundsen's [Building Hypermedia APIs with HTML5 and Node][building-hypermedia-apis]. +* Steve Klabnik's [Designing Hypermedia APIs][designing-hypermedia-apis]. +* The [Richardson Maturity Model][maturitymodel]. + +For a more thorough background, check out Klabnik's [Hypermedia API reading list][readinglist]. + +# Building Hypermedia APIs with REST framework + +REST framework is an agnositic Web API toolkit. It does help guide you towards building well-connected APIs, and makes it easy to design appropriate media types, but it does not strictly enforce any particular design style. + +### What REST framework *does* provide. + +It is self evident that REST framework makes it possible to build Hypermedia APIs. The browseable API that it offers is built on HTML - the hypermedia language of the web. + +REST framework also includes [serialization] and [parser]/[renderer] components that make it easy to build appropriate media types, [hyperlinked relations][fields] for building well-connected systems, and great support for [content negotiation][conneg]. + +### What REST framework *doesn't* provide. + +What REST framework doesn't do is give you is machine readable hypermedia formats such as [Collection+JSON][collection] by default, or the ability to auto-magically create HATEOAS style APIs. Doing so would involve making opinionated choices about API design that should really remain outside of the framework's scope. + +[cite]: http://vimeo.com/channels/restfest/page:2 +[dissertation]: http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm +[hypertext-driven]: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven +[restful-web-services]: +[building-hypermedia-apis]: … +[designing-hypermedia-apis]: http://designinghypermediaapis.com/ +[restisover]: http://blog.steveklabnik.com/posts/2012-02-23-rest-is-over +[readinglist]: http://blog.steveklabnik.com/posts/2012-02-27-hypermedia-api-reading-list +[maturitymodel]: http://martinfowler.com/articles/richardsonMaturityModel.html + +[collection]: http://www.amundsen.com/media-types/collection/ +[serialization]: ../api-guide/serializers.md +[parser]: ../api-guide/parsers.md +[renderer]: ../api-guide/renderers.md +[fields]: ../api-guide/fields.md +[conneg]: ../api-guide/content-negotiation.md \ No newline at end of file diff --git a/docs/tutorial/1-serialization.md b/docs/tutorial/1-serialization.md index 610d8ed1c..cd4b75584 100644 --- a/docs/tutorial/1-serialization.md +++ b/docs/tutorial/1-serialization.md @@ -45,11 +45,11 @@ The simplest way to get up and running will probably be to use an `sqlite3` data } } -We'll also need to add our new `blog` app and the `djangorestframework` app to `INSTALLED_APPS`. +We'll also need to add our new `blog` app and the `rest_framework` app to `INSTALLED_APPS`. INSTALLED_APPS = ( ... - 'djangorestframework', + 'rest_framework', 'blog' ) @@ -67,7 +67,7 @@ For the purposes of this tutorial we're going to start by creating a simple `Com from django.db import models - class Comment(models.Model): + class Comment(models.Model): email = models.EmailField() content = models.CharField(max_length=200) created = models.DateTimeField(auto_now_add=True) @@ -81,10 +81,11 @@ Don't forget to sync the database for the first time. We're going to create a simple Web API that we can use to edit these comment objects with. The first thing we need is a way of serializing and deserializing the objects into representations such as `json`. We do this by declaring serializers, that work very similarly to Django's forms. Create a file in the project named `serializers.py` and add the following. from blog import models - from djangorestframework import serializers + from rest_framework import serializers class CommentSerializer(serializers.Serializer): + id = serializers.IntegerField(readonly=True) email = serializers.EmailField() content = serializers.CharField(max_length=200) created = serializers.DateTimeField() @@ -114,8 +115,8 @@ Okay, once we've got a few imports out of the way, we'd better create a few comm from blog.models import Comment from blog.serializers import CommentSerializer - from djangorestframework.renderers import JSONRenderer - from djangorestframework.parsers import JSONParser + from rest_framework.renderers import JSONRenderer + from rest_framework.parsers import JSONParser c1 = Comment(email='leila@example.com', content='nothing to say') c2 = Comment(email='tom@example.com', content='foo bar') @@ -128,13 +129,13 @@ We've now got a few comment instances to play with. Let's take a look at serial serializer = CommentSerializer(instance=c1) serializer.data - # {'email': u'leila@example.com', 'content': u'nothing to say', 'created': datetime.datetime(2012, 8, 22, 16, 20, 9, 822774, tzinfo=)} + # {'id': 1, 'email': u'leila@example.com', 'content': u'nothing to say', 'created': datetime.datetime(2012, 8, 22, 16, 20, 9, 822774, tzinfo=)} At this point we've translated the model instance into python native datatypes. To finalise the serialization process we render the data into `json`. stream = JSONRenderer().render(serializer.data) stream - # '{"email": "leila@example.com", "content": "nothing to say", "created": "2012-08-22T16:20:09.822"}' + # '{"id": 1, "email": "leila@example.com", "content": "nothing to say", "created": "2012-08-22T16:20:09.822"}' Deserialization is similar. First we parse a stream into python native datatypes... @@ -159,9 +160,10 @@ Edit the `blog/views.py` file, and add the following. from blog.models import Comment from blog.serializers import CommentSerializer - from djangorestframework.renderers import JSONRenderer - from djangorestframework.parsers import JSONParser from django.http import HttpResponse + from django.views.decorators.csrf import csrf_exempt + from rest_framework.renderers import JSONRenderer + from rest_framework.parsers import JSONParser class JSONResponse(HttpResponse): @@ -177,6 +179,7 @@ Edit the `blog/views.py` file, and add the following. The root of our API is going to be a view that supports listing all the existing comments, or creating a new comment. + @csrf_exempt def comment_root(request): """ List all comments, or create a new comment. @@ -194,10 +197,13 @@ The root of our API is going to be a view that supports listing all the existing comment.save() return JSONResponse(serializer.data, status=201) else: - return JSONResponse(serializer.error_data, status=400) + return JSONResponse(serializer.errors, status=400) + +Note that because we want to be able to POST to this view from clients that won't have a CSRF token we need to mark the view as `csrf_exempt`. This isn't something that you'd normally want to do, and REST framework views actually use more sensible behavior than this, but it'll do for our purposes right now. We'll also need a view which corrosponds to an individual comment, and can be used to retrieve, update or delete the comment. + @csrf_exempt def comment_instance(request, pk): """ Retrieve, update or delete a comment instance. @@ -219,7 +225,7 @@ We'll also need a view which corrosponds to an individual comment, and can be us comment.save() return JSONResponse(serializer.data) else: - return JSONResponse(serializer.error_data, status=400) + return JSONResponse(serializer.errors, status=400) elif request.method == 'DELETE': comment.delete() @@ -251,4 +257,4 @@ Our API views don't do anything particularly special at the moment, beyond serve We'll see how we can start to improve things in [part 2 of the tutorial][tut-2]. [virtualenv]: http://www.virtualenv.org/en/latest/index.html -[tut-2]: 2-requests-and-responses.md \ No newline at end of file +[tut-2]: 2-requests-and-responses.md diff --git a/docs/tutorial/2-requests-and-responses.md b/docs/tutorial/2-requests-and-responses.md index 89f92c4b2..d889b1e00 100644 --- a/docs/tutorial/2-requests-and-responses.md +++ b/docs/tutorial/2-requests-and-responses.md @@ -40,9 +40,9 @@ We don't need our `JSONResponse` class anymore, so go ahead and delete that. On from blog.models import Comment from blog.serializers import CommentSerializer - from djangorestframework import status - from djangorestframework.decorators import api_view - from djangorestframework.response import Response + from rest_framework import status + from rest_framework.decorators import api_view + from rest_framework.response import Response @api_view(['GET', 'POST']) def comment_root(request): @@ -61,7 +61,7 @@ We don't need our `JSONResponse` class anymore, so go ahead and delete that. On comment.save() return Response(serializer.data, status=status.HTTP_201_CREATED) else: - return Response(serializer.error_data, status=status.HTTP_400_BAD_REQUEST) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) Our instance view is an improvement over the previous example. It's a little more concise, and the code now feels very similar to if we were working with the Forms API. We're also using named status codes, which makes the response meanings more obvious. @@ -87,7 +87,7 @@ Our instance view is an improvement over the previous example. It's a little mo comment.save() return Response(serializer.data) else: - return Response(serializer.error_data, status=status.HTTP_400_BAD_REQUEST) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) elif request.method == 'DELETE': comment.delete() @@ -112,7 +112,7 @@ and Now update the `urls.py` file slightly, to append a set of `format_suffix_patterns` in addition to the existing URLs. from django.conf.urls import patterns, url - from djangorestframework.urlpatterns import format_suffix_patterns + from rest_framework.urlpatterns import format_suffix_patterns urlpatterns = patterns('blogpost.views', url(r'^$', 'comment_root'), @@ -125,21 +125,27 @@ We don't necessarily need to add these extra url patterns in, but it gives us a ## How's it looking? -Go ahead and test the API from the command line, as we did in [tutorial part 1][2]. Everything is working pretty similarly, although we've got some nicer error handling if we send invalid requests. +Go ahead and test the API from the command line, as we did in [tutorial part 1][tut-1]. Everything is working pretty similarly, although we've got some nicer error handling if we send invalid requests. **TODO: Describe using accept headers, content-type headers, and format suffixed URLs** -Now go and open the API in a web browser, by visiting [http://127.0.0.1:8000/][3]." +Now go and open the API in a web browser, by visiting [http://127.0.0.1:8000/][devserver]." **Note: Right now the Browseable API only works with the CBV's. Need to fix that.** -**TODO: Describe browseable API awesomeness** +### Browsability + +Because the API chooses a return format based on what the client asks for, it will, by default, return an HTML-formatted representation of the resource when that resource is requested by a browser. This allows for the API to be easily browsable and usable by humans. + +See the [browsable api][browseable-api] topic for more information about the browsable API feature and how to customize it. + ## What's next? -In [tutorial part 3][4], we'll start using class based views, and see how generic views reduce the amount of code we need to write. +In [tutorial part 3][tut-3], we'll start using class based views, and see how generic views reduce the amount of code we need to write. [json-url]: http://example.com/api/items/4.json -[2]: 1-serialization.md -[3]: http://127.0.0.1:8000/ -[4]: 3-class-based-views.md \ No newline at end of file +[devserver]: http://127.0.0.1:8000/ +[browseable-api]: ../topics/browsable-api.md +[tut-1]: 1-serialization.md +[tut-3]: 3-class-based-views.md diff --git a/docs/tutorial/3-class-based-views.md b/docs/tutorial/3-class-based-views.md index 247851799..25d5773f1 100644 --- a/docs/tutorial/3-class-based-views.md +++ b/docs/tutorial/3-class-based-views.md @@ -1,6 +1,6 @@ # Tutorial 3: Class Based Views -We can also write our API views using class based views, rather than function based views. As we'll see this is a powerful pattern that allows us to reuse common functionality, and helps us keep our code [DRY][1]. +We can also write our API views using class based views, rather than function based views. As we'll see this is a powerful pattern that allows us to reuse common functionality, and helps us keep our code [DRY][dry]. ## Rewriting our API using class based views @@ -9,9 +9,9 @@ We'll start by rewriting the root view as a class based view. All this involves from blog.models import Comment from blog.serializers import CommentSerializer from django.http import Http404 - from djangorestframework.views import APIView - from djangorestframework.response import Response - from djangorestframework import status + from rest_framework.views import APIView + from rest_framework.response import Response + from rest_framework import status class CommentRoot(APIView): @@ -31,8 +31,6 @@ We'll start by rewriting the root view as a class based view. All this involves return Response(serializer.serialized, status=status.HTTP_201_CREATED) return Response(serializer.serialized_errors, status=status.HTTP_400_BAD_REQUEST) - comment_root = CommentRoot.as_view() - So far, so good. It looks pretty similar to the previous case, but we've got better seperation between the different HTTP methods. We'll also need to update the instance view. class CommentInstance(APIView): @@ -55,19 +53,31 @@ So far, so good. It looks pretty similar to the previous case, but we've got be comment = self.get_object(pk) serializer = CommentSerializer(request.DATA, instance=comment) if serializer.is_valid(): - comment = serializer.deserialized + comment = serializer.object comment.save() return Response(serializer.data) - return Response(serializer.error_data, status=status.HTTP_400_BAD_REQUEST) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) def delete(self, request, pk, format=None): comment = self.get_object(pk) comment.delete() return Response(status=status.HTTP_204_NO_CONTENT) - comment_instance = CommentInstance.as_view() - That's looking good. Again, it's still pretty similar to the function based view right now. + +We'll also need to refactor our URLconf slightly now we're using class based views. + + from django.conf.urls import patterns, url + from rest_framework.urlpatterns import format_suffix_patterns + from blogpost import views + + urlpatterns = patterns('', + url(r'^$', views.CommentRoot.as_view()), + url(r'^(?P[0-9]+)$', views.CommentInstance.as_view()) + ) + + urlpatterns = format_suffix_patterns(urlpatterns) + Okay, we're done. If you run the development server everything should be working just as before. ## Using mixins @@ -80,8 +90,8 @@ Let's take a look at how we can compose our views by using the mixin classes. from blog.models import Comment from blog.serializers import CommentSerializer - from djangorestframework import mixins - from djangorestframework import generics + from rest_framework import mixins + from rest_framework import generics class CommentRoot(mixins.ListModelMixin, mixins.CreateModelMixin, @@ -95,8 +105,6 @@ Let's take a look at how we can compose our views by using the mixin classes. def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) - comment_root = CommentRoot.as_view() - We'll take a moment to examine exactly what's happening here - We're building our view using `MultipleObjectBaseView`, and adding in `ListModelMixin` and `CreateModelMixin`. The base class provides the core functionality, and the mixin classes provide the `.list()` and `.create()` actions. We're then explictly binding the `get` and `post` methods to the appropriate actions. Simple enough stuff so far. @@ -117,8 +125,6 @@ The base class provides the core functionality, and the mixin classes provide th def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs) - comment_instance = CommentInstance.as_view() - Pretty similar. This time we're using the `SingleObjectBaseView` class to provide the core functionality, and adding in mixins to provide the `.retrieve()`, `.update()` and `.destroy()` actions. ## Using generic class based views @@ -127,26 +133,21 @@ Using the mixin classes we've rewritten the views to use slightly less code than from blog.models import Comment from blog.serializers import CommentSerializer - from djangorestframework import generics + from rest_framework import generics class CommentRoot(generics.RootAPIView): model = Comment serializer_class = CommentSerializer - comment_root = CommentRoot.as_view() - class CommentInstance(generics.InstanceAPIView): model = Comment serializer_class = CommentSerializer - comment_instance = CommentInstance.as_view() - - Wow, that's pretty concise. We've got a huge amount for free, and our code looks like good, clean, idomatic Django. -Next we'll move onto [part 4 of the tutorial][2], where we'll take a look at how we can customize the behavior of our views to support a range of authentication, permissions, throttling and other aspects. +Next we'll move onto [part 4 of the tutorial][tut-4], where we'll take a look at how we can customize the behavior of our views to support a range of authentication, permissions, throttling and other aspects. -[1]: http://en.wikipedia.org/wiki/Don't_repeat_yourself -[2]: 4-authentication-permissions-and-throttling.md +[dry]: http://en.wikipedia.org/wiki/Don't_repeat_yourself +[tut-4]: 4-authentication-permissions-and-throttling.md diff --git a/docs/tutorial/4-authentication-permissions-and-throttling.md b/docs/tutorial/4-authentication-permissions-and-throttling.md index 5c37ae13e..c8d7cbd34 100644 --- a/docs/tutorial/4-authentication-permissions-and-throttling.md +++ b/docs/tutorial/4-authentication-permissions-and-throttling.md @@ -1,3 +1,5 @@ -[part 5][5] +# Tutorial 4: Authentication & Permissions -[5]: 5-relationships-and-hyperlinked-apis.md \ No newline at end of file +Nothing to see here. Onwards to [part 5][tut-5]. + +[tut-5]: 5-relationships-and-hyperlinked-apis.md \ No newline at end of file diff --git a/docs/tutorial/5-relationships-and-hyperlinked-apis.md b/docs/tutorial/5-relationships-and-hyperlinked-apis.md index 3d9598d7d..a76f81e8d 100644 --- a/docs/tutorial/5-relationships-and-hyperlinked-apis.md +++ b/docs/tutorial/5-relationships-and-hyperlinked-apis.md @@ -1,9 +1,11 @@ +# Tutorial 5 - Relationships & Hyperlinked APIs + **TODO** * Create BlogPost model * Demonstrate nested relationships * Demonstrate and describe hyperlinked relationships -[part 6][1] +Onwards to [part 6][tut-6]. -[1]: 6-resource-orientated-projects.md +[tut-6]: 6-resource-orientated-projects.md diff --git a/docs/tutorial/6-resource-orientated-projects.md b/docs/tutorial/6-resource-orientated-projects.md index 4282c25d5..3c3e7fedc 100644 --- a/docs/tutorial/6-resource-orientated-projects.md +++ b/docs/tutorial/6-resource-orientated-projects.md @@ -1,31 +1,56 @@ -serializers.py +# Tutorial 6 - Resources - class BlogPostSerializer(URLModelSerializer): - class Meta: - model = BlogPost +Resource classes are just View classes that don't have any handler methods bound to them. The actions on a resource are defined, - class CommentSerializer(URLModelSerializer): - class Meta: - model = Comment +This allows us to: + +* Encapsulate common behaviour accross a class of views, in a single Resource class. +* Seperate out the actions of a Resource from the specfics of how those actions should be bound to a particular set of URLs. + +## Refactoring to use Resources, not Views + +For instance, we can re-write our 4 sets of views into something more compact... resources.py class BlogPostResource(ModelResource): serializer_class = BlogPostSerializer model = BlogPost - permissions = [AdminOrAnonReadonly()] - throttles = [AnonThrottle(rate='5/min')] + permissions_classes = (permissions.IsAuthenticatedOrReadOnly,) + throttle_classes = (throttles.UserRateThrottle,) class CommentResource(ModelResource): serializer_class = CommentSerializer model = Comment - permissions = [AdminOrAnonReadonly()] - throttles = [AnonThrottle(rate='5/min')] + permissions_classes = (permissions.IsAuthenticatedOrReadOnly,) + throttle_classes = (throttles.UserRateThrottle,) -Now that we're using Resources rather than Views, we don't need to design the urlconf ourselves. The conventions for wiring up resources into views and urls are handled automatically. All we need to do is register the appropriate resources with a router, and let it do the rest. Here's our re-wired `urls.py` file. +## Binding Resources to URLs explicitly +The handler methods only get bound to the actions when we define the URLConf. Here's our urls.py: + + comment_root = CommentResource.as_view(actions={ + 'get': 'list', + 'post': 'create' + }) + comment_instance = CommentInstance.as_view(actions={ + 'get': 'retrieve', + 'put': 'update', + 'delete': 'destroy' + }) + ... # And for blog post + + urlpatterns = patterns('blogpost.views', + url(r'^$', comment_root), + url(r'^(?P[0-9]+)$', comment_instance) + ... # And for blog post + ) + +## Using Routers + +Right now that hasn't really saved us a lot of code. However, now that we're using Resources rather than Views, we actually don't need to design the urlconf ourselves. The conventions for wiring up resources into views and urls can be handled automatically, using `Router` classes. All we need to do is register the appropriate resources with a router, and let it do the rest. Here's our re-wired `urls.py` file. from blog import resources - from djangorestframework.routers import DefaultRouter + from rest_framework.routers import DefaultRouter router = DefaultRouter() router.register(resources.BlogPostResource) @@ -44,6 +69,8 @@ We've reached the end of our tutorial. If you want to get more involved in the * Contribute on GitHub by reviewing issues, and submitting issues or pull requests. * Join the REST framework group, and help build the community. -* Follow me [on Twitter](https://twitter.com/_tomchristie) and say hi. +* Follow me [on Twitter][twitter] and say hi. -Now go build something great. \ No newline at end of file +**Now go build some awesome things.** + +[twitter]: https://twitter.com/_tomchristie diff --git a/mkdocs.py b/mkdocs.py index e04cfe0e9..8e1010dbf 100755 --- a/mkdocs.py +++ b/mkdocs.py @@ -24,7 +24,7 @@ else: main_header = '
  • {{ title }}
  • ' sub_header = '
  • {{ title }}
  • ' -code_label = r'\1' +code_label = r'\1' page = open(os.path.join(docs_dir, 'template.html'), 'r').read() diff --git a/requirements.txt b/requirements.txt index 120cbbe50..730c1d07a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1 @@ Django>=1.3 -URLObject>=2.0.0 diff --git a/djangorestframework/__init__.py b/rest_framework/__init__.py similarity index 100% rename from djangorestframework/__init__.py rename to rest_framework/__init__.py diff --git a/djangorestframework/authentication.py b/rest_framework/authentication.py similarity index 97% rename from djangorestframework/authentication.py rename to rest_framework/authentication.py index a66343921..fd5973977 100644 --- a/djangorestframework/authentication.py +++ b/rest_framework/authentication.py @@ -5,8 +5,8 @@ Authentication behavior is provided by mixing the :class:`mixins.RequestMixin` c """ from django.contrib.auth import authenticate -from djangorestframework.compat import CsrfViewMiddleware -from djangorestframework.authtoken.models import Token +from rest_framework.compat import CsrfViewMiddleware +from rest_framework.authtoken.models import Token import base64 diff --git a/djangorestframework/authtoken/__init__.py b/rest_framework/authtoken/__init__.py similarity index 100% rename from djangorestframework/authtoken/__init__.py rename to rest_framework/authtoken/__init__.py diff --git a/djangorestframework/authtoken/migrations/0001_initial.py b/rest_framework/authtoken/migrations/0001_initial.py similarity index 100% rename from djangorestframework/authtoken/migrations/0001_initial.py rename to rest_framework/authtoken/migrations/0001_initial.py diff --git a/djangorestframework/authtoken/migrations/__init__.py b/rest_framework/authtoken/migrations/__init__.py similarity index 100% rename from djangorestframework/authtoken/migrations/__init__.py rename to rest_framework/authtoken/migrations/__init__.py diff --git a/djangorestframework/authtoken/models.py b/rest_framework/authtoken/models.py similarity index 100% rename from djangorestframework/authtoken/models.py rename to rest_framework/authtoken/models.py diff --git a/djangorestframework/authtoken/views.py b/rest_framework/authtoken/views.py similarity index 100% rename from djangorestframework/authtoken/views.py rename to rest_framework/authtoken/views.py diff --git a/djangorestframework/compat.py b/rest_framework/compat.py similarity index 99% rename from djangorestframework/compat.py rename to rest_framework/compat.py index f21dc4ef6..fb3f67d94 100644 --- a/djangorestframework/compat.py +++ b/rest_framework/compat.py @@ -83,7 +83,7 @@ except ImportError: # from django.utils.decorators import classonlymethod # logger = getLogger('django.request') - We'll just drop support for logger if running Django <= 1.2 - # Might be nice to fix this up sometime to allow djangorestframework.compat.View to match 1.3's View more closely + # Might be nice to fix this up sometime to allow rest_framework.compat.View to match 1.3's View more closely class View(object): """ diff --git a/djangorestframework/decorators.py b/rest_framework/decorators.py similarity index 92% rename from djangorestframework/decorators.py rename to rest_framework/decorators.py index ac976bec8..1483cb568 100644 --- a/djangorestframework/decorators.py +++ b/rest_framework/decorators.py @@ -1,6 +1,12 @@ from functools import wraps from django.utils.decorators import available_attrs -from djangorestframework.views import APIView +from django.core.exceptions import PermissionDenied +from rest_framework import exceptions +from rest_framework import status +from rest_framework.response import Response +from rest_framework.request import Request +from rest_framework.settings import api_settings +from rest_framwork.views import APIView class LazyViewCreator(object): diff --git a/djangorestframework/exceptions.py b/rest_framework/exceptions.py similarity index 75% rename from djangorestframework/exceptions.py rename to rest_framework/exceptions.py index 3f5b23f67..e7836ecd3 100644 --- a/djangorestframework/exceptions.py +++ b/rest_framework/exceptions.py @@ -4,7 +4,7 @@ Handled exceptions raised by REST framework. In addition Django's built in 403 and 404 exceptions are handled. (`django.http.Http404` and `django.core.exceptions.PermissionDenied`) """ -from djangorestframework import status +from rest_framework import status class APIException(Exception): @@ -31,6 +31,14 @@ class PermissionDenied(APIException): self.detail = detail or self.default_detail +class InvalidFormat(APIException): + status_code = status.HTTP_404_NOT_FOUND + default_detail = "Format suffix '.%s' not found." + + def __init__(self, format, detail=None): + self.detail = (detail or self.default_detail) % format + + class MethodNotAllowed(APIException): status_code = status.HTTP_405_METHOD_NOT_ALLOWED default_detail = "Method '%s' not allowed." @@ -39,6 +47,15 @@ class MethodNotAllowed(APIException): self.detail = (detail or self.default_detail) % method +class NotAcceptable(APIException): + status_code = status.HTTP_406_NOT_ACCEPTABLE + default_detail = "Could not satisfy the request's Accept header" + + def __init__(self, detail=None, available_renderers=None): + self.detail = detail or self.default_detail + self.available_renderers = available_renderers + + class UnsupportedMediaType(APIException): status_code = status.HTTP_415_UNSUPPORTED_MEDIA_TYPE default_detail = "Unsupported media type '%s' in request." diff --git a/djangorestframework/fields.py b/rest_framework/fields.py similarity index 97% rename from djangorestframework/fields.py rename to rest_framework/fields.py index 13b0e37d3..eab90617c 100644 --- a/djangorestframework/fields.py +++ b/rest_framework/fields.py @@ -10,8 +10,8 @@ from django.db import DEFAULT_DB_ALIAS from django.db.models.related import RelatedObject from django.utils.encoding import is_protected_type, smart_unicode from django.utils.translation import ugettext_lazy as _ -from djangorestframework.compat import parse_date, parse_datetime -from djangorestframework.compat import timezone +from rest_framework.compat import parse_date, parse_datetime +from rest_framework.compat import timezone def is_simple_callable(obj): @@ -42,7 +42,11 @@ class Field(object): self.source = source self.readonly = readonly - self.required = not(readonly) + if required is None: + self.required = not(readonly) + else: + assert not readonly, "Cannot set required=True and readonly=True" + self.required = required messages = {} for c in reversed(self.__class__.__mro__): @@ -66,9 +70,8 @@ class Field(object): self.model_field = model_field def validate(self, value): - pass - # if value in validators.EMPTY_VALUES and self.required: - # raise ValidationError(self.error_messages['required']) + if value in validators.EMPTY_VALUES and self.required: + raise ValidationError(self.error_messages['required']) def run_validators(self, value): if value in validators.EMPTY_VALUES: diff --git a/djangorestframework/generics.py b/rest_framework/generics.py similarity index 98% rename from djangorestframework/generics.py rename to rest_framework/generics.py index 5815b73a4..106c99925 100644 --- a/djangorestframework/generics.py +++ b/rest_framework/generics.py @@ -2,7 +2,7 @@ Generic views that provide commmonly needed behaviour. """ -from djangorestframework import views, mixins +from rest_framework import views, mixins from django.views.generic.detail import SingleObjectMixin from django.views.generic.list import MultipleObjectMixin diff --git a/djangorestframework/mixins.py b/rest_framework/mixins.py similarity index 90% rename from djangorestframework/mixins.py rename to rest_framework/mixins.py index 1f06dd345..33a363d33 100644 --- a/djangorestframework/mixins.py +++ b/rest_framework/mixins.py @@ -7,8 +7,8 @@ which allows mixin classes to be composed in interesting ways. Eg. Use mixins to build a Resource class, and have a Router class perform the binding of http methods to actions for us. """ -from djangorestframework import status -from djangorestframework.response import Response +from rest_framework import status +from rest_framework.response import Response class CreateModelMixin(object): @@ -59,7 +59,7 @@ class UpdateModelMixin(object): self.object = serializer.object self.object.save() return Response(serializer.data) - return Response(serializer.error_data, status=status.HTTP_400_BAD_REQUEST) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class DestroyModelMixin(object): @@ -84,8 +84,8 @@ class MetadataMixin(object): content = { 'name': self.get_name(), 'description': self.get_description(), - 'renders': self._rendered_media_types, - 'parses': self._parsed_media_types, + 'renders': [renderer.media_type for renderer in self.renderer_classes], + 'parses': [parser.media_type for parser in self.parser_classes], } # TODO: Add 'fields', from serializer info. # form = self.get_bound_form() diff --git a/djangorestframework/models.py b/rest_framework/models.py similarity index 100% rename from djangorestframework/models.py rename to rest_framework/models.py diff --git a/rest_framework/negotiation.py b/rest_framework/negotiation.py new file mode 100644 index 000000000..0d3b368cb --- /dev/null +++ b/rest_framework/negotiation.py @@ -0,0 +1,74 @@ +from rest_framework import exceptions +from rest_framework.settings import api_settings +from rest_framework.utils.mediatypes import order_by_precedence + + +class BaseContentNegotiation(object): + def negotiate(self, request, renderers, format=None, force=False): + raise NotImplementedError('.negotiate() must be implemented') + + +class DefaultContentNegotiation(object): + settings = api_settings + + def negotiate(self, request, renderers, format=None, force=False): + """ + Given a request and a list of renderers, return a two-tuple of: + (renderer, media type). + + If force is set, then suppress exceptions, and forcibly return a + fallback renderer and media_type. + """ + try: + return self.unforced_negotiate(request, renderers, format) + except (exceptions.InvalidFormat, exceptions.NotAcceptable): + if force: + return (renderers[0], renderers[0].media_type) + raise + + def unforced_negotiate(self, request, renderers, format=None): + """ + As `.negotiate()`, but does not take the optional `force` agument, + or suppress exceptions. + """ + # Allow URL style format override. eg. "?format=json + format = format or request.GET.get(self.settings.URL_FORMAT_OVERRIDE) + + if format: + renderers = self.filter_renderers(renderers, format) + + accepts = self.get_accept_list(request) + + # Check the acceptable media types against each renderer, + # attempting more specific media types first + # NB. The inner loop here isn't as bad as it first looks :) + # Worst case is we're looping over len(accept_list) * len(self.renderers) + for media_type_set in order_by_precedence(accepts): + for renderer in renderers: + for media_type in media_type_set: + if renderer.can_handle_media_type(media_type): + return renderer, media_type + + raise exceptions.NotAcceptable(available_renderers=renderers) + + def filter_renderers(self, renderers, format): + """ + If there is a '.json' style format suffix, filter the renderers + so that we only negotiation against those that accept that format. + """ + renderers = [renderer for renderer in renderers + if renderer.can_handle_format(format)] + if not renderers: + raise exceptions.InvalidFormat(format) + return renderers + + def get_accept_list(self, request): + """ + Given the incoming request, return a tokenised list of media + type strings. + + Allows URL style accept override. eg. "?accept=application/json" + """ + header = request.META.get('HTTP_ACCEPT', '*/*') + header = request.GET.get(self.settings.URL_ACCEPT_OVERRIDE, header) + return [token.strip() for token in header.split(',')] diff --git a/djangorestframework/parsers.py b/rest_framework/parsers.py similarity index 89% rename from djangorestframework/parsers.py rename to rest_framework/parsers.py index fb08c5a0b..5151b2525 100644 --- a/djangorestframework/parsers.py +++ b/rest_framework/parsers.py @@ -15,28 +15,17 @@ from django.http import QueryDict from django.http.multipartparser import MultiPartParser as DjangoMultiPartParser from django.http.multipartparser import MultiPartParserError from django.utils import simplejson as json -from djangorestframework.compat import yaml -from djangorestframework.exceptions import ParseError -from djangorestframework.utils.mediatypes import media_type_matches +from rest_framework.compat import yaml +from rest_framework.exceptions import ParseError +from rest_framework.utils.mediatypes import media_type_matches from xml.etree import ElementTree as ET -from djangorestframework.compat import ETParseError +from rest_framework.compat import ETParseError from xml.parsers.expat import ExpatError import datetime import decimal from io import BytesIO -__all__ = ( - 'BaseParser', - 'JSONParser', - 'PlainTextParser', - 'FormParser', - 'MultiPartParser', - 'YAMLParser', - 'XMLParser' -) - - class DataAndFiles(object): def __init__(self, data, files): self.data = data @@ -45,8 +34,8 @@ class DataAndFiles(object): class BaseParser(object): """ - All parsers should extend :class:`BaseParser`, specifying a :attr:`media_type` attribute, - and overriding the :meth:`parse` method. + All parsers should extend `BaseParser`, specifying a `media_type` + attribute, and overriding the `.parse_stream()` method. """ media_type = None @@ -77,7 +66,7 @@ class BaseParser(object): def parse_stream(self, stream, **opts): """ - Given a *stream* to read from, return the deserialized output. + Given a stream to read from, return the deserialized output. Should return parsed data, or a DataAndFiles object consisting of the parsed data and files. """ @@ -245,16 +234,3 @@ class XMLParser(BaseParser): pass return value - - -DEFAULT_PARSERS = ( - JSONParser, - FormParser, - MultiPartParser, - XMLParser -) - -if yaml: - DEFAULT_PARSERS += (YAMLParser, ) -else: - YAMLParser = None diff --git a/djangorestframework/permissions.py b/rest_framework/permissions.py similarity index 94% rename from djangorestframework/permissions.py rename to rest_framework/permissions.py index 3a669822c..51837a017 100644 --- a/djangorestframework/permissions.py +++ b/rest_framework/permissions.py @@ -5,15 +5,6 @@ for checking if a request passes a certain set of constraints. Permission behavior is provided by mixing the :class:`mixins.PermissionsMixin` class into a :class:`View` class. """ -__all__ = ( - 'BasePermission', - 'FullAnonAccess', - 'IsAuthenticated', - 'IsAdminUser', - 'IsUserOrIsAnonReadOnly', - 'PerUserThrottling', - 'PerViewThrottling', -) SAFE_METHODS = ['GET', 'HEAD', 'OPTIONS'] diff --git a/djangorestframework/renderers.py b/rest_framework/renderers.py similarity index 67% rename from djangorestframework/renderers.py rename to rest_framework/renderers.py index 26e8cba14..eeba73390 100644 --- a/djangorestframework/renderers.py +++ b/rest_framework/renderers.py @@ -5,33 +5,18 @@ Django REST framework also provides HTML and PlainText renderers that help self- by serializing the output along with documentation regarding the View, output status and headers, and providing forms and links depending on the allowed methods, renderers and parsers on the View. """ +import string from django import forms from django.template import RequestContext, loader from django.utils import simplejson as json - -from djangorestframework.compat import yaml -from djangorestframework.settings import api_settings -from djangorestframework.utils import dict2xml -from djangorestframework.utils import encoders -from djangorestframework.utils.breadcrumbs import get_breadcrumbs -from djangorestframework.utils.mediatypes import get_media_type_params, add_media_type_param, media_type_matches -from djangorestframework import VERSION -from djangorestframework.fields import FloatField, IntegerField, DateTimeField, DateField, EmailField, CharField, BooleanField - -import string - - -__all__ = ( - 'BaseRenderer', - 'TemplateRenderer', - 'JSONRenderer', - 'JSONPRenderer', - 'DocumentingHTMLRenderer', - 'DocumentingXHTMLRenderer', - 'DocumentingPlainTextRenderer', - 'XMLRenderer', - 'YAMLRenderer' -) +from rest_framework.compat import yaml +from rest_framework.settings import api_settings +from rest_framework.utils import dict2xml +from rest_framework.utils import encoders +from rest_framework.utils.breadcrumbs import get_breadcrumbs +from rest_framework.utils.mediatypes import get_media_type_params, add_media_type_param, media_type_matches +from rest_framework import VERSION +from rest_framework import serializers class BaseRenderer(object): @@ -40,36 +25,28 @@ class BaseRenderer(object): and override the :meth:`render` method. """ - _FORMAT_QUERY_PARAM = 'format' - media_type = None format = None def __init__(self, view=None): self.view = view - def can_handle_response(self, accept): - """ - Returns :const:`True` if this renderer is able to deal with the given - *accept* media type. + def can_handle_format(self, format): + return format == self.format - The default implementation for this function is to check the *accept* - argument against the :attr:`media_type` attribute set on the class to see if + def can_handle_media_type(self, media_type): + """ + Returns `True` if this renderer is able to deal with the given + media type. + + The default implementation for this function is to check the media type + argument against the media_type attribute set on the class to see if they match. - This may be overridden to provide for other behavior, but typically you'll - instead want to just set the :attr:`media_type` attribute on the class. + This may be overridden to provide for other behavior, but typically + you'll instead want to just set the `media_type` attribute on the class. """ - # TODO: format overriding must go out of here - format = None - if self.view is not None: - format = self.view.kwargs.get(self._FORMAT_QUERY_PARAM, None) - if format is None and self.view is not None: - format = self.view.request.GET.get(self._FORMAT_QUERY_PARAM, None) - - if format is not None: - return format == self.format - return media_type_matches(self.media_type, accept) + return media_type_matches(self.media_type, media_type) def render(self, obj=None, media_type=None): """ @@ -91,7 +68,7 @@ class BaseRenderer(object): class JSONRenderer(BaseRenderer): """ - Renderer which serializes to JSON + Renderer which serializes to json. """ media_type = 'application/json' @@ -100,7 +77,7 @@ class JSONRenderer(BaseRenderer): def render(self, obj=None, media_type=None): """ - Renders *obj* into serialized JSON. + Render `obj` into json. """ if obj is None: return '' @@ -115,28 +92,37 @@ class JSONRenderer(BaseRenderer): except (ValueError, TypeError): indent = None - return json.dumps(obj, cls=self.encoder_class, indent=indent, sort_keys=sort_keys) + return json.dumps(obj, cls=self.encoder_class, + indent=indent, sort_keys=sort_keys) class JSONPRenderer(JSONRenderer): """ - Renderer which serializes to JSONP + Renderer which serializes to json, + wrapping the json output in a callback function. """ media_type = 'application/javascript' format = 'jsonp' - renderer_class = JSONRenderer callback_parameter = 'callback' + default_callback = 'callback' - def _get_callback(self): - return self.view.request.GET.get(self.callback_parameter, self.callback_parameter) - - def _get_renderer(self): - return self.renderer_class(self.view) + def get_callback(self): + """ + Determine the name of the callback to wrap around the json output. + """ + params = self.view.request.GET + return params.get(self.callback_parameter, self.default_callback) def render(self, obj=None, media_type=None): - callback = self._get_callback() - json = self._get_renderer().render(obj, media_type) + """ + Renders into jsonp, wrapping the json output in a callback function. + + Clients may set the callback function name using a query parameter + on the URL, for example: ?callback=exampleCallbackName + """ + callback = self.get_callback() + json = super(JSONPRenderer, self).render(obj, media_type) return "%s(%s);" % (callback, json) @@ -199,13 +185,13 @@ class TemplateRenderer(BaseRenderer): return template.render(context) -class DocumentingTemplateRenderer(BaseRenderer): +class DocumentingHTMLRenderer(BaseRenderer): """ - Base class for renderers used to self-document the API. - Implementing classes should extend this class and set the template attribute. + HTML renderer used to self-document the API. """ - - template = None + media_type = 'text/html' + format = 'html' + template = 'rest_framework/api.html' def _get_content(self, view, request, obj, media_type): """ @@ -217,7 +203,7 @@ class DocumentingTemplateRenderer(BaseRenderer): # Find the first valid renderer and render the content. (Don't use another documenting renderer.) renderers = [renderer for renderer in view.renderer_classes - if not issubclass(renderer, DocumentingTemplateRenderer)] + if not issubclass(renderer, DocumentingHTMLRenderer)] if not renderers: return '[No renderers were found]' @@ -238,13 +224,13 @@ class DocumentingTemplateRenderer(BaseRenderer): return # We need to map our Fields to Django's Fields. field_mapping = dict([ - [FloatField.__name__, forms.FloatField], - [IntegerField.__name__, forms.IntegerField], - [DateTimeField.__name__, forms.DateTimeField], - [DateField.__name__, forms.DateField], - [EmailField.__name__, forms.EmailField], - [CharField.__name__, forms.CharField], - [BooleanField.__name__, forms.BooleanField] + [serializers.FloatField.__name__, forms.FloatField], + [serializers.IntegerField.__name__, forms.IntegerField], + [serializers.DateTimeField.__name__, forms.DateTimeField], + [serializers.DateField.__name__, forms.DateField], + [serializers.EmailField.__name__, forms.EmailField], + [serializers.CharField.__name__, forms.CharField], + [serializers.BooleanField.__name__, forms.BooleanField] ]) # Creating an on the fly form see: http://stackoverflow.com/questions/3915024/dynamically-creating-classes-python @@ -254,6 +240,8 @@ class DocumentingTemplateRenderer(BaseRenderer): object = self.view.object serializer = self.view.get_serializer(instance=object) for k, v in serializer.fields.items(): + if v.readonly: + continue fields[k] = field_mapping[v.__class__.__name__]() OnTheFlyForm = type("OnTheFlyForm", (forms.Form,), fields) if object and not self.view.request.method == 'DELETE': # Don't fill in the form when the object is deleted @@ -280,8 +268,9 @@ class DocumentingTemplateRenderer(BaseRenderer): Add the fields dynamically.""" super(GenericContentForm, self).__init__() - contenttype_choices = [(media_type, media_type) for media_type in view._parsed_media_types] - initial_contenttype = view._default_parser.media_type + parsed_media_types = [parser.media_type for parser in view.parser_classes] + contenttype_choices = [(media_type, media_type) for media_type in parsed_media_types] + initial_contenttype = parsed_media_types[0] self.fields[request._CONTENTTYPE_PARAM] = forms.ChoiceField(label='Content Type', choices=contenttype_choices, @@ -317,8 +306,11 @@ class DocumentingTemplateRenderer(BaseRenderer): The context used in the template contains all the information needed to self-document the response to this request. """ + view = self.view + request = view.request + response = view.response - content = self._get_content(self.view, self.view.request, obj, media_type) + content = self._get_content(view, request, obj, media_type) put_form_instance = self._get_form_instance(self.view, 'put') post_form_instance = self._get_form_instance(self.view, 'post') @@ -331,19 +323,17 @@ class DocumentingTemplateRenderer(BaseRenderer): template = loader.get_template(self.template) context = RequestContext(self.view.request, { 'content': content, - 'view': self.view, - 'request': self.view.request, - 'response': self.view.response, + 'view': view, + 'request': request, + 'response': response, 'description': description, 'name': name, 'version': VERSION, 'breadcrumblist': breadcrumb_list, 'allowed_methods': self.view.allowed_methods, - 'available_formats': self.view._rendered_formats, + 'available_formats': [renderer.format for renderer in self.view.renderer_classes], 'put_form': put_form_instance, 'post_form': post_form_instance, - 'FORMAT_PARAM': self._FORMAT_QUERY_PARAM, - 'METHOD_PARAM': getattr(self.view, '_METHOD_PARAM', None), 'api_settings': api_settings }) @@ -356,53 +346,3 @@ class DocumentingTemplateRenderer(BaseRenderer): self.view.response.status_code = 200 return ret - - -class DocumentingHTMLRenderer(DocumentingTemplateRenderer): - """ - Renderer which provides a browsable HTML interface for an API. - See the examples at http://api.django-rest-framework.org to see this in action. - """ - - media_type = 'text/html' - format = 'html' - template = 'djangorestframework/api.html' - - -class DocumentingXHTMLRenderer(DocumentingTemplateRenderer): - """ - Identical to DocumentingHTMLRenderer, except with an xhtml media type. - We need this to be listed in preference to xml in order to return HTML to WebKit based browsers, - given their Accept headers. - """ - - media_type = 'application/xhtml+xml' - format = 'xhtml' - template = 'djangorestframework/api.html' - - -class DocumentingPlainTextRenderer(DocumentingTemplateRenderer): - """ - Renderer that serializes the object with the default renderer, but also provides plain-text - documentation of the returned status and headers, and of the resource's name and description. - Useful for browsing an API with command line tools. - """ - - media_type = 'text/plain' - format = 'txt' - template = 'djangorestframework/api.txt' - - -DEFAULT_RENDERERS = ( - JSONRenderer, - JSONPRenderer, - DocumentingHTMLRenderer, - DocumentingXHTMLRenderer, - DocumentingPlainTextRenderer, - XMLRenderer -) - -if yaml: - DEFAULT_RENDERERS += (YAMLRenderer, ) -else: - YAMLRenderer = None diff --git a/djangorestframework/request.py b/rest_framework/request.py similarity index 96% rename from djangorestframework/request.py rename to rest_framework/request.py index 450d2ac7d..2034ccc63 100644 --- a/djangorestframework/request.py +++ b/rest_framework/request.py @@ -11,12 +11,9 @@ The wrapped request then offers a richer API, in particular : """ from StringIO import StringIO -from djangorestframework import exceptions -from djangorestframework.settings import api_settings -from djangorestframework.utils.mediatypes import is_form_media_type - - -__all__ = ('Request',) +from rest_framework import exceptions +from rest_framework.settings import api_settings +from rest_framework.utils.mediatypes import is_form_media_type class Empty(object): @@ -103,6 +100,13 @@ class Request(object): self._load_stream() return self._stream + @property + def QUERY_PARAMS(self): + """ + More semantically correct name for request.GET. + """ + return self._request.GET + @property def DATA(self): """ diff --git a/rest_framework/resources.py b/rest_framework/resources.py new file mode 100644 index 000000000..41b7c1c6a --- /dev/null +++ b/rest_framework/resources.py @@ -0,0 +1,87 @@ +from functools import update_wrapper +import inspect +from django.utils.decorators import classonlymethod +from djanorestframework import views, generics + + +def wrapped(source, dest): + """ + Copy public, non-method attributes from source to dest, and return dest. + """ + for attr in [attr for attr in dir(source) + if not attr.startswith('_') and not inspect.ismethod(attr)]: + setattr(dest, attr, getattr(source, attr)) + return dest + + +class ResourceMixin(object): + """ + Clone Django's `View.as_view()` behaviour *except* using REST framework's + 'method -> action' binding for resources. + """ + + @classonlymethod + def as_view(cls, actions, **initkwargs): + """ + Main entry point for a request-response process. + """ + # sanitize keyword arguments + for key in initkwargs: + if key in cls.http_method_names: + raise TypeError("You tried to pass in the %s method name as a " + "keyword argument to %s(). Don't do that." + % (key, cls.__name__)) + if not hasattr(cls, key): + raise TypeError("%s() received an invalid keyword %r" % ( + cls.__name__, key)) + + def view(request, *args, **kwargs): + self = cls(**initkwargs) + + # Bind methods to actions + for method, action in actions.items(): + handler = getattr(self, action) + setattr(self, method, handler) + + # As you were, solider. + if hasattr(self, 'get') and not hasattr(self, 'head'): + self.head = self.get + return self.dispatch(request, *args, **kwargs) + + # take name and docstring from class + update_wrapper(view, cls, updated=()) + + # and possible attributes set by decorators + # like csrf_exempt from dispatch + update_wrapper(view, cls.dispatch, assigned=()) + return view + + +class Resource(ResourceMixin, views.APIView): + pass + + +class ModelResource(ResourceMixin, views.APIView): + root_class = generics.RootAPIView + detail_class = generics.InstanceAPIView + + def root_view(self): + return wrapped(self, self.root_class()) + + def detail_view(self): + return wrapped(self, self.detail_class()) + + def list(self, request, *args, **kwargs): + return self.root_view().list(request, args, kwargs) + + def create(self, request, *args, **kwargs): + return self.root_view().create(request, args, kwargs) + + def retrieve(self, request, *args, **kwargs): + return self.detail_view().retrieve(request, args, kwargs) + + def update(self, request, *args, **kwargs): + return self.detail_view().update(request, args, kwargs) + + def destroy(self, request, *args, **kwargs): + return self.detail_view().destroy(request, args, kwargs) diff --git a/rest_framework/response.py b/rest_framework/response.py new file mode 100644 index 000000000..90516837d --- /dev/null +++ b/rest_framework/response.py @@ -0,0 +1,48 @@ +from django.core.handlers.wsgi import STATUS_CODE_TEXT +from django.template.response import SimpleTemplateResponse + + +class Response(SimpleTemplateResponse): + """ + An HttpResponse that allows it's data to be rendered into + arbitrary media types. + """ + + def __init__(self, data=None, status=None, headers=None, + renderer=None, accepted_media_type=None): + """ + Alters the init arguments slightly. + For example, drop 'template_name', and instead use 'data'. + + Setting 'renderer' and 'media_type' will typically be defered, + For example being set automatically by the `APIView`. + """ + super(Response, self).__init__(None, status=status) + self.data = data + self.headers = headers and headers[:] or [] + self.renderer = renderer + + # Accepted media type is the portion of the request Accept header + # that the renderer satisfied. It could be '*/*', or somthing like + # application/json; indent=4 + # + # This is NOT the value that will be returned in the 'Content-Type' + # header, but we do need to know the value in case there are + # any specific parameters which affect the rendering process. + self.accepted_media_type = accepted_media_type + + @property + def rendered_content(self): + self['Content-Type'] = self.renderer.media_type + if self.data is None: + return self.renderer.render() + render_media_type = self.accepted_media_type or self.renderer.media_type + return self.renderer.render(self.data, render_media_type) + + @property + def status_text(self): + """ + Returns reason text corresponding to our HTTP response status code. + Provided for convenience. + """ + return STATUS_CODE_TEXT.get(self.status_code, '') diff --git a/djangorestframework/reverse.py b/rest_framework/reverse.py similarity index 100% rename from djangorestframework/reverse.py rename to rest_framework/reverse.py diff --git a/djangorestframework/runtests/__init__.py b/rest_framework/runtests/__init__.py similarity index 100% rename from djangorestframework/runtests/__init__.py rename to rest_framework/runtests/__init__.py diff --git a/djangorestframework/runtests/runcoverage.py b/rest_framework/runtests/runcoverage.py similarity index 79% rename from djangorestframework/runtests/runcoverage.py rename to rest_framework/runtests/runcoverage.py index 4fa7cb8db..5f7fc876f 100755 --- a/djangorestframework/runtests/runcoverage.py +++ b/rest_framework/runtests/runcoverage.py @@ -1,6 +1,6 @@ #!/usr/bin/env python """ -Useful tool to run the test suite for djangorestframework and generate a coverage report. +Useful tool to run the test suite for rest_framework and generate a coverage report. """ # http://ericholscher.com/blog/2009/jun/29/enable-setuppy-test-your-django-apps/ @@ -8,13 +8,13 @@ Useful tool to run the test suite for djangorestframework and generate a coverag # http://code.djangoproject.com/svn/django/trunk/tests/runtests.py import os import sys -os.environ['DJANGO_SETTINGS_MODULE'] = 'djangorestframework.runtests.settings' +os.environ['DJANGO_SETTINGS_MODULE'] = 'rest_framework.runtests.settings' from coverage import coverage def main(): - """Run the tests for djangorestframework and generate a coverage report.""" + """Run the tests for rest_framework and generate a coverage report.""" cov = coverage() cov.erase() @@ -32,16 +32,16 @@ def main(): 'Function-based test runners are deprecated. Test runners should be classes with a run_tests() method.', DeprecationWarning ) - failures = TestRunner(['djangorestframework']) + failures = TestRunner(['rest_framework']) else: test_runner = TestRunner() - failures = test_runner.run_tests(['djangorestframework']) + failures = test_runner.run_tests(['rest_framework']) cov.stop() # Discover the list of all modules that we should test coverage for - import djangorestframework + import rest_framework - project_dir = os.path.dirname(djangorestframework.__file__) + project_dir = os.path.dirname(rest_framework.__file__) cov_files = [] for (path, dirs, files) in os.walk(project_dir): diff --git a/djangorestframework/runtests/runtests.py b/rest_framework/runtests/runtests.py similarity index 85% rename from djangorestframework/runtests/runtests.py rename to rest_framework/runtests/runtests.py index 1628aff7c..b2438c9b2 100755 --- a/djangorestframework/runtests/runtests.py +++ b/rest_framework/runtests/runtests.py @@ -5,7 +5,7 @@ # http://code.djangoproject.com/svn/django/trunk/tests/runtests.py import os import sys -os.environ['DJANGO_SETTINGS_MODULE'] = 'djangorestframework.runtests.settings' +os.environ['DJANGO_SETTINGS_MODULE'] = 'rest_framework.runtests.settings' from django.conf import settings from django.test.utils import get_runner @@ -32,7 +32,7 @@ def main(): else: print usage() sys.exit(1) - failures = test_runner.run_tests(['djangorestframework' + test_case]) + failures = test_runner.run_tests(['rest_framework' + test_case]) sys.exit(failures) diff --git a/djangorestframework/runtests/settings.py b/rest_framework/runtests/settings.py similarity index 98% rename from djangorestframework/runtests/settings.py rename to rest_framework/runtests/settings.py index da2ae5b8f..93e38f467 100644 --- a/djangorestframework/runtests/settings.py +++ b/rest_framework/runtests/settings.py @@ -89,8 +89,8 @@ INSTALLED_APPS = ( # 'django.contrib.admin', # Uncomment the next line to enable admin documentation: # 'django.contrib.admindocs', - 'djangorestframework', - 'djangorestframework.authtoken', + 'rest_framework', + 'rest_framework.authtoken', ) STATIC_URL = '/static/' diff --git a/djangorestframework/runtests/urls.py b/rest_framework/runtests/urls.py similarity index 100% rename from djangorestframework/runtests/urls.py rename to rest_framework/runtests/urls.py diff --git a/djangorestframework/serializers.py b/rest_framework/serializers.py similarity index 98% rename from djangorestframework/serializers.py rename to rest_framework/serializers.py index 46980ee6b..4d5958d25 100644 --- a/djangorestframework/serializers.py +++ b/rest_framework/serializers.py @@ -1,10 +1,10 @@ -from decimal import Decimal -from django.core.serializers.base import DeserializedObject -from django.utils.datastructures import SortedDict import copy import datetime import types -from djangorestframework.fields import * +from decimal import Decimal +from django.core.serializers.base import DeserializedObject +from django.utils.datastructures import SortedDict +from rest_framework.fields import * class DictWithMetadata(dict): @@ -95,7 +95,7 @@ class BaseSerializer(Field): self.context = context or {} self.init_data = data - self.instance = instance + self.object = instance self._data = None self._errors = None @@ -247,7 +247,7 @@ class BaseSerializer(Field): self._errors = {} attrs = self.restore_fields(data) if not self._errors: - return self.restore_object(attrs, instance=getattr(self, 'instance', None)) + return self.restore_object(attrs, instance=getattr(self, 'object', None)) @property def errors(self): @@ -267,7 +267,7 @@ class BaseSerializer(Field): @property def data(self): if self._data is None: - self._data = self.to_native(self.instance) + self._data = self.to_native(self.object) return self._data diff --git a/djangorestframework/settings.py b/rest_framework/settings.py similarity index 71% rename from djangorestframework/settings.py rename to rest_framework/settings.py index e5181f4b4..312d707dc 100644 --- a/djangorestframework/settings.py +++ b/rest_framework/settings.py @@ -1,15 +1,15 @@ """ -Settings for REST framework are all namespaced in the API_SETTINGS setting. +Settings for REST framework are all namespaced in the REST_FRAMEWORK setting. For example your project's `settings.py` file might look like this: -API_SETTINGS = { +REST_FRAMEWORK = { 'DEFAULT_RENDERERS': ( - 'djangorestframework.renderers.JSONRenderer', - 'djangorestframework.renderers.YAMLRenderer', + 'rest_framework.renderers.JSONRenderer', + 'rest_framework.renderers.YAMLRenderer', ) 'DEFAULT_PARSERS': ( - 'djangorestframework.parsers.JSONParser', - 'djangorestframework.parsers.YAMLParser', + 'rest_framework.parsers.JSONParser', + 'rest_framework.parsers.YAMLParser', ) } @@ -23,21 +23,22 @@ from django.utils import importlib DEFAULTS = { 'DEFAULT_RENDERERS': ( - 'djangorestframework.renderers.JSONRenderer', - 'djangorestframework.renderers.JSONPRenderer', - 'djangorestframework.renderers.DocumentingHTMLRenderer', - 'djangorestframework.renderers.DocumentingPlainTextRenderer', + 'rest_framework.renderers.JSONRenderer', + 'rest_framework.renderers.DocumentingHTMLRenderer', ), 'DEFAULT_PARSERS': ( - 'djangorestframework.parsers.JSONParser', - 'djangorestframework.parsers.FormParser' + 'rest_framework.parsers.JSONParser', + 'rest_framework.parsers.FormParser' + 'rest_framework.parsers.MultiPartParser' ), 'DEFAULT_AUTHENTICATION': ( - 'djangorestframework.authentication.SessionAuthentication', - 'djangorestframework.authentication.UserBasicAuthentication' + 'rest_framework.authentication.SessionAuthentication', + 'rest_framework.authentication.UserBasicAuthentication' ), 'DEFAULT_PERMISSIONS': (), 'DEFAULT_THROTTLES': (), + 'DEFAULT_CONTENT_NEGOTIATION': + 'rest_framework.negotiation.DefaultContentNegotiation', 'UNAUTHENTICATED_USER': 'django.contrib.auth.models.AnonymousUser', 'UNAUTHENTICATED_TOKEN': None, @@ -46,6 +47,7 @@ DEFAULTS = { 'FORM_CONTENT_OVERRIDE': '_content', 'FORM_CONTENTTYPE_OVERRIDE': '_content_type', 'URL_ACCEPT_OVERRIDE': '_accept', + 'URL_FORMAT_OVERRIDE': 'format', 'FORMAT_SUFFIX_KWARG': 'format' } @@ -58,8 +60,9 @@ IMPORT_STRINGS = ( 'DEFAULT_AUTHENTICATION', 'DEFAULT_PERMISSIONS', 'DEFAULT_THROTTLES', + 'DEFAULT_CONTENT_NEGOTIATION', 'UNAUTHENTICATED_USER', - 'UNAUTHENTICATED_TOKEN' + 'UNAUTHENTICATED_TOKEN', ) @@ -68,7 +71,7 @@ def perform_import(val, setting): If the given setting is a string import notation, then perform the necessary import or imports. """ - if val is None or setting not in IMPORT_STRINGS: + if val is None or not setting in IMPORT_STRINGS: return val if isinstance(val, basestring): @@ -88,10 +91,7 @@ def import_from_string(val, setting): module_path, class_name = '.'.join(parts[:-1]), parts[-1] module = importlib.import_module(module_path) return getattr(module, class_name) - except Exception, e: - import traceback - tb = traceback.format_exc() - import pdb; pdb.set_trace() + except: msg = "Could not import '%s' for API setting '%s'" % (val, setting) raise ImportError(msg) @@ -101,7 +101,7 @@ class APISettings(object): A settings object, that allows API settings to be accessed as properties. For example: - from djangorestframework.settings import api_settings + from rest_framework.settings import api_settings print api_settings.DEFAULT_RENDERERS Any setting with string import paths will be automatically resolved @@ -113,7 +113,7 @@ class APISettings(object): try: # Check if present in user settings - val = perform_import(settings.API_SETTINGS[attr], attr) + val = perform_import(settings.REST_FRAMEWORK[attr], attr) except (AttributeError, KeyError): # Fall back to defaults val = perform_import(DEFAULTS[attr], attr) diff --git a/rest_framework/static/rest_framework/css/bootstrap-tweaks.css b/rest_framework/static/rest_framework/css/bootstrap-tweaks.css new file mode 100644 index 000000000..c650ef2e9 --- /dev/null +++ b/rest_framework/static/rest_framework/css/bootstrap-tweaks.css @@ -0,0 +1,22 @@ +/* + +This CSS file contains some tweaks specific to the included Bootstrap theme. +It's separate from `style.css` so that it can be easily overridden by replacing +a single block in the template. + +*/ + + +.form-actions { + background: transparent; + border-top-color: transparent; + padding-top: 0; +} + +.navbar-inverse .brand a { + color: #999; +} +.navbar-inverse .brand:hover a { + color: white; + text-decoration: none; +} \ No newline at end of file diff --git a/rest_framework/static/rest_framework/css/bootstrap.min.css b/rest_framework/static/rest_framework/css/bootstrap.min.css new file mode 100644 index 000000000..373f4b430 --- /dev/null +++ b/rest_framework/static/rest_framework/css/bootstrap.min.css @@ -0,0 +1,841 @@ +/*! + * Bootstrap v2.1.1 + * + * 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:"";line-height:0;} +.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:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} +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%;width:auto\9;height:auto;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;} +body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333333;background-color:#ffffff;} +a{color:#0088cc;text-decoration:none;} +a:hover{color:#005580;text-decoration:underline;} +.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;} +.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.2);-webkit-box-shadow:0 1px 3px rgba(0, 0, 0, 0.1);-moz-box-shadow:0 1px 3px rgba(0, 0, 0, 0.1);box-shadow:0 1px 3px rgba(0, 0, 0, 0.1);} +.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px;} +.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;} +.row:after{clear:both;} +[class*="span"]{float:left;min-height:1px;margin-left:20px;} +.container,.navbar-static-top .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:"";line-height:0;} +.row-fluid:after{clear:both;} +.row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;} +.row-fluid [class*="span"]:first-child{margin-left:0;} +.row-fluid .span12{width:100%;*width:99.94680851063829%;} +.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%;} +.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%;} +.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%;} +.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%;} +.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%;} +.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%;} +.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%;} +.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%;} +.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%;} +.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%;} +.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%;} +.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%;} +.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%;} +.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%;} +.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%;} +.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%;} +.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%;} +.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%;} +.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%;} +.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%;} +.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%;} +.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%;} +.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%;} +.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%;} +.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%;} +.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%;} +.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%;} +.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%;} +.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%;} +.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%;} +.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%;} +.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%;} +.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%;} +.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%;} +.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%;} +[class*="span"].hide,.row-fluid [class*="span"].hide{display:none;} +[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right;} +.container{margin-right:auto;margin-left:auto;*zoom:1;}.container:before,.container:after{display:table;content:"";line-height:0;} +.container:after{clear:both;} +.container-fluid{padding-right:20px;padding-left:20px;*zoom:1;}.container-fluid:before,.container-fluid:after{display:table;content:"";line-height:0;} +.container-fluid:after{clear:both;} +p{margin:0 0 10px;} +.lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px;} +small{font-size:85%;} +strong{font-weight:bold;} +em{font-style:italic;} +cite{font-style:normal;} +.muted{color:#999999;} +.text-warning{color:#c09853;} +.text-error{color:#b94a48;} +.text-info{color:#3a87ad;} +.text-success{color:#468847;} +h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:1;color:inherit;text-rendering:optimizelegibility;}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999999;} +h1{font-size:36px;line-height:40px;} +h2{font-size:30px;line-height:40px;} +h3{font-size:24px;line-height:40px;} +h4{font-size:18px;line-height:20px;} +h5{font-size:14px;line-height:20px;} +h6{font-size:12px;line-height:20px;} +h1 small{font-size:24px;} +h2 small{font-size:18px;} +h3 small{font-size:14px;} +h4 small{font-size:14px;} +.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eeeeee;} +ul,ol{padding:0;margin:0 0 10px 25px;} +ul ul,ul ol,ol ol,ol ul{margin-bottom:0;} +li{line-height:20px;} +ul.unstyled,ol.unstyled{margin-left:0;list-style:none;} +dl{margin-bottom:20px;} +dt,dd{line-height:20px;} +dt{font-weight:bold;} +dd{margin-left:10px;} +.dl-horizontal{*zoom:1;}.dl-horizontal:before,.dl-horizontal:after{display:table;content:"";line-height:0;} +.dl-horizontal:after{clear:both;} +.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;} +.dl-horizontal dd{margin-left:180px;} +hr{margin:20px 0;border:0;border-top:1px solid #eeeeee;border-bottom:1px solid #ffffff;} +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 20px;border-left:5px solid #eeeeee;}blockquote p{margin-bottom:0;font-size:16px;font-weight:300;line-height:25px;} +blockquote small{display:block;line-height:20px;color:#999999;}blockquote small:before{content:'\2014 \00A0';} +blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eeeeee;border-left:0;}blockquote.pull-right p,blockquote.pull-right small{text-align:right;} +blockquote.pull-right small:before{content:'';} +blockquote.pull-right small:after{content:'\00A0 \2014';} +q:before,q:after,blockquote:before,blockquote:after{content:"";} +address{display:block;margin-bottom:20px;font-style:normal;line-height:20px;} +code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,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:9.5px;margin:0 0 10px;font-size:13px;line-height:20px;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:20px;} +pre code{padding:0;color:inherit;background-color:transparent;border:0;} +.pre-scrollable{max-height:340px;overflow-y:scroll;} +.label,.badge{font-size:11.844px;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:#b94a48;} +.label-important[href],.badge-important[href]{background-color:#953b39;} +.label-warning,.badge-warning{background-color:#f89406;} +.label-warning[href],.badge-warning[href]{background-color:#c67605;} +.label-success,.badge-success{background-color:#468847;} +.label-success[href],.badge-success[href]{background-color:#356635;} +.label-info,.badge-info{background-color:#3a87ad;} +.label-info[href],.badge-info[href]{background-color:#2d6987;} +.label-inverse,.badge-inverse{background-color:#333333;} +.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a;} +.btn .label,.btn .badge{position:relative;top:-1px;} +.btn-mini .label,.btn-mini .badge{top:0;} +table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0;} +.table{width:100%;margin-bottom:20px;}.table th,.table td{padding:8px;line-height:20px;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:collapse;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,.table-bordered tfoot: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,.table-bordered tfoot: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-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px;} +.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topleft:4px;} +.table-striped tbody tr:nth-child(odd) td,.table-striped tbody tr:nth-child(odd) th{background-color:#f9f9f9;} +.table-hover tbody tr:hover td,.table-hover tbody tr:hover th{background-color:#f5f5f5;} +table [class*=span],.row-fluid table [class*=span]{display:table-cell;float:none;margin-left:0;} +.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;} +.table tbody tr.success td{background-color:#dff0d8;} +.table tbody tr.error td{background-color:#f2dede;} +.table tbody tr.warning td{background-color:#fcf8e3;} +.table tbody tr.info td{background-color:#d9edf7;} +.table-hover tbody tr.success:hover td{background-color:#d0e9c6;} +.table-hover tbody tr.error:hover td{background-color:#ebcccc;} +.table-hover tbody tr.warning:hover td{background-color:#faf2cc;} +.table-hover tbody tr.info:hover td{background-color:#c4e3f3;} +form{margin:0 0 20px;} +fieldset{padding:0;margin:0;border:0;} +legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333333;border:0;border-bottom:1px solid #e5e5e5;}legend small{font-size:15px;color:#999999;} +label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px;} +input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,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:20px;padding:4px 6px;margin-bottom:9px;font-size:14px;line-height:20px;color:#555555;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +input,textarea,.uneditable-input{width:206px;} +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-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 .2s, box-shadow linear .2s;-moz-transition:border linear .2s, box-shadow linear .2s;-o-transition:border linear .2s, box-shadow linear .2s;transition:border linear .2s, box-shadow linear .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;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);} +input[type="radio"],input[type="checkbox"]{margin:4px 0 0;*margin-top:0;margin-top:1px \9;line-height:normal;cursor:pointer;} +input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto;} +select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px;} +select{width:220px;border:1px solid #cccccc;background-color:#ffffff;} +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;} +.uneditable-input,.uneditable-textarea{color:#999999;background-color:#fcfcfc;border-color:#cccccc;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);cursor:not-allowed;} +.uneditable-input{overflow:hidden;white-space:nowrap;} +.uneditable-textarea{width:auto;height:auto;} +input:-moz-placeholder,textarea:-moz-placeholder{color:#999999;} +input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999999;} +input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999999;} +.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[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .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;} +.controls-row [class*="span"]+[class*="span"]{margin-left:20px;} +input.span12, textarea.span12, .uneditable-input.span12{width:926px;} +input.span11, textarea.span11, .uneditable-input.span11{width:846px;} +input.span10, textarea.span10, .uneditable-input.span10{width:766px;} +input.span9, textarea.span9, .uneditable-input.span9{width:686px;} +input.span8, textarea.span8, .uneditable-input.span8{width:606px;} +input.span7, textarea.span7, .uneditable-input.span7{width:526px;} +input.span6, textarea.span6, .uneditable-input.span6{width:446px;} +input.span5, textarea.span5, .uneditable-input.span5{width:366px;} +input.span4, textarea.span4, .uneditable-input.span4{width:286px;} +input.span3, textarea.span3, .uneditable-input.span3{width:206px;} +input.span2, textarea.span2, .uneditable-input.span2{width:126px;} +input.span1, textarea.span1, .uneditable-input.span1{width:46px;} +.controls-row{*zoom:1;}.controls-row:before,.controls-row:after{display:table;content:"";line-height:0;} +.controls-row:after{clear:both;} +.controls-row [class*="span"]{float:left;} +input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eeeeee;} +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:#c09853;} +.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853;} +.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-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);}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;} +.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853;} +.control-group.error>label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48;} +.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48;} +.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-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);}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;} +.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48;} +.control-group.success>label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847;} +.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847;} +.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-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);}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;} +.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847;} +.control-group.info>label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad;} +.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad;} +.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-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);}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3;} +.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad;} +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:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1;}.form-actions:before,.form-actions:after{display:table;content:"";line-height:0;} +.form-actions:after{clear:both;} +.help-block,.help-inline{color:#595959;} +.help-block{display:block;margin-bottom:10px;} +.help-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;padding-left:5px;} +.input-append,.input-prepend{margin-bottom:5px;font-size:0;white-space:nowrap;}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;font-size:14px;vertical-align:top;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2;} +.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #ffffff;background-color:#eeeeee;border:1px solid #ccc;} +.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546;} +.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 .add-on,.input-append .btn{margin-left:-1px;} +.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;} +input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;} +.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px;} +.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0;} +.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0;} +.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 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;*zoom:1;margin-bottom:0;vertical-align:middle;} +.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none;} +.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{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:10px;} +legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate;} +.form-horizontal .control-group{margin-bottom:20px;*zoom:1;}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;content:"";line-height:0;} +.form-horizontal .control-group:after{clear:both;} +.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right;} +.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0;}.form-horizontal .controls:first-child{*padding-left:180px;} +.form-horizontal .help-block{margin-bottom:0;} +.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block{margin-top:10px;} +.form-horizontal .form-actions{padding-left:180px;} +.btn{display:inline-block;*display:inline;*zoom:1;padding:4px 14px;margin-bottom:0;font-size:14px;line-height:20px;*line-height:20px;text-align:center;vertical-align:middle;cursor:pointer;color:#333333;text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);background-color:#f5f5f5;background-image:-moz-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(to bottom, #ffffff, #e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', 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;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border:1px solid #bbbbbb;*border:0;border-bottom-color:#a2a2a2;-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, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);}.btn:hover,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333333;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;background-position:0 -15px;-webkit-transition:background-position 0.1s linear;-moz-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, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 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:16px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;} +.btn-large [class^="icon-"]{margin-top:2px;} +.btn-small{padding:3px 9px;font-size:12px;line-height:18px;} +.btn-small [class^="icon-"]{margin-top:0;} +.btn-mini{padding:2px 6px;font-size:11px;line-height:17px;} +.btn-block{display:block;width:100%;padding-left:0;padding-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} +.btn-block+.btn-block{margin-top:5px;} +input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%;} +.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:#c5c5c5;border-color:rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25);} +.btn-primary{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#006dcc;background-image:-moz-linear-gradient(top, #0088cc, #0044cc);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));background-image:-webkit-linear-gradient(top, #0088cc, #0044cc);background-image:-o-linear-gradient(top, #0088cc, #0044cc);background-image:linear-gradient(to bottom, #0088cc, #0044cc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);border-color:#0044cc #0044cc #002a80;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#0044cc;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-primary:hover,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#ffffff;background-color:#0044cc;*background-color:#003bb3;} +.btn-primary:active,.btn-primary.active{background-color:#003399 \9;} +.btn-warning{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(to bottom, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);border-color:#f89406 #f89406 #ad6704;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#f89406;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-warning:hover,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#ffffff;background-color:#f89406;*background-color:#df8505;} +.btn-warning:active,.btn-warning.active{background-color:#c67605 \9;} +.btn-danger{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#da4f49;background-image:-moz-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(to bottom, #ee5f5b, #bd362f);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', 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;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-danger:hover,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#ffffff;background-color:#bd362f;*background-color:#a9302a;} +.btn-danger:active,.btn-danger.active{background-color:#942a25 \9;} +.btn-success{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#5bb75b;background-image:-moz-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(to bottom, #62c462, #51a351);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', 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;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-success:hover,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#ffffff;background-color:#51a351;*background-color:#499249;} +.btn-success:active,.btn-success.active{background-color:#408140 \9;} +.btn-info{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#49afcd;background-image:-moz-linear-gradient(top, #5bc0de, #2f96b4);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));background-image:-webkit-linear-gradient(top, #5bc0de, #2f96b4);background-image:-o-linear-gradient(top, #5bc0de, #2f96b4);background-image:linear-gradient(to bottom, #5bc0de, #2f96b4);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0);border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#2f96b4;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-info:hover,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#ffffff;background-color:#2f96b4;*background-color:#2a85a0;} +.btn-info:active,.btn-info.active{background-color:#24748c \9;} +.btn-inverse{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#363636;background-image:-moz-linear-gradient(top, #444444, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222));background-image:-webkit-linear-gradient(top, #444444, #222222);background-image:-o-linear-gradient(top, #444444, #222222);background-image:linear-gradient(to bottom, #444444, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', 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;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-inverse:hover,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#ffffff;background-color:#222222;*background-color:#151515;} +.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9;} +button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px;}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-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} +.btn-link{border-color:transparent;cursor:pointer;color:#0088cc;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.btn-link:hover{color:#005580;text-decoration:underline;background-color:transparent;} +.btn-link[disabled]:hover{color:#333333;text-decoration:none;} +[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;margin-top:1px;} +.icon-white,.nav-tabs>.active>a>[class^="icon-"],.nav-tabs>.active>a>[class*=" icon-"],.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"]{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;width:16px;} +.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;width:16px;} +.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;} +.btn-group{position:relative;font-size:0;vertical-align:middle;white-space:nowrap;*margin-left:.3em;}.btn-group:first-child{*margin-left:0;} +.btn-group+.btn-group{margin-left:5px;} +.btn-toolbar{font-size:0;margin-top:10px;margin-bottom:10px;}.btn-toolbar .btn-group{display:inline-block;*display:inline;*zoom:1;} +.btn-toolbar .btn+.btn,.btn-toolbar .btn-group+.btn,.btn-toolbar .btn+.btn-group{margin-left:5px;} +.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.btn-group>.btn+.btn{margin-left:-1px;} +.btn-group>.btn,.btn-group>.dropdown-menu{font-size:14px;} +.btn-group>.btn-mini{font-size:11px;} +.btn-group>.btn-small{font-size:12px;} +.btn-group>.btn-large{font-size:16px;} +.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>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);*padding-top:5px;*padding-bottom:5px;} +.btn-group>.btn-mini+.dropdown-toggle{padding-left:5px;padding-right:5px;*padding-top:2px;*padding-bottom:2px;} +.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px;} +.btn-group>.btn-large+.dropdown-toggle{padding-left:12px;padding-right:12px;*padding-top:7px;*padding-bottom:7px;} +.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);} +.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6;} +.btn-group.open .btn-primary.dropdown-toggle{background-color:#0044cc;} +.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406;} +.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:#2f96b4;} +.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222222;} +.btn .caret{margin-top:8px;margin-left:0;} +.btn-mini .caret,.btn-small .caret,.btn-large .caret{margin-top:6px;} +.btn-large .caret{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;} +.btn-group-vertical{display:inline-block;*display:inline;*zoom:1;} +.btn-group-vertical .btn{display:block;float:none;width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.btn-group-vertical .btn+.btn{margin-left:0;margin-top:-1px;} +.btn-group-vertical .btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;} +.btn-group-vertical .btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;} +.btn-group-vertical .btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0;} +.btn-group-vertical .btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;} +.nav{margin-left:0;margin-bottom:20px;list-style:none;} +.nav>li>a{display:block;} +.nav>li>a:hover{text-decoration:none;background-color:#eeeeee;} +.nav>.pull-right{float:right;} +.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;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:#0088cc;} +.nav-list [class^="icon-"]{margin-right:2px;} +.nav-list .divider{*width:100%;height:1px;margin:9px 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:"";line-height:0;} +.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:20px;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:#eeeeee #eeeeee #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:#0088cc;} +.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-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;} +.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius: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 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;} +.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;} +.nav .dropdown-toggle .caret{border-top-color:#0088cc;border-bottom-color:#0088cc;margin-top:6px;} +.nav .dropdown-toggle:hover .caret{border-top-color:#005580;border-bottom-color:#005580;} +.nav-tabs .dropdown-toggle .caret{margin-top:8px;} +.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff;} +.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555555;border-bottom-color:#555555;} +.nav>.dropdown.active>a:hover{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:"";line-height:0;} +.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:#eeeeee #dddddd #eeeeee #eeeeee;} +.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:#eeeeee #eeeeee #eeeeee #dddddd;} +.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover{border-color:#ddd #ddd #ddd transparent;*border-left-color:#ffffff;} +.nav>.disabled>a{color:#999999;} +.nav>.disabled>a:hover{text-decoration:none;background-color:transparent;cursor:default;} +.navbar{overflow:visible;margin-bottom:20px;color:#777777;*position:relative;*z-index:2;} +.navbar-inner{min-height:40px;padding-left:20px;padding-right:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top, #ffffff, #f2f2f2);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2));background-image:-webkit-linear-gradient(top, #ffffff, #f2f2f2);background-image:-o-linear-gradient(top, #ffffff, #f2f2f2);background-image:linear-gradient(to bottom, #ffffff, #f2f2f2);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0);border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);-moz-box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);*zoom:1;}.navbar-inner:before,.navbar-inner:after{display:table;content:"";line-height:0;} +.navbar-inner:after{clear:both;} +.navbar .container{width:auto;} +.nav-collapse.collapse{height:auto;} +.navbar .brand{float:left;display:block;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777777;text-shadow:0 1px 0 #ffffff;}.navbar .brand:hover{text-decoration:none;} +.navbar-text{margin-bottom:0;line-height:40px;} +.navbar-link{color:#777777;}.navbar-link:hover{color:#333333;} +.navbar .divider-vertical{height:40px;margin:0 9px;border-left:1px solid #f2f2f2;border-right:1px solid #ffffff;} +.navbar .btn,.navbar .btn-group{margin-top:5px;} +.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn{margin-top:0;} +.navbar-form{margin-bottom:0;*zoom:1;}.navbar-form:before,.navbar-form:after{display:table;content:"";line-height:0;} +.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,.navbar-form .btn{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:5px;margin-bottom:0;}.navbar-search .search-query{margin-bottom:0;padding:4px 14px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;} +.navbar-static-top{position:static;width:100%;margin-bottom:0;}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius: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-static-top .navbar-inner{border-width:0 0 1px;} +.navbar-fixed-bottom .navbar-inner{border-width:1px 0 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-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px;} +.navbar-fixed-top{top:0;} +.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.1), 0 1px 10px rgba(0, 0, 0, 0.1);-moz-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.1), 0 1px 10px rgba(0, 0, 0, 0.1);box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.1), 0 1px 10px rgba(0, 0, 0, 0.1);} +.navbar-fixed-bottom{bottom:0;}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:inset 0 1px 0 rgba(0, 0, 0, 0.1), 0 -1px 10px rgba(0, 0, 0, 0.1);-moz-box-shadow:inset 0 1px 0 rgba(0, 0, 0, 0.1), 0 -1px 10px rgba(0, 0, 0, 0.1);box-shadow:inset 0 1px 0 rgba(0, 0, 0, 0.1), 0 -1px 10px rgba(0, 0, 0, 0.1);} +.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0;} +.navbar .nav.pull-right{float:right;margin-right:0;} +.navbar .nav>li{float:left;} +.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777777;text-decoration:none;text-shadow:0 1px 0 #ffffff;} +.navbar .nav .dropdown-toggle .caret{margin-top:8px;} +.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{background-color:transparent;color:#333333;text-decoration:none;} +.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);-moz-box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);} +.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-left:5px;margin-right:5px;color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#ededed;background-image:-moz-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5));background-image:-webkit-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:-o-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:linear-gradient(to bottom, #f2f2f2, #e5e5e5);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0);border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#e5e5e5;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075);}.navbar .btn-navbar:hover,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#ffffff;background-color:#e5e5e5;*background-color:#d9d9d9;} +.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#cccccc \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 .nav>li>.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 .nav>li>.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 .nav>li>.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 .nav>li>.dropdown-menu:after{border-top:6px solid #ffffff;border-bottom:0;bottom:-6px;top:auto;} +.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{background-color:#e5e5e5;color:#555555;} +.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777777;border-bottom-color:#777777;} +.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555555;border-bottom-color:#555555;} +.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{left:auto;right:0;}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{left:auto;right:12px;} +.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{left:auto;right:13px;} +.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{left:auto;right:100%;margin-left:0;margin-right:-1px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px;} +.navbar-inverse{color:#999999;}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top, #222222, #111111);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111));background-image:-webkit-linear-gradient(top, #222222, #111111);background-image:-o-linear-gradient(top, #222222, #111111);background-image:linear-gradient(to bottom, #222222, #111111);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0);border-color:#252525;} +.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999999;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover{color:#ffffff;} +.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{background-color:transparent;color:#ffffff;} +.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#ffffff;background-color:#111111;} +.navbar-inverse .navbar-link{color:#999999;}.navbar-inverse .navbar-link:hover{color:#ffffff;} +.navbar-inverse .divider-vertical{border-left-color:#111111;border-right-color:#222222;} +.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{background-color:#111111;color:#ffffff;} +.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999999;border-bottom-color:#999999;} +.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;} +.navbar-inverse .navbar-search .search-query{color:#ffffff;background-color:#515151;border-color:#111111;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none;}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#cccccc;} +.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#cccccc;} +.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#cccccc;} +.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;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-inverse .btn-navbar{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#0e0e0e;background-image:-moz-linear-gradient(top, #151515, #040404);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404));background-image:-webkit-linear-gradient(top, #151515, #040404);background-image:-o-linear-gradient(top, #151515, #040404);background-image:linear-gradient(to bottom, #151515, #040404);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0);border-color:#040404 #040404 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#040404;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#ffffff;background-color:#040404;*background-color:#000000;} +.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000000 \9;} +.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.breadcrumb li{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 0 #ffffff;} +.breadcrumb .divider{padding:0 5px;color:#ccc;} +.breadcrumb .active{color:#999999;} +.pagination{height:40px;margin:20px 0;} +.pagination ul{display:inline-block;*display:inline;*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 ul>li{display:inline;} +.pagination ul>li>a,.pagination ul>li>span{float:left;padding:0 14px;line-height:38px;text-decoration:none;background-color:#ffffff;border:1px solid #dddddd;border-left-width:0;} +.pagination ul>li>a:hover,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5;} +.pagination ul>.active>a,.pagination ul>.active>span{color:#999999;cursor:default;} +.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover{color:#999999;background-color:transparent;cursor:default;} +.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{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 ul>li:last-child>a,.pagination ul>li:last-child>span{-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:20px 0;list-style:none;text-align:center;*zoom:1;}.pager:before,.pager:after{display:table;content:"";line-height:0;} +.pager:after{clear:both;} +.pager li{display:inline;} +.pager a,.pager span{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,.pager .next span{float:right;} +.pager .previous a{float:left;} +.pager .disabled a,.pager .disabled a:hover,.pager .disabled span{color:#999999;background-color:#fff;cursor:default;} +.thumbnails{margin-left:-20px;list-style:none;*zoom:1;}.thumbnails:before,.thumbnails:after{display:table;content:"";line-height:0;} +.thumbnails:after{clear:both;} +.row-fluid .thumbnails{margin-left:0;} +.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px;} +.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);-moz-box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;-o-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out;} +a.thumbnail:hover{border-color:#0088cc;-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;color:#555555;} +.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;color:#c09853;} +.alert h4{margin:0;} +.alert .close{position:relative;top:-2px;right:-21px;line-height:20px;} +.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#468847;} +.alert-danger,.alert-error{background-color:#f2dede;border-color:#eed3d7;color:#b94a48;} +.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#3a87ad;} +.alert-block{padding-top:14px;padding-bottom:14px;} +.alert-block>p,.alert-block>ul{margin-bottom:0;} +.alert-block p+p{margin-top:5px;} +@-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:20px;margin-bottom:20px;background-color:#f7f7f7;background-image:-moz-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(to bottom, #f5f5f5, #f9f9f9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', 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:100%;color:#ffffff;float:left;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:-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(to bottom, #149bdf, #0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', 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;box-sizing:border-box;-webkit-transition:width 0.6s ease;-moz-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease;} +.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15);-moz-box-shadow:inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15);box-shadow:inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15);} +.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:-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,.progress .bar-danger{background-color:#dd514c;background-image:-moz-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(to bottom, #ee5f5b, #c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0);} +.progress-danger.progress-striped .bar,.progress-striped .bar-danger{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:-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,.progress .bar-success{background-color:#5eb95e;background-image:-moz-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(to bottom, #62c462, #57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0);} +.progress-success.progress-striped .bar,.progress-striped .bar-success{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:-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,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-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(to bottom, #5bc0de, #339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0);} +.progress-info.progress-striped .bar,.progress-striped .bar-info{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:-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,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(to bottom, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);} +.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;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:-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);} +.hero-unit{padding:60px;margin-bottom:30px;background-color:#eeeeee;-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:30px;color:inherit;} +.tooltip{position:absolute;z-index:1030;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:-3px;} +.tooltip.right{margin-left:3px;} +.tooltip.bottom{margin-top:3px;} +.tooltip.left{margin-left:-3px;} +.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;border-color:transparent;border-style:solid;} +.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000000;} +.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000000;} +.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000000;} +.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000000;} +.popover{position:absolute;top:0;left:0;z-index:1010;display:none;width:236px;padding:1px;background-color:#ffffff;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-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);}.popover.top{margin-bottom:10px;} +.popover.right{margin-left:10px;} +.popover.bottom{margin-top:10px;} +.popover.left{margin-right:10px;} +.popover-title{margin:0;padding:8px 14px;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0;} +.popover-content{padding:9px 14px;}.popover-content p,.popover-content ul,.popover-content ol{margin-bottom:0;} +.popover .arrow,.popover .arrow:after{position:absolute;display:inline-block;width:0;height:0;border-color:transparent;border-style:solid;} +.popover .arrow:after{content:"";z-index:-1;} +.popover.top .arrow{bottom:-10px;left:50%;margin-left:-10px;border-width:10px 10px 0;border-top-color:#ffffff;}.popover.top .arrow:after{border-width:11px 11px 0;border-top-color:rgba(0, 0, 0, 0.25);bottom:-1px;left:-11px;} +.popover.right .arrow{top:50%;left:-10px;margin-top:-10px;border-width:10px 10px 10px 0;border-right-color:#ffffff;}.popover.right .arrow:after{border-width:11px 11px 11px 0;border-right-color:rgba(0, 0, 0, 0.25);bottom:-11px;left:-1px;} +.popover.bottom .arrow{top:-10px;left:50%;margin-left:-10px;border-width:0 10px 10px;border-bottom-color:#ffffff;}.popover.bottom .arrow:after{border-width:0 11px 11px;border-bottom-color:rgba(0, 0, 0, 0.25);top:-1px;left:-11px;} +.popover.left .arrow{top:50%;right:-10px;margin-top:-10px;border-width:10px 0 10px 10px;border-left-color:#ffffff;}.popover.left .arrow:after{border-width:11px 0 11px 11px;border-left-color:rgba(0, 0, 0, 0.25);bottom:-11px;right:-1px;} +.modal-open .modal .dropdown-menu{z-index:2050;} +.modal-open .modal .dropdown.open{*z-index:2050;} +.modal-open .modal .popover{z-index:2060;} +.modal-open .modal .tooltip{z-index:2080;} +.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;-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;-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-header h3{margin:0;line-height:30px;} +.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:"";line-height:0;} +.modal-footer:after{clear:both;} +.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0;} +.modal-footer .btn-group .btn+.btn{margin-left:-1px;} +.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:"";} +.dropdown .caret{margin-top:8px;margin-left:2px;} +.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;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:6px;-moz-border-radius:6px;border-radius:6px;-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:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;} +.dropdown-menu a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333333;white-space:nowrap;} +.dropdown-menu li>a:hover,.dropdown-menu li>a:focus,.dropdown-submenu:hover>a{text-decoration:none;color:#ffffff;background-color:#0088cc;background-color:#0081c2;background-image:-moz-linear-gradient(top, #0088cc, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));background-image:-webkit-linear-gradient(top, #0088cc, #0077b3);background-image:-o-linear-gradient(top, #0088cc, #0077b3);background-image:linear-gradient(to bottom, #0088cc, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);} +.dropdown-menu .active>a,.dropdown-menu .active>a:hover{color:#ffffff;text-decoration:none;outline:0;background-color:#0088cc;background-color:#0081c2;background-image:-moz-linear-gradient(top, #0088cc, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));background-image:-webkit-linear-gradient(top, #0088cc, #0077b3);background-image:-o-linear-gradient(top, #0088cc, #0077b3);background-image:linear-gradient(to bottom, #0088cc, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);} +.dropdown-menu .disabled>a,.dropdown-menu .disabled>a:hover{color:#999999;} +.dropdown-menu .disabled>a:hover{text-decoration:none;background-color:transparent;cursor:default;} +.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:"";} +.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px;} +.dropdown-submenu{position:relative;} +.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px;} +.dropdown-submenu:hover>.dropdown-menu{display:block;} +.dropdown-submenu>a:after{display:block;content:" ";float:right;width:0;height:0;border-color:transparent;border-style:solid;border-width:5px 0 5px 5px;border-left-color:#cccccc;margin-top:5px;margin-right:-10px;} +.dropdown-submenu:hover>a:after{border-left-color:#ffffff;} +.dropdown .dropdown-menu .nav-header{padding-left:20px;padding-right:20px;} +.typeahead{margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.accordion{margin-bottom:20px;} +.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:20px;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;-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:15px;background:#333333;background:rgba(0, 0, 0, 0.75);} +.carousel-caption h4,.carousel-caption p{color:#ffffff;line-height:20px;} +.carousel-caption h4{margin:0 0 5px;} +.carousel-caption p{margin-bottom:0;} +.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-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;} +.close{float:right;font-size:20px;font-weight:bold;line-height:20px;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;} +.pull-right{float:right;} +.pull-left{float:left;} +.hide{display:none;} +.show{display:block;} +.invisible{visibility:hidden;} +.affix{position:fixed;} +.fade{opacity:0;-webkit-transition:opacity 0.15s linear;-moz-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;-o-transition:height 0.35s ease;transition:height 0.35s ease;}.collapse.in{height:auto;} +.hidden{display:none;visibility:hidden;} +.visible-phone{display:none !important;} +.visible-tablet{display:none !important;} +.hidden-desktop{display:none !important;} +.visible-desktop{display:inherit !important;} +@media (min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit !important;} .visible-desktop{display:none !important ;} .visible-tablet{display:inherit !important;} .hidden-tablet{display:none !important;}}@media (max-width:767px){.hidden-desktop{display:inherit !important;} .visible-desktop{display:none !important;} .visible-phone{display:inherit !important;} .hidden-phone{display:none !important;}}@media (max-width:767px){body{padding-left:20px;padding-right:20px;} .navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-left:-20px;margin-right:-20px;} .container-fluid{padding:0;} .dl-horizontal dt{float:none;clear:none;width:auto;text-align:left;} .dl-horizontal dd{margin-left:0;} .container{width:auto;} .row-fluid{width:100%;} .row,.thumbnails{margin-left:0;} .thumbnails>li{float:none;margin-left:0;} [class*="span"],.row-fluid [class*="span"]{float:none;display:block;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} .span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} .input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-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;} .controls-row [class*="span"]+[class*="span"]{margin-left:0;} .modal{position:fixed;top:20px;left:20px;right:20px;width:auto;margin:0;}.modal.fade.in{top:auto;}}@media (max-width:480px){.nav-collapse{-webkit-transform:translate3d(0, 0, 0);} .page-header h1 small{display:block;line-height:20px;} input[type="checkbox"],input[type="radio"]{border:1px solid #ccc;} .form-horizontal .control-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-left:10px;padding-right:10px;} .modal{top:10px;left:10px;right:10px;} .modal-header .close{padding:10px;margin:-10px;} .carousel-caption{position:static;}}@media (min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;} .row:after{clear:both;} [class*="span"]{float:left;min-height:1px;margin-left:20px;} .container,.navbar-static-top .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:"";line-height:0;} .row-fluid:after{clear:both;} .row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;} .row-fluid [class*="span"]:first-child{margin-left:0;} .row-fluid .span12{width:100%;*width:99.94680851063829%;} .row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%;} .row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%;} .row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%;} .row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%;} .row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%;} .row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%;} .row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%;} .row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%;} .row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%;} .row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%;} .row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%;} .row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%;} .row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%;} .row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%;} .row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%;} .row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%;} .row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%;} .row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%;} .row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%;} .row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%;} .row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%;} .row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%;} .row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%;} .row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%;} .row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%;} .row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%;} .row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%;} .row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%;} .row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%;} .row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%;} .row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%;} .row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%;} .row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%;} .row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%;} .row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%;} input,textarea,.uneditable-input{margin-left:0;} .controls-row [class*="span"]+[class*="span"]{margin-left:20px;} input.span12, textarea.span12, .uneditable-input.span12{width:710px;} input.span11, textarea.span11, .uneditable-input.span11{width:648px;} input.span10, textarea.span10, .uneditable-input.span10{width:586px;} input.span9, textarea.span9, .uneditable-input.span9{width:524px;} input.span8, textarea.span8, .uneditable-input.span8{width:462px;} input.span7, textarea.span7, .uneditable-input.span7{width:400px;} input.span6, textarea.span6, .uneditable-input.span6{width:338px;} input.span5, textarea.span5, .uneditable-input.span5{width:276px;} input.span4, textarea.span4, .uneditable-input.span4{width:214px;} input.span3, textarea.span3, .uneditable-input.span3{width:152px;} input.span2, textarea.span2, .uneditable-input.span2{width:90px;} input.span1, textarea.span1, .uneditable-input.span1{width:28px;}}@media (min-width:1200px){.row{margin-left:-30px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;} .row:after{clear:both;} [class*="span"]{float:left;min-height:1px;margin-left:30px;} .container,.navbar-static-top .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:"";line-height:0;} .row-fluid:after{clear:both;} .row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;} .row-fluid [class*="span"]:first-child{margin-left:0;} .row-fluid .span12{width:100%;*width:99.94680851063829%;} .row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%;} .row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%;} .row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%;} .row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%;} .row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%;} .row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%;} .row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%;} .row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%;} .row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%;} .row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%;} .row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%;} .row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%;} .row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%;} .row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%;} .row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%;} .row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%;} .row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%;} .row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%;} .row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%;} .row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%;} .row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%;} .row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%;} .row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%;} .row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%;} .row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%;} .row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%;} .row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%;} .row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%;} .row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%;} .row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%;} .row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%;} .row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%;} .row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%;} .row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%;} .row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%;} input,textarea,.uneditable-input{margin-left:0;} .controls-row [class*="span"]+[class*="span"]{margin-left:30px;} input.span12, textarea.span12, .uneditable-input.span12{width:1156px;} input.span11, textarea.span11, .uneditable-input.span11{width:1056px;} input.span10, textarea.span10, .uneditable-input.span10{width:956px;} input.span9, textarea.span9, .uneditable-input.span9{width:856px;} input.span8, textarea.span8, .uneditable-input.span8{width:756px;} input.span7, textarea.span7, .uneditable-input.span7{width:656px;} input.span6, textarea.span6, .uneditable-input.span6{width:556px;} input.span5, textarea.span5, .uneditable-input.span5{width:456px;} input.span4, textarea.span4, .uneditable-input.span4{width:356px;} input.span3, textarea.span3, .uneditable-input.span3{width:256px;} input.span2, textarea.span2, .uneditable-input.span2{width:156px;} input.span1, textarea.span1, .uneditable-input.span1{width:56px;} .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,.navbar-fixed-bottom{position:static;} .navbar-fixed-top{margin-bottom:20px;} .navbar-fixed-bottom{margin-top:20px;} .navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px;} .navbar .container{width:auto;padding:0;} .navbar .brand{padding-left:10px;padding-right:10px;margin:0 0 0 -5px;} .nav-collapse{clear:both;} .nav-collapse .nav{float:none;margin:0 0 10px;} .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:#777777;text-shadow:none;} .nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777777;-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:#f2f2f2;} .navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:hover{background-color:#111111;} .nav-collapse.in .btn-group{margin-top:5px;padding:0;} .nav-collapse .dropdown-menu{position:static;top:auto;left:auto;float:none;display:block;max-width:none;margin:0 15px;padding:0;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 .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none;} .nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-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-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111111;border-bottom-color:#111111;} .navbar .nav-collapse .nav.pull-right{float:none;margin-left:0;} .nav-collapse,.nav-collapse.collapse{overflow:hidden;height:0;} .navbar .btn-navbar{display:block;} .navbar-static .navbar-inner{padding-left:10px;padding-right:10px;}}@media (min-width:980px){.nav-collapse.collapse{height:auto !important;overflow:visible !important;}} diff --git a/rest_framework/static/rest_framework/css/default.css b/rest_framework/static/rest_framework/css/default.css new file mode 100644 index 000000000..b569b1f5c --- /dev/null +++ b/rest_framework/static/rest_framework/css/default.css @@ -0,0 +1,71 @@ +body { + padding-top: 0; + padding-bottom: 1em; +} + +/* The navbar is fixed at >= 980px wide, so add padding to the body to prevent +content running up underneath it. */ +@media (min-width:980px) { + body { + padding-top: 60px; + } +} + +h1 { + font-weight: 500; +} + +h2, h3 { + font-weight: 300; +} + +.resource-description, .response-info { + margin-bottom: 2em; +} + +#footer { + border-top: 1px solid #eee; + margin-top: 2em; + padding-top: 1em; + text-align: right; +} + +.version:before { + content: "v"; + opacity: 0.6; + padding-right: 0.25em; +} + +.format-option { + font-family: Menlo, Consolas, "Andale Mono", "Lucida Console", monospace; +} + +.button-form { + float: right; + margin-right: 1em; +} + +/* To allow tooltips to work on disabled elements */ +.disabled-tooltip-shield { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; +} + +.errorlist { + margin-top: 0.5em; +} + +pre { + overflow: auto; + word-wrap: normal; + white-space: pre; + font-size: 12px; +} + +.page-header { + border-bottom: none; + padding-bottom: 0px; +} \ No newline at end of file diff --git a/rest_framework/static/rest_framework/css/prettify.css b/rest_framework/static/rest_framework/css/prettify.css new file mode 100644 index 000000000..d437aff62 --- /dev/null +++ b/rest_framework/static/rest_framework/css/prettify.css @@ -0,0 +1,30 @@ +.com { color: #93a1a1; } +.lit { color: #195f91; } +.pun, .opn, .clo { color: #93a1a1; } +.fun { color: #dc322f; } +.str, .atv { color: #D14; } +.kwd, .prettyprint .tag { color: #1e347b; } +.typ, .atn, .dec, .var { color: teal; } +.pln { color: #48484c; } + +.prettyprint { + padding: 8px; + background-color: #f7f7f9; + border: 1px solid #e1e1e8; +} +.prettyprint.linenums { + -webkit-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0; + -moz-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0; + box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0; +} + +/* Specify class=linenums on a pre to get line numbering */ +ol.linenums { + margin: 0 0 0 33px; /* IE indents via margin-left */ +} +ol.linenums li { + padding-left: 12px; + color: #bebec5; + line-height: 20px; + text-shadow: 0 1px 0 #fff; +} \ No newline at end of file diff --git a/rest_framework/static/rest_framework/img/glyphicons-halflings-white.png b/rest_framework/static/rest_framework/img/glyphicons-halflings-white.png new file mode 100644 index 000000000..3bf6484a2 Binary files /dev/null and b/rest_framework/static/rest_framework/img/glyphicons-halflings-white.png differ diff --git a/rest_framework/static/rest_framework/img/glyphicons-halflings.png b/rest_framework/static/rest_framework/img/glyphicons-halflings.png new file mode 100644 index 000000000..36c3b1ed9 Binary files /dev/null and b/rest_framework/static/rest_framework/img/glyphicons-halflings.png differ diff --git a/rest_framework/static/rest_framework/js/bootstrap.min.js b/rest_framework/static/rest_framework/js/bootstrap.min.js new file mode 100644 index 000000000..e0b220f40 --- /dev/null +++ b/rest_framework/static/rest_framework/js/bootstrap.min.js @@ -0,0 +1,7 @@ +/** +* Bootstrap.js by @fat & @mdo +* plugins: bootstrap-transition.js, bootstrap-modal.js, bootstrap-dropdown.js, bootstrap-scrollspy.js, bootstrap-tab.js, bootstrap-tooltip.js, bootstrap-popover.js, bootstrap-affix.js, bootstrap-alert.js, bootstrap-button.js, bootstrap-collapse.js, bootstrap-carousel.js, bootstrap-typeahead.js +* Copyright 2012 Twitter, Inc. +* http://www.apache.org/licenses/LICENSE-2.0.txt +*/ +!function(a){a(function(){a.support.transition=function(){var a=function(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"},c;for(c in b)if(a.style[c]!==undefined)return b[c]}();return a&&{end:a}}()})}(window.jQuery),!function(a){var b=function(b,c){this.options=c,this.$element=a(b).delegate('[data-dismiss="modal"]',"click.dismiss.modal",a.proxy(this.hide,this)),this.options.remote&&this.$element.find(".modal-body").load(this.options.remote)};b.prototype={constructor:b,toggle:function(){return this[this.isShown?"hide":"show"]()},show:function(){var b=this,c=a.Event("show");this.$element.trigger(c);if(this.isShown||c.isDefaultPrevented())return;a("body").addClass("modal-open"),this.isShown=!0,this.escape(),this.backdrop(function(){var c=a.support.transition&&b.$element.hasClass("fade");b.$element.parent().length||b.$element.appendTo(document.body),b.$element.show(),c&&b.$element[0].offsetWidth,b.$element.addClass("in").attr("aria-hidden",!1).focus(),b.enforceFocus(),c?b.$element.one(a.support.transition.end,function(){b.$element.trigger("shown")}):b.$element.trigger("shown")})},hide:function(b){b&&b.preventDefault();var c=this;b=a.Event("hide"),this.$element.trigger(b);if(!this.isShown||b.isDefaultPrevented())return;this.isShown=!1,a("body").removeClass("modal-open"),this.escape(),a(document).off("focusin.modal"),this.$element.removeClass("in").attr("aria-hidden",!0),a.support.transition&&this.$element.hasClass("fade")?this.hideWithTransition():this.hideModal()},enforceFocus:function(){var b=this;a(document).on("focusin.modal",function(a){b.$element[0]!==a.target&&!b.$element.has(a.target).length&&b.$element.focus()})},escape:function(){var a=this;this.isShown&&this.options.keyboard?this.$element.on("keyup.dismiss.modal",function(b){b.which==27&&a.hide()}):this.isShown||this.$element.off("keyup.dismiss.modal")},hideWithTransition:function(){var b=this,c=setTimeout(function(){b.$element.off(a.support.transition.end),b.hideModal()},500);this.$element.one(a.support.transition.end,function(){clearTimeout(c),b.hideModal()})},hideModal:function(a){this.$element.hide().trigger("hidden"),this.backdrop()},removeBackdrop:function(){this.$backdrop.remove(),this.$backdrop=null},backdrop:function(b){var c=this,d=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var e=a.support.transition&&d;this.$backdrop=a('