From aa150030eb672a78b0344b8a1e9f7e376a5007ec Mon Sep 17 00:00:00 2001 From: Ashesh Vashi Date: Tue, 30 Jun 2015 11:21:55 +0530 Subject: [PATCH] Introduced a mechanism to load required javascripts at runtime (lazy loading) using the require.js. This allows us to load the javascript required for any node, only when it was loaded in the browser tree. Also, introduced the mechanism to show/edit/create of any node in a tab panel (wcDocker.Panel). --- .gitignore | 1 + web/config.py | 3 +- web/pgAdmin4.py | 20 +- web/pgadmin/__init__.py | 18 +- web/pgadmin/about/__init__.py | 23 +- web/pgadmin/about/templates/about/about.js | 69 +- web/pgadmin/about/templates/about/index.html | 4 +- web/pgadmin/browser/__init__.py | 186 +- web/pgadmin/browser/server_groups/__init__.py | 132 +- .../browser/server_groups/servers/__init__.py | 319 +- .../servers/templates/servers/servers.js | 243 +- .../templates/server_groups/server_groups.js | 209 +- .../static/js/aciTree/jquery.aciTree.js | 6985 +++++++++++++++++ web/pgadmin/browser/static/js/frame.js | 49 + web/pgadmin/browser/static/js/menu.js | 127 + web/pgadmin/browser/static/js/panel.js | 51 + .../browser/templates/browser/css/node.css | 4 + .../browser/templates/browser/index.html | 78 +- .../browser/templates/browser/js/browser.js | 851 +- .../browser/templates/browser/js/error.js | 46 + .../browser/templates/browser/js/node.js | 846 ++ web/pgadmin/browser/utils.py | 115 +- web/pgadmin/help/__init__.py | 6 +- web/pgadmin/redirects/__init__.py | 10 + web/pgadmin/settings/__init__.py | 2 - web/pgadmin/settings/settings_model.py | 14 +- .../static/css/bootstrap-datepicker3.css | 751 ++ web/pgadmin/static/css/bootstrap-theme.css | 10 +- .../static/css/bootstrap-theme.css.map | 2 +- .../static/css/bootstrap-theme.min.css | 6 +- web/pgadmin/static/css/bootstrap.css | 328 +- web/pgadmin/static/css/bootstrap.css.map | 2 +- web/pgadmin/static/css/bootstrap.min.css | 6 +- web/pgadmin/static/css/font-awesome.css | 1801 +++++ web/pgadmin/static/css/font-awesome.min.css | 4 + web/pgadmin/static/css/font-mfizz.css | 318 + web/pgadmin/static/css/overrides.css | 268 +- web/pgadmin/static/fonts/FontAwesome.otf | Bin 0 -> 93888 bytes web/pgadmin/static/fonts/font-mfizz.eot | Bin 0 -> 43154 bytes web/pgadmin/static/fonts/font-mfizz.svg | 1344 ++++ web/pgadmin/static/fonts/font-mfizz.ttf | Bin 0 -> 45324 bytes web/pgadmin/static/fonts/font-mfizz.woff | Bin 0 -> 29056 bytes .../static/fonts/fontawesome-webfont.eot | Bin 0 -> 60767 bytes .../static/fonts/fontawesome-webfont.svg | 565 ++ .../static/fonts/fontawesome-webfont.ttf | Bin 0 -> 122092 bytes .../static/fonts/fontawesome-webfont.woff | Bin 0 -> 71508 bytes .../static/fonts/fontawesome-webfont.woff2 | Bin 0 -> 56780 bytes .../fonts/glyphicons-halflings-regular.eot | Bin 20335 -> 20127 bytes .../fonts/glyphicons-halflings-regular.svg | 485 +- .../fonts/glyphicons-halflings-regular.ttf | Bin 41280 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 23320 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes .../static/js/alertifyjs/pgadmin.defaults.js | 12 +- web/pgadmin/static/js/backbone-min.js | 2 + web/pgadmin/static/js/backbone.js | 1608 ++++ web/pgadmin/static/js/backform.js | 584 ++ web/pgadmin/static/js/backform.pgadmin.js | 192 + web/pgadmin/static/js/bootstrap-datepicker.js | 1813 +++++ .../static/js/bootstrap-datepicker.min.js | 8 + web/pgadmin/static/js/bootstrap.js | 281 +- web/pgadmin/static/js/bootstrap.min.js | 8 +- web/pgadmin/static/js/codemirror/mode/sql.js | 4 +- web/pgadmin/static/js/pgadmin.js | 16 + web/pgadmin/static/js/require.js | 2083 +++++ web/pgadmin/static/js/require.min.js | 36 + web/pgadmin/static/js/underscore-min.js | 6 + web/pgadmin/static/js/underscore.js | 1548 ++++ web/pgadmin/static/js/underscore.string.js | 1065 +++ .../static/js/underscore.string.min.js | 1 + web/pgadmin/templates/base.html | 58 +- web/pgadmin/templates/security/fields.html | 2 +- web/pgadmin/test/__init__.py | 38 +- web/pgadmin/test/static/js/test.js | 133 +- web/pgadmin/utils/__init__.py | 10 +- web/pgadmin/utils/ajax.py | 24 +- web/pgadmin/utils/menu.py | 16 +- web/setup.py | 50 +- 77 files changed, 24504 insertions(+), 1395 deletions(-) create mode 100644 web/pgadmin/browser/static/js/aciTree/jquery.aciTree.js create mode 100644 web/pgadmin/browser/static/js/frame.js create mode 100644 web/pgadmin/browser/static/js/menu.js create mode 100644 web/pgadmin/browser/static/js/panel.js create mode 100644 web/pgadmin/browser/templates/browser/js/error.js create mode 100644 web/pgadmin/browser/templates/browser/js/node.js create mode 100644 web/pgadmin/static/css/bootstrap-datepicker3.css create mode 100644 web/pgadmin/static/css/font-awesome.css create mode 100644 web/pgadmin/static/css/font-awesome.min.css create mode 100644 web/pgadmin/static/css/font-mfizz.css create mode 100644 web/pgadmin/static/fonts/FontAwesome.otf create mode 100644 web/pgadmin/static/fonts/font-mfizz.eot create mode 100644 web/pgadmin/static/fonts/font-mfizz.svg create mode 100644 web/pgadmin/static/fonts/font-mfizz.ttf create mode 100644 web/pgadmin/static/fonts/font-mfizz.woff create mode 100644 web/pgadmin/static/fonts/fontawesome-webfont.eot create mode 100644 web/pgadmin/static/fonts/fontawesome-webfont.svg create mode 100644 web/pgadmin/static/fonts/fontawesome-webfont.ttf create mode 100644 web/pgadmin/static/fonts/fontawesome-webfont.woff create mode 100644 web/pgadmin/static/fonts/fontawesome-webfont.woff2 create mode 100644 web/pgadmin/static/fonts/glyphicons-halflings-regular.woff2 create mode 100644 web/pgadmin/static/js/backbone-min.js create mode 100644 web/pgadmin/static/js/backbone.js create mode 100644 web/pgadmin/static/js/backform.js create mode 100644 web/pgadmin/static/js/backform.pgadmin.js create mode 100644 web/pgadmin/static/js/bootstrap-datepicker.js create mode 100644 web/pgadmin/static/js/bootstrap-datepicker.min.js create mode 100644 web/pgadmin/static/js/pgadmin.js create mode 100644 web/pgadmin/static/js/require.js create mode 100644 web/pgadmin/static/js/require.min.js create mode 100644 web/pgadmin/static/js/underscore-min.js create mode 100644 web/pgadmin/static/js/underscore.js create mode 100644 web/pgadmin/static/js/underscore.string.js create mode 100644 web/pgadmin/static/js/underscore.string.min.js diff --git a/.gitignore b/.gitignore index b257f71cf..0d2e2ce02 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ runtime/pgAdmin4.app/ runtime/pgAdmin4.pro.user* runtime/ui_BrowserWindow.h web/config_local.py +web/pgadmin4.log diff --git a/web/config.py b/web/config.py index a42abd75e..c65613fb6 100644 --- a/web/config.py +++ b/web/config.py @@ -20,6 +20,7 @@ import os # Name of the application to display in the UI APP_NAME = 'pgAdmin 4' +APP_ICON = 'icon-postgres-alt' # Application version number components APP_MAJOR = 1 @@ -125,7 +126,7 @@ MINIFY_HTML = True; # The schema version number for the configuration database # DO NOT CHANGE UNLESS YOU ARE A PGADMIN DEVELOPER!! -SETTINGS_SCHEMA_VERSION = 2 +SETTINGS_SCHEMA_VERSION = 3 # The default path to the SQLite database used to store user accounts and # settings. This default places the file in the same directory as this diff --git a/web/pgAdmin4.py b/web/pgAdmin4.py index 237cb3212..40ca3ec99 100644 --- a/web/pgAdmin4.py +++ b/web/pgAdmin4.py @@ -11,7 +11,8 @@ a webserver, this will provide the WSGI interface, otherwise, we're going to start a web server.""" -import os, sys +import os +import sys # We need to include the root directory in sys.path to ensure that we can # find everything we need when running in the standalone runtime. @@ -27,8 +28,9 @@ from pgadmin import create_app ########################################################################## # Check for local settings if running in server mode -if config.SERVER_MODE == True: - local_config = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'config_local.py') +if config.SERVER_MODE is True: + local_config = os.path.join(os.path.dirname(os.path.realpath(__file__)), + 'config_local.py') if not os.path.isfile(local_config): print "The configuration file %s does not exist.\n" % local_config print "Before running this application, ensure that config_local.py has been created" @@ -40,7 +42,8 @@ if config.SERVER_MODE == True: # Check if the database exists. If it does not, tell the user and exit. if not os.path.isfile(config.SQLITE_PATH): print "The configuration database %s does not exist.\n" % config.SQLITE_PATH - print "Please run 'python %s' to create it.\nExiting..." % os.path.join(os.path.dirname(os.path.realpath(__file__)), 'setup.py') + print "Please run 'python %s' to create it.\nExiting..." % os.path.join( + os.path.dirname(os.path.realpath(__file__)), 'setup.py') sys.exit(1) ########################################################################## @@ -57,10 +60,13 @@ if config.DEBUG: # runtime if we're running in desktop mode, otherwise we'll just use the # Flask default. if 'PGADMIN_PORT' in globals(): - app.logger.debug('PGADMIN_PORT set in the runtime environment to %s', PGADMIN_PORT) - server_port = PGADMIN_PORT + app.logger.debug('PGADMIN_PORT set in the runtime environment to %s', + globals()['PGADMIN_PORT']) + server_port = int(globals()['PGADMIN_PORT']) else: - app.logger.debug('PGADMIN_PORT is not set in the runtime environment, using default of %s', config.DEFAULT_SERVER_PORT) + app.logger.debug( + 'PGADMIN_PORT is not set in the runtime environment, using default of %s', + config.DEFAULT_SERVER_PORT) server_port = config.DEFAULT_SERVER_PORT try: diff --git a/web/pgadmin/__init__.py b/web/pgadmin/__init__.py index efd4b7cc3..c9131322a 100644 --- a/web/pgadmin/__init__.py +++ b/web/pgadmin/__init__.py @@ -69,6 +69,18 @@ class PgAdmin(Flask): panels.extend(module.get_panels()) return panels + @property + def menu_items(self): + from operator import attrgetter + + menu_items = defaultdict(list) + for module in self.submodules: + for key, value in module.menu_items.items(): + menu_items[key].extend(value) + menu_items = {key: sorted(values, key=attrgetter('priority')) + for key, values in menu_items.items()} + return menu_items + def _find_blueprint(): if request.blueprint: return current_app.blueprints[request.blueprint] @@ -195,13 +207,9 @@ def create_app(app_name=config.APP_NAME): @app.context_processor def inject_blueprint(): """Inject a reference to the current blueprint, if any.""" - menu_items = defaultdict(list) - for blueprint in app.submodules: - menu_items.update(getattr(blueprint, "menu_items", {})) return { 'current_app': current_app, - 'current_blueprint': current_blueprint, - 'menu_items': menu_items } + 'current_blueprint': current_blueprint } ########################################################################## # All done! diff --git a/web/pgadmin/about/__init__.py b/web/pgadmin/about/__init__.py index 5830c7cc6..93d583daa 100644 --- a/web/pgadmin/about/__init__.py +++ b/web/pgadmin/about/__init__.py @@ -20,21 +20,27 @@ import sys import config -class AboutModule(PgAdminModule): +class AboutModule(PgAdminModule): def get_own_menuitems(self): return { 'help_items': [ MenuItem(name='mnu_about', priority=999, - url='#', - onclick='about_show()', - label=gettext('About %(appname)s', appname=config.APP_NAME)) + module="pgAdmin.About", + callback='about_show', + icon='fa fa-info-circle', + label=gettext('About %(appname)s', + appname=config.APP_NAME)) ] } def get_own_javascripts(self): - return [url_for('about.script')] + return [{ + 'name': 'pgadmin.about', + 'path': url_for('about.index') + 'about', + 'when': None + }] blueprint = AboutModule(MODULE_NAME, __name__, @@ -47,10 +53,10 @@ blueprint = AboutModule(MODULE_NAME, __name__, @login_required def index(): """Render the about box.""" - info = { } + info = {} info['python_version'] = sys.version info['flask_version'] = __version__ - if config.SERVER_MODE == True: + if config.SERVER_MODE is True: info['app_mode'] = gettext('Server') else: info['app_mode'] = gettext('Desktop') @@ -58,10 +64,11 @@ def index(): return render_template(MODULE_NAME + '/index.html', info=info) + @blueprint.route("/about.js") @login_required def script(): - """Render the required Javascript""" + """render the required javascript""" return Response(response=render_template("about/about.js"), status=200, mimetype="application/javascript") diff --git a/web/pgadmin/about/templates/about/about.js b/web/pgadmin/about/templates/about/about.js index 30591df30..4b32d6cca 100644 --- a/web/pgadmin/about/templates/about/about.js +++ b/web/pgadmin/about/templates/about/about.js @@ -1,31 +1,42 @@ -function about_show() { - if (!alertify.aboutDialog) { - alertify.dialog('aboutDialog', function factory() { +define( + ['jquery', 'alertify', 'pgadmin'], + function($, alertify, pgAdmin) { + pgAdmin = pgAdmin || window.pgAdmin || {}; + + /* Return back, this has been called more than once */ + if (pgAdmin.About) + return; + + pgAdmin.About = { + about_show: function() { + if (!alertify.aboutDialog) { + alertify.dialog('aboutDialog', function factory() { return { - main:function(title, message) { - this.set('title', title); - this.message = message; - }, - setup:function() { - return { - buttons:[{ text: "OK", key: 27, className: "btn btn-primary" }], - options: { modal: 0, resizable: true } - }; - }, - build:function() { - - }, - prepare:function() { - this.setContent(this.message); - } - } - }); - } - - var content = ''; - $.get("{{ url_for('about.index') }}", - function(data) { - alertify.aboutDialog('About {{ config.APP_NAME }}', data).resizeTo(800, 450); + main:function(title, message) { + this.set('title', title); + this.message = message; + }, + setup:function() { + return { + buttons:[{ text: "OK", key: 27, className: "btn btn-primary" }], + options: { modal: 0, resizable: true } + }; + }, + build:function() {}, + prepare:function() { + this.setContent(this.message); + } + }; + }); } - ); -} \ No newline at end of file + + var content = ''; + $.get("{{ url_for('about.index') }}", + function(data) { + alertify.aboutDialog('About {{ config.APP_NAME }}', data).resizeTo(800, 450); + }); + } + }; + + return pgAdmin.About; + }); diff --git a/web/pgadmin/about/templates/about/index.html b/web/pgadmin/about/templates/about/index.html index 80c299a34..8cb0fd81c 100644 --- a/web/pgadmin/about/templates/about/index.html +++ b/web/pgadmin/about/templates/about/index.html @@ -24,5 +24,7 @@
-
{{ config.APP_NAME }}
+
{{ config.APP_NAME }}
\ No newline at end of file diff --git a/web/pgadmin/browser/__init__.py b/web/pgadmin/browser/__init__.py index ae4210449..aec41fca2 100644 --- a/web/pgadmin/browser/__init__.py +++ b/web/pgadmin/browser/__init__.py @@ -31,7 +31,8 @@ class BrowserModule(PgAdminModule): current_app.debug else \ 'css/wcDocker/wcDockerSkeleton.min.css'), ('static', 'css/wcDocker/theme.css'), - ('browser.static', 'css/aciTree/css/aciTree.css'), + ('browser.static', 'css/browser.css'), + ('browser.static', 'css/aciTree/css/aciTree.css') ]: stylesheets.append(url_for(endpoint, filename=filename)) stylesheets.append(url_for('browser.browser_css')) @@ -39,25 +40,90 @@ class BrowserModule(PgAdminModule): def get_own_javascripts(self): - scripts = [] - for (endpoint, filename) in [ - ('static', 'js/codemirror/codemirror.js'), - ('static', 'js/codemirror/mode/sql.js'), - ('static', 'js/jQuery-contextMenu/jquery.ui.position.js'), - ('static', 'js/jQuery-contextMenu/jquery.contextMenu.js'), - ('browser.static', 'js/aciTree/jquery.aciPlugin.min.js'), - ('browser.static', 'js/aciTree/jquery.aciTree.dom.js'), - ('browser.static', 'js/aciTree/jquery.aciTree.min.js')]: - scripts.append(url_for(endpoint, filename=filename)) - scripts.append(url_for('browser.browser_js')) - if current_app.debug: - scripts.append(url_for( - 'static', - filename='js/wcDocker/wcDocker.js')) - else: - scripts.append(url_for( - 'static', - filename='js/wcDocker/wcDocker.min.js')) + scripts = list() + scripts.append({ + 'name': 'alertify', + 'path': url_for('static', filename='js/alertifyjs/alertify' if current_app.debug \ + else 'js/alertifyjs/alertify.min'), + 'exports': 'alertify', + 'preloaded': True + }) + scripts.append({ + 'name': 'codemirror', + 'path': url_for('static', filename='js/codemirror/codemirror'), + 'exports': 'CodeMirror', + 'preloaded': True + }) + scripts.append({ + 'name': 'codemirror.sql', + 'path': url_for('static', filename='js/codemirror/mode/sql'), + 'deps': ['codemirror'], + 'exports': 'CodeMirror.modes.sql', + 'preloaded': True + }) + scripts.append({ + 'name': 'jqueryui.position', + 'path': url_for('static', + filename='js/jQuery-contextMenu/jquery.ui.position'), + 'deps': ['jquery'], + 'exports': 'jQuery.ui.position', + 'preloaded': True + + }) + scripts.append({ + 'name': 'jquery.contextmenu', + 'path': url_for('static', + filename='js/jQuery-contextMenu/jquery.contextMenu'), + 'deps': ['jquery', 'jqueryui.position'], + 'exports': 'jQuery.contextMenu', + 'preloaded': True + }) + scripts.append({ + 'name': 'jquery.aciplugin', + 'path': url_for('browser.static', + filename='js/aciTree/jquery.aciPlugin.min'), + 'deps': ['jquery'], + 'exports': 'aciPluginClass', + 'preloaded': True + }) + scripts.append({ + 'name': 'jquery.acitree', + 'path': url_for('browser.static', + filename='js/aciTree/jquery.aciTree' \ + if current_app.debug else \ + 'js/aciTree/jquery.aciTree.min'), + 'deps': ['jquery', 'jquery.aciplugin'], + 'exports': 'aciPluginClass.plugins.aciTree', + 'preloaded': True + }) + scripts.append({ + 'name': 'wcdocker', + 'path': url_for('static', + filename='js/wcDocker/wcDocker' if current_app.debug else \ + 'js/wcDocker/wcDocker.min'), + 'deps': ['jquery.contextmenu'], + 'exports': '', + 'preloaded': True + }) + + for name, script in [ + ['pgadmin.browser', 'js/browser'], + ['pgadmin.browser.error', 'js/error'], + ['pgadmin.browser.node', 'js/node']]: + scripts.append({ 'name': name, + 'path': url_for('browser.index') + script, 'preloaded': True }) + + for name, end in [ + ['pgadmin.browser.menu', 'js/menu'], + ['pgadmin.browser.panel', 'js/panel'], + ['pgadmin.browser.frame', 'js/frame']]: + scripts.append({ + 'name': name, 'path': url_for('browser.static', filename=end), + 'preloaded': True}) + + for module in self.submodules: + scripts.extend(module.get_own_javascripts()) + return scripts @@ -68,11 +134,12 @@ class BrowserPluginModule(PgAdminModule): Base class for browser submodules. """ + browser_url_prefix = blueprint.url_prefix + '/' __metaclass__ = ABCMeta def __init__(self, import_name, **kwargs): kwargs.setdefault("url_prefix", self.node_path) - kwargs.setdefault("static_url_path", 'static') + kwargs.setdefault("static_url_path", '/static') super(BrowserPluginModule, self).__init__("NODE-%s" % self.node_type, import_name, **kwargs) @@ -87,15 +154,49 @@ class BrowserPluginModule(PgAdminModule): # TODO: move those methods to BrowserModule subclass ? return [] + + def get_own_javascripts(self): + scripts = [] + + scripts.extend([{ + 'name': 'pgadmin.node.%s' % self.node_type, + 'path': url_for('browser.index') + '%s/module' % self.node_type, + 'when': self.script_load + }]) + + for module in self.submodules: + scripts.extend(module.get_own_javascripts()) + + return scripts + + + def generate_browser_node(self, node_id, parent_id, label, icon, inode): + obj = { + "id": "%s/%s" % (self.node_type, node_id), + "label": label, + "icon": icon, + "inode": inode, + "_type": self.node_type, + "_id": node_id, + "refid": parent_id + } + return obj + + @property def csssnippets(self): """ Returns a snippet of css to include in the page """ - # TODO: move those methods to BrowserModule subclass ? - return [render_template("browser/css/node.css", + snippets = [render_template("browser/css/node.css", node_type=self.node_type)] + for submodule in self.submodules: + snippets.extend(submodule.csssnippets) + + return snippets + + @abstractmethod def get_nodes(self): """ @@ -108,9 +209,27 @@ class BrowserPluginModule(PgAdminModule): def node_type(self): pass + @abstractproperty + def script_load(self): + """ + This property defines, when to load this script. + In order to allow creation of an object, we need to load script for any + node at the parent level. + + i.e. + - In order to allow creating a server object, it should be loaded at + server-group node. + """ + pass + @property def node_path(self): - return '/browser/nodes/' + self.node_type + return url_for('browser.index') + 'nodes/' + self.node_type + + + @property + def javascripts(self): + return [] @blueprint.route("/") @@ -128,7 +247,7 @@ def index(): return render_template(MODULE_NAME + "/index.html", username=current_user.email) -@blueprint.route("/browser.js") +@blueprint.route("/js/browser.js") @login_required def browser_js(): layout = get_setting('Browser/Layout', default='') @@ -142,12 +261,27 @@ def browser_js(): jssnippets=snippets), 200, {'Content-Type': 'application/x-javascript'}) +@blueprint.route("/js/error.js") +@login_required +def error_js(): + return make_response( + render_template('browser/js/error.js'), + 200, {'Content-Type': 'application/x-javascript'}) + +@blueprint.route("/js/node.js") +@login_required +def node_js(): + return make_response( + render_template('browser/js/node.js'), + 200, {'Content-Type': 'application/x-javascript'}) + + @blueprint.route("/browser.css") @login_required def browser_css(): """Render and return CSS snippets from the nodes and modules.""" snippets = [] - for submodule in current_blueprint.submodules: + for submodule in blueprint.submodules: snippets.extend(submodule.csssnippets) return make_response( render_template('browser/css/browser.css', snippets=snippets), diff --git a/web/pgadmin/browser/server_groups/__init__.py b/web/pgadmin/browser/server_groups/__init__.py index b5a4167a9..2939c9255 100644 --- a/web/pgadmin/browser/server_groups/__init__.py +++ b/web/pgadmin/browser/server_groups/__init__.py @@ -10,75 +10,45 @@ from abc import ABCMeta, abstractmethod import traceback -from flask import Blueprint, Response, current_app, request, render_template +import json +from flask import request, render_template, make_response, jsonify from flask.ext.babel import gettext from flask.ext.security import current_user, login_required from pgadmin import current_blueprint -from pgadmin.utils.ajax import make_json_response +from pgadmin.utils.ajax import make_json_response, \ + make_response as ajax_response from pgadmin.browser import BrowserPluginModule from pgadmin.utils.menu import MenuItem from pgadmin.settings.settings_model import db, ServerGroup -from pgadmin.browser.utils import generate_browser_node -import config class ServerGroupModule(BrowserPluginModule): NODE_TYPE = "server-group" - def get_own_menuitems(self): - return { - 'standard_items': [ - ServerGroupMenuItem(action="drop", priority=10, function="drop_server_group"), - ServerGroupMenuItem(action="rename", priority=10, function="rename_server_group") - ], - 'create_items': [ - ServerGroupMenuItem(name="create_server_group", - label=gettext('Server Group...'), - priority=10, - function="create_server_group", - types=[self.node_type]) - ], - 'context_items': [ - ServerGroupMenuItem(name="delete_server_group", - label=gettext('Delete server group'), - priority=10, - onclick='drop_server_group(item);'), - ServerGroupMenuItem(name="rename_server_group", - label=gettext('Rename server group...'), - priority=10, - onclick='rename_server_group(item);') - ] - } - - - @property - def jssnippets(self): - snippets = [render_template("server_groups/server_groups.js")] - for module in self.submodules: - snippets.extend(module.jssnippets) - return snippets - - def get_nodes(self, **kwargs): + def get_nodes(self, *arg, **kwargs): """Return a JSON document listing the server groups for the user""" groups = ServerGroup.query.filter_by(user_id=current_user.id) - # TODO: Move this JSON generation to a Server method - # this code is duplicated somewhere else for group in groups: - yield generate_browser_node( + group = self.generate_browser_node( "%d" % (group.id), + None, group.name, "icon-%s" % self.node_type, - True, - self.node_type) + True) + yield group @property def node_type(self): return self.NODE_TYPE + @property + def script_load(self): + return None + @property def node_path(self): - return '/browser/' + self.node_type + return BrowserPluginModule.browser_url_prefix + self.node_type class ServerGroupMenuItem(MenuItem): @@ -97,17 +67,25 @@ class ServerGroupPluginModule(BrowserPluginModule): @abstractmethod - def get_nodes(self, servergroup): + def get_nodes(self, *arg, **kwargs): pass @property def node_path(self): - return '/browser/' + self.node_type + return BrowserPluginModule.browser_url_prefix + self.node_type blueprint = ServerGroupModule( __name__, static_url_path='') +@blueprint.route('/module.js') +@login_required +def module(): + return make_response( + render_template("server_groups/server_groups.js"), + 200, {'Content-Type': 'application/x-javascript'}) + + # Initialise the module from pgadmin.browser.utils import NodeView @@ -136,14 +114,16 @@ class ServerGroupView(NodeView): if servergroup is None: return make_json_response( + status=417, success=0, errormsg=gettext('The specified server group could not be found.')) else: try: - db.session.delete(servergroup) + for sg in servergroup: + db.session.delete(sg) db.session.commit() except Exception as e: - return make_json_response(success=0, errormsg=e.message) + return make_json_response(status=410, success=0, errormsg=e.message) return make_json_response(result=request.form) @@ -156,17 +136,20 @@ class ServerGroupView(NodeView): user_id=current_user.id, id=gid).first() + data = request.form if request.form else json.loads(request.data) + if servergroup is None: return make_json_response( + status=417, success=0, errormsg=gettext('The specified server group could not be found.')) else: try: - if 'name' in request.form: - servergroup.name = request.form['name'] + if u'name' in data: + servergroup.name = data[u'name'] db.session.commit() except Exception as e: - return make_json_response(success=0, errormsg=e.message) + return make_json_response(status=410, success=0, errormsg=e.message) return make_json_response(result=request.form) @@ -182,34 +165,47 @@ class ServerGroupView(NodeView): if sg is None: return make_json_response( + status=417, success=0, errormsg=gettext('The specified server group could not be found.')) else: - return make_json_response(data={'id': sg.id, 'name': sg.name}) + return ajax_response(response={'id': sg.id, 'name': sg.name}, + status=200) def create(self): - data = [] - if request.form['name'] != '': - servergroup = ServerGroup( - user_id=current_user.id, - name=request.form['name']) + data = request.form if request.form else json.loads(request.data) + + if data[u'name'] != '': try: - db.session.add(servergroup) + sg = ServerGroup( + user_id=current_user.id, + name=data[u'name']) + db.session.add(sg) db.session.commit() - data['id'] = servergroup.id - data['name'] = servergroup.name + data[u'id'] = sg.id + data[u'name'] = sg.name + + return jsonify(node=blueprint.generate_browser_node( + "%d" % (sg.id), + None, + sg.name, + "icon-%s" % self.node_type, + True)) except Exception as e: - return make_json_response(success=0, errormsg=e.message) + print 'except' + return make_json_response( + status=410, + success=0, + errormsg=e.message) else: return make_json_response( + status=417, success=0, errormsg=gettext('No server group name was specified')) - return make_json_response(data=data) - def nodes(self, gid): """Build a list of treeview nodes from the child nodes.""" @@ -220,23 +216,23 @@ class ServerGroupView(NodeView): def sql(self, gid): - return make_json_response(data='') + return make_json_response(status=422) def modified_sql(self, gid): - return make_json_response(data='') + return make_json_response(status=422) def statistics(self, gid): - return make_json_response(data='') + return make_json_response(status=422) def dependencies(self, gid): - return make_json_response(data='') + return make_json_response(status=422) def dependents(self, gid): - return make_json_response(data='') + return make_json_response(status=422) ServerGroupView.register_node_view(blueprint) diff --git a/web/pgadmin/browser/server_groups/servers/__init__.py b/web/pgadmin/browser/server_groups/servers/__init__.py index 68e501c8e..a2a360ae1 100644 --- a/web/pgadmin/browser/server_groups/servers/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/__init__.py @@ -6,72 +6,58 @@ # This software is released under the PostgreSQL Licence # ########################################################################## -from flask import render_template, request -from pgadmin.browser.server_groups import ServerGroupPluginModule +import json +from flask import render_template, request, make_response, jsonify from flask.ext.security import login_required, current_user from pgadmin.settings.settings_model import db, Server, ServerGroup from pgadmin.utils.menu import MenuItem -from pgadmin.utils.ajax import make_json_response -from pgadmin.browser.utils import generate_browser_node, NodeView +from pgadmin.utils.ajax import make_json_response, \ + make_response as ajax_response +from pgadmin.browser.utils import NodeView, generate_browser_node import traceback from flask.ext.babel import gettext +import pgadmin.browser.server_groups as sg -class ServerModule(ServerGroupPluginModule): +class ServerModule(sg.ServerGroupPluginModule): NODE_TYPE = "server" @property def node_type(self): return self.NODE_TYPE + @property + def script_load(self): + """ + Load the module script for server, when any of the server-group node is + initialized. + """ + return sg.ServerGroupModule.NODE_TYPE + def get_nodes(self, server_group): """Return a JSON document listing the server groups for the user""" - servers = Server.query.filter_by(user_id=current_user.id, servergroup_id=server_group) + servers = Server.query.filter_by(user_id=current_user.id, + servergroup_id=server_group) # TODO: Move this JSON generation to a Server method for server in servers: - yield generate_browser_node( - "%d" % server.id, - server.name, - "icon-%s" % self.NODE_TYPE, - True, - self.NODE_TYPE - ) - - def get_own_menuitems(self): - return { - 'standard_items': [ - ServerMenuItem(action="drop", priority=50, function='drop_server'), - ServerMenuItem(action="rename", priority=50, function='rename_server') - ], - 'create_items': [ - ServerMenuItem(types=["server-group", "server"], - name="create_server", - label=gettext('Server...'), - priority=50, - function='create_server(item)') - ], - 'context_items': [ - ServerMenuItem(name='delete_server', - label=gettext('Delete server'), - priority=50, - onclick='drop_server(item)'), - ServerMenuItem(name='rename_server', - label=gettext('Rename server...'), - priority=60, - onclick='rename_server(item);') - ] - } + node = generate_browser_node( + "%d" % (server.id), + "%d" % server_group, + server.name, + "icon-%s-not-connected" % self.NODE_TYPE, + True, + self.NODE_TYPE) + yield node @property def jssnippets(self): - return [render_template("servers/servers.js")] + return [] class ServerMenuItem(MenuItem): - def __init__(self, **kwargs): kwargs.setdefault("type", ServerModule.NODE_TYPE) super(ServerMenuItem, self).__init__(**kwargs) @@ -80,59 +66,74 @@ class ServerMenuItem(MenuItem): blueprint = ServerModule(__name__) +@blueprint.route('/module.js') +@login_required +def module(): + return make_response( + render_template("servers/servers.js"), + 200, {'Content-Type': 'application/x-javascript'}) + + class ServerNode(NodeView): - node_type = ServerModule.NODE_TYPE - parent_ids = [{'type':'int', 'id':'gid'}] - ids = [{'type':'int', 'id':'sid'}] - + parent_ids = [{'type': 'int', 'id': 'gid'}] + ids = [{'type': 'int', 'id': 'sid'}] + operations = dict({ + 'obj': [ + {'get': 'properties', 'delete': 'delete', 'put': 'update'}, + {'get': 'list', 'post': 'create'} + ], + 'nodes': [{'get': 'nodes'}], + 'sql': [{'get': 'sql', 'post': 'modified_sql'}], + 'stats': [{'get': 'statistics'}], + 'deps': [{'get': 'dependencies', 'post': 'dependents'}], + 'connect': [{'get': 'connect_status', 'post': 'connect', 'delete': 'disconnect'}] + }) def list(self, gid): res = [] """Return a JSON document listing the server groups for the user""" servers = Server.query.filter_by(user_id=current_user.id, - servergroup_id=gid) + servergroup_id=gid) for server in servers: res.append( - generate_browser_node( - "%d/%d" % (gid, server.id), - server.name, - "icon-%s" % NODE_TYPE, - True, - NODE_TYPE - ) - ) + generate_browser_node( + "%s" % server.id, + "%s" % gid, + server.name, + "icon-%s-not-connected" % ServerModule.NODE_TYPE, + True, + ServerModule.NODE_TYPE) + ) return make_json_response(result=res) - def delete(self, gid, sid): """Delete a server node in the settings database""" - server = Server.query.filter_by(user_id=current_user.id, id=sid) + servers = Server.query.filter_by(user_id=current_user.id, id=sid) # TODO:: A server, which is connected, can not be deleted - if server is None: + if servers is None: return make_json_response( - success=0, - errormsg=gettext( - 'The specified server could not be found.\n' - 'Does the user have permission to access the ' - 'server?' - ) - ) + success=0, + errormsg=gettext( + 'The specified server could not be found.\n' + 'Does the user have permission to access the ' + 'server?' + ) + ) else: try: - db.session.delete(server) + for s in servers: + db.session.delete(s) db.session.commit() except Exception as e: return make_json_response( - success=0, - errormsg=e.message) - - return make_json_response(success=success, - errormsg=errormsg, - info=traceback.format_exc()) + success=0, + errormsg=e.message) + return make_json_response(success=1, + info=traceback.format_exc()) def update(self, gid, sid): """Update the server settings""" @@ -140,130 +141,139 @@ class ServerNode(NodeView): if server is None: return make_json_response( - success=0, - errormsg=gettext("Couldn't find the given server.") - ) + success=0, + errormsg=gettext("Couldn't find the given server.") + ) # TODO:: # Not all parameters can be modified, while the server is connected possible_args = { - 'name': 'name', - 'host': 'host', - 'port': 'port', - 'db': 'maintenance_db', - 'username': 'username', - 'sslmode': 'sslmode', - 'gid': 'servergroup_id' - } + 'name': 'name', + 'host': 'host', + 'port': 'port', + 'db': 'maintenance_db', + 'username': 'username', + 'sslmode': 'sslmode', + 'gid': 'servergroup_id', + 'comment': 'comment' + } idx = 0 + data = request.form if request.form else json.loads(request.data) + for arg in possible_args: - if arg in request.form: - server[possible_args[arg]] = request.form[arg] + if arg in data: + setattr(server, possible_args[arg], data[arg]) idx += 1 if idx == 0: return make_json_response( - success=0, - errormsg=gettext('No parameters were chagned!') - ) + success=0, + errormsg=gettext('No parameters were chagned!') + ) try: db.session.commit() except Exception as e: return make_json_response( - success=0, - errormsg=e.message - ) + success=0, + errormsg=e.message + ) return make_json_response( - success=1, - data={ - 'id': server.id, - 'gid': server.servergroup_id - } - ) - + success=1, + data={ + 'id': server.id, + 'gid': server.servergroup_id + } + ) def properties(self, gid, sid): """Return list of attributes of a server""" server = Server.query.filter_by( - user_id=current_user.id, - id=sid).first() + user_id=current_user.id, + id=sid).first() if server is None: return make_json_response( - success=0, - errormsg=gettext("Couldn't find the given server") - ) + success=0, + errormsg=gettext("Couldn't find the given server") + ) sg = ServerGroup.query.filter_by( - user_id=current_user.id, - id=server.servergroup_id - ).first() - - return make_json_response( - success=1, - data={ - 'id':server.id, - 'name':server.name, - 'host':server.host, - 'port':server.port, - 'db':server.maintenance_db, - 'username':server.username, - 'gid':server.servergroup_id, - 'group-name':sg.name - } - ) + user_id=current_user.id, + id=server.servergroup_id + ).first() + return ajax_response( + response={ + 'id': server.id, + 'name': server.name, + 'host': server.host, + 'port': server.port, + 'db': server.maintenance_db, + 'username': server.username, + 'gid': server.servergroup_id, + 'group-name': sg.name, + 'comment': server.comment, + # TODO:: Make sure - we do have correct values here + 'connected': True, + 'version': 'PostgreSQL 9.3 (linux-x64)' + } + ) def create(self, gid): """Add a server node to the settings database""" required_args = [ - 'name', - 'host', - 'port', - 'db', - 'username', - 'sslmode' - ] + u'name', + u'host', + u'port', + u'db', + u'username', + u'sslmode' + ] + + data = request.form if request.form else json.loads(request.data) for arg in required_args: - if arg not in request.form: + if arg not in data: return make_json_response( - success=0, - errormsg=gettext( - "Couldn't find the required parameter (%s)." % arg - ) - ) - - server = Server( - user_id=current_user.id, - servergroup_id=gid, - name=request.form['name'], - host=request.form['host'], - port=request.form['port'], - maintenance_db=request.form['db'], - username=request.form['username'], - sslmode=request.form['username'] + status=410, + success=0, + errormsg=gettext( + "Couldn't find the required parameter (%s)." % arg + ) ) try: + server = Server( + user_id=current_user.id, + servergroup_id=gid, + name=data[u'name'], + host=data[u'host'], + port=data[u'port'], + maintenance_db=data[u'db'], + username=data[u'username'], + ssl_mode=data['sslmode'], + comment=data['comment'] if 'comment' in data else None + ) db.session.add(server) db.session.commit() + + return jsonify(node=generate_browser_node( + '%s' % server.id, + '%s' % gid, + '%s' % server.name, + "icon-{0}-not-connected".format(ServerModule.NODE_TYPE), + True, + ServerModule.NODE_TYPE)) + except Exception as e: return make_json_response( - success=0, - errormsg=e.message - ) - - return make_json_response(success=1, - data={ - 'id': server.id, - 'name': server.name, - 'gid': gid - }) - + status=410, + success=0, + errormsg=e.message + ) def nodes(self, gid, sid): """Build a list of treeview nodes from the child nodes.""" @@ -275,23 +285,18 @@ class ServerNode(NodeView): nodes.extend(module.get_nodes(server=sid)) return make_json_response(data=nodes) - def sql(self, gid, sid): return make_json_response(data='') - def modified_sql(self, gid, sid): return make_json_response(data='') - def statistics(self, gid, sid): return make_json_response(data='') - def dependencies(self, gid, sid): return make_json_response(data='') - def dependents(self, gid, sid): return make_json_response(data='') diff --git a/web/pgadmin/browser/server_groups/servers/templates/servers/servers.js b/web/pgadmin/browser/server_groups/servers/templates/servers/servers.js index 5361229da..abc614292 100644 --- a/web/pgadmin/browser/server_groups/servers/templates/servers/servers.js +++ b/web/pgadmin/browser/server_groups/servers/templates/servers/servers.js @@ -1,94 +1,169 @@ -// Add a server -function create_server(item) { - var alert = alertify.prompt( - '{{ _('Create a server') }}', - '{{ _('Enter a name for the new server') }}', - '', - function(evt, value) { - var d = tree.itemData(item); - if (d._type != 'server-group') { +define( + ['jquery', 'underscore', 'pgadmin', 'pgadmin.browser', 'alertify'], +function($, _, pgAdmin, pgBrowser, alertify) { + + if (!pgBrowser.Nodes['server']) { + pgAdmin.Browser.Nodes['server'] = pgAdmin.Browser.Node.extend({ + parent_type: 'server-group', + type: 'server', + label: '{{ _('Server...') }}', + Init: function() { + + /* Avoid multiple registration of same menus */ + if (this.initialized) + return; + + this.initialized = true; + + pgBrowser.add_menus([{ + name: 'create_server_on_sg', node: 'server-group', module: this, + applies: ['object', 'context'], callback: 'show_obj_properties', + category: 'create', priority: 1, label: '{{ _('Server...') }}', + data: {action: 'create'}, icon: 'wcTabIcon icon-server' + }, { + name: 'create_server', node: 'server', module: this, + applies: ['object', 'context'], callback: 'show_obj_properties', + category: 'create', priority: 3, label: '{{ _('Server...') }}', + data: {action: 'create'}, icon: 'wcTabIcon icon-server' + }, { + name: 'edit_server', node: 'server', module: this, + applies: ['object', 'context'], callback: 'show_obj_properties', + category: 'edit', priority: 4, label: '{{ _('Edit...') }}', + data: {action: 'edit'}, icon: 'fa fa-pencil-square-o' + },{ + name: 'drop_server', node: 'server', module: this, + applies: ['object', 'context'], callback: 'delete_obj', + category: 'drop', priority: 3, label: '{{ _('Drop Server...') }}', + icon: 'fa fa-trash' + }]); + }, + callbacks: { + // Add a server + create_server: function (item) { + var alert = alertify.prompt( + '{{ _('Create a server') }}', + '{{ _('Enter a name for the new server') }}', + '', + function(evt, value) { + var d = tree.itemData(item); + if (d._type != 'server-group') { d = tree.itemData(tree.parent(item)); - } - $.post( - "{{ url_for('browser.index') }}server/obj/" + d.refid + '/', + } + $.post( + "{{ url_for('browser.index') }}server/obj/" + d.refid + '/' + d.id + '/', { name: value } ) .done(function(data) { - if (data.success == 0) { - report_error(data.errormsg, data.info); - } else { - var item = { - id: data.data.id, - label: data.data.name, - inode: true, - open: false, - icon: 'icon-server' - } - - tree.append(null, { - itemData: item - }); - + if (data.success == 0) { + report_error(data.errormsg, data.info); + } else { + var item = { + id: data.data.id, + label: data.data.name, + inode: true, + open: false, + icon: 'icon-server-not-connected' } - } - ) + tree.append(null, { + itemData: item + }); + } + }); + }, + null + ); + alert.show(); }, - null - ); - alert.show(); -} - -// Delete a server -function drop_server(item) { - alertify.confirm( - '{{ _('Drop server?') }}', - '{{ _('Are you sure you wish to drop the server "{0}"?') }}'.replace('{0}', tree.getLabel(item)), - function() { - var id = tree.getId(item).split('/').pop() - $.ajax({ - url:"{{ url_for('browser.index') }}" + d._type + "/obj/" + d.refid, - type:'DELETE', - success: function(data) { + /* Connect the server (if not connected), before opening this node */ + beforeopen: function(o) { + o.browser.tree.removeIcon(o.item); + if (o.data.connected) { + o.browser.tree.addIcon(o.item, {icon: 'icon-server-connected'}); + } else { + o.browser.tree.addIcon(o.item, {icon: 'icon-server-not-connected'}); + } + var data = o.data; + if(!data || data._type != 'server') { + return false; + } + if (!data.connected) { + alertify.confirm( + '{{ _('Connect to server') }}', + '{{ _('Do you want to connect the server?') }}', + function(evt) { + $.post( + "{{ url_for('browser.index') }}server/connect/" + data.refid + '/' + ).done(function(data) { if (data.success == 0) { - report_error(data.errormsg, data.info); - } else { - var next = tree.next(item); - var prev = tree.prev(item); - tree.remove(item); - if (next.length) { - tree.select(next); - } else if (prev.length) { - tree.select(prev); - } + report_error(data.errormsg, data.info); } - } - }) + }).fail(function() {}); + return true; + }, + function(evt) { + return true; + } + ); + return false; + } + return true; + } + }, + model: pgAdmin.Browser.Node.Model.extend({ + defaults: { + id: undefined, + name: undefined, + sslmode: 'prefer' }, - null - ) -} + schema: [{ + id: 'id', label: 'ID', type: 'int', group: null, + mode: ['properties'] + },{ + id: 'name', label:'Name', type: 'text', group: null, + mode: ['properties', 'edit', 'create'] + },{ + id: 'connected', label:'Connected', type: 'text', group: null, + mode: ['properties'] + },{ + id: 'version', label:'Version', type: 'text', group: null, + mode: ['properties'], show: 'isConnected' + },{ + id: 'comment', label:'Comments:', type: 'multiline', group: null, + mode: ['properties', 'edit', 'create'], disable: 'notEditMode' + },{ + id: 'host', label:'Host Name/Address', type: 'text', group: "Connection", + mode: ['properties', 'edit', 'create'] + },{ + id: 'port', label:'Port', type: 'int', group: "Connection", + mode: ['properties', 'edit', 'create'] + },{ + id: 'db', label:'Maintenance Database', type: 'text', group: "Connection", + mode: ['properties', 'edit', 'create'] + },{ + id: 'username', label:'User Name', type: 'text', group: "Connection", + mode: ['properties', 'edit', 'create'] + },{ + id: 'sslmode', label:'SSL Mode', type: 'options', group: "Connection", + mode: ['properties', 'edit', 'create'], + 'options': [{label:'Allow', value:'allow'}, {label: 'Prefer', value:'prefer'}, {label: 'Require', value: 'require'}, {label: 'Disable', value:'disable'}, {label:'Verify-CA', value: 'verify-ca'}, {label:'Verify-Full', value:'verify-full'}] + }], + validate: function(attrs, options) { + if (!this.isNew() && 'id' in this.changed) { + return '{{ _('Id can not be changed!') }}'; + } + if (String(this.name).replace(/^\s+|\s+$/g, '') == '') { + return '{{ _('Name can be empty!') }}'; + } + return null; + }, + isConnected: function(mode) { + return mode == 'properties' && this.get('connected'); + }, + notEditMode: function(mode) { + return mode != 'edit'; + }}) + }); + } -// Rename a server -function rename_server(item) { - alertify.prompt( - '{{ _('Rename server') }}', - '{{ _('Enter a new name for the server') }}', - tree.getLabel(item), - function(evt, value) { - var d = tree.itemData(item); - $.ajax({ - url:"{{ url_for('browser.index') }}" + d._type + "/obj/" + d.refid, - type:'PUT', - params: {name: value}, - success: function(data) { - if (data.success == 0) { - report_error(data.errormsg, data.info); - } else { - tree.setLabel(item, { label: value }); - } - } - }) - }, - null - ) -} + return pgBrowser.Nodes['server']; +}); diff --git a/web/pgadmin/browser/server_groups/templates/server_groups/server_groups.js b/web/pgadmin/browser/server_groups/templates/server_groups/server_groups.js index a15401276..9987e3c14 100644 --- a/web/pgadmin/browser/server_groups/templates/server_groups/server_groups.js +++ b/web/pgadmin/browser/server_groups/templates/server_groups/server_groups.js @@ -1,87 +1,152 @@ -// Add a server group -function create_server_group() { - var alert = alertify.prompt( - '{{ _('Add a server group') }}', - '{{ _('Enter a name for the new server group') }}', - '', - function(evt, value) { - $.post("{{ url_for('browser.index') }}server-group/obj/", { name: value }) - .done(function(data) { - if (data.success == 0) { - report_error(data.errormsg, data.info); - } else { - var item = { - id: data.data.id, - label: data.data.name, - inode: true, - open: false, - icon: 'icon-server-group' - } +define( + ['jquery', 'underscore', 'pgadmin', 'backbone', 'pgadmin.browser', 'pgadmin.browser.node'], +function($, _, pgAdmin, Backbone) { - tree.append(null, { - itemData: item - }); + if (!pgAdmin.Browser.Nodes['server-group']) { + pgAdmin.Browser.Nodes['server-group'] = pgAdmin.Browser.Node.extend({ + parent_type: null, + type: 'server-group', + label: '{{ _('Server Group') }}', + Init: function() { + /* Avoid mulitple registration of menus */ + if (this.initialized) + return; - } - } - ) + this.initialized = true; + + pgAdmin.Browser.add_menus([{ + name: 'create_server_group', node: 'server-group', module: this, + applies: ['object', 'context'], callback: 'show_obj_properties', + category: 'create', priority: 1, label: '{{ _('Server Group...') }}', + data: {'action': 'create'}, icon: 'wcTabIcon icon-server-group' + },{ + name: 'edit_server_group', node: 'server-group', module: this, + applies: ['object', 'context'], callback: 'show_obj_properties', + priority: 3, label: '{{ _('Edit...') }}', data: {'action': 'edit'}, + icon: 'fa fa-pencil-square-o' + }, { + name: 'drop_server_group', node: 'server-group', module: this, + applies: ['object', 'context'], callback: 'delete_obj', + priority: 2, label: '{{ _('Drop Server Group...') }}', + icon: 'fa fa-trash' + }]); + }, + model: pgAdmin.Browser.Node.Model.extend({ + defaults: { + id: undefined, + name: undefined }, - null - ); - alert.show(); -} + schema: [ + {id: 'id', label: 'ID', type: 'int', group: null, mode: ['properties']}, + {id: 'name', label:'Name', type: 'text', group: null, mode: ['properties', 'edit', 'create']} + ], + validate: function(attrs, options) { + if (!this.isNew() && 'id' in this.changed) { + return '{{ _('Id can not be changed!') }}'; + } + if (String(this.name).replace(/^\s+|\s+$/g, '') == '') { + return '{{ _('Name can be empty!') }}'; + } + return null; + } + }), + canDelete: function(i) { + var s = pgAdmin.Browser.tree.siblings(i, true); -// Delete a server group -function drop_server_group(item) { - alertify.confirm( - '{{ _('Delete server group?') }}', - '{{ _('Are you sure you wish to delete the server group "{0}"?') }}'.replace('{0}', tree.getLabel(item)), - function() { - var d = tree.itemData(item); - $.ajax({ + /* This is the only server group - we can't remove it*/ + if (!s || s.length == 0) { + return false; + } + return true; + }, + callbacks: { + // Add a server group + create_server_group: function() { + var tree = pgAdmin.Browser.tree; + var alert = alertify.prompt( + '{{ _('Add a server group') }}', + '{{ _('Enter a name for the new server group') }}', + function(evt, value) { + $.post("{{ url_for('browser.index') }}server-group/obj/", { name: value }) + .done(function(data) { + if (data.success == 0) { + report_error(data.errormsg, data.info); + } else { + var item = { + id: data.data.id, + label: data.data.name, + inode: true, + open: false, + icon: 'icon-server-group' + } + tree.append(null, { + itemData: item + }); + } + }) + }, + function() {} + ); + alert.show(); + }, + // Delete a server group + drop_server_group: function (item) { + var tree = pgAdmin.Browser.tree; + alertify.confirm( + '{{ _('Delete server group?') }}', + '{{ _('Are you sure you wish to delete the server group "{0}"?') }}'.replace('{0}', tree.getLabel(item)), + function() { + var d = tree.itemData(item); + $.ajax({ url:"{{ url_for('browser.index') }}" + d._type + "/obj/" + d.refid, type:'DELETE', success: function(data) { - if (data.success == 0) { - report_error(data.errormsg, data.info); - } else { - var next = tree.next(item); - var prev = tree.prev(item); - tree.remove(item); - if (next.length) { - tree.select(next); - } else if (prev.length) { - tree.select(prev); - } + if (data.success == 0) { + report_error(data.errormsg, data.info); + } else { + var next = tree.next(item); + var prev = tree.prev(item); + tree.remove(item); + if (next.length) { + tree.select(next); + } else if (prev.length) { + tree.select(prev); } + } } - }) + }); + }, + function() {} + ).show(); }, - null - ) -} - -// Rename a server group -function rename_server_group(item) { - alertify.prompt( - '{{ _('Rename server group') }}', - '{{ _('Enter a new name for the server group') }}', - tree.getLabel(item), - function(evt, value) { - var d = tree.itemData(item); - $.ajax({ + // Rename a server group + rename_server_group: function (item) { + var tree = pgAdmin.Browser.tree; + alertify.prompt( + '{{ _('Rename server group') }}', + '{{ _('Enter a new name for the server group') }}', + tree.getLabel(item), + function(evt, value) { + var d = tree.itemData(item); + $.ajax({ url:"{{ url_for('browser.index') }}" + d._type + "/obj/" + d.refid, type:'PUT', params: { name: value }, success: function(data) { - if (data.success == 0) { - report_error(data.errormsg, data.info); - } else { - tree.setLabel(item, { label: value }); - } + if (data.success == 0) { + report_error(data.errormsg, data.info); + } else { + tree.setLabel(item, { label: value }); + } } - }) - }, - null - ) -} + }) + }, + null + ).show(); + } + } + }); + } + + return pgAdmin.Browser.Nodes['server-group']; +}); diff --git a/web/pgadmin/browser/static/js/aciTree/jquery.aciTree.js b/web/pgadmin/browser/static/js/aciTree/jquery.aciTree.js new file mode 100644 index 000000000..7aca9c3f8 --- /dev/null +++ b/web/pgadmin/browser/static/js/aciTree/jquery.aciTree.js @@ -0,0 +1,6985 @@ +/* + * aciTree jQuery Plugin v4.5.0-rc.7 + * http://acoderinsights.ro + * + * Copyright (c) 2014 Dragos Ursu + * Dual licensed under the MIT or GPL Version 2 licenses. + * + * Require jQuery Library >= v1.9.0 http://jquery.com + * + aciPlugin >= v1.5.1 https://github.com/dragosu/jquery-aciPlugin + */ + +/* + * The aciTree low-level DOM functions. + * + * A collection of functions optimised for aciTree DOM structure. + * + * Need to be included before the aciTree core and after aciPlugin. + */ + +aciPluginClass.plugins.aciTree_dom = { + // get the UL container from a LI + // `node` must be valid LI DOM node + // can return NULL + container: function(node) { + var container = node.lastChild; + if (container && (container.nodeName == 'UL')) { + return container; + } + return null; + }, + // get the first children from a LI (with filtering) + // `node` must be valid LI DOM node + // `callback` can return FALSE to skip a node + // can return NULL + firstChild: function(node, callback) { + var container = this.container(node); + if (container) { + var firstChild = container.firstChild; + if (callback) { + while (firstChild && !callback.call(this, firstChild)) { + firstChild = firstChild.nextSibling; + } + } + return firstChild; + } + return null; + }, + // get the last children from a LI (with filtering) + // `node` must be valid LI DOM node + // `callback` can return FALSE to skip a node + // can return NULL + lastChild: function(node, callback) { + var container = this.container(node); + if (container) { + var lastChild = container.lastChild; + if (callback) { + while (lastChild && !callback.call(this, lastChild)) { + lastChild = lastChild.previousSibling; + } + } + return lastChild; + } + return null; + }, + // get the previous LI sibling (with filtering) + // `node` must be valid LI DOM node + // `callback` can return FALSE to skip a node + // can return NULL + prev: function(node, callback) { + var previous = node.previousSibling; + if (callback) { + while (previous && !callback.call(this, previous)) { + previous = previous.previousSibling; + } + } + return previous; + }, + // get the next LI sibling (with filtering) + // `node` must be valid LI DOM node + // `callback` can return FALSE to skip a node + // can return NULL + next: function(node, callback) { + var next = node.nextSibling; + if (callback) { + while (next && !callback.call(this, next)) { + next = next.nextSibling; + } + } + return next; + }, + // get the previous LI in tree order (with filtering) + // `node` must be valid LI DOM node + // `callback` can return FALSE to skip a node or NULL to prevent drill down/skip the node + // can return NULL + prevAll: function(node, callback) { + var previous, lastChild, drillDown, match, prev, parent; + while (true) { + previous = this.prev(node); + if (previous) { + if (callback) { + match = callback.call(this, previous); + if (match === null) { + node = previous; + continue; + } + } + lastChild = this.lastChild(previous); + if (lastChild) { + if (callback && (callback.call(this, lastChild) === null)) { + node = lastChild; + continue; + } + prev = false; + while (drillDown = this.lastChild(lastChild)) { + lastChild = drillDown; + if (callback) { + match = callback.call(this, lastChild); + if (match === null) { + node = lastChild; + prev = true; + break; + } + } + } + if (prev) { + continue; + } + if (callback) { + match = callback.call(this, lastChild); + if (match) { + return lastChild; + } else if (match !== null) { + node = lastChild; + continue; + } + } else { + return lastChild; + } + } else { + if (!callback || match) { + return previous; + } else { + node = previous; + continue; + } + } + } + parent = this.parent(node); + if (parent) { + if (callback) { + match = callback.call(this, parent); + if (match) { + return parent; + } else { + node = parent; + } + } else { + return parent; + } + } else { + return null; + } + } + return null; + }, + // get the next LI in tree order (with filtering) + // `node` must be valid LI DOM node + // `callback` can return FALSE to skip a node or NULL to prevent drill down/skip the node + // can return NULL + nextAll: function(node, callback) { + var firstChild, match, next, parent, child; + while (true) { + firstChild = this.firstChild(node); + if (firstChild) { + if (callback) { + match = callback.call(this, firstChild); + if (match) { + return firstChild; + } else { + node = firstChild; + if (match !== null) { + continue; + } + } + } else { + return firstChild; + } + } + while (true) { + next = this.next(node); + if (next) { + if (callback) { + match = callback.call(this, next); + if (match) { + return next; + } else { + node = next; + if (match !== null) { + break; + } else { + continue; + } + } + } else { + return next; + } + } else { + parent = node; + child = null; + while (parent = this.parent(parent)) { + next = this.next(parent); + if (next) { + if (callback) { + match = callback.call(this, next); + if (match) { + return next; + } else { + node = next; + if (match !== null) { + child = true; + } else { + child = false; + } + break; + } + } else { + return next; + } + } + } + if (child !== null) { + if (child) { + break; + } else { + continue; + } + } + return null; + } + } + } + return null; + }, + // get the first LI in tree order (with filtering) + // `node` must be valid LI DOM node + // `callback` can return FALSE to skip a node or NULL to prevent drill down/skip the node + // can return NULL + first: function(node, callback) { + var container = this.container(node); + if (container) { + var firstChild = container.firstChild; + if (firstChild) { + if (callback && !callback.call(this, firstChild)) { + return this.nextAll(firstChild, callback); + } + return firstChild; + } + } + return null; + }, + // get the last LI in tree order (with filtering) + // `node` must be valid LI DOM node + // `callback` can return FALSE to skip a node or NULL to prevent drill down/skip the node + // can return NULL + last: function(node, callback) { + var container = this.container(node); + if (container) { + var lastChild = container.lastChild; + if (lastChild) { + if (callback && (callback.call(this, lastChild) === null)) { + return this.prevAll(lastChild, callback); + } else { + var drillDown; + while (drillDown = this.lastChild(lastChild)) { + lastChild = drillDown; + } + if (callback && !callback.call(this, lastChild)) { + return this.prevAll(lastChild, callback); + } + return lastChild; + } + } + } + return null; + }, + // get the children LI from the node + // `node` must be valid LI DOM node + // `drillDown` if TRUE all children are returned + // `callback` can return FALSE to skip a node or NULL to prevent drill down/skip the node + children: function(node, drillDown, callback) { + var children = [], levels = [], match, next, skip; + var firstChild = this.firstChild(node); + if (firstChild) { + while (true) { + skip = false; + do { + if (callback) { + match = callback.call(this, firstChild); + if (match) { + children.push(firstChild); + } + if (drillDown && (match !== null)) { + next = this.firstChild(firstChild); + if (next) { + levels.push(firstChild); + firstChild = next; + skip = true; + break; + } + } + } else { + children.push(firstChild); + if (drillDown) { + next = this.firstChild(firstChild); + if (next) { + levels.push(firstChild); + firstChild = next; + skip = true; + break; + } + } + } + } while (firstChild = firstChild.nextSibling); + if (!skip) { + while (firstChild = levels.pop()) { + firstChild = firstChild.nextSibling; + if (firstChild) { + break; + } + } + if (!firstChild) { + break; + } + } + } + } + return children; + }, + // get a children from the node + // `node` must be valid DOM node + // `callback` can return FALSE to skip a node or NULL to stop the search + // can return NULL + childrenTill: function(node, callback) { + var levels = [], match, next, skip; + var firstChild = node.firstChild; + if (firstChild) { + while (true) { + skip = false; + do { + match = callback.call(this, firstChild); + if (match) { + return firstChild; + } else if (match === null) { + return null; + } + next = firstChild.firstChild; + if (next) { + levels.push(firstChild); + firstChild = next; + skip = true; + break; + } + } while (firstChild = firstChild.nextSibling); + if (!skip) { + while (firstChild = levels.pop()) { + firstChild = firstChild.nextSibling; + if (firstChild) { + break; + } + } + if (!firstChild) { + break; + } + } + } + } + return null; + }, + // get a children from the node having a class + // `node` must be valid DOM node + // `className` String or Array to check for + // can return NULL + childrenByClass: function(node, className) { + if (node.getElementsByClassName) { + var list = node.getElementsByClassName(className instanceof Array ? className.join(' ') : className); + return list ? list[0] : null; + } else { + return this.childrenTill(node, function(node) { + return this.hasClass(node, className); + }); + } + }, + // get the parent LI from the children LI + // `node` must be valid LI DOM node + // can return NULL + parent: function(node) { + var parent = node.parentNode.parentNode; + if (parent && (parent.nodeName == 'LI')) { + return parent; + } + return null; + }, + // get the parent LI from any children + // `node` must be valid children of a LI DOM node + // can return NULL + parentFrom: function(node) { + while (node.nodeName != 'LI') { + node = node.parentNode; + if (!node) { + return null; + } + } + return node; + }, + // get a parent from the node + // `node` must be valid DOM node + // `callback` can return FALSE to skip a node or NULL to stop the search + // can return NULL + parentTill: function(node, callback) { + var match; + while (node = node.parentNode) { + match = callback.call(this, node); + if (match) { + return node; + } else if (match === null) { + return null; + } + } + return null; + }, + // get a parent from the node having a class + // `node` must be valid DOM node + // `className` String or Array to check for + // can return NULL + parentByClass: function(node, className) { + return this.parentTill(node, function(node) { + return this.hasClass(node, className); + }); + }, + // test if node has class(es) + // `className` String or Array to check for + // `withOut` String or Array to exclude with + hasClass: function(node, className, withOut) { + var oldClass = ' ' + node.className + ' '; + if (withOut instanceof Array) { + for (var i = 0; i < withOut.length; i++) { + if (oldClass.indexOf(' ' + withOut[i] + ' ') != -1) { + return false; + } + } + } else { + if (withOut && oldClass.indexOf(' ' + withOut + ' ') != -1) { + return false; + } + } + if (className instanceof Array) { + for (var i = 0; i < className.length; i++) { + if (oldClass.indexOf(' ' + className[i] + ' ') == -1) { + return false; + } + } + } else { + if (className && oldClass.indexOf(' ' + className + ' ') == -1) { + return false; + } + } + return true; + }, + // filter nodes with class(es) + // `nodes` Array of DOM nodes + // @see `hasClass` + withClass: function(nodes, className, withOut) { + var filter = []; + for (var i = 0; i < nodes.length; i++) { + if (this.hasClass(nodes[i], className, withOut)) { + filter.push(nodes[i]); + } + } + return filter; + }, + // test if node has any class(es) + // `className` String or Array to check for (any class) + // `withOut` String or Array to exclude with + hasAnyClass: function(node, className, withOut) { + var oldClass = ' ' + node.className + ' '; + if (withOut instanceof Array) { + for (var i = 0; i < withOut.length; i++) { + if (oldClass.indexOf(' ' + withOut[i] + ' ') != -1) { + return false; + } + } + } else { + if (withOut && oldClass.indexOf(' ' + withOut + ' ') != -1) { + return false; + } + } + if (className instanceof Array) { + for (var i = 0; i < className.length; i++) { + if (oldClass.indexOf(' ' + className[i] + ' ') != -1) { + return true; + } + } + } else { + if (className && oldClass.indexOf(' ' + className + ' ') != -1) { + return true; + } + } + return false; + }, + // filter nodes with any class(es) + // `nodes` Array of DOM nodes + // @see `hasAnyClass` + withAnyClass: function(nodes, className, withOut) { + var filter = []; + for (var i = 0; i < nodes.length; i++) { + if (this.hasAnyClass(nodes[i], className, withOut)) { + filter.push(nodes[i]); + } + } + return filter; + }, + // add class(es) to node + // `node` must be valid DOM node + // `className` String or Array to add + // return TRUE if className changed + addClass: function(node, className) { + var oldClass = ' ' + node.className + ' ', append = ''; + if (className instanceof Array) { + for (var i = 0; i < className.length; i++) { + if (oldClass.indexOf(' ' + className[i] + ' ') == -1) { + append += ' ' + className[i]; + } + } + } else { + if (oldClass.indexOf(' ' + className + ' ') == -1) { + append += ' ' + className; + } + } + if (append) { + node.className = node.className + append; + return true; + } + return false; + }, + // add class(es) to nodes + // `nodes` Array of DOM nodes + // @see `addClass` + addListClass: function(nodes, className, callback) { + for (var i = 0; i < nodes.length; i++) { + this.addClass(nodes[i], className); + if (callback) { + callback.call(this, nodes[i]); + } + } + }, + // remove class(es) from node + // `node` must be valid DOM node + // `className` String or Array to remove + // return TRUE if className changed + removeClass: function(node, className) { + var oldClass = ' ' + node.className + ' '; + if (className instanceof Array) { + for (var i = 0; i < className.length; i++) { + oldClass = oldClass.replace(' ' + className[i] + ' ', ' '); + } + } else { + oldClass = oldClass.replace(' ' + className + ' ', ' '); + } + oldClass = oldClass.substr(1, oldClass.length - 2); + if (node.className != oldClass) { + node.className = oldClass; + return true; + } + return false; + }, + // remove class(es) from nodes + // `nodes` Array of DOM nodes + // @see `removeClass` + removeListClass: function(nodes, className, callback) { + for (var i = 0; i < nodes.length; i++) { + this.removeClass(nodes[i], className); + if (callback) { + callback.call(this, nodes[i]); + } + } + }, + // toggle node class(es) + // `node` must be valid DOM node + // `className` String or Array to toggle + // `add` TRUE to add them + // return TRUE if className changed + toggleClass: function(node, className, add) { + if (add) { + return this.addClass(node, className); + } else { + return this.removeClass(node, className); + } + }, + // toggle nodes class(es) + // `nodes` Array of DOM nodes + // @see `toggleClass` + toggleListClass: function(nodes, className, add, callback) { + for (var i = 0; i < nodes.length; i++) { + this.toggleClass(nodes[i], className, add); + if (callback) { + callback.call(this, nodes[i]); + } + } + }, + // add/remove and keep old class(es) + // `node` must be valid DOM node + // `addClass` String or Array to add + // `removeClass` String or Array to remove + // return TRUE if className changed + addRemoveClass: function(node, addClass, removeClass) { + var oldClass = ' ' + node.className + ' '; + if (removeClass) { + if (removeClass instanceof Array) { + for (var i = 0; i < removeClass.length; i++) { + oldClass = oldClass.replace(' ' + removeClass[i] + ' ', ' '); + } + } else { + oldClass = oldClass.replace(' ' + removeClass + ' ', ' '); + } + } + if (addClass) { + var append = ''; + if (addClass instanceof Array) { + for (var i = 0; i < addClass.length; i++) { + if (oldClass.indexOf(' ' + addClass[i] + ' ') == -1) { + append += addClass[i] + ' '; + } + } + } else { + if (oldClass.indexOf(' ' + addClass + ' ') == -1) { + append += addClass + ' '; + } + } + oldClass += append; + } + oldClass = oldClass.substr(1, oldClass.length - 2); + if (node.className != oldClass) { + node.className = oldClass; + return true; + } + return false; + }, + // add/remove and keep old class(es) + // `nodes` Array of DOM nodes + // @see `addRemoveClass` + addRemoveListClass: function(nodes, addClass, removeClass, callback) { + for (var i = 0; i < nodes.length; i++) { + this.addRemoveClass(nodes[i], addClass, removeClass); + if (callback) { + callback.call(this, nodes[i]); + } + } + } +}; + +/* + * aciTree jQuery Plugin v4.5.0-rc.7 + * http://acoderinsights.ro + * + * Copyright (c) 2014 Dragos Ursu + * Dual licensed under the MIT or GPL Version 2 licenses. + * + * Require jQuery Library >= v1.9.0 http://jquery.com + * + aciPlugin >= v1.5.1 https://github.com/dragosu/jquery-aciPlugin + */ + +/* + * The aciTree core. + * + * A few words about how item data looks like: + * + * for a leaf node (a node that does not have any children): + * + * { + * id: 'some_file_ID', // should be unique item ID + * label: 'This is a File Item', // the item label (text value) + * inode: false, // FALSE means is a leaf node (can be omitted) + * icon: 'fileIcon', // CSS class name for the icon (if any), can also be an Array ['CSS class name', background-position-x, background-position-y] + * disabled: false, // TRUE means the item is disabled (can be omitted) + * random_prop: 'random 1' // sample user defined property (you can have any number defined) + * } + * + * for a inner node (a node that have at least a children under it): + * + * { + * id: 'some_folder_ID', // should be unique item ID + * label: 'This is a Folder Item', // the item label (text value) + * inode: true, // can also be NULL to find at runtime if its an inode (on load will be transformed in a leaf node if there aren't any children) + * open: false, // if TRUE then the node will be opened when the tree is loaded (can be omitted) + * icon: 'folderIcon', // CSS class name for the icon (if any), can also be an Array ['CSS class name', background-position-x, background-position-y] + * disabled: false, // TRUE means the item is disabled (can be omitted) + * source: 'myDataSource', // the data source name (if any) to read the children from, by default `aciTree.options.ajax` is used + * branch: [ // a list of children + * { ... item data ... }, + * { ... item data ... }, + * ... + * ], + * random_prop: 'random 2' // sample user defined property (you can have any number defined) + * } + * + * The `branch` array can be empty, in this case the children will be loaded when the node will be opened for the first time. + * + * Please note that the item data should be valid (in the expected format). No checking is done and errors can appear on invalid data. + * + * One note about a item: a item is always the LI element with the class 'aciTreeLi'. + * The children of a node are all added under a UL element with the class 'aciTreeUl'. + * + * Almost all API functions expect only one item. If you need to process more at once then you'll need to loop between all of them yourself. + * + * The `options` parameter for all API methods (when there is one) is a object with the properties (not all are required or used): + * + * { + * uid: string -> operation UID (defaults to `ui`) + * success: function (item, options) -> callback to be called on success (you can access plugin API with `this` keyword inside the callback) + * fail: function (item, options) -> callback to be called on fail (you can access plugin API with `this` keyword inside the callback) + * notify: function (item, options) -> notify callback (internal use for when already in the requested state, will call `success` by default) + * expand: true/false -> propagate on open/toggle + * collapse: true/false -> propagate on close/toggle + * unique: true/false -> should other branches be closed (on open/toggle) ? + * unanimated: true/false -> if it's TRUE then no animations are to be run (used on open/close/toggle) + * itemData: object[item data]/array[item data] -> used when adding/updating items + * } + * + * Note: when using the API methods that support the `options` parameter, you will need to use the success/fail callbacks if you need to do + * any processing after the API call. This because there can be async operations that will complete at a later time and the API methods will + * exit before the job is actually completed. This will happen when items are loaded with AJAX, on animations and other delayed operations (see _queue). + * + */ + +(function($, window, undefined) { + + // default options + + var options = { + // the AJAX options (see jQuery.ajax) where the `success` and `error` are overridden by aciTree + ajax: { + url: null, // URL from where to take the data, something like `path/script?nodeId=` (the node ID value will be added for each request) + dataType: 'json' + }, + dataSource: null, // a list of data sources to be used (each entry in `aciTree.options.ajax` format) + rootData: null, // initial ROOT data for the Tree (if NULL then one initial AJAX request is made on init) + queue: { + async: 4, // the number of simultaneous async (AJAX) tasks + interval: 50, // interval [ms] after which to insert a `delay` + delay: 20 // how many [ms] delay between tasks (after `interval` expiration) + }, + loaderDelay: 500, // how many msec to wait before showing the main loader ? (on lengthy operations) + expand: false, // if TRUE then all children of a node are expanded when the node is opened + collapse: false, // if TRUE then all children of a node are collapsed when the node is closed + unique: false, // if TRUE then a single tree branch will stay open, the oters are closed when a node is opened + empty: false, // if TRUE then all children of a node are removed when the node is closed + show: {// show node/ROOT animation (default is slideDown) + props: { + 'height': 'show' + }, + duration: 'medium', + easing: 'linear' + }, + animateRoot: true, // if the ROOT should be animated on init + hide: {// hide node animation (default is slideUp) + props: { + 'height': 'hide' + }, + duration: 'medium', + easing: 'linear' + }, + view: {// scroll item into view animation + duration: 'medium', + easing: 'linear' + }, + // called for each AJAX request when a node needs to be loaded + // `item` is the item who will be loaded + // `settings` is the `aciTree.options.ajax` object or an entry from `aciTree.options.dataSource` + ajaxHook: function(item, settings) { + // the default implementation changes the URL by adding the item ID at the end + settings.url += (item ? this.getId(item) : ''); + }, + // called after each item is created but before is inserted into the DOM + // `parent` is the parent item (can be empty) + // `item` is the new created item + // `itemData` is the object used to create the item + // `level` is the #0 based item level + itemHook: function(parent, item, itemData, level) { + // there is no default implementation + }, + // called for each item to serialize its value + // `item` is the tree item to be serialized + // `what` is the option telling what is being serialized + // `value` is the current serialized value (from the `item`, value type depending of `what`) + serialize: function(item, what, value) { + if (typeof what == 'object') { + return value; + } else { + // the default implementation uses a `|` (pipe) character to separate values + return '|' + value; + } + } + }; + + // aciTree plugin core + + var aciTree_core = { + // add extra data + __extend: function() { + $.extend(this._instance, { + queue: new this._queue(this, this._instance.options.queue) // the global tree queue + }); + $.extend(this._private, { + locked: false, // to tell the tree state + itemClone: {// keep a clone of the LI for faster tree item creation + }, + // timeouts for the loader + loaderHide: null, + loaderInterval: null, + // busy delay counter + delayBusy: 0 + }); + }, + // init the treeview + init: function(options) { + options = this._options(options); + // check if was init already + if (this.wasInit()) { + this._trigger(null, 'wasinit', options); + this._fail(null, options); + return; + } + // check if is locked + if (this.isLocked()) { + this._trigger(null, 'locked', options); + this._fail(null, options); + return; + } + // a way to cancel the operation + if (!this._trigger(null, 'beforeinit', options)) { + this._trigger(null, 'initfail', options); + this._fail(null, options); + return; + } + this._private.locked = true; + this._instance.jQuery.addClass('aciTree' + this._instance.index).attr('role', 'tree').on('click' + this._instance.nameSpace, '.aciTreeButton', this.proxy(function(e) { + // process click on button + var item = this.itemFrom(e.target); + // skip when busy + if (!this.isBusy(item)) { + // tree button pressed + this.toggle(item, { + collapse: this._instance.options.collapse, + expand: this._instance.options.expand, + unique: this._instance.options.unique + }); + } + })).on('mouseenter' + this._instance.nameSpace + ' mouseleave' + this._instance.nameSpace, '.aciTreePush', function(e) { + // handle the aciTreeHover class + var element = e.target; + if (!domApi.hasClass(element, 'aciTreePush')) { + element = domApi.parentByClass(element, 'aciTreePush'); + } + domApi.toggleClass(element, 'aciTreeHover', e.type == 'mouseenter'); + }).on('mouseenter' + this._instance.nameSpace + ' mouseleave' + this._instance.nameSpace, '.aciTreeLine', function(e) { + // handle the aciTreeHover class + var element = e.target; + if (!domApi.hasClass(element, 'aciTreeLine')) { + element = domApi.parentByClass(element, 'aciTreeLine'); + } + domApi.toggleClass(element, 'aciTreeHover', e.type == 'mouseenter'); + }); + this._initHook(); + // call on success + var success = this.proxy(function() { + // call the parent + this._super(); + this._private.locked = false; + this._trigger(null, 'init', options); + this._success(null, options); + }); + // call on fail + var fail = this.proxy(function() { + // call the parent + this._super(); + this._private.locked = false; + this._trigger(null, 'initfail', options); + this._fail(null, options); + }); + if (this._instance.options.rootData) { + // the rootData was set, use it to init the tree + this.loadFrom(null, this._inner(options, { + success: success, + fail: fail, + itemData: this._instance.options.rootData + })); + } else if (this._instance.options.ajax.url) { + // the AJAX url was set, init with AJAX + this.ajaxLoad(null, this._inner(options, { + success: success, + fail: fail + })); + } else { + success.apply(this); + } + }, + _initHook: function() { + // override this to do extra init + }, + // check locked state + isLocked: function() { + return this._private.locked; + }, + // get a formatted message + // `raw` is the raw message text (can contain %NUMBER sequences, replaced with values from `params`) + // `params` is a list of values to be replaced into the message (by #0 based index) + _format: function(raw, params) { + if (!(params instanceof Array)) { + return raw; + } + var parts = raw.split(/(%[0-9]+)/gm); + var compile = '', part, index, last = false, len; + var test = new window.RegExp('^%[0-9]+$'); + for (var i = 0; i < parts.length; i++) { + part = parts[i]; + len = part.length; + if (len) { + if (!last && test.test(part)) { + index = window.parseInt(part.substr(1)) - 1; + if ((index >= 0) && (index < params.length)) { + compile += params[index]; + continue; + } + } else { + last = false; + if (part.substr(len - 1) == '%') { + if (part.substr(len - 2) != '%%') { + last = true; + } + part = part.substr(0, len - 1); + } + } + compile += part; + } + } + return compile; + }, + // low level DOM functions + _coreDOM: { + // set as leaf node + leaf: function(items) { + domApi.addRemoveListClass(items.toArray(), 'aciTreeLeaf', ['aciTreeInode', 'aciTreeInodeMaybe', 'aciTreeOpen'], function(node) { + node.firstChild.removeAttribute('aria-expanded'); + }); + }, + // set as inner node + inode: function(items, branch) { + domApi.addRemoveListClass(items.toArray(), branch ? 'aciTreeInode' : 'aciTreeInodeMaybe', 'aciTreeLeaf', function(node) { + node.firstChild.setAttribute('aria-expanded', false); + }); + }, + // set as open/closed + toggle: function(items, state) { + domApi.toggleListClass(items.toArray(), 'aciTreeOpen', state, function(node) { + node.firstChild.setAttribute('aria-expanded', state); + }); + }, + // set odd/even classes + oddEven: function(items, odd) { + var list = items.toArray(); + for (var i = 0; i < list.length; i++) { + domApi.addRemoveClass(list[i], odd ? 'aciTreeOdd' : 'aciTreeEven', odd ? 'aciTreeEven' : 'aciTreeOdd'); + odd = !odd; + } + } + }, + // a small queue implementation + // `context` the context to be used with `callback.call` + // `options` are the queue options + _queue: function(context, options) { + var locked = false; + var fifo = [], fifoAsync = []; + var load = 0, loadAsync = 0, schedule = 0, stack = 0; + // run the queue + var run = function() { + if (locked) { + stack--; + return; + } + var now = new window.Date().getTime(); + if (schedule > now) { + stack--; + return; + } + var callback, async = false; + if (load < options.async * 2) { + // get the next synchronous callback + callback = fifo.shift(); + } + if (!callback && (loadAsync < options.async)) { + // get the next async callback + callback = fifoAsync.shift(); + async = true; + } + if (callback) { + // run the callback + if (async) { + loadAsync++; + callback.call(context, function() { + loadAsync--; + }); + if (stack < 40) { + stack++; + run(); + } + } else { + load++; + callback.call(context, function() { + if (now - schedule > options.interval) { + schedule = now + options.delay; + } + load--; + if (stack < 40) { + stack++; + run(); + } + }); + } + } + stack--; + }; + var interval = []; + // start the queue + var start = function() { + for (var i = 0; i < 4; i++) { + interval[i] = window.setInterval(function() { + if (stack < 20) { + stack++; + run(); + } + }, 10); + } + }; + // stop the queue + var stop = function() { + for (var i = 0; i < interval.length; i++) { + window.clearInterval(interval[i]); + } + }; + start(); + // init the queue + this.init = function() { + this.destroy(); + start(); + return this; + }; + // push `callback` function (complete) for later call + // `async` tells if is async callback + this.push = function(callback, async) { + if (!locked) { + if (async) { + fifoAsync.push(callback); + } else { + fifo.push(callback); + } + } + return this; + }; + // test if busy + this.busy = function() { + return (load != 0) || (loadAsync != 0) || (fifo.length != 0) || (fifoAsync.length != 0); + }; + // destroy queue + this.destroy = function() { + locked = true; + stop(); + fifo = []; + fifoAsync = []; + load = 0; + loadAsync = 0; + schedule = 0; + stack = 0; + locked = false; + return this; + }; + }, + // used with a `queue` to execute something at the end + // `endCallback` function (complete) is the callback called at the end + _task: function(queue, endCallback) { + var counter = 0, finish = false; + // push a `callback` function (complete) for later call + this.push = function(callback, async) { + counter++; + queue.push(function(complete) { + var context = this; + callback.call(this, function() { + counter--; + if ((counter < 1) && !finish) { + finish = true; + endCallback.call(context, complete); + } else { + complete(); + } + }); + }, async); + }; + }, + // helper function to extend the `options` object + // `object` the initial options object + // _success, _fail, _notify are callbacks or string (the event name to be triggered) + // `item` is the item to trigger events for + _options: function(object, _success, _fail, _notify, item) { + // options object (need to be in this form for all API functions + // that have the `options` parameter, not all properties are required) + var options = $.extend({ + uid: 'ui', + success: null, // success callback + fail: null, // fail callback + notify: null, // notify callback (internal use for when already in the requested state) + expand: this._instance.options.expand, // propagate (on open) + collapse: this._instance.options.collapse, // propagate (on close) + unique: this._instance.options.unique, // keep a single branch open (on open) + unanimated: false, // unanimated (open/close/toggle) + itemData: { + } // items data (object) or a list (array) of them (used when creating branches) + }, + object); + var success = _success ? ((typeof _success == 'string') ? function() { + this._trigger(item, _success, options); + } : _success) : null; + var fail = _fail ? ((typeof _fail == 'string') ? function() { + this._trigger(item, _fail, options); + } : _fail) : null; + var notify = _notify ? ((typeof _notify == 'string') ? function() { + this._trigger(item, _notify, options); + } : _notify) : null; + if (success) { + // success callback + if (object && object.success) { + options.success = function() { + success.apply(this, arguments); + object.success.apply(this, arguments); + }; + } else { + options.success = success; + } + } + if (fail) { + // fail callback + if (object && object.fail) { + options.fail = function() { + fail.apply(this, arguments); + object.fail.apply(this, arguments); + }; + } else { + options.fail = fail; + } + } + if (notify) { + // notify callback + if (object && object.notify) { + options.notify = function() { + notify.apply(this, arguments); + object.notify.apply(this, arguments); + }; + } else if (!options.notify && object && object.success) { + options.notify = function() { + notify.apply(this, arguments); + object.success.apply(this, arguments); + }; + } else { + options.notify = notify; + } + } else if (!options.notify && object && object.success) { + // by default, run success callback + options.notify = object.success; + } + return options; + }, + // helper for passing `options` object to inner methods + // the callbacks are removed and `override` can be used to update properties + _inner: function(options, override) { + // removing success/fail/notify from options + return $.extend({ + }, options, { + success: null, + fail: null, + notify: null + }, + override); + }, + // trigger the aciTree events on the tree container + _trigger: function(item, eventName, options) { + var event = $.Event('acitree'); + if (!options) { + options = this._options(); + } + this._instance.jQuery.trigger(event, [this, item, eventName, options]); + return !event.isDefaultPrevented(); + }, + // call on success + _success: function(item, options) { + if (options && options.success) { + options.success.call(this, item, options); + } + }, + // call on fail + _fail: function(item, options) { + if (options && options.fail) { + options.fail.call(this, item, options); + } + }, + // call on notify (should be same as `success` but called when already in the requested state) + _notify: function(item, options) { + if (options && options.notify) { + options.notify.call(this, item, options); + } + }, + // delay callback on busy item + _delayBusy: function(item, callback) { + if ((this._private.delayBusy < 10) && this.isBusy(item)) { + this._private.delayBusy++; + window.setTimeout(this.proxy(function() { + this._delayBusy.call(this, item, callback); + this._private.delayBusy--; + }), 10); + return; + } + callback.apply(this); + }, + // return the data source for item + // defaults to `aciTree.options.ajax` if not set on the item/his parents + _dataSource: function(item) { + var dataSource = this._instance.options.dataSource; + if (dataSource) { + var data = this.itemData(item); + if (data && data.source && dataSource[data.source]) { + return dataSource[data.source]; + } + var parent; + do { + parent = this.parent(item); + data = this.itemData(parent); + if (data && data.source && dataSource[data.source]) { + return dataSource[data.source]; + } + } while (parent.length); + } + return this._instance.options.ajax; + }, + // process item loading with AJAX + // `item` can be NULL to load the ROOT + // loaded data need to be array of item objects + // each item can have children (defined as `itemData.branch` - array of item data objects) + ajaxLoad: function(item, options) { + if (item && this.isBusy(item)) { + // delay the load if busy + this._delayBusy(item, function() { + this.ajaxLoad(item, options); + }); + return; + } + options = this._options(options, function() { + this._loading(item); + this._trigger(item, 'loaded', options); + }, function() { + this._loading(item); + this._trigger(item, 'loadfail', options); + }, function() { + this._loading(item); + this._trigger(item, 'wasloaded', options); + }); + if (!item || this.isInode(item)) { + // add the task to the queue + this._instance.queue.push(function(complete) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeload', options)) { + this._fail(item, options); + complete(); + return; + } + this._loading(item, true); + if (this.wasLoad(item)) { + // was load already + this._notify(item, options); + complete(); + return; + } + // ensure we work on a copy of the dataSource object + var settings = $.extend({ + }, this._dataSource(item)); + // call the `aciTree.options.ajaxHook` + this._instance.options.ajaxHook.call(this, item, settings); + // loaded data need to be array of item objects + settings.success = this.proxy(function(itemList) { + if (itemList && (itemList instanceof Array) && itemList.length) { + // the AJAX returned some items + var process = function() { + if (this.wasLoad(item)) { + this._notify(item, options); + complete(); + } else { + // create a branch from `itemList` + this._createBranch(item, this._inner(options, { + success: function() { + this._success(item, options); + complete(); + }, + fail: function() { + this._fail(item, options); + complete(); + }, + itemData: itemList + })); + } + }; + if (!item || this.isInode(item)) { + process.apply(this); + } else { + // change the item to inode, then load + this.setInode(item, this._inner(options, { + success: process, + fail: options.fail + })); + } + } else { + // the AJAX response was not just right (or not a inode) + var process = function() { + this._fail(item, options); + complete(); + }; + if (!item || this.isLeaf(item)) { + process.apply(this); + } else { + // change the item to leaf + this.setLeaf(item, this._inner(options, { + success: process, + fail: process + })); + } + } + }); + settings.error = this.proxy(function() { + // AJAX failed + this._fail(item, options); + complete(); + }); + $.ajax(settings); + }, true); + } else { + this._fail(item, options); + } + }, + // process item loading + // `item` can be NULL to load the ROOT + // `options.itemData` need to be array of item objects + // each item can have children (defined as `itemData.branch` - array of item data objects) + loadFrom: function(item, options) { + if (item && this.isBusy(item)) { + // delay the load if busy + this._delayBusy(item, function() { + this.loadFrom(item, options); + }); + return; + } + options = this._options(options, function() { + this._loading(item); + this._trigger(item, 'loaded', options); + }, function() { + this._loading(item); + this._trigger(item, 'loadfail', options); + }, function() { + this._loading(item); + this._trigger(item, 'wasloaded', options); + }); + if (!item || this.isInode(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeload', options)) { + this._fail(item, options); + return; + } + this._loading(item, true); + if (this.wasLoad(item)) { + // was load already + this._notify(item, options); + return; + } + // data need to be array of item objects + if (options.itemData && (options.itemData instanceof Array) && options.itemData.length) { + // create the branch from `options.itemData` + var process = function() { + if (this.wasLoad(item)) { + this._notify(item, options); + } else { + this._createBranch(item, options); + } + }; + if (!item || this.isInode(item)) { + process.apply(this); + } else { + // change the item to inode, then create children + this.setInode(item, this._inner(options, { + success: process, + fail: options.fail + })); + } + } else { + // this is not a inode + if (!item || this.isLeaf(item)) { + this._fail(item, options); + } else { + // change the item to leaf + this.setLeaf(item, this._inner(options, { + success: options.fail, + fail: options.fail + })); + } + } + } else { + this._fail(item, options); + } + }, + // unload item + // `item` can be NULL to unload the entire tree + unload: function(item, options) { + options = this._options(options, function() { + this._loading(item); + this._trigger(item, 'unloaded', options); + }, function() { + this._loading(item); + this._trigger(item, 'unloadfail', options); + }, function() { + this._loading(item); + this._trigger(item, 'notloaded', options); + }); + if (!item || this.isInode(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeunload', options)) { + this._fail(item, options); + return; + } + this._loading(item, true); + if (!this.wasLoad(item)) { + // if was not loaded + this._notify(item, options); + return; + } + // first check each children + var cancel = false; + var children = this.children(item, true, true); + children.each(this.proxy(function(element) { + var item = $(element); + if (this.isInode(item)) { + if (this.isOpen(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeclose', options)) { + cancel = true; + return false; + } + } + if (this.wasLoad(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeunload', options)) { + cancel = true; + return false; + } + } + } + // a way to cancel the operation + if (!this._trigger(item, 'beforeremove', options)) { + cancel = true; + return false; + } + }, true)); + if (cancel) { + // it was canceled + this._fail(item, options); + return; + } + var process = function() { + children.each(this.proxy(function(element) { + // trigger the events before DOM changes + var item = $(element); + if (this.isInode(item)) { + if (this.isOpen(item)) { + this._trigger(item, 'closed', options); + } + if (this.wasLoad(item)) { + this._trigger(item, 'unloaded', options); + } + } + this._trigger(item, 'removed', options); + }, true)); + }; + // process the child remove + if (item) { + if (this.isOpen(item)) { + // first close the item, then remove children + this.close(item, this._inner(options, { + success: function() { + process.call(this); + this._removeContainer(item); + this._success(item, options); + }, + fail: options.fail + })); + } else { + process.call(this); + this._removeContainer(item); + this._success(item, options); + } + } else { + // unload the ROOT + this._animate(item, false, !this._instance.options.animateRoot || options.unanimated, function() { + process.call(this); + this._removeContainer(); + this._success(item, options); + }); + } + } else { + this._fail(item, options); + } + }, + // remove item + remove: function(item, options) { + if (this.isItem(item)) { + if (this.hasSiblings(item, true)) { + options = this._options(options, function() { + if (this.isOpenPath(item)) { + // if the parents are opened (visible) update the item states + domApi.removeClass(item[0], 'aciTreeVisible'); + this._setOddEven(item); + } + this._trigger(item, 'removed', options); + }, 'removefail', null, item); + // a way to cancel the operation + if (!this._trigger(item, 'beforeremove', options)) { + this._fail(item, options); + return; + } + if (this.wasLoad(item)) { + // unload the inode then remove + this.unload(item, this._inner(options, { + success: function() { + this._success(item, options); + this._removeItem(item); + }, + fail: options.fail + })); + } else { + // just remove the item + this._success(item, options); + this._removeItem(item); + } + } else { + var parent = this.parent(item); + if (parent.length) { + this.setLeaf(parent, options); + } else { + this.unload(null, options); + } + } + } else { + this._trigger(item, 'removefail', options) + this._fail(item, options); + } + }, + // open item children + _openChildren: function(item, options) { + if (options.expand) { + var queue = this._instance.queue; + // process the children inodes + this.inodes(this.children(item)).each(function() { + var item = $(this); + // queue node opening + queue.push(function(complete) { + this.open(item, this._inner(options)); + complete(); + }); + }); + queue.push(function(complete) { + this._success(item, options); + complete(); + }); + } else { + this._success(item, options); + } + }, + // process item open + _openItem: function(item, options) { + if (!options.unanimated && !this.isVisible(item)) { + options.unanimated = true; + } + if (options.unique) { + // close other opened nodes + this.closeOthers(item); + options.unique = false; + } + // open the node + this._coreDOM.toggle(item, true); + // (temporarily) update children states + this._setOddEvenChildren(item); + this._animate(item, true, options.unanimated, function() { + this._openChildren(item, options); + }); + }, + // open item and his children if requested + open: function(item, options) { + options = this._options(options, function() { + if (this.isOpenPath(item)) { + // if all parents are open, update the items after + this._updateVisible(item); + this._setOddEven(item); + } + this._trigger(item, 'opened', options); + }, 'openfail', 'wasopened', item); + if (this.isInode(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeopen', options)) { + this._fail(item, options); + return; + } + if (this.isOpen(item)) { + options.success = options.notify; + // propagate/open children (if required) + this._openChildren(item, options); + } else { + if (this.wasLoad(item)) { + this._openItem(item, options); + } else { + // try to load the node, then open + this.ajaxLoad(item, this._inner(options, { + success: function() { + this._openItem(item, options); + }, + fail: options.fail + })); + } + } + } else { + this._fail(item, options); + } + }, + // close item children + _closeChildren: function(item, options) { + if (this._instance.options.empty) { + // unload on close + options.unanimated = true; + this.unload(item, options); + } else if (options.collapse) { + var queue = this._instance.queue; + // process the children inodes + this.inodes(this.children(item)).each(function() { + var item = $(this); + // queue node close + queue.push(function(complete) { + this.close(item, this._inner(options, { + unanimated: true + })); + complete(); + }); + }); + queue.push(function(complete) { + this._success(item, options); + complete(); + }); + } else { + this._success(item, options); + } + }, + // process item close + _closeItem: function(item, options) { + if (!options.unanimated && !this.isVisible(item)) { + options.unanimated = true; + } + // close the item + this._coreDOM.toggle(item, false); + this._animate(item, false, options.unanimated, function() { + this._closeChildren(item, options); + }); + }, + // close item and his children if requested + close: function(item, options) { + options = this._options(options, function() { + if (this.isOpenPath(item)) { + // if all parents are open, update the items after + this._updateVisible(item); + this._setOddEven(item); + } + this._trigger(item, 'closed', options); + }, 'closefail', 'wasclosed', item); + if (this.isInode(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeclose', options)) { + this._fail(item, options); + return; + } + if (this.isOpen(item)) { + this._closeItem(item, options); + } else if (this.wasLoad(item)) { + options.success = options.notify; + // propagate/close/empty children (if required) + this._closeChildren(item, options); + } else { + this._notify(item, options); + } + } else { + this._fail(item, options); + } + }, + // update visible state + _updateVisible: function(item) { + if (this.isOpenPath(item)) { + if (!this.isHidden(item)) { + // if open parents and not hidden + domApi.addClass(item[0], 'aciTreeVisible'); + if (this.isOpen(item)) { + // process children + domApi.children(item[0], false, this.proxy(function(node) { + if (!domApi.hasClass(node, 'aciTreeVisible')) { + this._updateVisible($(node)); + } + })); + } else { + // children are not visible + domApi.children(item[0], true, function(node) { + return domApi.removeClass(node, 'aciTreeVisible') ? true : null; + }); + } + } + } else if (domApi.removeClass(item[0], 'aciTreeVisible')) { + domApi.children(item[0], true, function(node) { + return domApi.removeClass(node, 'aciTreeVisible') ? true : null; + }); + } + }, + // keep just one branch open + closeOthers: function(item, options) { + options = this._options(options); + if (this.isItem(item)) { + var queue = this._instance.queue; + // exclude the item and his parents + var exclude = item.add(this.path(item)).add(this.children(item, true)); + // close all other open nodes + this.inodes(this.children(null, true, true), true).not(exclude).each(function() { + var item = $(this); + // add node to close queue + queue.push(function(complete) { + this.close(item, this._inner(options)); + complete(); + }); + }); + queue.push(function(complete) { + this._success(item, options); + complete(); + }); + } else { + this._fail(item, options); + } + }, + // toggle item + toggle: function(item, options) { + options = this._options(options, 'toggled', 'togglefail', null, item); + if (this.isInode(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforetoggle', options)) { + this._fail(item, options); + return; + } + if (this.isOpen(item)) { + this.close(item, options); + } else { + this.open(item, options); + } + } else { + this._fail(item, options); + } + }, + // get item path starting from the top parent (ROOT) + // when `reverse` is TRUE returns the path in reverse order + path: function(item, reverse) { + if (item) { + var parent = item[0], list = []; + while (parent = domApi.parent(parent)) { + list.push(parent); + } + return reverse ? $(list) : $(list.reverse()); + } + return $([]); + }, + // test if item is in view + // when `center` is TRUE will test if is centered in view + isVisible: function(item, center) { + if (item && domApi.hasClass(item[0], 'aciTreeVisible')) { + // the item path need to be open + var rect = this._instance.jQuery[0].getBoundingClientRect(); + var size = item[0].firstChild; + var test = size.getBoundingClientRect(); + var height = size.offsetHeight; + var offset = center ? (rect.bottom - rect.top) / 2 : 0; + if ((test.bottom - height < rect.top + offset) || (test.top + height > rect.bottom - offset)) { + // is out of view + return false; + } + return true; + } + return false; + }, + // open path to item + openPath: function(item, options) { + options = this._options(options); + if (this.isItem(item)) { + var queue = this._instance.queue; + // process closed inodes + this.inodes(this.path(item), false).each(function() { + var item = $(this); + // add node to open queue + queue.push(function(complete) { + this.open(item, this._inner(options)); + complete(); + }); + }); + queue.push(function(complete) { + this._success(item, options); + complete(); + }); + } else { + this._fail(item, options); + } + }, + // test if path to item is open + isOpenPath: function(item) { + var parent = this.parent(item); + return parent[0] ? this.isOpen(parent) && domApi.hasClass(parent[0], 'aciTreeVisible') : true; + }, + // get animation speed vs. offset size + // `speed` is the raw speed + // `totalSize` is the available size + // `required` is the offset used for calculations + _speedFraction: function(speed, totalSize, required) { + if ((required < totalSize) && totalSize) { + var numeric = parseInt(speed); + if (isNaN(numeric)) { + // predefined string values + switch (speed) { + case 'slow': + numeric = 600; + break; + case 'medium': + numeric = 400; + break; + case 'fast': + numeric = 200; + break; + default: + return speed; + } + } + return numeric * required / totalSize; + } + return speed; + }, + // bring item in view + // `options.center` says if should be centered in view + setVisible: function(item, options) { + options = this._options(options, 'visible', 'visiblefail', 'wasvisible', item); + if (this.isItem(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforevisible', options)) { + this._fail(item, options); + return; + } + if (this.isVisible(item)) { + // is visible already + this._notify(item, options); + return; + } + var process = function() { + // compute position with getBoundingClientRect + var rect = this._instance.jQuery[0].getBoundingClientRect(); + var size = item[0].firstChild; + var test = size.getBoundingClientRect(); + var height = size.offsetHeight; + var offset = options.center ? (rect.bottom - rect.top) / 2 : 0; + if (test.bottom - height < rect.top + offset) { + // item somewhere before the first visible + var diff = rect.top + offset - test.bottom + height; + if (!options.unanimated && this._instance.options.view) { + this._instance.jQuery.stop(true).animate({ + scrollTop: this._instance.jQuery.scrollTop() - diff + }, + { + duration: this._speedFraction(this._instance.options.view.duration, rect.bottom - rect.top, diff), + easing: this._instance.options.view.easing, + complete: this.proxy(function() { + this._success(item, options); + }) + }); + } else { + this._instance.jQuery.stop(true)[0].scrollTop = this._instance.jQuery.scrollTop() - diff; + this._success(item, options); + } + } else if (test.top + height > rect.bottom - offset) { + // item somewhere after the last visible + var diff = test.top - rect.bottom + offset + height; + if (!options.unanimated && this._instance.options.view) { + this._instance.jQuery.stop(true).animate({ + scrollTop: this._instance.jQuery.scrollTop() + diff + }, + { + duration: this._speedFraction(this._instance.options.view.duration, rect.bottom - rect.top, diff), + easing: this._instance.options.view.easing, + complete: this.proxy(function() { + this._success(item, options); + }) + }); + } else { + this._instance.jQuery.stop(true)[0].scrollTop = this._instance.jQuery.scrollTop() + diff; + this._success(item, options); + } + } else { + this._success(item, options); + } + }; + if (this.hasParent(item)) { + // first we need to open the path to item + this.openPath(item, this._inner(options, { + success: process, + fail: options.fail + })); + } else { + process.apply(this); + } + } else { + this._fail(item, options); + } + }, + // test if item has parent + hasParent: function(item) { + return this.parent(item).length > 0; + }, + // get item parent + parent: function(item) { + return item ? $(domApi.parent(item[0])) : $([]); + }, + // get item top (ROOT) parent + topParent: function(item) { + return this.path(item).eq(0); + }, + // create tree branch + // `options.itemData` need to be in the same format as for .append + _createBranch: function(item, options) { + var total = 0; + var count = function(itemList) { + var itemData; + for (var i = 0; i < itemList.length; i++) { + itemData = itemList[i]; + if (itemData.branch && (itemData.branch instanceof Array) && itemData.branch.length) { + count(itemData.branch); + } + } + total++; + }; + count(options.itemData); + var index = 0; + var complete = this.proxy(function() { + index++; + if (index >= total) { + this._success(item, options); + } + }); + var process = this.proxy(function(node, itemList) { + if (node) { + // set it as a inode + domApi.addRemoveClass(node[0], 'aciTreeInode', 'aciTreeInodeMaybe'); + } + // use .append to add new items + this.append(node, this._inner(options, { + success: function(item, options) { + var itemData; + for (var i = 0; i < options.itemData.length; i++) { + itemData = options.itemData[i]; + // children need to be array of item objects + if (itemData.branch && (itemData.branch instanceof Array) && itemData.branch.length) { + process(options.items.eq(i), itemData.branch); + } + if (itemData.open) { + // open the item is requuested + this.open(options.items.eq(i), this._inner(options, { + itemData: null, + items: null + })); + } + } + complete(); + }, + fail: options.fail, + itemData: itemList + })); + }); + process(item, options.itemData); + }, + // get first/last items + _getFirstLast: function(parent) { + if (!parent) { + parent = this._instance.jQuery; + } + return $(domApi.withAnyClass(domApi.children(parent[0]), ['aciTreeFirst', 'aciTreeLast'])); + }, + // update first/last items + _setFirstLast: function(parent, clear) { + if (clear) { + domApi.removeListClass(clear.toArray(), ['aciTreeFirst', 'aciTreeLast']); + } + var first = this.first(parent); + if (first[0]) { + domApi.addClass(first[0], 'aciTreeFirst'); + domApi.addClass(this.last(parent)[0], 'aciTreeLast'); + } + }, + // update odd/even state + _setOddEven: function(items) { + // consider only visible items + var visible; + if (this._instance.jQuery[0].getElementsByClassName) { + visible = this._instance.jQuery[0].getElementsByClassName('aciTreeVisible'); + visible = visible ? window.Array.prototype.slice.call(visible) : []; + } else { + visible = $(domApi.children(this._instance.jQuery[0], true, function(node) { + return this.hasClass(node, 'aciTreeVisible') ? true : null; + })); + } + var odd = true; + if (visible.length) { + var index = 0; + if (items) { + // search the item to start with (by index) + items.each(function() { + if (visible.indexOf) { + var found = visible.indexOf(this); + if (found != -1) { + index = window.Math.min(found, index); + } + } else { + for (var i = 0; i < visible.length; i++) { + if (visible[i] === this) { + index = window.Math.min(i, index); + break; + } + } + } + }); + index = window.Math.max(index - 1, 0); + } + if (index > 0) { + // determine with what to start with (odd/even) + var first = visible[index]; + if (domApi.hasClass(first, 'aciTreOdd')) { + odd = false; + } + // process only after index + visible = visible.slice(index + 1); + } + } + this._coreDOM.oddEven($(visible), odd); + }, + // update odd/even state for direct children + _setOddEvenChildren: function(item) { + var odd = domApi.hasClass(item[0], 'aciTreeOdd'); + var children = this.children(item); + this._coreDOM.oddEven(children, !odd); + }, + // process item before inserting into the DOM + _itemHook: function(parent, item, itemData, level) { + if (this._instance.options.itemHook) { + this._instance.options.itemHook.apply(this, arguments); + } + }, + // create item by `itemData` + // `level` is the #0 based item level + _createItem: function(itemData, level) { + if (this._private.itemClone[level]) { + var li = this._private.itemClone[level].cloneNode(true); + var line = li.firstChild; + var icon = line; + for (var i = 0; i < level; i++) { + icon = icon.firstChild; + } + icon = icon.firstChild.lastChild.firstChild; + var text = icon.nextSibling; + } else { + var li = window.document.createElement('LI'); + li.setAttribute('role', 'presentation'); + var line = window.document.createElement('DIV'); + li.appendChild(line); + line.setAttribute('tabindex', -1); + line.setAttribute('role', 'treeitem'); + line.setAttribute('aria-selected', false); + line.className = 'aciTreeLine'; + var last = line, branch; + for (var i = 0; i < level; i++) { + branch = window.document.createElement('DIV'); + last.appendChild(branch); + branch.className = 'aciTreeBranch aciTreeLevel' + i; + last = branch; + } + var entry = window.document.createElement('DIV'); + last.appendChild(entry); + entry.className = 'aciTreeEntry'; + var button = window.document.createElement('SPAN'); + entry.appendChild(button); + button.className = 'aciTreeButton'; + var push = window.document.createElement('SPAN'); + button.appendChild(push); + push.className = 'aciTreePush'; + push.appendChild(window.document.createElement('SPAN')); + var item = window.document.createElement('SPAN'); + entry.appendChild(item); + item.className = 'aciTreeItem'; + var icon = window.document.createElement('SPAN'); + item.appendChild(icon); + var text = window.document.createElement('SPAN'); + item.appendChild(text); + text.className = 'aciTreeText'; + this._private.itemClone[level] = li.cloneNode(true); + } + li.className = 'aciTreeLi' + (itemData.inode || (itemData.inode === null) ? (itemData.inode || (itemData.branch && itemData.branch.length) ? ' aciTreeInode' : ' aciTreeInodeMaybe') : ' aciTreeLeaf') + ' aciTreeLevel' + level + (itemData.disabled ? ' aciTreeDisabled' : ''); + line.setAttribute('aria-level', level + 1); + if (itemData.inode || (itemData.inode === null)) { + line.setAttribute('aria-expanded', false); + } + if (itemData.icon) { + if (itemData.icon instanceof Array) { + icon.className = 'aciTreeIcon ' + itemData.icon[0]; + icon.style.backgroundPosition = itemData.icon[1] + 'px ' + itemData.icon[2] + 'px'; + } else { + icon.className = 'aciTreeIcon ' + itemData.icon; + } + } else { + icon.parentNode.removeChild(icon); + } + text.innerHTML = itemData.label; + var $li = $(li); + $li.data('itemData' + this._instance.nameSpace, $.extend({ + }, itemData, { + branch: itemData.branch && itemData.branch.length + })); + return $li; + }, + // remove item + _removeItem: function(item) { + var parent = this.parent(item); + item.remove(); + // update sibling state + this._setFirstLast(parent.length ? parent : null); + }, + // create & add one or more items + // `ul`, `before` and `after` are set depending on the caller + // `itemData` need to be array of objects or just an object (one item) + // `level` is the #0 based level + // `callback` function (items) is called at the end of the operation + _createItems: function(ul, before, after, itemData, level, callback) { + var items = [], fragment = window.document.createDocumentFragment(); + var task = new this._task(this._instance.queue, function(complete) { + items = $(items); + if (items.length) { + // add the new items + if (ul) { + ul[0].appendChild(fragment); + } else if (before) { + before[0].parentNode.insertBefore(fragment, before[0]); + } else if (after) { + after[0].parentNode.insertBefore(fragment, after[0].nextSibling); + } + } + callback.call(this, items); + complete(); + }); + if (itemData) { + this._loader(true); + var parent; + if (ul) { + parent = this.itemFrom(ul); + } else if (before) { + parent = this.parent(before); + } else if (after) { + parent = this.parent(after); + } + if (itemData instanceof Array) { + // this is a list of items + for (var i = 0; i < itemData.length; i++) { + (function(itemData) { + task.push(function(complete) { + var item = this._createItem(itemData, level); + this._itemHook(parent, item, itemData, level); + fragment.appendChild(item[0]); + items.push(item[0]); + complete(); + }); + })(itemData[i]); + } + } else { + task.push(function(complete) { + // only one item + var item = this._createItem(itemData, level); + this._itemHook(parent, item, itemData, level); + fragment.appendChild(item[0]); + items.push(item[0]); + complete(); + }); + } + } + // run at least once + task.push(function(complete) { + complete(); + }); + }, + // create children container + _createContainer: function(item) { + if (!item) { + item = this._instance.jQuery; + } + // ensure we have a UL in place + var ul = domApi.container(item[0]); + if (!ul) { + var ul = window.document.createElement('UL'); + ul.setAttribute('role', 'group'); + ul.className = 'aciTreeUl'; + ul.style.display = 'none'; + item[0].appendChild(ul); + } + return $(ul); + }, + // remove children container + _removeContainer: function(item) { + if (!item) { + item = this._instance.jQuery; + } + var ul = domApi.container(item[0]); + ul.parentNode.removeChild(ul); + }, + // append one or more items to item + // `options.itemData` can be a item object or array of item objects + // `options.items` will keep a list of added items + append: function(item, options) { + options = this._options(options, 'appended', 'appendfail', null, item); + if (item) { + if (this.isInode(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeappend', options)) { + this._fail(item, options); + return; + } + var container = this._createContainer(item); + var last = this.last(item); + this._createItems(container, null, null, options.itemData, this.level(item) + 1, function(list) { + if (list.length) { + // some items created, update states + domApi.addRemoveClass(item[0], 'aciTreeInode', 'aciTreeInodeMaybe'); + this._setFirstLast(item, last); + if (this.isHidden(item)) { + domApi.addListClass(list.toArray(), 'aciTreeHidden'); + } else if (this.isOpenPath(item) && this.isOpen(item)) { + domApi.addListClass(list.toArray(), 'aciTreeVisible'); + this._setOddEven(list.first()); + } + // trigger `added` for each item + list.each(this.proxy(function(element) { + this._trigger($(element), 'added', options); + }, true)); + } else if (!this.hasChildren(item, true)) { + container.remove(); + } + options.items = list; + this._success(item, options); + }); + } else { + this._fail(item, options); + } + } else { + // a way to cancel the operation + if (!this._trigger(item, 'beforeappend', options)) { + this._fail(item, options); + return; + } + var container = this._createContainer(); + var last = this.last(); + this._createItems(container, null, null, options.itemData, 0, function(list) { + if (list.length) { + // some items created, update states + this._setFirstLast(null, last); + domApi.addListClass(list.toArray(), 'aciTreeVisible'); + this._setOddEven(); + // trigger `added` for each item + list.each(this.proxy(function(element) { + this._trigger($(element), 'added', options); + }, true)); + this._animate(null, true, !this._instance.options.animateRoot || options.unanimated); + } else if (!this.hasChildren(null, true)) { + // remove the children container + container.remove(); + } + options.items = list; + this._success(item, options); + }); + } + }, + // insert one or more items before item + // `options.itemData` can be a item object or array of item objects + // `options.items` will keep a list of added items + before: function(item, options) { + options = this._options(options, 'before', 'beforefail', null, item); + if (this.isItem(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforebefore', options)) { + this._fail(item, options); + return; + } + var prev = this.prev(item); + this._createItems(null, item, null, options.itemData, this.level(item), function(list) { + if (list.length) { + // some items created, update states + if (!prev.length) { + domApi.removeClass(item[0], 'aciTreeFirst'); + domApi.addClass(list.first()[0], 'aciTreeFirst'); + } + var parent = this.parent(item); + if (parent.length && this.isHidden(parent)) { + domApi.addListClass(list.toArray(), 'aciTreeHidden'); + } else if (this.isOpenPath(item)) { + domApi.addListClass(list.toArray(), 'aciTreeVisible'); + this._setOddEven(list.first()); + } + // trigger `added` for each item + list.each(this.proxy(function(element) { + this._trigger($(element), 'added', options); + }, true)); + } + options.items = list; + this._success(item, options); + }); + } else { + this._fail(item, options); + } + }, + // insert one or more items after item + // `options.itemData` can be a item object or array of item objects + // `options.items` will keep a list of added items + after: function(item, options) { + options = this._options(options, 'after', 'afterfail', null, item); + if (this.isItem(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeafter', options)) { + this._fail(item, options); + return; + } + var next = this.next(item); + this._createItems(null, null, item, options.itemData, this.level(item), function(list) { + if (list.length) { + // some items created, update states + if (!next.length) { + domApi.removeClass(item[0], 'aciTreeLast'); + domApi.addClass(list.last()[0], 'aciTreeLast'); + } + var parent = this.parent(item); + if (parent.length && this.isHidden(parent)) { + domApi.addListClass(list.toArray(), 'aciTreeHidden'); + } else if (this.isOpenPath(item)) { + domApi.addListClass(list.toArray(), 'aciTreeVisible'); + this._setOddEven(list.first()); + } + // trigger `added` for each item + list.each(this.proxy(function(element) { + this._trigger($(element), 'added', options); + }, true)); + } + options.items = list; + this._success(item, options); + }); + } else { + this._fail(item, options); + } + }, + // get item having the element + itemFrom: function(element) { + if (element) { + var item = $(element); + if (item[0] === this._instance.jQuery[0]) { + return $([]); + } else { + return $(domApi.parentFrom(item[0])); + } + } + return $([]); + }, + // get item children + // if `branch` is TRUE then all children are returned + // if `hidden` is TRUE then the hidden items will be considered too + children: function(item, branch, hidden) { + return $(domApi.children(item && item[0] ? item[0] : this._instance.jQuery[0], branch, hidden ? null : function(node) { + return this.hasClass(node, 'aciTreeHidden') ? null : true; + })); + }, + // filter only the visible items (items with all parents opened) + // if `view` is TRUE then only the items in view are returned + visible: function(items, view) { + var list = domApi.withClass(items.toArray(), 'aciTreeVisible'); + if (view) { + var filter = []; + for (var i = 0; i < list.length; i++) { + if (this.isVisible($(list[i]))) { + filter.push(list[i]); + } + } + return $(filter); + } + return $(list); + }, + // filter only inner nodes from items + // if `state` is set then filter only open/closed ones + inodes: function(items, state) { + if (state !== undefined) { + if (state) { + return $(domApi.withClass(items.toArray(), 'aciTreeOpen')); + } else { + return $(domApi.withAnyClass(items.toArray(), ['aciTreeInode', 'aciTreeInodeMaybe'], 'aciTreeOpen')); + } + } + return $(domApi.withAnyClass(items.toArray(), ['aciTreeInode', 'aciTreeInodeMaybe'])); + }, + // filter only leaf nodes from items + leaves: function(items) { + return $(domApi.withClass(items.toArray(), 'aciTreeLeaf')); + }, + // test if is a inner node + isInode: function(item) { + return item && domApi.hasAnyClass(item[0], ['aciTreeInode', 'aciTreeInodeMaybe']); + }, + // test if is a leaf node + isLeaf: function(item) { + return item && domApi.hasClass(item[0], 'aciTreeLeaf'); + }, + // test if item was loaded + wasLoad: function(item) { + if (item) { + return domApi.container(item[0]) !== null; + } + return domApi.container(this._instance.jQuery[0]) !== null; + }, + // set item as inner node + setInode: function(item, options) { + options = this._options(options, 'inodeset', 'inodefail', 'wasinode', item); + if (this.isItem(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeinode', options)) { + this._fail(item, options); + return; + } + if (this.isLeaf(item)) { + this._coreDOM.inode(item, true); + this._success(item, options); + } else { + this._notify(item, options); + } + } else { + this._fail(item, options); + } + }, + // set item as leaf node + setLeaf: function(item, options) { + options = this._options(options, 'leafset', 'leaffail', 'wasleaf', item); + if (this.isItem(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeleaf', options)) { + this._fail(item, options); + return; + } + if (this.isInode(item)) { + var process = function() { + this._coreDOM.leaf(item); + this._success(item, options); + }; + if (this.wasLoad(item)) { + // first unload the node + this.unload(item, this._inner(options, { + success: process, + fail: options.fail + })); + } else { + process.apply(this); + } + } else { + this._notify(item, options); + } + } else { + this._fail(item, options); + } + }, + // add/update item icon + // `options.icon` can be the CSS class name or array['CSS class name', background-position-x, background-position-y] + // `options.oldIcon` will keep the old icon + addIcon: function(item, options) { + options = this._options(options, 'iconadded', 'addiconfail', 'wasicon', item); + if (this.isItem(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeaddicon', options)) { + this._fail(item, options); + return; + } + var data = this.itemData(item); + // keep the old one + options.oldIcon = data.icon; + var parent = domApi.childrenByClass(item[0].firstChild, 'aciTreeItem'); + var found = domApi.childrenByClass(parent, 'aciTreeIcon'); + if (found && data.icon && (options.icon.toString() == data.icon.toString())) { + this._notify(item, options); + } else { + if (!found) { + found = window.document.createElement('DIV'); + parent.insertBefore(found, parent.firstChild); + } + if (options.icon instanceof Array) { + // icon with background-position + found.className = 'aciTreeIcon ' + options.icon[0]; + found.style.backgroundPosition = options.icon[1] + 'px ' + options.icon[2] + 'px'; + } else { + // only the CSS class name + found.className = 'aciTreeIcon ' + options.icon; + } + // remember this one + data.icon = options.icon; + this._success(item, options); + } + } else { + this._fail(item, options); + } + }, + // remove item icon + // options.oldIcon will keep the old icon + removeIcon: function(item, options) { + options = this._options(options, 'iconremoved', 'removeiconfail', 'noticon', item); + if (this.isItem(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeremoveicon', options)) { + this._fail(item, options); + return; + } + var data = this.itemData(item); + // keep the old one + options.oldIcon = data.icon; + var parent = domApi.childrenByClass(item[0].firstChild, 'aciTreeItem'); + var found = domApi.childrenByClass(parent, 'aciTreeIcon'); + if (found) { + parent.removeChild(found); + // remember was removed + data.icon = null; + this._success(item, options); + } else { + this._notify(item, options); + } + } else { + this._fail(item, options); + } + }, + // test if item has icon + hasIcon: function(item) { + return !!this.getIcon(item); + }, + // get item icon + getIcon: function(item) { + var data = this.itemData(item); + return data ? data.icon : null; + }, + // set item label + // `options.label` is the new label + // `options.oldLabel` will keep the old label + setLabel: function(item, options) { + options = this._options(options, 'labelset', 'labelfail', 'waslabel', item); + if (this.isItem(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforelabel', options)) { + this._fail(item, options); + return; + } + var data = this.itemData(item); + // keep the old one + options.oldLabel = data.label; + if (options.label == options.oldLabel) { + this._notify(item, options); + } else { + // set the label + domApi.childrenByClass(item[0].firstChild, 'aciTreeText').innerHTML = options.label; + // remember this one + data.label = options.label; + this._success(item, options); + } + } else { + this._fail(item, options); + } + }, + // disable item + disable: function(item, options) { + options = this._options(options, 'disabled', 'disablefail', 'wasdisabled', item); + if (this.isItem(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforedisable', options)) { + this._fail(item, options); + return; + } + if (this.isDisabled(item)) { + this._notify(item, options); + } else { + domApi.addClass(item[0], 'aciTreeDisabled'); + this._success(item, options); + } + } else { + this._fail(item, options); + } + }, + // test if item is disabled + isDisabled: function(item) { + return item && domApi.hasClass(item[0], 'aciTreeDisabled'); + }, + // test if any of parents are disabled + isDisabledPath: function(item) { + return domApi.withClass(this.path(item).toArray(), 'aciTreeDisabled').length > 0; + }, + // filter only the disabled items + disabled: function(items) { + return $(domApi.withClass(items.toArray(), 'aciTreeDisabled')); + }, + // enable item + enable: function(item, options) { + options = this._options(options, 'enabled', 'enablefail', 'wasenabled', item); + if (this.isItem(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeenable', options)) { + this._fail(item, options); + return; + } + if (this.isDisabled(item)) { + domApi.removeClass(item[0], 'aciTreeDisabled'); + this._success(item, options); + } else { + this._notify(item, options); + } + } else { + this._fail(item, options); + } + }, + // test if item is enabled + isEnabled: function(item) { + return item && !domApi.hasClass(item[0], 'aciTreeDisabled'); + }, + // test if all parents are enabled + isEnabledPath: function(item) { + return domApi.withClass(this.path(item).toArray(), 'aciTreeDisabled').length == 0; + }, + // filter only the enabled items + enabled: function(items) { + return $(domApi.withClass(items.toArray(), null, 'aciTreeDisabled')); + }, + // set item as hidden + hide: function(item, options) { + options = this._options(options, 'hidden', 'hidefail', 'washidden', item); + if (this.isItem(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforehide', options)) { + this._fail(item, options); + return; + } + if (this.isHidden(item)) { + this._notify(item, options); + } else { + domApi.addRemoveClass(item[0], 'aciTreeHidden', 'aciTreeVisible'); + // process children + domApi.addRemoveClass(this.children(item, true).toArray(), 'aciTreeHidden', 'aciTreeVisible'); + // update item states + var parent = this.parent(item); + this._setFirstLast(parent.length ? parent : null, item); + this._setOddEven(item); + this._success(item, options); + } + } else { + this._fail(item, options); + } + }, + // test if item is hidden + isHidden: function(item) { + return item && domApi.hasClass(item[0], 'aciTreeHidden'); + }, + // test if any of parents are hidden + isHiddenPath: function(item) { + var parent = this.parent(item); + return parent[0] && domApi.hasClass(parent[0], 'aciTreeHidden'); + }, + // update hidden state + _updateHidden: function(item) { + if (this.isHiddenPath(item)) { + if (!this.isHidden(item)) { + domApi.addClass(item[0], 'aciTreeHidden'); + this._updateVisible(item); + } + } else { + this._updateVisible(item); + } + }, + // filter only the hidden items + hidden: function(items) { + return $(domApi.withClass(items.toArray(), 'aciTreeHidden')); + }, + // show hidden item + _showHidden: function(item) { + var parent = null; + this.path(item).add(item).each(this.proxy(function(element) { + var item = $(element); + if (this.isHidden(item)) { + domApi.removeClass(item[0], 'aciTreeHidden'); + if (this.isOpenPath(item) && (!parent || this.isOpen(parent))) { + domApi.addClass(item[0], 'aciTreeVisible'); + } + // update item states + this._setFirstLast(parent, this._getFirstLast(parent)); + } + parent = item; + }, true)); + }, + // show hidden item + show: function(item, options) { + options = this._options(options, 'shown', 'showfail', 'wasshown', item); + if (this.isItem(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeshow', options)) { + this._fail(item, options); + return; + } + if (this.isHidden(item)) { + this._showHidden(item); + var parent = this.topParent(item); + // update item states + this._setOddEven(parent.length ? parent : item); + this._success(item, options); + } else { + this._notify(item, options); + } + } else { + this._fail(item, options); + } + }, + // test if item is open + isOpen: function(item) { + return item && domApi.hasClass(item[0], 'aciTreeOpen'); + }, + // test if item is closed + isClosed: function(item) { + return item && !domApi.hasClass(item[0], 'aciTreeOpen'); + }, + // test if item has children + // if `hidden` is TRUE then the hidden items will be considered too + hasChildren: function(item, hidden) { + return this.children(item, false, hidden).length > 0; + }, + // test if item has siblings + // if `hidden` is TRUE then the hidden items will be considered too + hasSiblings: function(item, hidden) { + return this.siblings(item, hidden).length > 0; + }, + // test if item has another before + // if `hidden` is TRUE then the hidden items will be considered too + hasPrev: function(item, hidden) { + return this.prev(item, hidden).length > 0; + }, + // test if item has another after + // if `hidden` is TRUE then the hidden items will be considered too + hasNext: function(item, hidden) { + return this.next(item, hidden).length > 0; + }, + // get item siblings + // if `hidden` is TRUE then the hidden items will be considered too + siblings: function(item, hidden) { + return item ? $(domApi.children(item[0].parentNode.parentNode, false, function(node) { + return (node != item[0]) && (hidden || !this.hasClass(node, 'aciTreeHidden')); + })) : $([]); + }, + // get previous item + // if `hidden` is TRUE then the hidden items will be considered too + prev: function(item, hidden) { + return item ? $(domApi.prev(item[0], hidden ? null : function(node) { + return !this.hasClass(node, 'aciTreeHidden'); + })) : $([]); + }, + // get next item + // if `hidden` is TRUE then the hidden items will be considered too + next: function(item, hidden) { + return item ? $(domApi.next(item[0], hidden ? null : function(node) { + return !this.hasClass(node, 'aciTreeHidden'); + })) : $([]); + }, + // get item level - starting from 0 + // return -1 for invalid items + level: function(item) { + var level = -1; + if (item) { + var node = item[0]; + while (domApi.hasClass(node, 'aciTreeLi')) { + node = node.parentNode.parentNode; + level++; + } + } + return level; + }, + // get item ID + getId: function(item) { + var data = this.itemData(item); + return data ? data.id : null; + }, + // get item data + itemData: function(item) { + return item ? item.data('itemData' + this._instance.nameSpace) : null; + }, + // set item ID + // `options.id` is the new item ID + // `options.oldId` will keep the old ID + setId: function(item, options) { + options = this._options(options, 'idset', 'idfail', 'wasid', item); + if (this.isItem(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeid', options)) { + this._fail(item, options); + return; + } + var data = this.itemData(item); + // keep the old one + options.oldId = data.id; + if (options.id == options.oldId) { + this._notify(item, options); + } else { + // remember this one + data.id = options.id; + this._success(item, options); + } + } else { + this._fail(item, options); + } + }, + // get item index - starting from #0 + getIndex: function(item) { + if (item && item[0]) { + if (window.Array.prototype.indexOf) { + return window.Array.prototype.indexOf.call(item[0].parentNode.childNodes, item[0]); + } else { + var children = item[0].parentNode.childNodes; + for (var i = 0; i < children.length; i++) { + if (children[i] == item[0]) { + return i; + } + } + } + } + return null; + }, + // set item index - #0 based + // `options.index` is the new index + // `options.oldIndex` will keep the old index + setIndex: function(item, options) { + options = this._options(options, 'indexset', 'indexfail', 'wasindex', item); + if (this.isItem(item)) { + var oldIndex = this.getIndex(item); + var siblings = this.siblings(item); + if ((options.index != oldIndex) && !siblings.length) { + this._fail(item, options); + return; + } + // a way to cancel the operation + if (!this._trigger(item, 'beforeindex', options)) { + this._fail(item, options); + return; + } + // keep the old one + options.oldIndex = oldIndex; + if (options.index == oldIndex) { + this._notify(item, options); + } else { + // set the new index + if (options.index < 1) { + siblings.first().before(item); + } else if (options.index >= siblings.length) { + siblings.last().after(item); + } else { + siblings.eq(options.index).before(item); + } + var parent = this.parent(item); + // update item states + this._setFirstLast(parent.length ? parent : null, item.add([siblings[0], siblings.get(-1)])); + this._setOddEven(parent); + this._success(item, options); + } + } else { + this._fail(item, options); + } + }, + // get item label + getLabel: function(item) { + var data = this.itemData(item); + return data ? data.label : null; + }, + // test if is valid item + isItem: function(item) { + return item && domApi.hasClass(item[0], 'aciTreeLi'); + }, + // item animation + // `state` if TRUE then show, FALSE then hide + // `unanimated` if TRUE then don't use animations + // `callback` function () to call at the end + _animate: function(item, state, unanimated, callback) { + if (!item) { + item = this._instance.jQuery; + } + if (!unanimated) { + // use the defined animation props + var setting = state ? this._instance.options.show : this._instance.options.hide; + if (setting) { + var ul = domApi.container(item[0]); + if (ul) { + // animate children container + $(ul).stop(true, true).animate(setting.props, { + duration: setting.duration, + easing: setting.easing, + complete: callback ? this.proxy(callback) : null + }); + } else if (callback) { + callback.apply(this); + } + return; + } + } + // use no animation + $(domApi.container(item[0])).stop(true, true).toggle(state); + if (callback) { + callback.apply(this); + } + }, + // get first children of item + // if `hidden` is TRUE then the hidden items will be considered too + first: function(item, hidden) { + if (!item) { + item = this._instance.jQuery; + } + return $(domApi.firstChild(item[0], hidden ? null : function(node) { + return !this.hasClass(node, 'aciTreeHidden'); + })); + }, + // test if item is the first one for his parent + // if `hidden` is TRUE then the hidden items will be considered too + isFirst: function(item, hidden) { + if (item) { + var parent = domApi.parent(item[0]); + return this.first(parent ? $(parent) : null, hidden)[0] == item[0]; + } + return false; + }, + // get last children of item + // if `hidden` is TRUE then the hidden items will be considered too + last: function(item, hidden) { + if (!item) { + item = this._instance.jQuery; + } + return $(domApi.lastChild(item[0], hidden ? null : function(node) { + return !this.hasClass(node, 'aciTreeHidden'); + })); + }, + // test if item is the last one for his parent + // if `hidden` is TRUE then the hidden items will be considered too + isLast: function(item, hidden) { + if (item) { + var parent = domApi.parent(item[0]); + return this.last(parent ? $(parent) : null, hidden)[0] == item[0]; + } + return false; + }, + // test if item is busy/loading + isBusy: function(item) { + if (item) { + return domApi.hasClass(item[0], 'aciTreeLoad'); + } else { + return this._instance.queue.busy(); + } + }, + // set loading state + _loading: function(item, state) { + if (item) { + domApi.toggleClass(item[0], 'aciTreeLoad', state); + if (state) { + item[0].firstChild.setAttribute('aria-busy', true); + } else { + item[0].firstChild.removeAttribute('aria-busy'); + } + } else if (state) { + this._loader(state); + } + }, + // show loader image + _loader: function(show) { + if (show || this.isBusy()) { + if (!this._private.loaderInterval) { + this._private.loaderInterval = window.setInterval(this.proxy(function() { + this._loader(); + }), this._instance.options.loaderDelay); + } + domApi.addClass(this._instance.jQuery[0], 'aciTreeLoad'); + window.clearTimeout(this._private.loaderHide); + this._private.loaderHide = window.setTimeout(this.proxy(function() { + domApi.removeClass(this._instance.jQuery[0], 'aciTreeLoad'); + }), this._instance.options.loaderDelay * 2); + } + }, + // test if parent has children + isChildren: function(parent, children) { + if (!parent) { + parent = this._instance.jQuery; + } + return children && (parent.has(children).length > 0); + }, + // test if parent has immediate children + isImmediateChildren: function(parent, children) { + if (!parent) { + parent = this._instance.jQuery; + } + return children && parent.children('.aciTreeUl').children('.aciTreeLi').is(children); + }, + // test if items share the same parent + sameParent: function(item1, item2) { + if (item1 && item2) { + var parent1 = this.parent(item1); + var parent2 = this.parent(item2); + return (!parent1.length && !parent2.length) || (parent1[0] == parent2[0]); + } + return false; + }, + // test if items share the same top parent + sameTopParent: function(item1, item2) { + if (item1 && item2) { + var parent1 = this.topParent(item1); + var parent2 = this.topParent(item2); + return (!parent1.length && !parent2.length) || (parent1[0] == parent2[0]); + } + return false; + }, + // return the updated item data + // `callback` function (item) called for each item + _serialize: function(item, callback) { + var data = this.itemData(item); + if (this.isInode(item)) { + data.inode = true; + if (this.wasLoad(item)) { + if (data.hasOwnProperty('open')) { + data.open = this.isOpen(item); + } else if (this.isOpen(item)) { + data.open = true; + } + data.branch = []; + this.children(item, false, true).each(this.proxy(function(element) { + var entry = this._serialize($(element), callback); + if (callback) { + entry = callback.call(this, $(element), { + }, entry); + } else { + entry = this._instance.options.serialize.call(this, $(element), { + }, entry); + } + if (entry) { + data.branch.push(entry); + } + }, true)); + if (!data.branch.length) { + data.branch = null; + } + } else { + if (data.hasOwnProperty('open')) { + data.open = false; + } + if (data.hasOwnProperty('branch')) { + data.branch = null; + } + } + } else { + if (data.hasOwnProperty('inode')) { + data.inode = false; + } + if (data.hasOwnProperty('open')) { + data.open = null; + } + if (data.hasOwnProperty('branch')) { + data.branch = null; + } + } + if (data.hasOwnProperty('disabled')) { + data.disabled = this.isDisabled(item); + } else if (this.isDisabled(item)) { + data.disabled = true; + } + return data; + }, + // return serialized data + // `callback` function (item, what, value) - see `aciTree.options.serialize` + serialize: function(item, what, callback) { + // override this to provide serialized data + if (typeof what == 'object') { + if (item) { + var data = this._serialize(item, callback); + if (callback) { + data = callback.call(this, item, { + }, data); + } else { + data = this._instance.options.serialize.call(this, item, { + }, data); + } + return data; + } else { + var list = []; + this.children(null, false, true).each(this.proxy(function(element) { + var data = this._serialize($(element), callback); + if (callback) { + data = callback.call(this, $(element), { + }, data); + } else { + data = this._instance.options.serialize.call(this, $(element), { + }, data); + } + if (data) { + list.push(data); + } + }, true)); + return list; + } + } + return ''; + }, + // destroy the control + destroy: function(options) { + options = this._options(options); + // check if was init + if (!this.wasInit()) { + this._trigger(null, 'notinit', options); + this._fail(null, options); + return; + } + // check if is locked + if (this.isLocked()) { + this._trigger(null, 'locked', options); + this._fail(null, options); + return; + } + // a way to cancel the operation + if (!this._trigger(null, 'beforedestroy', options)) { + this._trigger(null, 'destroyfail', options); + this._fail(null, options); + return; + } + this._private.locked = true; + this._instance.jQuery.addClass('aciTreeLoad').attr('aria-busy', true); + this._instance.queue.destroy(); + this._destroyHook(false); + // unload the entire treeview + this.unload(null, this._inner(options, { + success: this.proxy(function() { + window.clearTimeout(this._private.loaderHide); + window.clearInterval(this._private.loaderInterval); + this._private.itemClone = { + }; + this._destroyHook(true); + this._instance.jQuery.unbind(this._instance.nameSpace).off(this._instance.nameSpace, '.aciTreeButton').off(this._instance.nameSpace, '.aciTreeLine'); + this._instance.jQuery.removeClass('aciTree' + this._instance.index + ' aciTreeLoad').removeAttr('role aria-busy'); + this._private.locked = false; + // call the parent + this._super(); + this._trigger(null, 'destroyed', options); + this._success(null, options); + }), + fail: function() { + this._instance.jQuery.removeClass('aciTreeLoad'); + this._private.locked = false; + this._trigger(null, 'destroyfail', options); + this._fail(null, options); + } + })); + }, + _destroyHook: function(unloaded) { + // override this to do extra destroy before/after unload + } + + }; + + // extend the base aciPluginUi class and store into aciPluginClass.plugins + aciPluginClass.plugins.aciTree = aciPluginClass.aciPluginUi.extend(aciTree_core, 'aciTreeCore'); + + // publish the plugin & the default options + aciPluginClass.publish('aciTree', options); + + // for internal access + var domApi = aciPluginClass.plugins.aciTree_dom; + +})(jQuery, this); + +/* + * aciTree jQuery Plugin v4.5.0-rc.7 + * http://acoderinsights.ro + * + * Copyright (c) 2014 Dragos Ursu + * Dual licensed under the MIT or GPL Version 2 licenses. + * + * Require jQuery Library >= v1.9.0 http://jquery.com + * + aciPlugin >= v1.5.1 https://github.com/dragosu/jquery-aciPlugin + */ + +/* + * A few utility functions for aciTree. + */ + +(function($, window, undefined) { + + // extra default options + + var options = { + // called when items need to be filtered, for each tree item + // return TRUE/FALSE to include/exclude items on filtering + filterHook: function(item, search, regexp) { + return search.length ? regexp.test(window.String(this.getLabel(item))) : true; + } + }; + + // aciTree utils extension + // adds item update option, branch processing, moving items & item swapping, item search by ID + + var aciTree_utils = { + __extend: function() { + // add extra data + $.extend(this._instance, { + filter: new this._queue(this, this._instance.options.queue) + }); + // stop queue until needed + this._instance.filter.destroy(); + // call the parent + this._super(); + }, + // call the `callback` function (item) for each children of item + // when `load` is TRUE will also try to load nodes + branch: function(item, callback, load) { + var queue = this._instance.queue; + var process = this.proxy(function(item, callback, next) { + var child = next ? this.next(item) : this.first(item); + if (child.length) { + if (this.isInode(child)) { + if (this.wasLoad(child)) { + queue.push(function(complete) { + callback.call(this, child); + process(child, callback); + process(child, callback, true); + complete(); + }); + } else if (load) { + // load the item first + this.ajaxLoad(child, { + success: function() { + callback.call(this, child); + process(child, callback); + process(child, callback, true); + }, + fail: function() { + process(child, callback, true); + } + }); + } else { + queue.push(function(complete) { + callback.call(this, child); + process(child, callback, true); + complete(); + }); + } + } else { + queue.push(function(complete) { + callback.call(this, child); + process(child, callback, true); + complete(); + }); + } + } + }); + process(item, callback); + }, + // swap two items (they can't be parent & children) + // `options.item1` & `options.item2` are the swapped items + swap: function(options) { + options = this._options(options, null, 'swapfail', null, null); + var item1 = options.item1; + var item2 = options.item2; + if (this.isItem(item1) && this.isItem(item2) && !this.isChildren(item1, item2) && !this.isChildren(item2, item1) && (item1[0] != item2[0])) { + // a way to cancel the operation + if (!this._trigger(null, 'beforeswap', options)) { + this._fail(null, options); + return; + } + var prev = this.prev(item1); + if (prev.length) { + if (item2[0] == prev[0]) { + item2.before(item1); + } else { + item1.insertAfter(item2); + item2.insertAfter(prev); + } + } else { + var next = this.next(item1); + if (next.length) { + if (item2[0] == next[0]) { + item2.after(item1); + } else { + item1.insertAfter(item2); + item2.insertBefore(next); + } + } else { + var parent = item1.parent(); + item1.insertAfter(item2); + parent.append(item2); + } + } + // update item states + this._updateLevel(item1); + var parent = this.parent(item1); + this._setFirstLast(parent.length ? parent : null, item1); + this._updateHidden(item1); + this._updateLevel(item2); + parent = this.parent(item2); + this._setFirstLast(parent.length ? parent : null, item2); + this._updateHidden(item2); + this._setOddEven(item1.add(item2)); + this._trigger(null, 'swapped', options); + this._success(null, options); + } else { + this._fail(null, options); + } + }, + // update item level + _updateItemLevel: function(item, fromLevel, toLevel) { + domApi.addRemoveClass(item[0], 'aciTreeLevel' + toLevel, 'aciTreeLevel' + fromLevel); + var line = item[0].firstChild; + line.setAttribute('aria-level', toLevel + 1); + var entry = domApi.childrenByClass(line, 'aciTreeEntry'); + if (fromLevel < toLevel) { + line = entry.parentNode; + var branch; + for (var i = fromLevel; i < toLevel; i++) { + branch = window.document.createElement('DIV'); + line.appendChild(branch); + branch.className = 'aciTreeBranch aciTreeLevel' + i; + line = branch; + } + line.appendChild(entry); + } else { + var branch = entry; + for (var i = toLevel; i <= fromLevel; i++) { + branch = branch.parentNode; + } + branch.removeChild(branch.firstChild); + branch.appendChild(entry); + } + }, + // update child level + _updateChildLevel: function(item, fromLevel, toLevel) { + this.children(item, false, true).each(this.proxy(function(element) { + var item = $(element); + this._updateItemLevel(item, fromLevel, toLevel); + if (this.isInode(item)) { + this._updateChildLevel(item, fromLevel + 1, toLevel + 1); + } + }, true)); + }, + // update item level + _updateLevel: function(item) { + var level = this.level(item); + var found = window.parseInt(item.attr('class').match(/aciTreeLevel[0-9]+/)[0].match(/[0-9]+/)); + if (level != found) { + this._updateItemLevel(item, found, level); + this._updateChildLevel(item, found + 1, level + 1); + } + }, + // move item up + moveUp: function(item, options) { + options = this._options(options); + options.index = window.Math.max(this.getIndex(item) - 1, 0); + this.setIndex(item, options); + }, + // move item down + moveDown: function(item, options) { + options = this._options(options); + options.index = window.Math.min(this.getIndex(item) + 1, this.siblings(item).length); + this.setIndex(item, options); + }, + // move item in first position + moveFirst: function(item, options) { + options = this._options(options); + options.index = 0; + this.setIndex(item, options); + }, + // move item in last position + moveLast: function(item, options) { + options = this._options(options); + options.index = this.siblings(item).length; + this.setIndex(item, options); + }, + // move item before another (they can't be parent & children) + // `options.before` is the element before which the item will be moved + moveBefore: function(item, options) { + options = this._options(options, null, 'movefail', 'wasbefore', item); + var before = options.before; + if (this.isItem(item) && this.isItem(before) && !this.isChildren(item, before) && (item[0] != before[0])) { + // a way to cancel the operation + if (!this._trigger(item, 'beforemove', options)) { + this._fail(item, options); + return; + } + if (this.prev(before, true)[0] == item[0]) { + this._notify(item, options); + } else { + var parent = this.parent(item); + var prev = this.prev(item, true); + if (!prev.length) { + prev = parent.length ? parent : this.first(); + } + item.insertBefore(before); + if (parent.length && !this.hasChildren(parent, true)) { + this.setLeaf(parent); + } + this._updateLevel(item); + // update item states + this._setFirstLast(parent.length ? parent : null); + parent = this.parent(item); + this._setFirstLast(parent.length ? parent : null, item.add(before)); + this._updateHidden(item); + this._setOddEven(item.add(before).add(prev)); + this._trigger(item, 'moved', options); + this._success(item, options); + } + } else { + this._fail(item, options); + } + }, + // move item after another (they can't be parent & children) + // `options.after` is the element after which the item will be moved + moveAfter: function(item, options) { + options = this._options(options, null, 'movefail', 'wasafter', item); + var after = options.after; + if (this.isItem(item) && this.isItem(after) && !this.isChildren(item, after) && (item[0] != after[0])) { + // a way to cancel the operation + if (!this._trigger(item, 'beforemove', options)) { + this._fail(item, options); + return; + } + if (this.next(after, true)[0] == item[0]) { + this._notify(item, options); + } else { + var parent = this.parent(item); + var prev = this.prev(item, true); + if (!prev.length) { + prev = parent.length ? parent : this.first(); + } + item.insertAfter(after); + if (parent.length && !this.hasChildren(parent, true)) { + this.setLeaf(parent); + } + this._updateLevel(item); + this._setFirstLast(parent.length ? parent : null); + parent = this.parent(item); + this._setFirstLast(parent.length ? parent : null, item.add(after)); + this._updateHidden(item); + this._setOddEven(item.add(after).add(prev)); + this._trigger(item, 'moved', options); + this._success(item, options); + } + } else { + this._fail(item, options); + } + }, + // move item to be a child of another (they can't be parent & children and the targeted parent item must be empty) + // `options.parent` is the parent element on which the item will be added + asChild: function(item, options) { + options = this._options(options, null, 'childfail', null, item); + var parent = options.parent; + if (this.isItem(item) && this.isItem(parent) && !this.isChildren(item, parent) && !this.hasChildren(parent, true) && (item[0] != parent[0])) { + // a way to cancel the operation + if (!this._trigger(item, 'beforechild', options)) { + this._fail(item, options); + return; + } + var process = function() { + var oldParent = this.parent(item); + var prev = this.prev(item); + if (!prev.length) { + prev = oldParent.length ? oldParent : this.first(); + } + var container = this._createContainer(parent); + container.append(item); + if (oldParent.length && !this.hasChildren(oldParent, true)) { + // no more children + this.setLeaf(oldParent); + } + // update item states + this._updateLevel(item); + this._setFirstLast(oldParent.length ? oldParent : null); + this._setFirstLast(parent.length ? parent : null, item); + this._updateHidden(item); + this._setOddEven(item.add(prev)); + this._trigger(item, 'childset', options); + this._success(item, options); + }; + if (this.isInode(parent)) { + process.apply(this); + } else { + // set as inode first + this.setInode(parent, this._inner(options, { + success: process, + fail: options.fail + })); + } + } else { + this._fail(item, options); + } + }, + // search a `path` ID from a parent + _search: function(parent, pathId) { + var items = this.children(parent); + var item, id, length, found, exact = false; + for (var i = 0, size = items.length; i < size; i++) { + item = items.eq(i); + id = window.String(this.getId(item)); + length = id.length; + if (length) { + if (id == pathId.substr(0, length)) { + found = item; + exact = pathId.length == length; + break; + } + } + } + if (found) { + if (!exact) { + // try to search children + var child = this._search(found, pathId); + if (child) { + return child; + } + } + return { + item: found, + exact: exact + }; + } else { + return null; + } + }, + // search items by ID + // `options.id` is the ID to search for + // if `path` is TRUE then the search will be more optimized + // and reduced to the first branch that matches the ID + // but the ID must be set like a path otherwise will not work + // if `load` is TRUE will also try to load nodes (works only when `path` is TRUE) + searchId: function(path, load, options) { + options = this._options(options); + var id = options.id; + if (path) { + if (load) { + var process = this.proxy(function(item) { + var found = this._search(item, id); + if (found) { + if (found.exact) { + this._success(found.item, options); + } else { + if (this.wasLoad(found.item)) { + this._fail(item, options); + } else { + // load the item + this.ajaxLoad(found.item, this._inner(options, { + success: function() { + process(found.item); + }, + fail: options.fail + })); + } + } + } else { + this._fail(item, options); + } + }); + process(); + } else { + var found = this._search(null, id); + if (found && found.exact) { + this._success(found.item, options); + } else { + this._fail(null, options); + } + } + } else { + var found = $(); + this._instance.jQuery.find('.aciTreeLi').each(this.proxy(function(element) { + if (id == this.getId($(element))) { + found = $(element); + return false; + } + }, true)); + if (found.length) { + this._success(found, options); + } else { + this._fail(null, options); + } + } + }, + // search nodes by ID or custom property starting from item + // `options.search` is the value to be searched + // `options.load` if TRUE will try to load nodes + // `options.callback` function (item, search) return TRUE for the custom match + // `options.results` will keep the search results + search: function(item, options) { + var results = []; + options = this._options(options); + var task = new this._task(new this._queue(this, this._instance.options.queue), function(complete) { + // run this at the end + if (results.length) { + options.results = $(results); + this._success($(results[0]), options); + } else { + this._fail(item, options); + } + complete(); + }); + var children = this.proxy(function(item) { + this.children(item, false, true).each(this.proxy(function(element) { + if (options.callback) { + // custom search + var match = options.callback.call(this, $(element), options.search); + if (match) { + results.push(element); + } else if (match === null) { + // skip childrens + return; + } + } else if (this.getId($(element)) == options.search) { + // default ID match + results.push(element); + } + if (this.isInode($(element))) { + // process children + task.push(function(complete) { + search($(element)); + complete(); + }); + } + }, true)); + }); + var search = this.proxy(function(item) { + if (this.wasLoad(item)) { + // process children + task.push(function(complete) { + children(item); + complete(); + }); + } else if (options.load) { + task.push(function(complete) { + // load the item first + this.ajaxLoad(item, { + success: function() { + children(item); + complete(); + }, + fail: complete + }); + }); + } + }); + // run the search + task.push(function(complete) { + search(item); + complete(); + }); + }, + // search node by a list of IDs starting from item + // `options.path` is a list of IDs to be searched - the path to the node + // `options.load` if TRUE will try to load nodes + searchPath: function(item, options) { + options = this._options(options); + var path = options.path; + var search = this.proxy(function(item, id) { + this.search(item, { + success: function(item) { + if (path.length) { + search(item, path.shift()); + } else { + this._success(item, options); + } + }, + fail: function() { + this._fail(item, options); + }, + search: id, + load: options.load, + callback: function(item, search) { + // prevent drill-down + return (this.getId(item) == search) ? true : null; + } + }); + }); + search(item, path.shift()); + }, + // get item path IDs starting from the top parent (ROOT) + // when `reverse` is TRUE returns the IDs in reverse order + pathId: function(item, reverse) { + var path = this.path(item, reverse), id = []; + path.each(this.proxy(function(element) { + id.push(this.getId($(element))); + }, true)); + return id; + }, + // escape string and return RegExp + _regexp: function(search) { + return new window.RegExp(window.String(search).replace(/([-()\[\]{}+?*.$\^|,:#= v1.9.0 http://jquery.com + * + aciPlugin >= v1.5.1 https://github.com/dragosu/jquery-aciPlugin + */ + +/* + * This extension adds item selection/keyboard navigation to aciTree and need to + * be always included if you care about accessibility. + * + * There is an extra property for the item data: + * + * { + * ... + * selected: false, // TRUE means the item will be selected + * ... + * } + * + */ + +(function($, window, undefined) { + + // extra default options + + var options = { + selectable: true, // if TRUE then one item can be selected (and the tree navigation with the keyboard will be enabled) + multiSelectable: false, // if TRUE then multiple items can be selected at a time + // the 'tabIndex' attribute need to be >= 0 set on the tree container (by default will be set to 0) + fullRow: false, // if TRUE then the selection will be made on the entire row (the CSS should reflect this) + textSelection: false // if FALSE then the item text can't be selected + }; + + // aciTree selectable extension + // adds item selection & keyboard navigation (left/right, up/down, pageup/pagedown, home/end, space, enter, escape) + // dblclick also toggles the item + + var aciTree_selectable = { + __extend: function() { + // add extra data + $.extend(this._instance, { + focus: false + }); + $.extend(this._private, { + blurTimeout: null, + spinPoint: null // the selected item to operate against when using the shift key with selection + }); + // call the parent + this._super(); + }, + // test if has focus + hasFocus: function() { + return this._instance.focus; + }, + // init selectable + _selectableInit: function() { + if (this._instance.jQuery.attr('tabindex') === undefined) { + // ensure the tree can get focus + this._instance.jQuery.attr('tabindex', 0); + } + if (!this._instance.options.textSelection) { + // disable text selection + this._selectable(false); + } + this._instance.jQuery.bind('acitree' + this._private.nameSpace, function(event, api, item, eventName, options) { + switch (eventName) { + case 'closed': + var focused = api.focused(); + if (api.isChildren(item, focused)) { + // move focus to parent on close + api._focusOne(item); + } + // deselect children on parent close + api.children(item, true).each(api.proxy(function(element) { + var item = $(element); + if (this.isSelected(item)) { + this.deselect(item); + } + }, true)); + break; + } + }).bind('focusin' + this._private.nameSpace, this.proxy(function() { + // handle tree focus + window.clearTimeout(this._private.blurTimeout); + if (!this.hasFocus()) { + this._instance.focus = true; + domApi.addClass(this._instance.jQuery[0], 'aciTreeFocus'); + this._trigger(null, 'focused'); + } + })).bind('focusout' + this._private.nameSpace, this.proxy(function() { + // handle tree focus + window.clearTimeout(this._private.blurTimeout); + this._private.blurTimeout = window.setTimeout(this.proxy(function() { + if (this.hasFocus()) { + this._instance.focus = false; + domApi.removeClass(this._instance.jQuery[0], 'aciTreeFocus'); + this._trigger(null, 'blurred'); + } + }), 10); + })).bind('keydown' + this._private.nameSpace, this.proxy(function(e) { + if (!this.hasFocus()) { + // do not handle if we do not have focus + return; + } + var focused = this.focused(); + if (focused.length && this.isBusy(focused)) { + // skip when busy + return false; + } + var item = $([]); + switch (e.which) { + case 65: // aA + if (this._instance.options.multiSelectable && e.ctrlKey) { + // select all visible items + var select = this.visible(this.enabled(this.children(null, true))).not(this.selected()); + select.each(this.proxy(function(element) { + this.select($(element), { + focus: false + }); + }, true)); + if (!this.focused().length) { + // ensure one item has focus + this._focusOne(this.visible(select, true).first()); + } + // prevent default action + e.preventDefault(); + } + break; + case 38: // up + item = focused.length ? this._prev(focused) : this.first(); + break; + case 40: // down + item = focused.length ? this._next(focused) : this.first(); + break; + case 37: // left + if (focused.length) { + if (this.isOpen(focused)) { + item = focused; + // close the item + this.close(focused, { + collapse: this._instance.options.collapse, + expand: this._instance.options.expand, + unique: this._instance.options.unique + }); + } else { + item = this.parent(focused); + } + } else { + item = this._first(); + } + break; + case 39: // right + if (focused.length) { + if (this.isInode(focused) && this.isClosed(focused)) { + item = focused; + // open the item + this.open(focused, { + collapse: this._instance.options.collapse, + expand: this._instance.options.expand, + unique: this._instance.options.unique + }); + } else { + item = this.first(focused); + } + } else { + item = this._first(); + } + break; + case 33: // pgup + item = focused.length ? this._prevPage(focused) : this._first(); + break; + case 34: // pgdown + item = focused.length ? this._nextPage(focused) : this._first(); + break; + case 36: // home + item = this._first(); + break; + case 35: // end + item = this._last(); + break; + case 13: // enter + case 107: // numpad [+] + item = focused; + if (this.isInode(focused) && this.isClosed(focused)) { + // open the item + this.open(focused, { + collapse: this._instance.options.collapse, + expand: this._instance.options.expand, + unique: this._instance.options.unique + }); + } + break; + case 27: // escape + case 109: // numpad [-] + item = focused; + if (this.isOpen(focused)) { + // close the item + this.close(focused, { + collapse: this._instance.options.collapse, + expand: this._instance.options.expand, + unique: this._instance.options.unique + }); + } + if (e.which == 27) { + // prevent default action on ESC + e.preventDefault(); + } + break; + case 32: // space + item = focused; + if (this.isInode(focused) && !e.ctrlKey) { + // toggle the item + this.toggle(focused, { + collapse: this._instance.options.collapse, + expand: this._instance.options.expand, + unique: this._instance.options.unique + }); + } + // prevent page scroll + e.preventDefault(); + break; + case 106: // numpad [*] + item = focused; + if (this.isInode(focused)) { + // open all children + this.open(focused, { + collapse: this._instance.options.collapse, + expand: true, + unique: this._instance.options.unique + }); + } + break; + } + if (item.length) { + if (this._instance.options.multiSelectable && !e.ctrlKey && !e.shiftKey) { + // unselect others + this._unselect(this.selected().not(item)); + } + if (!this.isVisible(item)) { + // bring it into view + this.setVisible(item); + } + if (e.ctrlKey) { + if ((e.which == 32) && this.isEnabled(item)) { // space + if (this.isSelected(item)) { + this.deselect(item); + } else { + this.select(item); + } + // remember for later + this._private.spinPoint = item; + } else { + this._focusOne(item); + } + } else if (e.shiftKey) { + this._shiftSelect(item); + } else { + if (!this.isSelected(item) && this.isEnabled(item)) { + this.select(item); + } else { + this._focusOne(item); + } + // remember for later + this._private.spinPoint = item; + } + return false; + } + })); + this._fullRow(this._instance.options.fullRow); + this._multiSelectable(this._instance.options.multiSelectable); + }, + // change full row mode + _fullRow: function(state) { + this._instance.jQuery.off(this._private.nameSpace, '.aciTreeLine,.aciTreeItem').off(this._private.nameSpace, '.aciTreeItem'); + this._instance.jQuery.on('mousedown' + this._private.nameSpace + ' click' + this._private.nameSpace, state ? '.aciTreeLine,.aciTreeItem' : '.aciTreeItem', this.proxy(function(e) { + var item = this.itemFrom(e.target); + if (!this.isVisible(item)) { + this.setVisible(item); + } + if (e.ctrlKey) { + if (e.type == 'click') { + if (this.isEnabled(item)) { + // (de)select item + if (this.isSelected(item)) { + this.deselect(item); + this._focusOne(item); + } else { + this.select(item); + } + } else { + this._focusOne(item); + } + } + } else if (this._instance.options.multiSelectable && e.shiftKey) { + this._shiftSelect(item); + } else { + if (this._instance.options.multiSelectable && (!this.isSelected(item) || (e.type == 'click'))) { + // deselect all other (keep the old focus) + this._unselect(this.selected().not(item)); + } + this._selectOne(item); + } + if (!e.shiftKey) { + this._private.spinPoint = item; + } + })).on('dblclick' + this._private.nameSpace, state ? '.aciTreeLine,.aciTreeItem' : '.aciTreeItem', this.proxy(function(e) { + var item = this.itemFrom(e.target); + if (this.isInode(item)) { + // toggle the item + this.toggle(item, { + collapse: this._instance.options.collapse, + expand: this._instance.options.expand, + unique: this._instance.options.unique + }); + return false; + } + })); + if (state) { + domApi.addClass(this._instance.jQuery[0], 'aciTreeFullRow'); + } else { + domApi.removeClass(this._instance.jQuery[0], 'aciTreeFullRow'); + } + }, + // change selection mode + _multiSelectable: function(state) { + if (state) { + this._instance.jQuery.attr('aria-multiselectable', true); + } else { + var focused = this.focused(); + this._unselect(this.selected().not(focused)); + this._instance.jQuery.removeAttr('aria-multiselectable'); + } + }, + // process `shift` key selection + _shiftSelect: function(item) { + var spinPoint = this._private.spinPoint; + if (!spinPoint || !$.contains(this._instance.jQuery[0], spinPoint[0]) || !this.isOpenPath(spinPoint)) { + spinPoint = this.focused(); + } + if (spinPoint.length) { + // select a range of items + var select = [item[0]], start = spinPoint[0], found = false, stop = item[0]; + var visible = this.visible(this.children(null, true)); + visible.each(this.proxy(function(element) { + // find what items to select + if (found) { + if (this.isEnabled($(element))) { + select.push(element); + } + if ((element == start) || (element == stop)) { + return false; + } + } else if ((element == start) || (element == stop)) { + if (this.isEnabled($(element))) { + select.push(element); + } + if ((element == start) && (element == stop)) { + return false; + } + found = true; + } + }, true)); + this._unselect(this.selected().not(select)); + // select the items + $(select).not(item).each(this.proxy(function(element) { + var item = $(element); + if (!this.isSelected(item)) { + // select item (keep the old focus) + this.select(item, { + focus: false + }); + } + }, true)); + } + this._selectOne(item); + }, + // override `_initHook` + _initHook: function() { + if (this.extSelectable()) { + this._selectableInit(); + } + // call the parent + this._super(); + }, + // override `_itemHook` + _itemHook: function(parent, item, itemData, level) { + if (this.extSelectable() && itemData.selected) { + this._selectableDOM.select(item, true); + } + // call the parent + this._super(parent, item, itemData, level); + }, + // low level DOM functions + _selectableDOM: { + // (de)select one or more items + select: function(items, state) { + if (state) { + domApi.addListClass(items.toArray(), 'aciTreeSelected', function(node) { + node.firstChild.setAttribute('aria-selected', true); + }); + } else { + domApi.removeListClass(items.toArray(), 'aciTreeSelected', function(node) { + node.firstChild.setAttribute('aria-selected', false); + }); + } + }, + // focus one item, unfocus one or more items + focus: function(items, state) { + if (state) { + domApi.addClass(items[0], 'aciTreeFocus'); + items[0].firstChild.focus(); + } else { + domApi.removeListClass(items.toArray(), 'aciTreeFocus'); + } + } + }, + // make element (un)selectable + _selectable: function(state) { + if (state) { + this._instance.jQuery.css({ + '-webkit-user-select': 'text', + '-moz-user-select': 'text', + '-ms-user-select': 'text', + '-o-user-select': 'text', + 'user-select': 'text' + }).attr({ + 'unselectable': null, + 'onselectstart': null + }).unbind('selectstart' + this._private.nameSpace); + } else { + this._instance.jQuery.css({ + '-webkit-user-select': 'none', + '-moz-user-select': '-moz-none', + '-ms-user-select': 'none', + '-o-user-select': 'none', + 'user-select': 'none' + }).attr({ + 'unselectable': 'on', + 'onselectstart': 'return false' + }).bind('selectstart' + this._private.nameSpace, function(e) { + if (!$(e.target).is('input,textarea')) { + return false; + } + }); + } + }, + // get first visible item + _first: function() { + return $(domApi.first(this._instance.jQuery[0], function(node) { + return this.hasClass(node, 'aciTreeVisible') ? true : null; + })); + }, + // get last visible item + _last: function() { + return $(domApi.last(this._instance.jQuery[0], function(node) { + return this.hasClass(node, 'aciTreeVisible') ? true : null; + })); + }, + // get previous visible starting with item + _prev: function(item) { + return $(domApi.prevAll(item[0], function(node) { + return this.hasClass(node, 'aciTreeVisible') ? true : null; + })); + }, + // get next visible starting with item + _next: function(item) { + return $(domApi.nextAll(item[0], function(node) { + return this.hasClass(node, 'aciTreeVisible') ? true : null; + })); + }, + // get previous page starting with item + _prevPage: function(item) { + var space = this._instance.jQuery.height(); + var now = item[0].firstChild.offsetHeight; + var prev = item, last = $(); + while (now < space) { + prev = this._prev(prev); + if (prev[0]) { + now += prev[0].firstChild.offsetHeight; + last = prev; + } else { + break; + } + } + return last; + }, + // get next page starting with item + _nextPage: function(item) { + var space = this._instance.jQuery.height(); + var now = item[0].firstChild.offsetHeight; + var next = item, last = $(); + while (now < space) { + next = this._next(next); + if (next[0]) { + now += next[0].firstChild.offsetHeight; + last = next; + } else { + break; + } + } + return last; + }, + // select one item + _selectOne: function(item) { + if (this.isSelected(item)) { + this._focusOne(item); + } else { + if (this.isEnabled(item)) { + // select the item + this.select(item); + } else { + this._focusOne(item); + } + } + }, + // unselect the items + _unselect: function(items) { + items.each(this.proxy(function(element) { + this.deselect($(element)); + }, true)); + }, + // focus one item + _focusOne: function(item) { + if (!this._instance.options.multiSelectable) { + this._unselect(this.selected().not(item)); + } + if (!this.isFocused(item)) { + this.focus(item); + } + }, + // select item + // `options.focus` when set to FALSE will not set the focus + // `options.oldSelected` will keep the old selected items + select: function(item, options) { + options = this._options(options, 'selected', 'selectfail', 'wasselected', item); + if (this.extSelectable() && this.isItem(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeselect', options)) { + this._fail(item, options); + return; + } + // keep the old ones + options.oldSelected = this.selected(); + if (!this._instance.options.multiSelectable) { + // deselect all other + var unselect = options.oldSelected.not(item); + this._selectableDOM.select(unselect, false); + unselect.each(this.proxy(function(element) { + this._trigger($(element), 'deselected', options); + }, true)); + } + if (this.isSelected(item)) { + this._notify(item, options); + } else { + this._selectableDOM.select(item, true); + this._success(item, options); + } + // process focus + if ((options.focus === undefined) || options.focus) { + if (!this.isFocused(item) || options.focus) { + this.focus(item, this._inner(options)); + } + } + } else { + this._fail(item, options); + } + }, + // deselect item + deselect: function(item, options) { + options = this._options(options, 'deselected', 'deselectfail', 'notselected', item); + if (this.extSelectable() && this.isItem(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforedeselect', options)) { + this._fail(item, options); + return; + } + if (this.isSelected(item)) { + this._selectableDOM.select(item, false); + this._success(item, options); + } else { + this._notify(item, options); + } + } else { + this._fail(item, options); + } + }, + // set `virtual` focus + // `options.oldFocused` will keep the old focused item + focus: function(item, options) { + options = this._options(options, 'focus', 'focusfail', 'wasfocused', item); + if (this.extSelectable() && this.isItem(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforefocus', options)) { + this._fail(item, options); + return; + } + // keep the old ones + options.oldFocused = this.focused(); + // blur all other + var unfocus = options.oldFocused.not(item); + this._selectableDOM.focus(unfocus, false); + // unfocus all others + unfocus.each(this.proxy(function(element) { + this._trigger($(element), 'blur', options); + }, true)); + if (this.isFocused(item)) { + this._notify(item, options); + } else { + this._selectableDOM.focus(item, true); + this._success(item, options); + } + } else { + this._fail(item, options); + } + }, + // remove `virtual` focus + blur: function(item, options) { + options = this._options(options, 'blur', 'blurfail', 'notfocused', item); + if (this.extSelectable() && this.isItem(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeblur', options)) { + this._fail(item, options); + return; + } + if (this.isFocused(item)) { + this._selectableDOM.focus(item, false); + this._success(item, options); + } else { + this._notify(item, options); + } + } else { + this._fail(item, options); + } + }, + // get selected items + selected: function() { + return this._instance.jQuery.find('.aciTreeSelected'); + }, + // override `_serialize` + _serialize: function(item, callback) { + // call the parent + var data = this._super(item, callback); + if (data && this.extSelectable()) { + if (data.hasOwnProperty('selected')) { + data.selected = this.isSelected(item); + } else if (this.isSelected(item)) { + data.selected = true; + } + } + return data; + }, + // test if item is selected + isSelected: function(item) { + return item && domApi.hasClass(item[0], 'aciTreeSelected'); + }, + // return the focused item + focused: function() { + return this._instance.jQuery.find('.aciTreeFocus'); + }, + // test if item is focused + isFocused: function(item) { + return item && domApi.hasClass(item[0], 'aciTreeFocus'); + }, + // test if selectable is enabled + extSelectable: function() { + return this._instance.options.selectable; + }, + // override set `option` + option: function(option, value) { + if (this.wasInit() && !this.isLocked()) { + if ((option == 'selectable') && (value != this.extSelectable())) { + if (value) { + this._selectableInit(); + } else { + this._selectableDone(); + } + } + if ((option == 'multiSelectable') && (value != this._instance.options.multiSelectable)) { + this._multiSelectable(value); + } + if ((option == 'fullRow') && (value != this._instance.options.fullRow)) { + this._fullRow(value); + } + if ((option == 'textSelection') && (value != this._instance.options.textSelection)) { + this._selectable(value); + } + } + // call the parent + this._super(option, value); + }, + // done selectable + _selectableDone: function(destroy) { + if (this._instance.jQuery.attr('tabindex') == 0) { + this._instance.jQuery.removeAttr('tabindex'); + } + if (!this._instance.options.textSelection) { + this._selectable(true); + } + this._instance.jQuery.unbind(this._private.nameSpace); + this._instance.jQuery.off(this._private.nameSpace, '.aciTreeLine,.aciTreeItem').off(this._private.nameSpace, '.aciTreeItem'); + domApi.removeClass(this._instance.jQuery[0], ['aciTreeFocus', 'aciTreeFullRow']); + this._instance.jQuery.removeAttr('aria-multiselectable'); + this._instance.focus = false; + this._private.spinPoint = null; + if (!destroy) { + // remove selection + this._unselect(this.selected()); + var focused = this.focused(); + if (focused.length) { + this.blur(focused); + } + } + }, + // override `_destroyHook` + _destroyHook: function(unloaded) { + if (unloaded) { + this._selectableDone(true); + } + // call the parent + this._super(unloaded); + } + + }; + + // extend the base aciTree class and add the selectable stuff + aciPluginClass.plugins.aciTree = aciPluginClass.plugins.aciTree.extend(aciTree_selectable, 'aciTreeSelectable'); + + // add extra default options + aciPluginClass.defaults('aciTree', options); + + // for internal access + var domApi = aciPluginClass.plugins.aciTree_dom; + +})(jQuery, this); + +/* + * aciTree jQuery Plugin v4.5.0-rc.7 + * http://acoderinsights.ro + * + * Copyright (c) 2014 Dragos Ursu + * Dual licensed under the MIT or GPL Version 2 licenses. + * + * Require jQuery Library >= v1.9.0 http://jquery.com + * + aciPlugin >= v1.5.1 https://github.com/dragosu/jquery-aciPlugin + */ + +/* + * This extension adds checkbox support to aciTree, + * should be used with the selectable extension. + * + * The are a few extra properties for the item data: + * + * { + * ... + * checkbox: true, // TRUE (default) means the item will have a checkbox (can be omitted if the `radio` extension is not used) + * checked: false, // if should be checked or not + * ... + * } + * + */ + +(function($, window, undefined) { + + // extra default options + + var options = { + checkbox: false, // if TRUE then each item will have a checkbox + checkboxChain: true, + // if TRUE the selection will propagate to the parents/children + // if -1 the selection will propagate only to parents + // if +1 the selection will propagate only to children + // if FALSE the selection will not propagate in any way + checkboxBreak: true, // if TRUE then a missing checkbox will break the chaining + checkboxClick: false // if TRUE then a click will trigger a state change only when made over the checkbox itself + }; + + // aciTree checkbox extension + + var aciTree_checkbox = { + // init checkbox + _checkboxInit: function() { + this._instance.jQuery.bind('acitree' + this._private.nameSpace, function(event, api, item, eventName, options) { + switch (eventName) { + case 'loaded': + // check/update on item load + api._checkboxLoad(item); + break; + } + }).bind('keydown' + this._private.nameSpace, this.proxy(function(e) { + switch (e.which) { + case 32: // space + // support `selectable` extension + if (this.extSelectable && this.extSelectable() && !e.ctrlKey) { + var item = this.focused(); + if (this.hasCheckbox(item) && this.isEnabled(item)) { + if (this.isChecked(item)) { + this.uncheck(item); + } else { + this.check(item); + } + e.stopImmediatePropagation(); + // prevent page scroll + e.preventDefault(); + } + } + break; + } + })).on('click' + this._private.nameSpace, '.aciTreeItem', this.proxy(function(e) { + if (!this._instance.options.checkboxClick || $(e.target).is('.aciTreeCheck')) { + var item = this.itemFrom(e.target); + if (this.hasCheckbox(item) && this.isEnabled(item) && (!this.extSelectable || !this.extSelectable() || (!e.ctrlKey && !e.shiftKey))) { + // change state on click + if (this.isChecked(item)) { + this.uncheck(item); + } else { + this.check(item); + } + e.preventDefault(); + } + } + })); + }, + // override `_initHook` + _initHook: function() { + if (this.extCheckbox()) { + this._checkboxInit(); + } + // call the parent + this._super(); + }, + // override `_itemHook` + _itemHook: function(parent, item, itemData, level) { + if (this.extCheckbox()) { + // support `radio` extension + var radio = this.extRadio && this.hasRadio(item); + if (!radio && (itemData.checkbox || ((itemData.checkbox === undefined) && (!this.extRadio || !this.extRadio())))) { + this._checkboxDOM.add(item, itemData); + } + } + // call the parent + this._super(parent, item, itemData, level); + }, + // low level DOM functions + _checkboxDOM: { + // add item checkbox + add: function(item, itemData) { + domApi.addClass(item[0], itemData.checked ? ['aciTreeCheckbox', 'aciTreeChecked'] : 'aciTreeCheckbox'); + var text = domApi.childrenByClass(item[0].firstChild, 'aciTreeText'); + var parent = text.parentNode; + var label = window.document.createElement('LABEL'); + var check = window.document.createElement('SPAN'); + check.className = 'aciTreeCheck'; + label.appendChild(check); + label.appendChild(text); + parent.appendChild(label); + item[0].firstChild.setAttribute('aria-checked', !!itemData.checked); + }, + // remove item checkbox + remove: function(item) { + domApi.removeClass(item[0], ['aciTreeCheckbox', 'aciTreeChecked', 'aciTreeTristate']); + var text = domApi.childrenByClass(item[0].firstChild, 'aciTreeText'); + var label = text.parentNode; + var parent = label.parentNode; + parent.replaceChild(text, label) + item[0].firstChild.removeAttribute('aria-checked'); + }, + // (un)check items + check: function(items, state) { + domApi.toggleListClass(items.toArray(), 'aciTreeChecked', state, function(node) { + node.firstChild.setAttribute('aria-checked', state); + }); + }, + // (un)set tristate items + tristate: function(items, state) { + domApi.toggleListClass(items.toArray(), 'aciTreeTristate', state); + } + }, + // update items on load, starting from the loaded node + _checkboxLoad: function(item) { + if (this._instance.options.checkboxChain === false) { + // do not update on load + return; + } + var state = undefined; + if (this.hasCheckbox(item)) { + if (this.isChecked(item)) { + if (!this.checkboxes(this.children(item, false, true), true).length) { + // the item is checked but no children are, check them all + state = true; + } + } else { + // the item is not checked, uncheck all children + state = false; + } + } + this._checkboxUpdate(item, state); + }, + // get children list + _checkboxChildren: function(item) { + if (this._instance.options.checkboxBreak) { + var list = []; + var process = this.proxy(function(item) { + var children = this.children(item, false, true); + children.each(this.proxy(function(element) { + var item = $(element); + // break on missing checkbox + if (this.hasCheckbox(item)) { + list.push(element); + process(item); + } + }, true)); + }); + process(item); + return $(list); + } else { + var children = this.children(item, true, true); + return this.checkboxes(children); + } + }, + // update checkbox state + _checkboxUpdate: function(item, state) { + // update children + var checkDown = this.proxy(function(item, count, state) { + var children = this.children(item, false, true); + var total = 0; + var checked = 0; + children.each(this.proxy(function(element) { + var item = $(element); + var subCount = { + total: 0, + checked: 0 + }; + if (this.hasCheckbox(item)) { + if ((state !== undefined) && (this._instance.options.checkboxChain !== -1)) { + this._checkboxDOM.check(item, state); + } + total++; + if (this.isChecked(item)) { + checked++; + } + checkDown(item, subCount, state); + } else { + if (this._instance.options.checkboxBreak) { + var reCount = { + total: 0, + checked: 0 + }; + checkDown(item, reCount); + } else { + checkDown(item, subCount, state); + } + } + total += subCount.total; + checked += subCount.checked; + }, true)); + if (item) { + this._checkboxDOM.tristate(item, (checked > 0) && (checked != total)); + count.total += total; + count.checked += checked; + } + }); + var count = { + total: 0, + checked: 0 + }; + checkDown(item, count, state); + // update parents + var checkUp = this.proxy(function(item, tristate, state) { + var parent = this.parent(item); + if (parent.length) { + if (!tristate) { + var children = this._checkboxChildren(parent); + var checked = this.checkboxes(children, true).length; + var tristate = (checked > 0) && (checked != children.length); + } + if (this.hasCheckbox(parent)) { + if ((state !== undefined) && (this._instance.options.checkboxChain !== 1)) { + this._checkboxDOM.check(parent, tristate ? true : state); + } + this._checkboxDOM.tristate(parent, tristate); + checkUp(parent, tristate, state); + } else { + if (this._instance.options.checkboxBreak) { + checkUp(parent); + } else { + checkUp(parent, tristate, state); + } + } + } + }); + checkUp(item, undefined, state); + }, + // test if item have a checkbox + hasCheckbox: function(item) { + return item && domApi.hasClass(item[0], 'aciTreeCheckbox'); + }, + // add checkbox + addCheckbox: function(item, options) { + options = this._options(options, 'checkboxadded', 'addcheckboxfail', 'wascheckbox', item); + if (this.isItem(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeaddcheckbox', options)) { + this._fail(item, options); + return; + } + if (this.hasCheckbox(item)) { + this._notify(item, options); + } else { + var process = function() { + this._checkboxDOM.add(item, { + }); + this._success(item, options); + }; + // support `radio` extension + if (this.extRadio && this.hasRadio(item)) { + // remove radio first + this.removeRadio(item, this._inner(options, { + success: process, + fail: options.fail + })); + } else { + process.apply(this); + } + } + } else { + this._fail(item, options); + } + }, + // remove checkbox + removeCheckbox: function(item, options) { + options = this._options(options, 'checkboxremoved', 'removecheckboxfail', 'notcheckbox', item); + if (this.isItem(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeremovecheckbox', options)) { + this._fail(item, options); + return; + } + if (this.hasCheckbox(item)) { + this._checkboxDOM.remove(item); + this._success(item, options); + } else { + this._notify(item, options); + } + } else { + this._fail(item, options); + } + }, + // test if it's checked + isChecked: function(item) { + if (this.hasCheckbox(item)) { + return domApi.hasClass(item[0], 'aciTreeChecked'); + } + // support `radio` extension + if (this._super) { + // call the parent + return this._super(item); + } + return false; + }, + // check checkbox + check: function(item, options) { + if (this.extCheckbox && this.hasCheckbox(item)) { + options = this._options(options, 'checked', 'checkfail', 'waschecked', item); + // a way to cancel the operation + if (!this._trigger(item, 'beforecheck', options)) { + this._fail(item, options); + return; + } + if (this.isChecked(item)) { + this._notify(item, options); + } else { + this._checkboxDOM.check(item, true); + if (this._instance.options.checkboxChain !== false) { + // chain them + this._checkboxUpdate(item, true); + } + this._success(item, options); + } + } else { + // support `radio` extension + if (this._super) { + // call the parent + this._super(item, options); + } else { + this._trigger(item, 'checkfail', options); + this._fail(item, options); + } + } + }, + // uncheck checkbox + uncheck: function(item, options) { + if (this.extCheckbox && this.hasCheckbox(item)) { + options = this._options(options, 'unchecked', 'uncheckfail', 'notchecked', item); + // a way to cancel the operation + if (!this._trigger(item, 'beforeuncheck', options)) { + this._fail(item, options); + return; + } + if (this.isChecked(item)) { + this._checkboxDOM.check(item, false); + if (this._instance.options.checkboxChain !== false) { + // chain them + this._checkboxUpdate(item, false); + } + this._success(item, options); + } else { + this._notify(item, options); + } + } else { + // support `radio` extension + if (this._super) { + // call the parent + this._super(item, options); + } else { + this._trigger(item, 'uncheckfail', options); + this._fail(item, options); + } + } + }, + // filter items with checkbox by state (if set) + checkboxes: function(items, state) { + if (state !== undefined) { + return $(domApi.withClass(items.toArray(), state ? ['aciTreeCheckbox', 'aciTreeChecked'] : 'aciTreeCheckbox', state ? null : 'aciTreeChecked')); + } + return $(domApi.withClass(items.toArray(), 'aciTreeCheckbox')); + }, + // override `_serialize` + _serialize: function(item, callback) { + var data = this._super(item, callback); + if (data && this.extCheckbox()) { + if (data.hasOwnProperty('checkbox')) { + data.checkbox = this.hasCheckbox(item); + data.checked = this.isChecked(item); + } else if (this.hasCheckbox(item)) { + if (this.extRadio && this.extRadio()) { + data.checkbox = true; + } + data.checked = this.isChecked(item); + } + } + return data; + }, + // override `serialize` + serialize: function(item, what, callback) { + if (what == 'checkbox') { + var serialized = ''; + var children = this.children(item, true, true); + this.checkboxes(children, true).each(this.proxy(function(element) { + var item = $(element); + if (callback) { + serialized += callback.call(this, item, what, this.getId(item)); + } else { + serialized += this._instance.options.serialize.call(this, item, what, this.getId(item)); + } + }, true)); + return serialized; + } + return this._super(item, what, callback); + }, + // test if item is in tristate + isTristate: function(item) { + return item && domApi.hasClass(item[0], 'aciTreeTristate'); + }, + // filter tristate items + tristate: function(items) { + return $(domApi.withClass(items.toArray(), 'aciTreeTristate')); + }, + // test if checkbox is enabled + extCheckbox: function() { + return this._instance.options.checkbox; + }, + // override set `option` + option: function(option, value) { + if (this.wasInit() && !this.isLocked()) { + if ((option == 'checkbox') && (value != this.extCheckbox())) { + if (value) { + this._checkboxInit(); + } else { + this._checkboxDone(); + } + } + } + // call the parent + this._super(option, value); + }, + // done checkbox + _checkboxDone: function(destroy) { + this._instance.jQuery.unbind(this._private.nameSpace); + this._instance.jQuery.off(this._private.nameSpace, '.aciTreeItem'); + if (!destroy) { + // remove checkboxes + this.checkboxes(this.children(null, true, true)).each(this.proxy(function(element) { + this.removeCheckbox($(element)); + }, true)); + } + }, + // override `_destroyHook` + _destroyHook: function(unloaded) { + if (unloaded) { + this._checkboxDone(true); + } + // call the parent + this._super(unloaded); + } + + }; + + // extend the base aciTree class and add the checkbox stuff + aciPluginClass.plugins.aciTree = aciPluginClass.plugins.aciTree.extend(aciTree_checkbox, 'aciTreeCheckbox'); + + // add extra default options + aciPluginClass.defaults('aciTree', options); + + // for internal access + var domApi = aciPluginClass.plugins.aciTree_dom; + +})(jQuery, this); + +/* + * aciTree jQuery Plugin v4.5.0-rc.7 + * http://acoderinsights.ro + * + * Copyright (c) 2014 Dragos Ursu + * Dual licensed under the MIT or GPL Version 2 licenses. + * + * Require jQuery Library >= v1.9.0 http://jquery.com + * + aciPlugin >= v1.5.1 https://github.com/dragosu/jquery-aciPlugin + */ + +/* + * This extension adds radio-button support to aciTree, + * should be used with the selectable extension. + * + * The are a few extra properties for the item data: + * + * { + * ... + * radio: true, // TRUE (default) means the item will have a radio button (can be omitted if the `checkbox` extension is not used) + * checked: false, // if should be checked or not + * ... + * } + * + */ + +(function($, window, undefined) { + + // extra default options + + var options = { + radio: false, // if TRUE then each item will have a radio button + radioChain: true, // if TRUE the selection will propagate to the parents/children + radioBreak: true, // if TRUE then a missing radio button will break the chaining + radioClick: false // if TRUE then a click will trigger a state change only when made over the radio-button itself + }; + + // aciTree radio extension + + var aciTree_radio = { + // init radio + _radioInit: function() { + this._instance.jQuery.bind('acitree' + this._private.nameSpace, function(event, api, item, eventName, options) { + switch (eventName) { + case 'loaded': + if (item) { + // check/update on item load + api._radioLoad(item); + } + break; + } + }).bind('keydown' + this._private.nameSpace, this.proxy(function(e) { + switch (e.which) { + case 32: // space + // support `selectable` extension + if (this.extSelectable && this.extSelectable() && !e.ctrlKey) { + var item = this.focused(); + if (this.hasRadio(item) && this.isEnabled(item)) { + if (!this.isChecked(item)) { + this.check(item); + } + e.stopImmediatePropagation(); + // prevent page scroll + e.preventDefault(); + } + } + break; + } + })).on('click' + this._private.nameSpace, '.aciTreeItem', this.proxy(function(e) { + if (!this._instance.options.radioClick || $(e.target).is('.aciTreeCheck')) { + var item = this.itemFrom(e.target); + if (this.hasRadio(item) && this.isEnabled(item) && (!this.extSelectable || !this.extSelectable() || (!e.ctrlKey && !e.shiftKey))) { + // change state on click + if (!this.isChecked(item)) { + this.check(item); + } + e.preventDefault(); + } + } + })); + }, + // override `_initHook` + _initHook: function() { + if (this.extRadio()) { + this._radioInit(); + } + // call the parent + this._super(); + }, + // override `_itemHook` + _itemHook: function(parent, item, itemData, level) { + if (this.extRadio()) { + // support `checkbox` extension + var checkbox = this.extCheckbox && this.hasCheckbox(item); + if (!checkbox && (itemData.radio || ((itemData.radio === undefined) && (!this.extCheckbox || !this.extCheckbox())))) { + this._radioDOM.add(item, itemData); + } + } + // call the parent + this._super(parent, item, itemData, level); + }, + // low level DOM functions + _radioDOM: { + // add item radio + add: function(item, itemData) { + domApi.addClass(item[0], itemData.checked ? ['aciTreeRadio', 'aciTreeChecked'] : 'aciTreeRadio'); + var text = domApi.childrenByClass(item[0].firstChild, 'aciTreeText'); + var parent = text.parentNode; + var label = window.document.createElement('LABEL'); + var check = window.document.createElement('SPAN'); + check.className = 'aciTreeCheck'; + label.appendChild(check); + label.appendChild(text); + parent.appendChild(label); + item[0].firstChild.setAttribute('aria-checked', !!itemData.checked); + }, + // remove item radio + remove: function(item) { + domApi.removeClass(item[0], ['aciTreeRadio', 'aciTreeChecked']); + var text = domApi.childrenByClass(item[0].firstChild, 'aciTreeText'); + var label = text.parentNode; + var parent = label.parentNode; + parent.replaceChild(text, label) + item[0].firstChild.removeAttribute('aria-checked'); + }, + // (un)check items + check: function(items, state) { + domApi.toggleListClass(items.toArray(), 'aciTreeChecked', state, function(node) { + node.firstChild.setAttribute('aria-checked', state); + }); + } + }, + // update item on load + _radioLoad: function(item) { + if (!this._instance.options.radioChain) { + // do not update on load + return; + } + if (this.hasRadio(item)) { + if (this.isChecked(item)) { + if (!this.radios(this.children(item, false, true), true).length) { + // the item is checked but no children are, check the children + this._radioUpdate(item, true); + } + } else { + // the item is not checked, uncheck children + this._radioUpdate(item); + } + } + }, + // get children list + _radioChildren: function(item) { + if (this._instance.options.radioBreak) { + var list = []; + var process = this.proxy(function(item) { + var children = this.children(item, false, true); + children.each(this.proxy(function(element) { + var item = $(element); + // break on missing radio + if (this.hasRadio(item)) { + list.push(element); + process(item); + } + }, true)); + }); + process(item); + return $(list); + } else { + var children = this.children(item, true, true); + return this.radios(children); + } + }, + // get children across items + _radioLevel: function(items) { + var list = []; + items.each(this.proxy(function(element) { + var item = $(element); + var children = this.children(item, false, true); + children.each(this.proxy(function(element) { + var item = $(element); + if (!this._instance.options.radioBreak || this.hasRadio(item)) { + list.push(element); + } + }, true)); + }, true)); + return $(list); + }, + // update radio state + _radioUpdate: function(item, state) { + // update siblings + var siblings = this.proxy(function(item) { + var siblings = this.siblings(item, true); + this._radioDOM.check(this.radios(siblings), false); + siblings.each(this.proxy(function(element) { + var item = $(element); + if (!this._instance.options.radioBreak || this.hasRadio(item)) { + this._radioDOM.check(this._radioChildren(item), false); + } + }, true)); + }); + if (state) { + siblings(item); + } + // update children + var checkDown = this.proxy(function(item) { + var children = this._radioLevel(item); + var radios = this.radios(children); + if (radios.length) { + var checked = this.radios(children, true); + if (checked.length) { + checked = checked.first(); + this._radioDOM.check(checked, true); + siblings(checked); + checkDown(checked); + } else { + checked = radios.first(); + this._radioDOM.check(checked, true); + siblings(checked); + checkDown(checked); + } + } else if (children.length) { + checkDown(children); + } + }); + if (state) { + checkDown(item); + } else { + this._radioDOM.check(this._radioChildren(item), false); + } + // update parents + var checkUp = this.proxy(function(item) { + var parent = this.parent(item); + if (parent.length) { + if (this.hasRadio(parent)) { + if (state) { + siblings(parent); + } + this._radioDOM.check(parent, state); + checkUp(parent); + } else { + if (!this._instance.options.radioBreak) { + if (state) { + siblings(parent); + } + checkUp(parent); + } + } + } + }); + if (state !== undefined) { + checkUp(item); + } + }, + // test if item have a radio + hasRadio: function(item) { + return item && domApi.hasClass(item[0], 'aciTreeRadio'); + }, + // add radio button + addRadio: function(item, options) { + options = this._options(options, 'radioadded', 'addradiofail', 'wasradio', item); + if (this.isItem(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeaddradio', options)) { + this._fail(item, options); + return; + } + if (this.hasRadio(item)) { + this._notify(item, options); + } else { + var process = function() { + this._radioDOM.add(item, { + }); + this._success(item, options); + }; + // support `checkbox` extension + if (this.extCheckbox && this.hasCheckbox(item)) { + // remove checkbox first + this.removeCheckbox(item, this._inner(options, { + success: process, + fail: options.fail + })); + } else { + process.apply(this); + } + } + } else { + this._fail(item, options); + } + }, + // remove radio button + removeRadio: function(item, options) { + options = this._options(options, 'radioremoved', 'removeradiofail', 'notradio', item); + if (this.isItem(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeremoveradio', options)) { + this._fail(item, options); + return; + } + if (this.hasRadio(item)) { + this._radioDOM.remove(item); + this._success(item, options); + } else { + this._notify(item, options); + } + } else { + this._fail(item, options); + } + }, + // test if it's checked + isChecked: function(item) { + if (this.hasRadio(item)) { + return domApi.hasClass(item[0], 'aciTreeChecked'); + } + // support `checkbox` extension + if (this._super) { + // call the parent + return this._super(item); + } + return false; + }, + // check radio button + check: function(item, options) { + if (this.extRadio && this.hasRadio(item)) { + options = this._options(options, 'checked', 'checkfail', 'waschecked', item); + // a way to cancel the operation + if (!this._trigger(item, 'beforecheck', options)) { + this._fail(item, options); + return; + } + if (this.isChecked(item)) { + this._notify(item, options); + } else { + this._radioDOM.check(item, true); + if (this._instance.options.radioChain) { + // chain them + this._radioUpdate(item, true); + } + this._success(item, options); + } + } else { + // support `checkbox` extension + if (this._super) { + // call the parent + this._super(item, options); + } else { + this._trigger(item, 'checkfail', options); + this._fail(item, options); + } + } + }, + // uncheck radio button + uncheck: function(item, options) { + if (this.extRadio && this.hasRadio(item)) { + options = this._options(options, 'unchecked', 'uncheckfail', 'notchecked', item); + // a way to cancel the operation + if (!this._trigger(item, 'beforeuncheck', options)) { + this._fail(item, options); + return; + } + if (this.isChecked(item)) { + this._radioDOM.check(item, false); + if (this._instance.options.radioChain) { + // chain them + this._radioUpdate(item, false); + } + this._success(item, options); + } else { + this._notify(item, options); + } + } else { + // support `checkbox` extension + if (this._super) { + // call the parent + this._super(item, options); + } else { + this._trigger(item, 'uncheckfail', options); + this._fail(item, options); + } + } + }, + // filter items with radio by state (if set) + radios: function(items, state) { + if (state !== undefined) { + return $(domApi.withClass(items.toArray(), state ? ['aciTreeRadio', 'aciTreeChecked'] : 'aciTreeRadio', state ? null : 'aciTreeChecked')); + } + return $(domApi.withClass(items.toArray(), 'aciTreeRadio')); + }, + // override `_serialize` + _serialize: function(item, callback) { + var data = this._super(item, callback); + if (data && this.extRadio()) { + if (data.hasOwnProperty('radio')) { + data.radio = this.hasRadio(item); + data.checked = this.isChecked(item); + } else if (this.hasRadio(item)) { + if (this.extCheckbox && this.extCheckbox()) { + data.radio = true; + } + data.checked = this.isChecked(item); + } + } + return data; + }, + // override `serialize` + serialize: function(item, what, callback) { + if (what == 'radio') { + var serialized = ''; + var children = this.children(item, true, true); + this.radios(children, true).each(this.proxy(function(element) { + var item = $(element); + if (callback) { + serialized += callback.call(this, item, what, this.getId(item)); + } else { + serialized += this._instance.options.serialize.call(this, item, what, this.getId(item)); + } + }, true)); + return serialized; + } + return this._super(item, what, callback); + }, + // test if radio is enabled + extRadio: function() { + return this._instance.options.radio; + }, + // override set `option` + option: function(option, value) { + if (this.wasInit() && !this.isLocked()) { + if ((option == 'radio') && (value != this.extRadio())) { + if (value) { + this._radioInit(); + } else { + this._radioDone(); + } + } + } + // call the parent + this._super(option, value); + }, + // done radio + _radioDone: function(destroy) { + this._instance.jQuery.unbind(this._private.nameSpace); + this._instance.jQuery.off(this._private.nameSpace, '.aciTreeItem'); + if (!destroy) { + // remove radios + this.radios(this.children(null, true, true)).each(this.proxy(function(element) { + this.removeRadio($(element)); + }, true)); + } + }, + // override `_destroyHook` + _destroyHook: function(unloaded) { + if (unloaded) { + this._radioDone(true); + } + // call the parent + this._super(unloaded); + } + + }; + + // extend the base aciTree class and add the radio stuff + aciPluginClass.plugins.aciTree = aciPluginClass.plugins.aciTree.extend(aciTree_radio, 'aciTreeRadio'); + + // add extra default options + aciPluginClass.defaults('aciTree', options); + + // for internal access + var domApi = aciPluginClass.plugins.aciTree_dom; + +})(jQuery, this); + +/* + * aciTree jQuery Plugin v4.5.0-rc.7 + * http://acoderinsights.ro + * + * Copyright (c) 2014 Dragos Ursu + * Dual licensed under the MIT or GPL Version 2 licenses. + * + * Require jQuery Library >= v1.9.0 http://jquery.com + * + aciPlugin >= v1.5.1 https://github.com/dragosu/jquery-aciPlugin + */ + +/* + * This extension adds multiple column support to aciTree. + * + * The `columnData` option is used to tell what are the columns and show one or + * more values that will be read from the item data object. + * + * Column data is an array of column definitions, each column definition is + * an object: + * + * { + * width: 100, + * props: 'column_x', + * value: 'default' + * } + * + * where the `width` is the column width in [px], if undefined - then the value + * from the CSS will be used; the `props` is the property name that will be + * read from the item data, if undefined (or the `item-data[column.props]` + * is undefined) then a default value will be set for the column: the `value`. + * + */ + +(function($, window, undefined) { + + // extra default options + + var options = { + columnData: [] // column definitions list + }; + + // aciTree columns extension + // adds item columns, set width with CSS or using the API + + var aciTree_column = { + __extend: function() { + // add extra data + $.extend(this._private, { + propsIndex: { // column index cache + } + }); + // call the parent + this._super(); + }, + // override `_initHook` + _initHook: function() { + if (this._instance.options.columnData.length) { + // check column width + var found = false, data; + for (var i in this._instance.options.columnData) { + data = this._instance.options.columnData[i]; + if (data.width !== undefined) { + // update column width + this._updateCss('.aciTree.aciTree' + this._instance.index + ' .aciTreeColumn' + i, 'width:' + data.width + 'px;'); + found = true; + } + this._private.propsIndex[data.props] = i; + } + if (found) { + // at least a column width set + this._updateWidth(); + } + } + // call the parent + this._super(); + }, + // read property value from a CSS class name + _getCss: function(className, property, numeric) { + var id = '_getCss_' + window.String(className).replace(/[^a-z0-9_-]/ig, '_'); + var test = $('body').find('#' + id); + if (!test.length) { + if (className instanceof Array) { + var style = '', end = ''; + for (var i in className) { + style += '
'; + end += '
'; + } + style += end; + } else { + var style = '
'; + } + $('body').append('
' + style + '
'); + test = $('body').find('#' + id); + } + var value = test.find('*:last').css(property); + if (numeric) { + value = parseInt(value); + if (isNaN(value)) { + value = null; + } + } + return value; + }, + // dynamically change a CSS class definition + _updateCss: function(className, definition) { + var id = '_updateCss_' + window.String(className).replace('>', '_gt_').replace(/[^a-z0-9_-]/ig, '_'); + var style = ''; + var test = $('body').find('#' + id); + if (test.length) { + test.replaceWith(style); + } else { + $('body').prepend(style); + } + }, + // get column width + // `index` is the #0 based column index + getWidth: function(index) { + if ((index >= 0) && (index < this.columns())) { + return this._getCss(['aciTree aciTree' + this._instance.index, 'aciTreeColumn' + index], 'width', true); + } + return null; + }, + // set column width + // `index` is the #0 based column index + setWidth: function(index, width) { + if ((index >= 0) && (index < this.columns())) { + this._updateCss('.aciTree.aciTree' + this._instance.index + ' .aciTreeColumn' + index, 'width:' + width + 'px;'); + this._updateWidth(); + } + }, + // update item margins + _updateWidth: function() { + var width = 0; + for (var i in this._instance.options.columnData) { + if (this.isColumn(i)) { + width += this.getWidth(i); + } + } + var icon = this._getCss(['aciTree', 'aciTreeIcon'], 'width', true); + // add item padding + width += this._getCss(['aciTree', 'aciTreeItem'], 'padding-left', true) + this._getCss(['aciTree', 'aciTreeItem'], 'padding-right', true); + this._updateCss('.aciTree.aciTree' + this._instance.index + ' .aciTreeItem', 'margin-right:' + (icon + width) + 'px;'); + this._updateCss('.aciTree[dir=rtl].aciTree' + this._instance.index + ' .aciTreeItem', 'margin-right:0;margin-left:' + (icon + width) + 'px;'); + }, + // test if column is visible + // `index` is the #0 based column index + isColumn: function(index) { + if ((index >= 0) && (index < this.columns())) { + return this._getCss(['aciTree aciTree' + this._instance.index, 'aciTreeColumn' + index], 'display') != 'none'; + } + return false; + }, + // get column index by `props` + // return -1 if the column does not exists + columnIndex: function(props) { + if (this._private.propsIndex[props] !== undefined) { + return this._private.propsIndex[props]; + } + return -1; + }, + // get the column count + columns: function() { + return this._instance.options.columnData.length; + }, + // set column to be visible or hidden + // `index` is the #0 based column index + // if `show` is undefined then the column visibility will be toggled + toggleColumn: function(index, show) { + if ((index >= 0) && (index < this.columns())) { + if (show === undefined) { + var show = !this.isColumn(index); + } + this._updateCss('.aciTree.aciTree' + this._instance.index + ' .aciTreeColumn' + index, 'display:' + (show ? 'inherit' : 'none') + ';'); + this._updateWidth(); + } + }, + // override `_itemHook` + _itemHook: function(parent, item, itemData, level) { + if (this.columns()) { + var position = domApi.childrenByClass(item[0].firstChild, 'aciTreeEntry'), data, column; + for (var i in this._instance.options.columnData) { + data = this._instance.options.columnData[i]; + column = this._createColumn(itemData, data, i); + position.insertBefore(column, position.firstChild); + } + } + // call the parent + this._super(parent, item, itemData, level); + }, + // create column markup + // `itemData` item data object + // `columnData` column data definition + // `index` is the #0 based column index + _createColumn: function(itemData, columnData, index) { + var value = columnData.props && (itemData[columnData.props] !== undefined) ? itemData[columnData.props] : + ((columnData.value === undefined) ? '' : columnData.value); + var column = window.document.createElement('DIV'); + column.className = 'aciTreeColumn aciTreeColumn' + index; + column.innerHTML = value.length ? value : ' '; + return column; + }, + // set column content + // `options.index` the #0 based column index + // `options.value` is the new content + // `options.oldValue` will keep the old content + setColumn: function(item, options) { + options = this._options(options, 'columnset', 'columnfail', 'wascolumn', item); + if (this.isItem(item) && (options.index >= 0) && (options.index < this.columns())) { + // a way to cancel the operation + if (!this._trigger(item, 'beforecolumn', options)) { + this._fail(item, options); + return; + } + var data = this.itemData(item); + // keep the old one + options.oldValue = data[this._instance.options.columnData[options.index].props]; + if (options.value == options.oldValue) { + this._notify(item, options); + } else { + // set the column + item.children('.aciTreeLine').find('.aciTreeColumn' + options.index).html(options.value); + // remember this one + data[this._instance.options.columnData[options.index].props] = options.value; + this._success(item, options); + } + } else { + this._fail(item, options); + } + }, + // get column content + getColumn: function(item, index) { + if ((index >= 0) && (index < this.columns())) { + var data = this.itemData(item); + return data ? data[this._instance.options.columnData[index].props] : null; + } + return null; + } + }; + + // extend the base aciTree class and add the columns stuff + aciPluginClass.plugins.aciTree = aciPluginClass.plugins.aciTree.extend(aciTree_column, 'aciTreeColumn'); + + // add extra default options + aciPluginClass.defaults('aciTree', options); + + // for internal access + var domApi = aciPluginClass.plugins.aciTree_dom; + +})(jQuery, this); + +/* + * aciTree jQuery Plugin v4.5.0-rc.7 + * http://acoderinsights.ro + * + * Copyright (c) 2014 Dragos Ursu + * Dual licensed under the MIT or GPL Version 2 licenses. + * + * Require jQuery Library >= v1.9.0 http://jquery.com + * + aciPlugin >= v1.5.1 https://github.com/dragosu/jquery-aciPlugin + */ + +/* + * This extension adds inplace edit support to aciTree, + * should be used with the selectable extension. + */ + +(function($, window, undefined) { + + // extra default options + + var options = { + editable: false, // if TRUE then each item will be inplace editable + editDelay: 250 // how many [ms] to wait (with mouse down) before starting the edit (on mouse release) + }; + + // aciTree editable extension + // add inplace item editing by pressing F2 key or mouse click (to enter edit mode) + // press enter/escape to save/cancel the text edit + + var aciTree_editable = { + __extend: function() { + // add extra data + $.extend(this._private, { + editTimestamp: null + }); + // call the parent + this._super(); + }, + // init editable + _editableInit: function() { + this._instance.jQuery.bind('acitree' + this._private.nameSpace, function(event, api, item, eventName, options) { + switch (eventName) { + case 'blurred': + // support `selectable` extension + var item = api.edited(); + if (item.length) { + // cancel edit/save the changes + api.endEdit(); + } + break; + case 'deselected': + // support `selectable` extension + if (api.isEdited(item)) { + // cancel edit/save the changes + api.endEdit(); + } + break; + } + }).bind('click' + this._private.nameSpace, this.proxy(function() { + // click on the tree + var item = this.edited(); + if (item.length) { + // cancel edit/save the changes + this.endEdit(); + } + })).bind('keydown' + this._private.nameSpace, this.proxy(function(e) { + switch (e.which) { + case 113: // F2 + // support `selectable` extension + if (this.extSelectable && this.extSelectable()) { + var item = this.focused(); + if (item.length && !this.isEdited(item) && this.isEnabled(item)) { + // enable edit on F2 key + this.edit(item); + // prevent default F2 key function + e.preventDefault(); + } + } + break; + } + })).on('mousedown' + this._private.nameSpace, '.aciTreeItem', this.proxy(function(e) { + if ($(e.target).is('.aciTreeItem,.aciTreeText')) { + this._private.editTimestamp = $.now(); + } + })).on('mouseup' + this._private.nameSpace, '.aciTreeItem', this.proxy(function(e) { + if ($(e.target).is('.aciTreeItem,.aciTreeText')) { + var passed = $.now() - this._private.editTimestamp; + // start edit only after N [ms] but before N * 4 [ms] have passed + if ((passed > this._instance.options.editDelay) && (passed < this._instance.options.editDelay * 4)) { + var item = this.itemFrom(e.target); + if ((!this.extSelectable || !this.extSelectable() || (this.isFocused(item) && (this.selected().length == 1))) && this.isEnabled(item)) { + // edit on mouseup + this.edit(item); + } + } + } + })).on('keydown' + this._private.nameSpace, 'input[type=text]', this.proxy(function(e) { + // key handling + switch (e.which) { + case 13: // enter + this.itemFrom(e.target).focus(); + this.endEdit(); + e.stopPropagation(); + break; + case 27: // escape + this.itemFrom(e.target).focus(); + this.endEdit({ + save: false + }); + e.stopPropagation(); + // prevent default action on ESC + e.preventDefault(); + break; + case 38: // up + case 40: // down + case 37: // left + case 39: // right + case 33: // pgup + case 34: // pgdown + case 36: // home + case 35: // end + case 32: // space + case 107: // numpad [+] + case 109: // numpad [-] + case 106: // numpad [*] + e.stopPropagation(); + break; + } + })).on('blur' + this._private.nameSpace, 'input[type=text]', this.proxy(function() { + if (!this.extSelectable || !this.extSelectable()) { + // cancel edit/save the changes + this.endEdit(); + } + })).on('click' + this._private.nameSpace + ' dblclick' + this._private.nameSpace, 'input[type=text]', function(e) { + e.stopPropagation(); + }); + }, + // override `_initHook` + _initHook: function() { + if (this.extEditable()) { + this._editableInit(); + } + // call the parent + this._super(); + }, + // low level DOM functions + _editableDOM: { + // add edit field + add: function(item) { + var line = item.addClass('aciTreeEdited').children('.aciTreeLine'); + line.find('.aciTreeText').html(''); + line.find('label').attr('for', 'aciTree-editable-tree-item'); + this._editableDOM.get(item).val(this.getLabel(item)); + }, + // remove edit field + remove: function(item, label) { + var line = item.removeClass('aciTreeEdited').children('.aciTreeLine'); + line.find('.aciTreeText').html(this.getLabel(item)); + line.find('label').removeAttr('for'); + }, + // return edit field + get: function(item) { + return item ? item.children('.aciTreeLine').find('input[type=text]') : $([]); + } + }, + // get edited item + edited: function() { + return this._instance.jQuery.find('.aciTreeEdited'); + }, + // test if item is edited + isEdited: function(item) { + return item && domApi.hasClass(item[0], 'aciTreeEdited'); + }, + // set focus to the input + _focusEdit: function(item) { + var field = this._editableDOM.get(item).focus().trigger('click')[0]; + if (field) { + if (typeof field.selectionStart == 'number') { + field.selectionStart = field.selectionEnd = field.value.length; + } else if (field.createTextRange !== undefined) { + var range = field.createTextRange(); + range.collapse(false); + range.select(); + } + } + }, + // override `setLabel` + setLabel: function(item, options) { + if (!this.extEditable() || !this.isEdited(item)) { + // call the parent + this._super(item, options); + } + }, + // edit item inplace + edit: function(item, options) { + options = this._options(options, 'edit', 'editfail', 'wasedit', item); + if (this.extEditable() && this.isItem(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeedit', options)) { + this._fail(item, options); + return; + } + var edited = this.edited(); + if (edited.length) { + if (edited[0] == item[0]) { + this._notify(item, options); + return; + } else { + this._editableDOM.remove.call(this, edited); + this._trigger(edited, 'endedit', options); + } + } + this._editableDOM.add.call(this, item); + this._focusEdit(item); + this._success(item, options); + } else { + this._fail(item, options); + } + }, + // end edit + // `options.save` when set to FALSE will not save the changes + endEdit: function(options) { + var item = this.edited(); + options = this._options(options, 'edited', 'endeditfail', 'endedit', item); + if (this.extEditable() && this.isItem(item)) { + // a way to cancel the operation + if (!this._trigger(item, 'beforeendedit', options)) { + this._fail(item, options); + return; + } + var text = this._editableDOM.get(item).val(); + this._editableDOM.remove.call(this, item); + if ((options.save === undefined) || options.save) { + this.setLabel(item, { + label: text + }); + this._success(item, options); + } else { + this._notify(item, options); + } + } else { + this._fail(item, options); + } + }, + // test if editable is enabled + extEditable: function() { + return this._instance.options.editable; + }, + // override set `option` + option: function(option, value) { + if (this.wasInit() && !this.isLocked()) { + if ((option == 'editable') && (value != this.extEditable())) { + if (value) { + this._editableInit(); + } else { + this._editableDone(); + } + } + } + // call the parent + this._super(option, value); + }, + // done editable + _editableDone: function() { + this._instance.jQuery.unbind(this._private.nameSpace); + this._instance.jQuery.off(this._private.nameSpace, '.aciTreeItem'); + this._instance.jQuery.off(this._private.nameSpace, 'input[type=text]'); + var edited = this.edited(); + if (edited.length) { + this.endEdit(); + } + }, + // override `_destroyHook` + _destroyHook: function(unloaded) { + if (unloaded) { + this._editableDone(); + } + // call the parent + this._super(unloaded); + } + + }; + + // extend the base aciTree class and add the editable stuff + aciPluginClass.plugins.aciTree = aciPluginClass.plugins.aciTree.extend(aciTree_editable, 'aciTreeEditable'); + + // add extra default options + aciPluginClass.defaults('aciTree', options); + + // for internal access + var domApi = aciPluginClass.plugins.aciTree_dom; + +})(jQuery, this); + +/* + * aciTree jQuery Plugin v4.5.0-rc.7 + * http://acoderinsights.ro + * + * Copyright (c) 2014 Dragos Ursu + * Dual licensed under the MIT or GPL Version 2 licenses. + * + * Require jQuery Library >= v1.9.0 http://jquery.com + * + aciPlugin >= v1.5.1 https://github.com/dragosu/jquery-aciPlugin + */ + +/* + * This extension adds save/restore support for item states (open/selected) using local storage. + * The states are saved on item select/open and restored on treeview init. + * Require jStorage https://github.com/andris9/jStorage and the utils extension for finding items by ID. + */ + +(function($, window, undefined) { + + // extra default options + + var options = { + persist: null // the storage key name to keep the states (should be unique/treeview) + }; + + // aciTree persist extension + // save/restore item state in/from local storage + + var aciTree_persist = { + __extend: function() { + $.extend(this._private, { + // timeouts for the save operation + selectTimeout: null, + focusTimeout: null, + openTimeout: null + }); + // call the parent + this._super(); + }, + // init persist + _initPersist: function() { + this._instance.jQuery.bind('acitree' + this._private.nameSpace, function(event, api, item, eventName, options) { + if (options.uid == 'ui.persist') { + // skip processing itself + return; + } + switch (eventName) { + case 'init': + api._persistRestore(); + break; + case 'selected': + case 'deselected': + // support `selectable` extension + api._persistLater('selected'); + break; + case 'focus': + case 'blur': + // support `selectable` extension + api._persistLater('focused'); + break; + case 'opened': + case 'closed': + api._persistLater('opened'); + break; + } + }); + }, + // override `_initHook` + _initHook: function() { + if (this.extPersist()) { + this._initPersist(); + } + // call the parent + this._super(); + }, + // persist states + _persistLater: function(type) { + switch (type) { + case 'selected': + window.clearTimeout(this._private.selectTimeout); + this._private.selectTimeout = window.setTimeout(this.proxy(function() { + this._persistSelected(); + }), 250); + break; + case 'focused': + window.clearTimeout(this._private.focusTimeout); + this._private.focusTimeout = window.setTimeout(this.proxy(function() { + this._persistFocused(); + }), 250); + break; + case 'opened': + window.clearTimeout(this._private.openTimeout); + this._private.openTimeout = window.setTimeout(this.proxy(function() { + this._persistOpened(); + }), 250); + break; + } + }, + // restore item states + _persistRestore: function() { + var queue = new this._queue(this, this._instance.options.queue); + var task = new this._task(queue, function(complete) { + // support `selectable` extension + if (this.extSelectable && this.extSelectable()) { + var selected = $.jStorage.get('aciTree_' + this._instance.options.persist + '_selected'); + if (selected instanceof Array) { + // select all saved items + for (var i in selected) { + (function(path) { + queue.push(function(complete) { + this.searchPath(null, { + success: function(item) { + this.select(item, { + uid: 'ui.persist', + success: function() { + complete(); + }, + fail: complete, + focus: false + }); + }, + fail: complete, + path: path.split(';') + }); + }); + })(selected[i]); + if (!this._instance.options.multiSelectable) { + break; + } + } + } + var focused = $.jStorage.get('aciTree_' + this._instance.options.persist + '_focused'); + if (focused instanceof Array) { + // focus all saved items + for (var i in focused) { + (function(path) { + queue.push(function(complete) { + this.searchPath(null, { + success: function(item) { + this.focus(item, { + uid: 'ui.persist', + success: function(item) { + this.setVisible(item, { + center: true + }); + complete(); + }, + fail: complete + }); + }, + fail: complete, + path: path.split(';') + }); + }); + })(focused[i]); + } + } + } + complete(); + }); + var opened = $.jStorage.get('aciTree_' + this._instance.options.persist + '_opened'); + if (opened instanceof Array) { + // open all saved items + for (var i in opened) { + (function(path) { + // add item to queue + task.push(function(complete) { + this.searchPath(null, { + success: function(item) { + this.open(item, { + uid: 'ui.persist', + success: complete, + fail: complete + }); + }, + fail: complete, + path: path.split(';'), + load: true + }); + }); + })(opened[i]); + } + } + }, + // persist selected items + _persistSelected: function() { + // support `selectable` extension + if (this.extSelectable && this.extSelectable()) { + var selected = []; + this.selected().each(this.proxy(function(element) { + var item = $(element); + var path = this.pathId(item); + path.push(this.getId(item)); + selected.push(path.join(';')); + }, true)); + $.jStorage.set('aciTree_' + this._instance.options.persist + '_selected', selected); + } + }, + // persist focused item + _persistFocused: function() { + // support `selectable` extension + if (this.extSelectable && this.extSelectable()) { + var focused = []; + this.focused().each(this.proxy(function(element) { + var item = $(element); + var path = this.pathId(item); + path.push(this.getId(item)); + focused.push(path.join(';')); + }, true)); + $.jStorage.set('aciTree_' + this._instance.options.persist + '_focused', focused); + } + }, + // persist opened items + _persistOpened: function() { + var opened = []; + this.inodes(this.children(null, true), true).each(this.proxy(function(element) { + var item = $(element); + if (this.isOpenPath(item)) { + var path = this.pathId(item); + path.push(this.getId(item)); + opened.push(path.join(';')); + } + }, true)); + $.jStorage.set('aciTree_' + this._instance.options.persist + '_opened', opened); + }, + // test if there is any saved data + isPersist: function() { + if (this.extPersist()) { + var selected = $.jStorage.get('aciTree_' + this._instance.options.persist + '_selected'); + if (selected instanceof Array) { + return true; + } + var focused = $.jStorage.get('aciTree_' + this._instance.options.persist + '_focused'); + if (focused instanceof Array) { + return true; + } + var opened = $.jStorage.get('aciTree_' + this._instance.options.persist + '_opened'); + if (opened instanceof Array) { + return true; + } + } + return false; + }, + // remove any saved states + unpersist: function() { + if (this.extPersist()) { + $.jStorage.deleteKey('aciTree_' + this._instance.options.persist + '_selected'); + $.jStorage.deleteKey('aciTree_' + this._instance.options.persist + '_focused'); + $.jStorage.deleteKey('aciTree_' + this._instance.options.persist + '_opened'); + } + }, + // test if persist is enabled + extPersist: function() { + return this._instance.options.persist; + }, + // override set `option` + option: function(option, value) { + var persist = this.extPersist(); + // call the parent + this._super(option, value); + if (this.extPersist() != persist) { + if (persist) { + this._donePersist(); + } else { + this._initPersist(); + } + } + }, + // done persist + _donePersist: function() { + this._instance.jQuery.unbind(this._private.nameSpace); + }, + // override `_destroyHook` + _destroyHook: function(unloaded) { + if (unloaded) { + this._donePersist(); + } + // call the parent + this._super(unloaded); + } + }; + + // extend the base aciTree class and add the persist stuff + aciPluginClass.plugins.aciTree = aciPluginClass.plugins.aciTree.extend(aciTree_persist, 'aciTreePersist'); + + // add extra default options + aciPluginClass.defaults('aciTree', options); + +})(jQuery, this); + +/* + * aciTree jQuery Plugin v4.5.0-rc.7 + * http://acoderinsights.ro + * + * Copyright (c) 2014 Dragos Ursu + * Dual licensed under the MIT or GPL Version 2 licenses. + * + * Require jQuery Library >= v1.9.0 http://jquery.com + * + aciPlugin >= v1.5.1 https://github.com/dragosu/jquery-aciPlugin + */ + +/* + * This extension adds hash/fragment support using aciFragment, it opens/select item(s) based on variables stored in the fragment part of the URL. + * The states are loaded from the URL fragment and set on treeview init. Multiple item IDs separated with ";" are supported for + * opening/selecting deep items (if loading nodes is required). + * Require aciFragment https://github.com/dragosu/jquery-aciFragment and the utils extension for finding items by ID. + */ + +(function($, window, undefined) { + + // extra default options + + var options = { + selectHash: null, // hash key name to select a item (item path IDs as key value, multiple item IDs separated with a ";") + openHash: null // hash key name to open item(s) (item path IDs as key value, multiple item IDs separated with a ";") + }; + + // aciTree hash extension + // select/open items based on IDs stored in the fragment of the current URL + + var aciTree_hash = { + __extend: function() { + $.extend(this._private, { + lastSelect: null, + lastOpen: null, + // store `aciFragment` api + hashApi: null + }); + // call the parent + this._super(); + }, + // init hash + _hashInit: function() { + // init `aciFragment` + this._instance.jQuery.aciFragment(); + this._private.hashApi = this._instance.jQuery.aciFragment('api'); + this._instance.jQuery.bind('acitree' + this._private.nameSpace, function(event, api, item, eventName, options) { + switch (eventName) { + case 'init': + api._hashRestore(); + break; + } + }).bind('acifragment' + this._private.nameSpace, this.proxy(function(event, api, anchorChanged) { + event.stopPropagation(); + this._hashRestore(); + })); + }, + // override `_initHook` + _initHook: function() { + if (this.extHast()) { + this._hashInit(); + } + // call the parent + this._super(); + }, + // restore item states from hash + _hashRestore: function() { + var queue = this._instance.queue; + var process = function(opened) { + // open all hash items + for (var i in opened) { + (function(id) { + // add item to queue + queue.push(function(complete) { + this.search(null, { + success: function(item) { + this.open(item, { + uid: 'ui.hash', + success: complete, + fail: complete + }); + }, + fail: complete, + search: id + }); + }); + })(opened[i]); + } + }; + if (this._instance.options.openHash) { + var hash = this._private.hashApi.get(this._instance.options.openHash, ''); + if (hash.length && (hash != this._private.lastOpen)) { + this._private.lastOpen = hash; + var opened = hash.split(';'); + process(opened); + } + } + // support `selectable` extension + if (this._instance.options.selectHash && this.extSelectable && this.extSelectable()) { + var hash = this._private.hashApi.get(this._instance.options.selectHash, ''); + if (hash.length && (hash != this._private.lastSelect)) { + this._private.lastSelect = hash; + var opened = hash.split(';'); + var selected = opened.pop(); + process(opened); + if (selected) { + // select item + queue.push(function(complete) { + this.search(null, { + success: function(item) { + this.select(item, { + uid: 'ui.hash', + success: function(item) { + this.setVisible(item, { + center: true + }); + complete(); + }, + fail: complete + }); + }, + fail: complete, + search: selected + }); + }); + } + } + } + }, + // test if hash is enabled + extHast: function() { + return this._instance.options.selectHash || this._instance.options.openHash; + }, + // override set option + option: function(option, value) { + var hash = this.extHast(); + // call the parent + this._super(option, value); + if (this.extHast() != hash) { + if (hash) { + this._hashDone(); + } else { + this._hashInit(); + } + } + }, + // done hash + _hashDone: function() { + this._instance.jQuery.unbind(this._private.nameSpace); + this._private.hashApi = null; + this._instance.jQuery.aciFragment('destroy'); + }, + // override `_destroyHook` + _destroyHook: function(unloaded) { + if (unloaded) { + this._hashDone(); + } + // call the parent + this._super(unloaded); + } + }; + + // extend the base aciTree class and add the hash stuff + aciPluginClass.plugins.aciTree = aciPluginClass.plugins.aciTree.extend(aciTree_hash, 'aciTreeHash'); + + // add extra default options + aciPluginClass.defaults('aciTree', options); + +})(jQuery, this); + +/* + * aciTree jQuery Plugin v4.5.0-rc.7 + * http://acoderinsights.ro + * + * Copyright (c) 2014 Dragos Ursu + * Dual licensed under the MIT or GPL Version 2 licenses. + * + * Require jQuery Library >= v1.9.0 http://jquery.com + * + aciPlugin >= v1.5.1 https://github.com/dragosu/jquery-aciPlugin + */ + +/* + * This extension adds the possibility to sort the tree items. + * Require aciSortable https://github.com/dragosu/jquery-aciSortable and the utils extension for reordering items. + */ + +(function($, window, undefined) { + + // extra default options + + var options = { + sortable: false, // if TRUE then the tree items can be sorted + sortDelay: 750, // how many [ms] before opening a inode on hovering when in drag + // called by the `aciSortable` inside the `drag` callback + sortDrag: function(item, placeholder, isValid, helper) { + if (!isValid) { + var move = this.getLabel(item); + if (this._private.dragDrop && (this._private.dragDrop.length > 1)) { + move += ' and #' + (this._private.dragDrop.length - 1) + ' more'; + } + helper.html(move); + } + }, + // called by the `aciSortable` inside the `valid` callback + sortValid: function(item, hover, before, isContainer, placeholder, helper) { + var move = this.getLabel(item); + if (this._private.dragDrop.length > 1) { + move += ' and #' + (this._private.dragDrop.length - 1) + ' more'; + } + if (isContainer) { + helper.html('move ' + move + ' to ' + this.getLabel(this.itemFrom(hover))); + placeholder.removeClass('aciTreeAfter aciTreeBefore'); + } else if (before !== null) { + if (before) { + helper.html('move ' + move + ' before ' + this.getLabel(hover)); + placeholder.removeClass('aciTreeAfter').addClass('aciTreeBefore'); + } else { + helper.html('move ' + move + ' after ' + this.getLabel(hover)); + placeholder.removeClass('aciTreeBefore').addClass('aciTreeAfter'); + } + } + } + }; + + // aciTree sortable extension + + var aciTree_sortable = { + __extend: function() { + // add extra data + $.extend(this._private, { + openTimeout: null, + dragDrop: null // the items used in drag & drop + }); + // call the parent + this._super(); + }, + // init sortable + _sortableInit: function() { + this._instance.jQuery.aciSortable({ + container: '.aciTreeUl', + item: '.aciTreeLi', + child: 50, + childHolder: '', + childHolderSelector: '.aciTreeChild', + placeholder: '
  • ', + placeholderSelector: '.aciTreePlaceholder', + helper: '
    ', + helperSelector: '.aciTreeHelper', + // just before drag start + before: this.proxy(function(item) { + // init before drag + if (!this._initDrag(item)) { + return false; + } + // a way to cancel the operation + if (!this._trigger(item, 'beforedrag')) { + this._trigger(item, 'dragfail'); + return false; + } + return true; + }), + // just after drag start, before dragging + start: this.proxy(function(item, placeholder, helper) { + this._instance.jQuery.addClass('aciTreeDragDrop'); + helper.stop(true).css('opacity', 1); + }), + // when in drag + drag: this.proxy(function(item, placeholder, isValid, helper) { + if (!isValid) { + window.clearTimeout(this._private.openTimeout); + } + if (this._instance.options.sortDrag) { + this._instance.options.sortDrag.apply(this, arguments); + } + }), + // to check the drop target (when the placeholder is repositioned) + valid: this.proxy(function(item, hover, before, isContainer, placeholder, helper) { + window.clearTimeout(this._private.openTimeout); + if (!this._checkDrop(item, hover, before, isContainer, placeholder, helper)) { + return false; + } + var options = this._options({ + hover: hover, + before: before, + isContainer: isContainer, + placeholder: placeholder, + helper: helper + }); + // a way to cancel the operation + if (!this._trigger(item, 'checkdrop', options)) { + return false; + } + if (this.isInode(hover) && !this.isOpen(hover)) { + this._private.openTimeout = window.setTimeout(this.proxy(function() { + this.open(hover); + }), this._instance.options.sortDelay); + } + if (this._instance.options.sortValid) { + this._instance.options.sortValid.apply(this, arguments); + } + return true; + }), + // when dragged as child + create: this.proxy(function(api, item, hover) { + if (this.isLeaf(hover)) { + hover.append(api._instance.options.childHolder); + return true; + } + return false; + }, true), + // on drag end + end: this.proxy(function(item, hover, placeholder, helper) { + window.clearTimeout(this._private.openTimeout); + var options = { + placeholder: placeholder, + helper: helper + }; + options = this._options(options, 'sorted', 'dropfail', null, item); + if (placeholder.parent().length) { + var prev = this.prev(placeholder, true); + if (prev.length) { + // add after a item + placeholder.detach(); + var items = $(this._private.dragDrop.get().reverse()); + this._private.dragDrop = null; + items.each(this.proxy(function(element) { + this.moveAfter($(element), this._inner(options, { + success: options.success, + fail: options.fail, + after: prev + })); + }, true)); + } else { + var next = this.next(placeholder, true); + if (next.length) { + // add before a item + placeholder.detach(); + var items = $(this._private.dragDrop.get().reverse()); + this._private.dragDrop = null; + items.each(this.proxy(function(element) { + this.moveBefore($(element), this._inner(options, { + success: options.success, + fail: options.fail, + before: next + })); + }, true)); + } else { + // add as a child + var parent = this.parent(placeholder); + var container = placeholder.parent(); + placeholder.detach(); + container.remove(); + if (this.isLeaf(parent)) { + // we can set asChild only for leaves + var items = this._private.dragDrop; + this.asChild(items.eq(0), this._inner(options, { + success: function() { + this._success(item, options); + this.open(parent); + items.filter(':gt(0)').each(this.proxy(function(element) { + this.moveAfter($(element), this._inner(options, { + success: options.success, + fail: options.fail, + after: this.last(parent) + })); + }, true)); + }, + fail: options.fail, + parent: parent + })); + } else { + this._fail(item, options); + } + } + } + } else { + this._fail(item, options); + } + this._private.dragDrop = null; + if (helper.parent().length) { + // the helper is inserted in the DOM + var top = $(window).scrollTop(); + var left = $(window).scrollLeft(); + var rect = item[0].getBoundingClientRect(); + // animate helper to item position + helper.animate({ + top: rect.top + top, + left: rect.left + left, + opacity: 0 + }, + { + complete: function() { + // detach the helper when completed + helper.detach(); + } + }); + } + this._instance.jQuery.removeClass('aciTreeDragDrop'); + }) + }); + }, + // override `_initHook` + _initHook: function() { + if (this.extSortable()) { + this._sortableInit(); + } + // call the parent + this._super(); + }, + // reduce items by removing the childrens + _parents: function(items) { + var len = items.length, a, b, remove = []; + for (var i = 0; i < len - 1; i++) { + a = items.eq(i); + for (var j = i + 1; j < len; j++) { + b = items.eq(j); + if (this.isChildren(a, b)) { + remove.push(items[j]); + } else if (this.isChildren(b, a)) { + remove.push(items[i]); + } + } + } + return items.not(remove); + }, + // called before drag start + _initDrag: function(item) { + // support `selectable` extension + if (this.extSelectable && this.extSelectable()) { + if (!this.hasFocus()) { + this._instance.jQuery.focus(); + } + if (!this.isEnabled(item)) { + return false; + } + var drag = this.selected(); + if (drag.length) { + if (!this.isSelected(item)) { + return false; + } + } else { + drag = item; + } + this._private.dragDrop = this._parents(drag); + } else { + this._instance.jQuery.focus(); + this._private.dragDrop = item; + } + return true; + }, + // check the drop target + _checkDrop: function(item, hover, before, isContainer, placeholder, helper) { + var items = this._private.dragDrop; + if (!items) { + return false; + } + var test = this.itemFrom(hover); + if (items.is(test) || items.has(test[0]).length) { + return false; + } + if (!isContainer) { + test = before ? this.prev(hover) : this.next(hover); + if (items.is(test)) { + return false; + } + } + return true; + }, + // test if sortable is enabled + extSortable: function() { + return this._instance.options.sortable; + }, + // override set `option` + option: function(option, value) { + if (this.wasInit() && !this.isLocked()) { + if ((option == 'sortable') && (value != this.extSortable())) { + if (value) { + this._sortableInit(); + } else { + this._sortableDone(); + } + } + } + // call the parent + this._super(option, value); + }, + // done sortable + _sortableDone: function() { + this._instance.jQuery.unbind(this._private.nameSpace); + this._instance.jQuery.aciSortable('destroy'); + }, + // override `_destroyHook` + _destroyHook: function(unloaded) { + if (unloaded) { + this._sortableDone(); + } + // call the parent + this._super(unloaded); + } + }; + + // extend the base aciTree class and add the sortable stuff + aciPluginClass.plugins.aciTree = aciPluginClass.plugins.aciTree.extend(aciTree_sortable, 'aciTreeSortable'); + + // add extra default options + aciPluginClass.defaults('aciTree', options); + +})(jQuery, this); diff --git a/web/pgadmin/browser/static/js/frame.js b/web/pgadmin/browser/static/js/frame.js new file mode 100644 index 000000000..77b4e1ea6 --- /dev/null +++ b/web/pgadmin/browser/static/js/frame.js @@ -0,0 +1,49 @@ +define( + ['underscore', 'pgadmin', 'wcdocker'], +function(_, pgAdmin) { + + pgAdmin.Browser = pgAdmin.Browser || {}; + pgAdmin.Browser.Frame = function(options) { + var defaults = [ + 'name', 'title', 'width', 'height', 'showTitle', 'isClosable', + 'isPrivate', 'url']; + _.extend(this, _.pick(options, defaults)); + } + + _.extend(pgAdmin.Browser.Frame.prototype, { + name:'', + title: '', + width: 300, + height: 600, + showTitle: true, + isClosable: true, + isPrivate: false, + url: 'about:blank', + panel: null, + frame: null, + load: function(docker) { + var that = this; + if (!that.panel) { + docker.registerPanelType(this.name, { + title: that.title, + isPrivate: that.isPrivate, + onCreate: function(myPanel) { + myPanel.initSize(that.width, that.height); + if (myPanel.showTitle == false) + myPanle.title(false); + myPanel.closeable(that.isCloseable == true); + + var $frameArea = $('
    '); + myPanel.layout().addItem($frameArea).parent().css('height', '100%'); + that.panel = myPanel; + that.frame = new wcIFrame($frameArea, myPanel); + + setTimeout(function() { that.frame.openURL(that.url); }, 500); + } + }); + } + } + }); + + return pgAdmin.Browser.Frame; +}); diff --git a/web/pgadmin/browser/static/js/menu.js b/web/pgadmin/browser/static/js/menu.js new file mode 100644 index 000000000..0088acc71 --- /dev/null +++ b/web/pgadmin/browser/static/js/menu.js @@ -0,0 +1,127 @@ +define( + ['underscore', 'pgadmin', 'jquery'], +function(_, pgAdmin, $) { + 'use strict'; + + pgAdmin.Browser = pgAdmin.Browser || {}; + pgAdmin.Browser.MenuItem = function(opts) { + var menu_opts = [ + 'name', 'label', 'priority', 'module', 'callback', 'data', 'enable', + 'category', 'target', 'url', 'icon' + ], + defaults = { + url: '#', + target: '_self', + enable: true + }; + _.extend(this, defaults, _.pick(opts, menu_opts)); + }; + + _.extend(pgAdmin.Browser.MenuItem.prototype, { + generate: function() { + var url = $('', { + 'id': this.name, + 'href': this.url, + 'target': this.target, + 'data-toggle': 'pg-menu' + }).data('pgMenu', { + module: this.module || pgAdmin.Browser, + cb: this.callback, + data: this.data + }).addClass('menu-link'); + if (this.icon) { + url.append($('', {'class': this.icon})); + } + url.append($('').text(' ' + this.label)); + + return $('
  • ') + .addClass('menu-item') + .append(url); + }, + disabled: function(o) { + if (_.isFunction(this.enable)) return !this.enable.apply(this.module, [this.data]); + if (_.isBoolean(this.enable)) return !this.enable; + if (this.module && _.isBoolean(this.module[this.enable])) return !this.module[this.enable]; + if (this.module && _.isFunction(this.module[this.enable])) return !this.enable.apply(this.module, [this.data]); + if (_.isFunction(o[this.enable])) return !this.enable.apply(o, [this.data]); + + return false; + } + }); + + + // MENU PUBLIC CLASS DEFINITION + // ============================== + var Menu = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Menu.DEFAULTS, options) + this.isLoading = false + } + + Menu.DEFAULTS = {} + + Menu.prototype.toggle = function (ev) { + var $parent = this.$element.closest('.menu-item'); + if ($parent.hasClass('disabled')) { + ev.preventDefault() + return false; + } + var d = this.$element.data('pgMenu'); + if (d.cb) { + var cb = d.module && d.module['callbacks'] && d.module['callbacks'][d.cb] || d.module && d.module[d.cb]; + if (cb) { + cb.apply(d.module, [d.data]); + ev.preventDefault() + } else { + pgAdmin.Browser.report_error('Developer Warning: Callback - "' + d.cb + '" not found!'); + } + } + } + + + // BUTTON PLUGIN DEFINITION + // ======================== + + function Plugin(option, ev) { + return this.each(function () { + var $this = $(this) + var data = $this.data('pg.menu') + var options = typeof option == 'object' && option + + if (!data) $this.data('pg.menu', (data = new Menu(this, options))) + + data.toggle(ev) + }) + } + + var old = $.fn.button + + $.fn.pgmenu = Plugin + $.fn.pgmenu.Constructor = Menu + + + // BUTTON NO CONFLICT + // ================== + + $.fn.pgmenu.noConflict = function () { + $.fn.pgmenu = old; + return this; + } + + // MENU DATA-API + // ============= + + $(document) + .on('click.pg.menu.data-api', '[data-toggle^="pg-menu"]', function (ev) { + var $menu = $(ev.target) + if (!$menu.hasClass('menu-link')) + $menu = $menu.closest('.menu-link') + Plugin.call($menu, 'toggle', ev) + }) + .on('focus.pg.menu.data-api blur.pg.menu.data-api', '[data-toggle^="pg-menu"]', + function (e) { + $(e.target).closest('.menu').toggleClass('focus', /^focus(in)?$/.test(e.type)) + }); + + return pgAdmin.Browser.MenuItem; +}); diff --git a/web/pgadmin/browser/static/js/panel.js b/web/pgadmin/browser/static/js/panel.js new file mode 100644 index 000000000..b2edb8991 --- /dev/null +++ b/web/pgadmin/browser/static/js/panel.js @@ -0,0 +1,51 @@ +define( + ['underscore', 'pgadmin', 'wcdocker'], +function(_, pgAdmin) { + pgAdmin.Browser = pgAdmin.Browser || {}; + pgAdmin.Browser.Panel = function(options) { + var defaults = [ + 'name', 'title', 'width', 'height', 'showTitle', 'isCloseable', + 'isPrivate', 'content', 'events']; + _.extend(this, _.pick(options, defaults)); + } + + _.extend(pgAdmin.Browser.Panel.prototype, { + name:'', + title: '', + width: 300, + height: 600, + showTitle: true, + isCloseable: true, + isPrivate: false, + content: '', + panel: null, + load: function(docker, title) { + var that = this; + if (!that.panel) { + docker.registerPanelType(that.name, { + title: that.title, + isPrivate: that.isPrivate, + onCreate: function(myPanel) { + myPanel.initSize(that.width, that.height); + if (!that.showTitle) + myPanel.title(false); + else + myPanel.title(title || that.title); + myPanel.closeable(that.isCloseable == true); + myPanel.layout().addItem(that.content, 0, 0).parent().css('height', '100%'); + that.panel = myPanel; + if (that.events && _.isObject(that.events)) { + _.each(that.events, function(v, k) { + if (v && _.isFunction(v)) { + myPanel.on(k, v); + } + }); + } + } + }); + } + } + }); + + return pgAdmin.Browser.Panel; +}); diff --git a/web/pgadmin/browser/templates/browser/css/node.css b/web/pgadmin/browser/templates/browser/css/node.css index da56d6910..eda34f497 100644 --- a/web/pgadmin/browser/templates/browser/css/node.css +++ b/web/pgadmin/browser/templates/browser/css/node.css @@ -1,3 +1,7 @@ .icon-{{node_type}} { background-image: url('{{ url_for('NODE-%s.static' % node_type, filename='img/%s.png' % node_type )}}') !important; + background-repeat: no-repeat; + align-content: center; + vertical-align: middle; + height: 1.3em; } diff --git a/web/pgadmin/browser/templates/browser/index.html b/web/pgadmin/browser/templates/browser/index.html index dd3a4b25a..6b26f2514 100644 --- a/web/pgadmin/browser/templates/browser/index.html +++ b/web/pgadmin/browser/templates/browser/index.html @@ -1,5 +1,21 @@ {% extends "base.html" %} {% block title %}{{ config.APP_NAME }}{% endblock %} +{% block init_script %} +try { + require( + ['pgadmin', 'pgadmin.browser'], + function(pgAdmin, pgBrowser) { + pgBrowser.init(); + }, + function() { + /* TODO:: Show proper error dialog */ + console.log(arguments); + }); +} catch (err) { + /* Show proper error dialog */ + console.log(err); +} +{% endblock %} {% block body %}
  • -
    +
    {% include 'browser/messages.html' %} diff --git a/web/pgadmin/browser/templates/browser/js/browser.js b/web/pgadmin/browser/templates/browser/js/browser.js index dbdf0343d..1c9a13aeb 100644 --- a/web/pgadmin/browser/templates/browser/js/browser.js +++ b/web/pgadmin/browser/templates/browser/js/browser.js @@ -1,221 +1,24 @@ -// Page globals -var docker; -var editor; -var tree; -var dashboardPanel; -var propertiesPanel; -var statisticsPanel; -var dependenciesPanel; -var dependentsPanel; -var sqlPanel; -var browserPanel; +define( + ['require', 'jquery', 'underscore', 'underscore.string', 'bootstrap', + 'pgadmin', 'alertify', 'codemirror', 'codemirror.sql', 'wcdocker', + 'jquery.contextmenu', 'jquery.acitree', 'pgadmin.alertifyjs', + 'pgadmin.browser.menu', 'pgadmin.browser.panel', 'jquery.aciplugin', + 'pgadmin.browser.error', 'pgadmin.browser.frame', + 'pgadmin.browser.node' + ], +function(require, $, _, S, Bootstrap, pgAdmin, alertify, CodeMirror) { -// Store the main browser layout -$(window).bind('unload', function() { - state = docker.save(); - settings = { setting: "Browser/Layout", - value: state } + // Some scripts do export their object in the window only. + // Generally the one, which do no have AMD support. + var wcDocker = window.wcDocker; + $ = $ || window.jQuery || window.$; + Bootstrap = Bootstrap || window.Bootstrap; - $.post("{{ url_for('settings.store') }}", settings); + pgAdmin.Browser = pgAdmin.Browser || {}; - return true -}); - -// Build a regular dock panel -function buildPanel(docker, name, title, width, height, showTitle, isCloseable, isPrivate, content) { - docker.registerPanelType(name, { - title: title, - isPrivate: isPrivate, - onCreate: function(myPanel) { - myPanel.initSize(width, height); - - if (showTitle == false) - myPanel.title(false); - - myPanel.closeable(isCloseable); - - myPanel.layout().addItem(content, 0, 0).parent().css('height', '100%'); - } - }); -} - -// Build an iFrame dock panel -function buildIFramePanel(docker, name, title, width, height, showTitle, isCloseable, isPrivate, url) { - docker.registerPanelType(name, { - title: title, - isPrivate: isPrivate, - onCreate: function(myPanel) { - myPanel.initSize(width, height); - - if (showTitle == false) - myPanel.title(false); - - myPanel.closeable(isCloseable); - - var $frameArea = $('
    '); - myPanel.layout().addItem($frameArea).parent().css('height', '100%'); - - var iFrame = new wcIFrame($frameArea, myPanel); - iFrame.openURL(url); - } - }); -} - -// Build the default layout -function buildDefaultLayout() { - dashboardPanel = docker.addPanel('pnl_dashboard', wcDocker.DOCK_TOP, propertiesPanel); - propertiesPanel = docker.addPanel('pnl_properties', wcDocker.DOCK_STACKED, dashboardPanel); - sqlPanel = docker.addPanel('pnl_sql', wcDocker.DOCK_STACKED, dashboardPanel); - statisticsPanel = docker.addPanel('pnl_statistics', wcDocker.DOCK_STACKED, dashboardPanel); - dependenciesPanel = docker.addPanel('pnl_dependencies', wcDocker.DOCK_STACKED, dashboardPanel); - dependentsPanel = docker.addPanel('pnl_dependents', wcDocker.DOCK_STACKED, dashboardPanel); - browserPanel = docker.addPanel('pnl_browser', wcDocker.DOCK_LEFT, browserPanel); -} - -function report_error(message, info) { - - text = '
    \ -
    \ - \ -
    \ -
    ' + message + '
    \ -
    \ -
    ' - - if (info != null && info != '') { - text += '
    \ - \ -
    \ -
    ' + info + '
    \ -
    \ -
    \ -
    ' - } - - text += '
    ' - - alertify.alert( - '{{ _('An error has occurred') }}', - text - ) -} - - -// Enable/disable menu options -function enable_disable_menus() { - - // Disable everything first - $("#mnu_create").html('\n'); - $("#mnu_drop_object").addClass("mnu-disabled"); - $("#mnu_rename_object").addClass("mnu-disabled"); - node_type = get_selected_node_type() - - // List the possible standard items, their types and actions - var handlers = [{% for standard_item in menu_items.standard_items %} - "{{ standard_item.type }}:{{ standard_item.action }}",{% endfor %} - ] - - // Check if we have a matching action for the object type in the list, and - // if so, enable the menu item - if ($.inArray(node_type + ":drop", handlers) >= 0) - $("#mnu_drop_object").removeClass("mnu-disabled"); - - if ($.inArray(node_type + ":rename", handlers) >= 0) - $("#mnu_rename_object").removeClass("mnu-disabled"); - - // List the possibe create items - var creators = [{% for create_item in menu_items.create_items %} - [{{ create_item.types | tojson }}, "{{ create_item.name }}", "{{ create_item.label }}", "{{ create_item.function }}"],{% endfor %} - ] - - // Loop through the list of creators and add links for any that apply to this - // node type to the Create menu's UL element - items = '' - - for (i = 0; i < creators.length; ++i) { - if ($.inArray(node_type, creators[i][0]) >= 0) { - items = items + '\n' - } - } - if (items != '') - $("#mnu_create").html(items); -} - -// Get the selected treeview item type, or nowt -function get_selected_node_type() { - item = tree.selected() - if (!item || item.length != 1) - return ""; - - return tree.itemData(tree.selected())._type; -} - -// Create a new object of the type currently selected -function create_object() { - node_type = get_selected_node_type() - if (node_type == "") - return; - - switch(node_type) { - {% for standard_item in menu_items.standard_items %}{% if standard_item.action == 'create' %} - case '{{ standard_item.type }}': - {{ standard_item.function }}() - break; - {% endif %}{% endfor %} - } -} - -// Drop the selected object -function drop_object() { - node_type = get_selected_node_type() - if (node_type == "") - return; - - switch(node_type) { - {% for standard_item in menu_items.standard_items %}{% if standard_item.action == 'drop' %} - case '{{ standard_item.type }}': - {{ standard_item.function }}(tree.selected()) - break; - {% endif %}{% endfor %} - } -} - -// Rename the selected object -function rename_object() { - node_type = get_selected_node_type() - if (node_type == "") - return; - - switch(node_type) { - {% for standard_item in menu_items.standard_items %}{% if standard_item.action == 'rename' %} - case '{{ standard_item.type }}': - {{ standard_item.function }}(tree.selected()) - break; - {% endif %}{% endfor %} - } -} - - -// Setup the browser -$(document).ready(function(){ - - docker = new wcDocker('.dockerContainer'); - if (docker) { - - demoSql = '-- DROP TABLE tickets_detail; \n\ - \n\ + // TODO:: Remove dmeo SQL (once completed) + var demoSql = '-- DROP TABLE tickets_detail; \n\ +\n\ CREATE TABLE tickets_detail \n\ ( \n\ id serial NOT NULL, \n\ @@ -226,132 +29,564 @@ CREATE TABLE tickets_detail \n\ msgid character varying(100), \n\ CONSTRAINT tickets_detail_pkey PRIMARY KEY (id), \n\ CONSTRAINT ticket_id_refs_id_6b8dc130 FOREIGN KEY (ticket_id) \n\ - REFERENCES tickets_ticket (id) MATCH SIMPLE \n\ - ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED, \n\ + REFERENCES tickets_ticket (id) MATCH SIMPLE \n\ + ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED, \n\ CONSTRAINT tickets_detail_logger_id_fkey FOREIGN KEY (logger_id) \n\ - REFERENCES auth_user (id) MATCH SIMPLE \n\ - ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED \n\ + REFERENCES auth_user (id) MATCH SIMPLE \n\ + ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED \n\ ) \n\ WITH ( \n\ OIDS=FALSE \n\ ); \n\ ALTER TABLE tickets_detail \n\ - OWNER TO helpdesk;\n'; +OWNER TO helpdesk;\n'; - buildPanel(docker, 'pnl_browser', '{{ _('Browser') }}', 300, 600, false, false, true, - '
    ') - buildIFramePanel(docker, 'pnl_dashboard', '{{ _('Dashboard') }}', 500, 600, true, false, true, - 'http://www.pgadmin.org/') - buildPanel(docker, 'pnl_properties', '{{ _('Properties') }}', 500, 600, true, false, true, - '

    Properties pane

    ') - buildPanel(docker, 'pnl_sql', '{{ _('SQL') }}', 500, 600, true, false, true, - '') - buildPanel(docker, 'pnl_statistics', '{{ _('Statistics') }}', 500, 600, true, false, true, - '

    Statistics pane

    ') - buildPanel(docker, 'pnl_dependencies', '{{ _('Dependencies') }}', 500, 600, true, false, true, - '

    Depedencies pane

    ') - buildPanel(docker, 'pnl_dependents', '{{ _('Dependents') }}', 500, 600, true, false, true, - '

    Dependents pane

    ') + var panelEvents = {}; + panelEvents[wcDocker.EVENT_VISIBILITY_CHANGED] = function() { - // Add hooked-in panels - {% for panel_item in current_app.panels %}{% if panel_item.isIframe %} - buildIFramePanel(docker, '{{ panel_item.name }}', '{{ panel_item.title }}', - {{ panel_item.width }}, {{ panel_item.height }}, - {{ panel_item.showTitle|lower }}, {{ panel_item.isCloseable|lower }}, - {{ panel_item.isPrivate|lower }}, '{{ panel_item.content }}') - {% else %} - buildPanel(docker, '{{ panel_item.name }}', '{{ panel_item.title }}', - {{ panel_item.width }}, {{ panel_item.height }}, - {{ panel_item.showTitle|lower }}, {{ panel_item.isCloseable|lower }}, - {{ panel_item.isPrivate|lower }}, '{{ panel_item.content }}') - {% endif %}{% endfor %} + if (this.isVisible()) { + var obj = pgAdmin.Browser, + i = obj.tree.selected(), + d = i && i.length == 1 ? obj.tree.itemData(i) : undefined; + if (d && obj.Nodes[d._type].callbacks['selected'] && + _.isFunction(obj.Nodes[d._type].callbacks['selected'])) { + return obj.Nodes[d._type].callbacks['selected'].apply( + obj.Nodes[d._type], + [{ data: d, browser: obj, item: i }]); + } + } + }; + + // Extend the browser class attributes + _.extend(pgAdmin.Browser, { + // The base url for browser + URL: {{ url_for('browser.index') }}, + // We do have docker of type wcDocker to take care of different + // containers. (i.e. panels, tabs, frames, etc.) + docker:null, + // Reversed Engineer query for the selected database node object goes + // here + editor:null, + // Left hand browser tree + tree:null, + // list of script to be loaded, when a certain type of node is loaded + // It will be used to register extensions, tools, child node scripts, + // etc. + scripts: {}, + // Default panels + panels: { + // Panel to keep the left hand browser tree + 'browser': new pgAdmin.Browser.Panel({ + name: 'browser', + title: '{{ _('Browser') }}', + showTitle: false, + isCloseable: false, + isPrivate: true, + content: '
    ' + }), + // Properties of the object node + 'properties': new pgAdmin.Browser.Panel({ + name: 'properties', + title: '{{ _('Properties') }}', + width: 500, + isCloseable: false, + isPrivate: true, + content: '
    No object selected!
    ', + events: panelEvents + }), + // Statistics of the object + 'statistics': new pgAdmin.Browser.Panel({ + name: 'statistics', + title: '{{ _('Statistics') }}', + width: 500, + isCloseable: false, + isPrivate: true, + content: '

    Statistics pane

    ', + events: panelEvents + }), + // Reversed engineered SQL for the object + 'sql': new pgAdmin.Browser.Panel({ + name: 'sql', + title: '{{ _('SQL') }}', + width: 500, + isCloseable: false, + isPrivate: true, + // TODO:: Revove demoSql later + content: '', + events: panelEvents + }), + // Dependencies of the object + 'dependencies': new pgAdmin.Browser.Panel({ + name: 'dependencies', + title: '{{ _('Dependencies') }}', + width: 500, + isCloseable: false, + isPrivate: true, + content: '

    Depedencies pane

    ', + events: panelEvents + }), + // Dependents of the object + 'dependents': new pgAdmin.Browser.Panel({ + name: 'dependents', + title: '{{ _('Dependents') }}', + width: 500, + isCloseable: false, + isPrivate: true, + content: '

    Dependent pane

    ', + events: panelEvents + })/* Add hooked-in panels by extensions */{% for panel_item in current_app.panels %}{% if not panel_item.isIframe %},'{{ panel_item.name }}' : new pgAdmin.Browser.Panel({ + name: '{{ panel_item.name }}', + title: '{{ panel_item.title }}', + width: {{ panel_item.width }}, + height: {{ panel_item.height }}, + showTitle: (Boolean('{{ panel_item.showTitle|lower }}') == true), + isCloseable: (Boolean('{{ panel_item.isCloseable|lower }}') == true), + isPrivate: (Boolean('{{ panel_item.isPrivate|lower }}') == true), + content: '{{ panel_item.content }}'{% if panel_item.events is not none %}, + events: {{ panel_item.events }} {% endif %} + }){% endif %}{% endfor %} + }, + // We also support showing dashboards, HTML file, external URL + frames: { + // Dashboard + 'dashboard': new pgAdmin.Browser.Frame({ + name: 'dashboard', + title: '{{ _('Dashboard') }}', + width: 500, + isCloseable: false, + isPrivate: true, + url: 'about:blank' /* TODO:: Change it with http://www.pgadmin.org later */ + })/* Add hooked-in frames by extensions */{% for panel_item in current_app.panels %}{% if panel_item.isIframe %}, + '{{ panel_item.name }}' : new pgAdmin.Browser.Frame({ + name: '{{ panel_item.name }}', + title: '{{ panel_item.title }}', + width: {{ panel_item.width }}, + height: {{ panel_item.height }}, + showTitle: (Boolean('{{ panel_item.showTitle|lower }}') == true), + isCloseable: (Boolean('{{ panel_item.isCloseable|lower }}') == true), + isPrivate: (Boolean('{{ panel_item.isPrivate|lower }}') == true), + url: '{{ panel_item.content }}' + }){% endif %}{% endfor %} + }, + /* Menus */ + // pgAdmin.Browser.MenuItem.add_menus(...) will register all the menus + // in this container + menus: { + // All context menu goes here under certain menu types. + // i.e. context: {'server': [...], 'server-group': [...]} + context: {}, + // File menus + file: {}, + // Edit menus + edit: {}, + // Object menus + object: {}, + // Management menus + management: {}, + // Tools menus + tools: {}, + // Help menus + help: {} + }, + // A callback to load/fetch a script when a certain node is loaded + register_script: function(n, m, p) { + var scripts = this.scripts; + scripts[n] = _.isArray(scripts[n]) ? scripts[n] : []; + scripts[n].push({'name': m, 'path': p, loaded: false}); + }, + // Build the default layout + buildDefaultLayout: function() { + this.docker.addPanel('dashboard', wcDocker.DOCK_RIGHT); + this.docker.addPanel('properties', wcDocker.DOCK_STACKED, + this.frames['dashboard'].panel); + this.docker.addPanel('sql', wcDocker.DOCK_STACKED, + this.frames['dashboard'].panel); + this.docker.addPanel('statistics', wcDocker.DOCK_STACKED, + this.frames['dashboard'].panel); + this.docker.addPanel('dependencies', wcDocker.DOCK_STACKED, + this.frames['dashboard'].panel); + this.docker.addPanel('dependents', wcDocker.DOCK_STACKED, + this.frames['dashboard'].panel); + this.docker.addPanel('browser', wcDocker.DOCK_LEFT, + this.frames['dashboard'].panel); + }, + // Enable/disable menu options + enable_disable_menus: function(item) { + // Mechanism to enable/disable menus depending on the condition. + var obj = this, j, e, + // menu navigation bar + navbar = $('#navbar-menu > ul').first(), + // Drop down menu for objects + obj_mnu = navbar.find('li#mnu_obj > ul#mnu_dropdown_obj').first(), + // Drop down menu for create object + create_mnu = navbar.find("#mnu_create_obj").empty(), + // data for current selected object + d = this.tree.itemData(item); + // All menus from the object menus (except the create drop-down + // menu) needs to be removed. + obj_mnu.children("li:not(:first-child)").remove(); + // Create a dummy 'no object seleted' menu + create_mnu.html('\n'); + + // All menus (except for the object menus) are already present. + // They will just require to check, wheather they are + // enabled/disabled. + _.each([ + {m: 'file', id: '#mnu_file'}, + {m: 'edit', id: '#mnu_edit'}, + {m: 'management', id: '#mnu_management'}, + {m: 'tools', id: '#mnu_tools'}, + {m: 'help', id:'#mnu_help'}], function(o) { + j = navbar.children(o.id).children('.dropdown-menu').first(); + _.each(obj.menus[o.m], + function(v, k) { + // Remove disabled class in any case first. + e = j.find('#' + k).closest('.menu-item').removeClass('disabled'); + if (v.disabled(obj)) { + // Make this menu disabled + e.addClass('disabled'); + } + }); + }); + + // Create the object menu dynamically + if (item && this.menus['object'] && this.menus['object'][d._type]) { + var create_items = []; + // The menus will be created based on the priority given. + // Menu with lowest value has the highest priority. + _.each(_.sortBy( + this.menus['object'][d._type], + function(o) { return o.priority; }), + function(m) { + if (m.category && m.category == 'create') { + create_items.push(m.generate()); + } else { + obj_mnu.append(m.generate()); + } + }); + // Create menus goes seperately + if (create_items.length > 0) { + create_mnu.empty(); + _.each(create_items, function(c) { + create_mnu.append(c); + }); + } + } + + }, + init: function() { + var obj=this; + + // Store the main browser layout + $(window).bind('unload', function() { + if(obj.docker) { + state = obj.docker.save(); + settings = { setting: "Browser/Layout", value: state }; + $.post("{{ url_for('settings.store') }}", settings); + } + return true; + }); + + // Initialize the Docker + obj.docker = new wcDocker( + '#dockerContainer', { + allowContextMenu: false + }); + if (obj.docker) { + // Initialize all the panels + _.each(obj.panels, function(panel, name) { + obj.panels[name].load(obj.docker); + }); + // Initialize all the frames + _.each(obj.frames, function(frame, name) { + obj.frames[name].load(obj.docker); + }); + + // Stored layout in database from the previous session var layout = '{{ layout }}'; // Try to restore the layout if there is one if (layout != '') { - try { - docker.restore(layout) - } - catch(err) { - docker.clear() - buildDefaultLayout() - } + try { + obj.docker.restore(layout) + } + catch(err) { + obj.docker.clear() + obj.buildDefaultLayout() + } } else { - buildDefaultLayout() + obj.buildDefaultLayout() } - } + } - // Syntax highlight the SQL Pane - editor = CodeMirror.fromTextArea(document.getElementById("sql-textarea"), { - lineNumbers: true, - mode: "text/x-sql", - readOnly: true, - }); + // Syntax highlight the SQL Pane + obj.editor = CodeMirror.fromTextArea( + document.getElementById("sql-textarea"), { + lineNumbers: true, + mode: "text/x-sql", + readOnly: true, + }); - // Initialise the treeview - $('#tree').aciTree({ + // Initialise the treeview + $('#tree').aciTree({ ajax: { - url: '{{ url_for('browser.get_nodes') }}', - converters: { - 'text json': function(payload) { - return $.parseJSON(payload).data; - } + url: '{{ url_for('browser.get_nodes') }}', + converters: { + 'text json': function(payload) { + return $.parseJSON(payload).data; } + } }, ajaxHook: function(item, settings) { - if (item != null) { - var d = this.itemData(item); - settings.url = '{{ url_for('browser.index') }}' + d._type + '/nodes/' + d.refid - } + if (item != null) { + var d = this.itemData(item); + settings.url = '{{ url_for('browser.index') }}' + d._type + '/nodes/' + (d.refid ? d.refid + '/' : '') + d._id + } } - }); - tree = $('#tree').aciTree('api'); + }); - // Build the treeview context menu - $('#tree').contextMenu({ + obj.tree = $('#tree').aciTree('api'); + + // Build the treeview context menu + $('#tree').contextMenu({ selector: '.aciTreeLine', build: function(element) { - var item = tree.itemFrom(element); - var menu = { }; - var createMenu = { }; + var item = obj.tree.itemFrom(element), + menu = { }, + createMenu = { }, + d = obj.tree.itemData(item), + menus = obj.menus['context'][d._type], + cb = function(name) { + var o = undefined; - {% for create_item in menu_items.create_items %} - if ($.inArray(tree.itemData(item)._type, {{ create_item.types | tojson }}) >= 0) { - createMenu['{{ create_item.name }}'] = { name: '{{ create_item.label }}', callback: function() { {{ create_item.function }}() }}; + _.each(menus, function(m) { + if (name == (m.module.type + '_' + m.callback)) { + o = m; + } + }); + + if (o) { + var cb; + if (o.module['callbacks'] && ( + o.callback in o.module['callbacks'])) { + cb = o.module['callbacks'][o.callback]; + } else if (o.callback in o.module) { + cb = o.module[o.callback]; + } + + if (cb) { + var args = {item: item}; + cb.apply(o.module, [_.extend(args, o.data)]); + } else { + pgAdmin.Browser.report_error( + S('Developer Warning: Callback - "%s" not found!'). + sprintf(o.cb).value()); + } } - {% endfor %} + }; - menu["create"] = { "name": "Create" } - menu["create"]["items"] = createMenu + _.each( + _.sortBy(menus, function(m) { return m.priority; }), + function(m) { + if (m.category == 'create') + createMenu[m.module.type + '_' + m.callback] = { name: m.label }; + }); - {% for context_item in menu_items.context_items %} - if (tree.itemData(item)._type == '{{ context_item.type }}') { - menu['{{ context_item.name }}'] = { name: '{{ context_item.label }}', callback: function() { {{ context_item.onclick }} }}; + menu["create"] = { "name": "{{ _('Create') }}" } + menu["create"]["items"] = createMenu + + _.each( + _.sortBy(menus, function(m) { return m.priority; }), + function(m) { + if (m.category != 'create') + menu[m.module.type + '_' + m.callback] = { name: m.label }; + }); + + return { + autoHide: true, + items: menu, + callback: cb + }; + } + }); + + // Treeview event handler + $('#tree').on('acitree', function(event, api, item, eventName, options) { + var d = null; + if (item) { + d = obj.tree.itemData(item); + if (d && obj.Nodes[d._type] && + _.isObject(obj.Nodes[d._type].callbacks) && + eventName in obj.Nodes[d._type].callbacks && + typeof obj.Nodes[d._type].callbacks[eventName] == + 'function') { + return obj.Nodes[d._type].callbacks[eventName].apply( + obj.Nodes[d._type], [{ + data: d, browser: obj, item: item, + eventName: eventName, options: options + }]); + } + } + switch (eventName) { + // When a node is added in the browser tree, we need to + // load the registered scripts + case "added": + if (d) { + /* Loading all the scripts registered to be loaded on this node */ + if (obj.scripts && obj.scripts[d._type]) { + _.each(obj.scripts[d._type], function(s) { + if (!s.loaded) { + require([s.name], function(m) { + s.loaded = true; + // Call the initialize (if present) + if (m && m.init && typeof m.init == 'function') { + try { + m.init(); + } catch (err) { + obj.report_error( + '{{ _('Error Initializing script - ') }}' + s.path, err); + } + } + }, function() { + obj.report_error( + '{{ _('Error loading script - ') }}' + s.path); + }); + } + }); + } } - {% endfor %} - return { - autoHide: true, - items: menu, - callback: null - }; + break; } - }); + }); - // Treeview event handler - $('#tree').on('acitree', function(event, api, item, eventName, options){ - switch (eventName){ - case "selected": - enable_disable_menus() - break; + // There are some scripts which needed to be loaded immediately, + // but - not all. We will will need to generate all the menus only + // after they all were loaded completely. + var counter = {total: 0, loaded: 0}; + {% for script in current_app.javascripts %}{% if 'when' in script %} + {% if script.when %}/* Registering '{{ script.path }}.js' to be loaded when a node '{{ script.when }}' is loaded */ + this.register_script('{{ script.when }}', '{{ script.name }}', '{{ script.path }}.js');{% else %}/* Loading '{{ script.path }}' */ + counter.total += 1; + this.load_module('{{ script.name }}', '{{ script.path }}', counter);{% endif %}{% endif %}{% endfor %} + + var geneate_menus = function() { + // Generate the menu items only when all the initial scripts + // were loaded completely. + // + // First - register the menus from the other + // modules/extensions. + if (counter.total == counter.loaded) { + {% set cnt = 1 %} + obj.add_menus([{% for key in ('File', 'Edit', 'Object' 'Tools', 'Management', 'Help') %}{% for item in current_app.menu_items['%s_items' % key.lower()] %}{% if cnt != 1 %}, {% endif %} { + name: "{{ item.name }}", + {% if item.module %}module: {{ item.module }}, + {% endif %}{% if item.url %}url: "{{ item.url }}", + {% endif %}{% if item.target %}target: "{{ item.target }}", + {% endif %}{% if item.callback %}callback: "{{ item.callback }}", + {% endif %}{% if item.icon %}icon: '{{ item.icon }}', + {% endif %}{% if item.data %}data: {{ item.data }}, + {% endif %}label: '{{ item.label }}', applies: ['{{ key.lower() }}'], + priority: {{ item.priority }}, + enable: '{{ item.enable }}' + }{% set cnt = cnt + 1 %}{% endfor %}{% set cnt = cnt + 1 %}{% endfor %}]); + obj.create_menus(); + } else { + // recall after some time + setTimeout(function() { geneate_menus(); }, 300); } - }); + }; + geneate_menus(); + }, + // load the module right now + load_module: function(name, path, c) { + require([name],function(m) { + try { + // initialze the module (if 'init' function present). + if (m.init && typeof(m.init) == 'function') + m.init(); + } catch (e) { + obj.report_error( + '{{ _('Error loading script - ') }}' + path); + } + if (c) + c.loaded += 1; + }, function() { + /* TODO:: Show proper error */ + obj.report_error( + '{{ _('Error loading script - ') }}' + path); + }); + }, + // Add menus of module/extension at appropriate menu + add_menus: function(menus) { + var pgMenu = this.menus; + var MenuItem = pgAdmin.Browser.MenuItem; + _.each(menus, function(m) { + _.each(m.applies, function(a) { + /* We do support menu type only from this list */ + if ($.inArray(a, [ + 'context', 'file', 'edit', 'object', + 'management', 'tools', 'help']) >= 0) { + var menus; + pgMenu[a] = pgMenu[a] || {}; + if (_.isString(m.node)) { + menus = pgMenu[a][m.node] = pgMenu[a][m.node] || {}; + } else { + menus = pgMenu[a]; + } - // Setup the menus - enable_disable_menus() + if (_.has(menus, m.name)) { + console.log(m.name + + ' has been ignored!\nIt is already exist in the ' + + a + + ' list of menus!'); + } else { + menus[m.name] = new MenuItem({ + name: m.name, label: m.label, module: m.module, + category: m.category, callback: m.callback, + priority: m.priority, data: m.data, url: m.url, + icon: m.icon, enable: (m.enable == '' ? true : + (_.isString(m.enable) && + m.enable.toLowerCase() == 'false') ? + false : m.enable) + }); + } + } else { + console && console.log && + console.log( + "Developer warning: Category '" + + a + + "' is not supported!\nSupported categories are: context, file, edit, object, tools, management, help"); + } + }); + }); + }, + // Create the menus + create_menus: function() { + /* Create menus */ + var navbar = $('#navbar-menu > ul').first(); + var obj = this; + + _.each([ + {menu: 'file', id: '#mnu_file'}, + {menu: 'edit', id: '#mnu_edit'}, + {menu: 'management', id: '#mnu_management'}, + {menu: 'tools', id: '#mnu_tools'}, + {menu: 'help', id:'#mnu_help'}], function(o) { + var j = navbar.children(o.id).children('.dropdown-menu').first().empty(); + _.each( + _.sortBy(obj.menus[o.menu], + function(v, k) { return v.priority; }), + function(v) { + j.closest('.dropdown').removeClass('hide'); + j.append(v.generate()); + }); + navbar.children('#mnu_obj').removeClass('hide'); + }); + obj.enable_disable_menus(); + } + }); + + return pgAdmin.Browser; }); - -{% for snippet in jssnippets %} - {{ snippet }} -{% endfor %} diff --git a/web/pgadmin/browser/templates/browser/js/error.js b/web/pgadmin/browser/templates/browser/js/error.js new file mode 100644 index 000000000..64ac56852 --- /dev/null +++ b/web/pgadmin/browser/templates/browser/js/error.js @@ -0,0 +1,46 @@ +define( + ['underscore', 'alertify', 'pgadmin'], +function(_, alertify, pgAdmin) { + pgAdmin.Browser = pgAdmin.Browser || {}; + + _.extend(pgAdmin.Browser, { + report_error: function(message, info) { + text = '
    \ +
    \ + \ +
    \ +
    ' + message + '
    \ +
    \ +
    '; + + if (info != null && info != '') { + text += '
    \ + \ +
    \ +
    ' + unescape(info) + '
    \ +
    \ +
    \ +
    ' + } + + text += '
    ' + alertify.alert( + "{{ _('An error has occurred') }}", + text + ) + }, + }); + + return pgAdmin.Browser.report_error; +}); diff --git a/web/pgadmin/browser/templates/browser/js/node.js b/web/pgadmin/browser/templates/browser/js/node.js new file mode 100644 index 000000000..a2ee3d68e --- /dev/null +++ b/web/pgadmin/browser/templates/browser/js/node.js @@ -0,0 +1,846 @@ +define( + ['jquery', 'underscore', 'underscore.string', 'pgadmin', 'pgadmin.browser.menu', + 'backbone', 'alertify', 'backform', 'pgadmin.backform', 'wcdocker'], +function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) { + + var pgBrowser = pgAdmin.Browser = pgAdmin.Browser || {}; + var wcDocker = window.wcDocker; + + // It has already been defined. + // Avoid running this script again. + if (pgBrowser.Node) + return pgBrowser.Node; + + pgBrowser.Nodes = pgBrowser.Nodes || {}; + + // A helper (base) class for all the nodes, this has basic + // operations/callbacks defined for basic operation. + pgBrowser.Node = function() {}; + + // Helper function to correctly set up the property chain, for subclasses. + // Uses a hash of class properties to be extended. + // + // It is unlikely - we will instantiate an object for this class. + // (Inspired by Backbone.extend function) + pgBrowser.Node.extend = function(props) { + var parent = this; + var child; + + // The constructor function for the new subclass is defined to simply call + // the parent's constructor. + child = function(){ return parent.apply(this, arguments); }; + + // Add static properties to the constructor function, if supplied. + _.extend(child, parent, _.omit(props, 'callbacks')); + + // Make sure - a child have all the callbacks of the parent. + child.callbacks = _.extend({}, parent.callbacks, props.callbacks); + + // Registering the node by calling child.Init(...) function + child.Init.apply(child); + + // Initialize the parent + this.Init.apply(child); + + return child; + }; + + // Defines - which control needs to be instantiated in different modes. + // i.e. Node properties, create, edit, etc. + var controlType = { + 'properties': { + 'int': 'uneditable-input', + 'text': 'uneditable-input', + 'numeric': 'uneditable-input', + 'date': 'date', + 'boolean': 'bool-text', + 'options': 'uneditable-input', + 'multiline': 'textarea' + }, + 'edit': { + 'int': 'input', + 'text': 'input', + 'numeric': 'input', + 'date': 'date', + 'boolean': 'boolean', + 'options': 'select', + 'multiline': 'textarea' + }, + 'create': { + 'int': 'input', + 'text': 'input', + 'numeric': 'input', + 'date': 'date', + 'boolean': 'boolean', + 'options': 'select', + 'multiline': 'textarea' + } + }; + + _.extend(pgAdmin.Browser.Node, { + // Node type + type: undefined, + // Label + label: '', + title: function(d) { + return d ? d.label : ''; + }, + /////// + // Initialization function + // Generally - used to register the menus for this type of node. + // + // Also, look at pgAdmin.Browser.add_menus(...) function. + // + // NOTE: Override this for each node for initialization purpose + Init: function() { + if (this.node_initialized) + return; + this.node_initialized = true; + + pgAdmin.Browser.add_menus([{ + name: 'show_obj_properties', node: this.type, module: this, + applies: ['object', 'context'], callback: 'show_obj_properties', + priority: 3, label: '{{ _("Properties...") }}', + data: {'action': 'properties'}, icon: 'fa fa-th-list' + }]); + }, + /////// + // Generate a Backform view using the node's model type + // + // Used to generate view for the particular node properties, edit, + // creation. + getView: function(type, el, node, formType, callback) { + + if (!this.type || this.type == '' || !type in controlType) + // We have no information, how to generate view for this type. + return null; + + if (this.model) { + // This will be the URL, used for object manipulation. + // i.e. Create, Update in these cases + var urlBase = this.generate_url(type, node); + + if (!urlBase) + // Ashamed of myself, I don't know how to manipulate this + // node. + return null; + + var opts = {}; + + // In order to get the object data from the server, we must set + // object-id in the model (except in the create mode). + if (type !== 'create') { + opts[this.model.idAttribute || 'id'] = node._id; + } + + // We know - which data model to be used for this object. + var newModel = new (this.model.extend({urlRoot: urlBase}))(opts); + + // 'schema' has the information about how to generate the form. + if (newModel.schema && _.isArray(newModel.schema)) { + var groups = {}; + + _.each(newModel.schema, function(f) { + // Do we understand - what control, we're creating + // here? + if (f && f.mode && _.isObject(f.mode) && + _.indexOf(f.mode, type) != -1 && + type in controlType) { + // Each field is kept in specified group, or in + // 'General' category. + var group = f.group || '{{ _("General") }}'; + + // Generate the empty group list (if not exists) + if (!groups[group]) { + groups[group] = []; + } + + // Temporarily store in dictionaly format for + // utilizing it later. + groups[group].push({ + name: f.id, label: f.label, + control: controlType[type][f.type], + // Do we need to show this control in this mode? + show: f.show && newModel[f.show] && + typeof newModel[f.show] == "function" ? + newModel[f.show] : undefined, + // This can be disabled in some cases (if not hidden) + disable: f.disable && newModel[f.disable] && + typeof newModel[f.disable] == "function" ? + newModel[f.disable] : undefined, + options: f.options + }); + } + }); + + // Do we have fields to genreate controls, which we + // understand? + if (_.isEmpty(groups)) { + return null; + } + + var fields = []; + // This will contain the actual view + var view; + + // Create an array from the dictionary with proper required + // structure. + _.each(groups, function(val, key) { + fields.push({label: key, fields: val}); + }); + + if (formType == 'fieldset') { + // It is used to show, edit, create the object in the + // properties tab. + view = new Backform.Fieldset({ + el: el, model: newModel, schema: fields + }); + } else { + // This generates a view to be used by the node dialog + // (for create/edit operation). + view = new Backform.Dialog({ + el: el, model: newModel, schema: fields + }); + } + + if (!newModel.isNew()) { + // This is definetely not in create mode + newModel.fetch() + .success(function(res, msg, xhr) { + if (res) { + // We got the latest attributes of the + // object. Render the view now. + view.render(); + if (typeof(callback) != "undefined") { + callback(view); + } + } + }) + .error(function() { + // TODO:: Handle the error message properly. + }); + } else { + // Yay - render the view now! + view.render(); + if (typeof(callback) != "undefined") { + callback(view); + } + } + } + + return view; + } + + return null; + }, + register_node_panel: function() { + var w = pgBrowser.docker, + p = w.findPanels('node_props'); + + if (p && p.length == 1) + return; + + p = new pgBrowser.Panel({ + name: 'node_props', + showTitle: true, + isCloseable: false, + isPrivate: false, + content: '
    No object selected!
    ' + }); + p.load(pgBrowser.docker); + }, + /****************************************************************** + * This function determines the given item is deletable or not. + * + * Override this, when a node is not deletable. + */ + canDelete: function(i) { + return true; + }, + // List of common callbacks - that can be used for different + // operations! + callbacks: { + /****************************************************************** + * This function allows to create/edit/show properties of any + * object depending on the arguments provided. + * + * args must be a object containing: + * action - create/edit/properties + * item - The properties of the item (tree ndoe item) + * + * NOTE: + * if item is not provided, the action will be done on the + * currently selected tree item node. + * + **/ + show_obj_properties: function(args) { + var t = pgBrowser.tree, + i = args.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined + o = this, + l = o.title(d); + + // Make sure - the properties dialog type registered + pgBrowser.Node.register_node_panel(); + + // No node selected. + if (!d) + return; + + if (args.action == 'create') { + // If we've parent, we will get the information of it for + // proper object manipulation. + // + // You know - we're working with RDBMS, relation is everything + // for us. + if (this.parent_type && this.parent_type != d._type) { + // In browser tree, I can be under any node, But - that + // does not mean, it is my parent. + // + // We have some group nodes too. + // + // i.e. + // Tables, Views, etc. nodes under Schema node + // + // And, actual parent of a table is schema, not Tables. + while (i && t.hasParent(i)) { + i = t.parent(i); + pd = t.itemData(i); + + if (this.parent_type == pd._type) { + // Assign the data, this is my actual parent. + d = pd; + break; + } + } + } + + // Seriously - I really don't have parent data present? + // + // The only node - which I know - who does not have parent + // node, is the Server Group (and, comes directly under root + // node - which has no parent.) + if (!d || (d._type != this.parent_type && + this.parent_type != null)) { + // It should never come here. + // If it is here, that means - we do have some bug in code. + return; + } + + if (!d) + return; + + l = S('{{ _("Create - %%s") }}').sprintf( + [this.label]).value(); + p = pgBrowser.docker.addPanel('node_props', + wcDocker.DOCK_FLOAT, undefined, + {w: '500', h: '400'}); + setTimeout(function() { + o.showProperties(i, d, p, args.action); + }, 10); + } else { + if (pgBrowser.Node.panels && pgBrowser.Node.panels[d.id] && + pgBrowser.Node.panels[d.id].$container) { + p = pgBrowser.Node.panels[d.id]; + /** TODO :: + * Run in edit mode (if asked) only when it is + * not already been running edit mode + **/ + var mode = p.$container.attr('action-mode'); + if (mode) { + var msg = '{{ _('Are you sure wish to stop editing the properties of the %%s - "%%s"?') }}'; + if (args.action == 'edit') { + msg = '{{ _('Are you sure wish to reset the current changes, and reopen the panel for %%s = "%%s"?') }}'; + } + + Alertify.confirm( + '{{ _('Edit in progress?') }}', + S(msg).sprintf(o.label, d.label).value(), + function() { + setTimeout(function() { + o.showProperties(i, d, p, args.action); + }, 10); + }, + null).show(); + } else { + setTimeout(function() { + o.showProperties(i, d, p, args.action); + }, 10); + } + } else { + p = pgBrowser.docker.addPanel('node_props', + wcDocker.DOCK_FLOAT, undefined, + {w: '500', h: '400'}); + pgBrowser.Node.panels = pgBrowser.Node.panels || {}; + pgBrowser.Node.panels[d.id] = p; + + setTimeout(function() { + o.showProperties(i, d, p, args.action); + }, 10); + } + } + + p.title(l); + p.icon('icon-' + this.type); + + // Make sure the properties dialog is visible + p.focus(); + }, + // Delete the selected object + delete_obj: function(args) { + var input = args || {}; + obj = this, + t = pgBrowser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + + if (!d) + return; + + if (!pgBrowser.Nodes[d._type].canDelete(i)) { + Alertify.notify( + S('The %s - "%s" can not be deleted!') + .sprintf(obj.label, d.label).value(), + 'error', + 10 + ); + return; + } + + Alertify.confirm( + S('{{ _('Drop %%s?') }}').sprintf(obj.label).value(), + S('{{ _('Are you sure you wish to drop the %%s - "%%s"?') }}') + .sprintf(obj.label, d.label).value(), + function() { + $.ajax({ + url: obj.generate_url('drop', d, true), + type:'DELETE', + success: function(res) { + if (res.success == 0) { + pgBrowser.report_error(res.errormsg, res.info); + } else { + var n = t.next(i); + if (!n || !n.length) + n = t.prev(i); + t.remove(i); + if (n.length) { + t.select(n); + } + } + }, + error: function(jqx) { + var msg = jqx.responseText; + /* Error from the server */ + if (jqx.status == 410) { + try { + var data = $.parseJSON( + jqx.responseText); + msg = data.errormsg; + } catch (e) {} + } + pgBrowser.report_error( + S('{{ _('Error droping the %%s - "%%s"') }}') + .sprintf(obj.label, d.label) + .value(), msg); + } + }); + }, + null).show() + }, + // Callback called - when a node is selected in browser tree. + selected: function(o) { + // Show (One of these, whose panel is open) + // + Properties + // + Query + // + Dependents + // + Dependencies + // + Statistics + + // Update the menu items + pgAdmin.Browser.enable_disable_menus.apply(o.browser, [o.item]); + + if (o && o.data && o.browser) { + var br = o.browser; + if ('properties' in br.panels && + br.panels['properties'] && + br.panels['properties'].panel && + br.panels['properties'].panel.isVisible()) { + // Show object properties (only when the 'properties' tab + // is active). + this.showProperties(o.item, o.data, + pgBrowser.panels['properties'].panel); + } else if ('sql' in br.panels && + br.panels['sql'] && + br.panels['sql'].panel && + br.panels['sql'].panel.isVisible()) { + // Show reverse engineered query for this object (when + // the 'sql' tab is active.) + } else if ('statistics' in br.panels && + br.panels['statistics'] && + br.panels['statistics'].panel && + br.panels['statistics'].panel.isVisible()) { + // Show statistics for this object (when the + // 'statistics' tab is active.) + } else if ('dependencies' in br.panels && + br.panels['dependencies'] && + br.panels['dependencies'].panel && + br.panels['dependencies'].panel.isVisible()) { + // Show dependencies for this object (when the + // 'dependencies' tab is active.) + } else if ('dependents' in br.panels && + br.panels['dependents'] && + br.panels['dependents'].panel && + br.panels['dependents'].panel.isVisible()) { + // Show dependents for this object (when the + // 'dependents' tab is active.) + } + } + } + }, + /********************************************************************** + * A hook (not a callback) to show object properties in given HTML + * element. + * + * This has been used for the showing, editing properties of the node. + * This has also been used for creating a node. + **/ + showProperties: function(item, data, panel, action) { + var that = this, + tree = pgAdmin.Browser.tree, + j = panel.$container.find('.obj_properties').first(), + view = j.data('obj-view'), + content = $('
    ') + .addClass('has-pg-prop-btn-group pg-prop-content col-xs-12'), + // Template function to create the button-group + createButtons = function(buttons) { + // arguments must be non-zero length array of type + // object, which contains following attributes: + // label, type, extraClasses, register + if (buttons && _.isArray(buttons) && buttons.length > 0) { + // All buttons will be created within a single + // div area. + var btnGroup = + $('
    ').addClass( + 'pg-prop-btn-group col-xs-12' + ).appendTo(j), + // Template used for creating a button + tmpl = _.template([ + '' + ].join(' ')); + _.each(buttons, function(btn) { + // Create the actual button, and append to + // the group div + + // icon may not present for this button + if (!btn.icon) { + btn.icon = ""; + } + var b = $(tmpl(btn)); + btnGroup.append(b); + // Register is a callback to set callback + // for certain operatio for this button. + btn.register(b); + }); + return btnGroup; + } + return null; + }, + // Callback to show object properties + properties = function() { + // We need to release any existing view, before + // creating new view. + if (view) { + // Release the view + view.remove(); + // Deallocate the view + delete view; + view = null; + // Reset the data object + j.data('obj-view', null); + } + // Make sure the HTML element is empty. + j.empty(); + // Create a view to show the properties in fieldsets + view = that.getView('properties', content, data, 'fieldset'); + if (view) { + // Save it for release it later + j.data('obj-view', view); + // Create proper buttons + var buttons = []; + if (action) { + buttons.push({ + label: '{{ _("Close") }}', type: 'close', + extraClasses: ['btn-danger'], + icon: 'fa fa-lg fa-close', + register: function(btn) { + btn.click(function() { + closePanel(); + }); + } + }); + } + buttons.push({ + label: '{{ _("Edit") }}', type: 'edit', + extraClasses: ['btn-primary'], + icon: 'fa fa-lg fa-pencil-square-o', + register: function(btn) { + btn.click(function() { + onEdit(); + }); + } + }); + createButtons(buttons); + } + j.append(content); + }, + editFunc = function() { + if (action && action == 'properties') { + action = 'edit'; + } + panel.$container.attr('action-mode', action); + // We need to release any existing view, before + // creating the new view. + if (view) { + // Release the view + view.remove(); + // Deallocate the view + delete view; + view = null; + // Reset the data object + j.data('obj-view', null); + } + // Make sure the HTML element is empty. + j.empty(); + // Create a view to edit/create the properties in fieldsets + view = that.getView(action, content, data, 'fieldset'); + + if (view) { + // Save it to release it later + j.data('obj-view', view); + // Create proper buttons + createButtons([{ + label: '{{ _("Save") }}', type: 'save', + extraClasses: ['btn-primary'], + icon: 'fa fa-lg fa-save', + register: function(btn) { + // Save the changes + btn.click(function() { + + var m = view.model, + c = m.isNew() ? m.attributes : + m.changedAttributes(); + + if (c && !_.isEmpty(c)) { + m.save({} ,{ + attrs: (m.isNew() ? + m.attributes : + m.changedAttributes()), + success: function() { + onSaveFunc.call(); + }, + error: function() { + /* Reset the changed attributes on failure */ + m.changed = c; + + /* TODO:: Alert for the user on error */ + console.log('ERROR:'); + console.log(arguments); + } + }); + } + }); + } + },{ + label: '{{ _('Cancel') }}', type: 'cancel', + extraClasses: ['btn-danger'], + icon: 'fa fa-lg fa-close', + register: function(btn) { + btn.click(function() { + // Removing the action-mode + panel.$container.removeAttr('action-mode'); + onCancelFunc.call(arguments); + }); + } + },{ + label: '{{ _("Reset") }}', type: 'reset', + extraClasses: ['btn-warning'], + icon: 'fa fa-lg fa-recycle', + register: function(btn) { + btn.click(function() { + setTimeout(function() { editFunc.call(); }, 0); + }); + } + }]); + }; + // Show contents after buttons + j.append(content); + }, + closePanel = function() { + // Closing this panel + panel.close() + }, + updateTreeItem = function() { + // Update the item lable (if lable is modified.) + tree.setLabel(item, {label: view.model.get("name")}); + panel.$container.removeAttr('action-mode'); + setTimeout(function() { properties(); }, 0); + }, + saveNewNode = function() { + /* TODO:: Create new tree node for this */ + if (view.model.tnode) { + var d = _.extend({}, view.model.tnode), + func = function(i) { + /* Register this panel for this node */ + pgBrowser.Node.panels = + pgBrowser.Node.panels || {}; + pgBrowser.Node.panels[d.id] = panel; + panel.title(that.title(d)); + setTimeout(function() { + that.showProperties(i, d, panel, + 'properties'); + }, 0); + tree.setVisible(i); + tree.select(i); + }; + + delete view.model.tnode; + + if (that.parent_type) { + if (tree.wasLoad(item)) { + tree.append(item, { + itemData: d, + success: function(i, o) { + func(o.items.eq(0)); + } + }); + } else { + /* When no children found, it was loaded. + * It sets the item to non-inode. + */ + if (!tree.isInode(item)) { + tree.setInode(item); + } + tree.open(item, { + expand: true, + success: function() { + var s = tree.search(item, { + search: d.id, + callback: function(i, s) { + var data = tree.itemData(i); + + return (d._id == data._id); + }, + success: function(i, o) { + func(i); + }, + fail: function() { + console.log(arguments); + } + }); + + }, + fail: function() { + console.log(arguments); + } + }); + } + } else { + tree.append(null, { + itemData: d, + success: function(i, o) { + func(i); + } + }); + } + } + }, + editInNewPanel = function() { + // Open edit in separate panel + setTimeout(function() { + that.callbacks.show_obj_properties.apply(that, [{ + 'action': 'edit', + 'item': item + }]); + }, 0); + }, + onCancelFunc = properties, + onSaveFunc = updateTreeItem, + onEdit = editFunc; + + if (action) { + if (action == 'create'){ + onCancelFunc = closePanel; + onSaveFunc = saveNewNode; + } + if (action != 'properties') { + // We need to keep track edit/create mode for this panel. + editFunc(); + } else { + properties(); + } + } else { + /* Show properties */ + properties(); + onEdit = editInNewPanel; + } + }, + /********************************************************************** + * Generate the URL for different operations + * + * arguments: + * type: Create/drop/edit/properties/sql/depends/statistics + * d: Provide the ItemData for the current item node + * with_id: Required id information at the end? + * + * Supports url generation for create, drop, edit, properties, sql, + * depends, statistics + */ + generate_url: function(type, d, with_id) { + var url = pgAdmin.Browser.URL + '{TYPE}/{REDIRECT}{REF}', + ref = S('/%s/').sprintf(d._id).value(), + opURL = { + 'create': 'obj', 'drop': 'obj', 'edit': 'obj', + 'properties': 'obj', 'depends': 'deps', + 'statistics': 'stats' + }; + + if (d._type == this.type) { + ref = ''; + if (d.refid) + ref = S('/%s').sprintf(d.refid).value(); + if (with_id) + ref = S('%s/%s').sprintf(ref, d._id).value(); + } + + var args = { 'TYPE': this.type, 'REDIRECT': '', 'REF': ref }; + + if (type in opURL) { + args.REDIRECT = opURL[type]; + if (type == 'create' && !this.parent_type) { + args.REF = '/'; + } + } else { + args.REDIRECT = type; + } + + return url.replace(/{(\w+)}/g, function(match, arg) { + return args[arg]; + }); + }, + // Base class for Node Model + Model: Backbone.Model.extend({ + parse: function(res) { + if ('node' in res && res['node']) { + this.tnode = _.extend({}, res.node); + delete res.node; + } + return res; + } + }) + }); + + return pgAdmin.Browser.Node; +}); diff --git a/web/pgadmin/browser/utils.py b/web/pgadmin/browser/utils.py index db33120e8..b49fb2039 100644 --- a/web/pgadmin/browser/utils.py +++ b/web/pgadmin/browser/utils.py @@ -9,19 +9,24 @@ """Browser helper utilities""" -from flask import request +import flask from flask.views import View, MethodViewType, with_metaclass +from pgadmin.utils.ajax import make_json_response +import gettext -def generate_browser_node(node_id, label, icon, inode, node_type): - return { - "id": "%s/%s" % (node_type, node_id), - "label": label, - "icon": icon, - "inode": inode, - "_type": node_type, - "refid": node_id +def generate_browser_node(node_id, parent_id, label, icon, inode, node_type): + obj = { + "id": "%s/%s" % (node_type, node_id), + "label": label, + "icon": icon, + "inode": inode, + "_type": node_type, + "_id": node_id, + "refid": parent_id, + "module": 'pgadmin.node.%s' % node_type } + return obj class NodeView(with_metaclass(MethodViewType, View)): @@ -67,34 +72,32 @@ class NodeView(with_metaclass(MethodViewType, View)): In order to identify the TABLE object, we need server -> database -> schema information. """ - operations = { + operations = dict({ 'obj': [ {'get': 'properties', 'delete': 'delete', 'put': 'update'}, {'get': 'list', 'post': 'create'} ], - 'nodes': [{'get': 'nodes'}, {}], - 'sql': [{'get': 'sql', 'post': 'modified_sql'}, {}], - 'stats': [{'get': 'statistics'}, {}], - 'deps': [{'get': 'dependencies', 'post': 'dependents'}, {}] - } - + 'nodes': [{'get': 'nodes'}], + 'sql': [{'get': 'sql', 'post': 'modified_sql'}], + 'stats': [{'get': 'statistics'}], + 'deps': [{'get': 'dependencies', 'post': 'dependents'}] + }) @classmethod def generate_ops(cls): cmds = [] for op in cls.operations: - idx=0 + idx = 0 for ops in cls.operations[op]: meths = [] for meth in ops: meths.append(meth.upper()) if len(meths) > 0: - cmds.append({'cmd': op, 'req':idx==0, 'methods': meths}) - idx+=1 + cmds.append({'cmd': op, 'req': idx == 0, 'methods': meths}) + idx += 1 return cmds - # Inherited class needs to modify these parameters node_type = None # This must be an array object with attributes (type and id) @@ -102,30 +105,28 @@ class NodeView(with_metaclass(MethodViewType, View)): # This must be an array object with attributes (type and id) ids = [] - @classmethod def get_node_urls(cls): - assert cls.node_type is not None, "Please set the node_type for this class (%r)" % cls + assert cls.node_type is not None, \ + "Please set the node_type for this class ({0})".format( + str(cls.__class__.__name__)) common_url = '/' for p in cls.parent_ids: - common_url += '<' + p['type'] + ":" + p['id'] + '>/' + common_url += '<{0}:{1}>/'.format(str(p['type']), str(p['id'])) - id_url = common_url - idx = 0 + id_url = None for p in cls.ids: - id_url += '/<' if idx == 1 else '<' + p['type'] + ":" + p['id'] + '>' - idx += 1 + id_url = '{0}<{1}:{2}>'.format(common_url if not id_url else id_url, + p['type'], p['id']) return id_url, common_url - - def __init__(self, cmd): - self.cmd = cmd; - + def __init__(self, **kwargs): + self.cmd = kwargs['cmd'] # Check the existance of all the required arguments from parent_ids # and return combination of has parent arguments, and has id arguments - def check_args(self, *args, **kwargs): + def check_args(self, **kwargs): has_id = has_args = True for p in self.parent_ids: if p['id'] not in kwargs: @@ -139,33 +140,43 @@ class NodeView(with_metaclass(MethodViewType, View)): return has_args, has_id and has_args - def dispatch_request(self, *args, **kwargs): - meth = request.method.lower() + meth = flask.request.method.lower() if meth == 'head': meth = 'get' - assert self.cmd in NodeView.operations, \ - "Unimplemented Command (%s) for Node View" % self.cmd - has_args, has_id = self.check_args(*args, **kwargs) + assert self.cmd in self.operations, \ + "Unimplemented Command ({0}) for {1}".format( + self.cmd, + str(self.__class__.__name__)) + has_args, has_id = self.check_args(**kwargs) - assert (has_id and meth in NodeView.operations[self.cmd][0]) \ - or (not has_id and meth in NodeView.operations[self.cmd][1]), \ - "Unimplemented method (%s) for command (%s), which %s an id" \ - % (meth, self.cmd, 'requires' if has_id else 'does not require') + assert ((has_id and len(self.operations[self.cmd]) >= 0 and meth in + self.operations[self.cmd][0]) or ( + not has_id and len( + self.operations[self.cmd]) > 0 and meth in + self.operations[self.cmd][1])), \ + "Unimplemented method ({0}) for command ({1}), which {2} an id".format( + meth, self.cmd, + 'requires' if has_id else 'does not require') - meth = NodeView.operations[self.cmd][0][meth] if has_id else \ - NodeView.operations[self.cmd][1][meth] + meth = self.operations[self.cmd][0][meth] if has_id else \ + self.operations[self.cmd][1][meth] method = getattr(self, meth, None) - assert method is not None, \ - "Unimplemented method (%s) for this url (%u)" % \ - (meth, request.path) + if method is None: + return make_json_response( + status=406, + success=0, + errormsg=gettext.gettext( + "Unimplemented method ({0}) for this url ({1})".format( + meth, flask.request.path) + ) + ) return method(*args, **kwargs) - @classmethod def register_node_view(cls, blueprint): id_url, url = cls.get_node_urls() @@ -174,8 +185,8 @@ class NodeView(with_metaclass(MethodViewType, View)): for c in commands: blueprint.add_url_rule( - '/%s%s' % (c['cmd'], id_url if c['req'] else url), - view_func=cls.as_view( - '%s%s' % (c['cmd'], '_id' if c['req'] else ''), - cmd=c['cmd']), - methods=c['methods']) + '/{0}{1}'.format(c['cmd'], id_url if c['req'] else url), + view_func=cls.as_view( + '%s%s' % (c['cmd'], '_id' if c['req'] else ''), + cmd=c['cmd']), + methods=c['methods']) diff --git a/web/pgadmin/help/__init__.py b/web/pgadmin/help/__init__.py index 6d753f85e..113cd45f2 100644 --- a/web/pgadmin/help/__init__.py +++ b/web/pgadmin/help/__init__.py @@ -26,19 +26,19 @@ class HelpModule(PgAdminModule): MenuItem(name='mnu_online_help', label=gettext('Online Help'), priority=100, - target='_new', + target='blank', url=url_for('help.static', filename='index.html')), MenuItem(name='mnu_pgadmin_website', label= gettext('pgAdmin Website'), priority= 200, - target= '_new', + target= 'blank', url= 'http://www.pgadmin.org/' ), MenuItem(name= 'mnu_postgresql_website', label= gettext('PostgreSQL Website'), priority= 300, - target= '_new', + target= 'blank', url= 'http://www.postgresql.org/' )]} def get_panels(self): diff --git a/web/pgadmin/redirects/__init__.py b/web/pgadmin/redirects/__init__.py index 31c6fe587..c9a76d35a 100644 --- a/web/pgadmin/redirects/__init__.py +++ b/web/pgadmin/redirects/__init__.py @@ -1,3 +1,12 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2015, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + from pgadmin import PgAdminModule from flask.ext.security import login_required from flask import redirect, url_for @@ -13,6 +22,7 @@ def index(): """Redirect users hitting the root to the browser""" return redirect(url_for('browser.index')) + @blueprint.route('/favicon.ico') def favicon(): """Redirect to the favicon""" diff --git a/web/pgadmin/settings/__init__.py b/web/pgadmin/settings/__init__.py index e96f50e77..7d6ac731d 100644 --- a/web/pgadmin/settings/__init__.py +++ b/web/pgadmin/settings/__init__.py @@ -104,5 +104,3 @@ def get(setting=None, default=None): errormsg=errormsg, info=traceback.format_exc(), result=request.form) - - diff --git a/web/pgadmin/settings/settings_model.py b/web/pgadmin/settings/settings_model.py index 377272848..e0067e7c4 100644 --- a/web/pgadmin/settings/settings_model.py +++ b/web/pgadmin/settings/settings_model.py @@ -84,7 +84,6 @@ class Server(db.Model): db.ForeignKey('servergroup.id'), nullable=False ) - name = db.Column(db.String(128), nullable=False) host = db.Column(db.String(128), nullable=False) port = db.Column( @@ -94,8 +93,11 @@ class Server(db.Model): maintenance_db = db.Column(db.String(64), nullable=False) username = db.Column(db.String(64), nullable=False) ssl_mode = db.Column( - db.String(16), - db.CheckConstraint( - "ssl_mode IN ('allow', 'prefer', 'require', 'disable', 'verify-ca', 'verify-full')" - ), - nullable=False) + db.String(16), + db.CheckConstraint( + "ssl_mode IN ('allow', 'prefer', 'require', 'disable', 'verify-ca', 'verify-full')" + ), + nullable=False) + comment = db.Column( + db.String(1024), + nullable=True) diff --git a/web/pgadmin/static/css/bootstrap-datepicker3.css b/web/pgadmin/static/css/bootstrap-datepicker3.css new file mode 100644 index 000000000..fa369ca95 --- /dev/null +++ b/web/pgadmin/static/css/bootstrap-datepicker3.css @@ -0,0 +1,751 @@ +/*! + * Datepicker for Bootstrap v1.5.0-dev (https://github.com/eternicode/bootstrap-datepicker) + * + * Copyright 2012 Stefan Petre + * Improvements by Andrew Rowls + * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) + */ +.datepicker { + border-radius: 4px; + direction: ltr; +} +.datepicker-inline { + width: 220px; +} +.datepicker.datepicker-rtl { + direction: rtl; +} +.datepicker.datepicker-rtl table tr td span { + float: right; +} +.datepicker-dropdown { + top: 0; + left: 0; +} +.datepicker-dropdown:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-top: 0; + border-bottom-color: rgba(0, 0, 0, 0.2); + position: absolute; +} +.datepicker-dropdown:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #fff; + border-top: 0; + position: absolute; +} +.datepicker-dropdown.datepicker-orient-left:before { + left: 6px; +} +.datepicker-dropdown.datepicker-orient-left:after { + left: 7px; +} +.datepicker-dropdown.datepicker-orient-right:before { + right: 6px; +} +.datepicker-dropdown.datepicker-orient-right:after { + right: 7px; +} +.datepicker-dropdown.datepicker-orient-top:before { + top: -7px; +} +.datepicker-dropdown.datepicker-orient-top:after { + top: -6px; +} +.datepicker-dropdown.datepicker-orient-bottom:before { + bottom: -7px; + border-bottom: 0; + border-top: 7px solid #999; +} +.datepicker-dropdown.datepicker-orient-bottom:after { + bottom: -6px; + border-bottom: 0; + border-top: 6px solid #fff; +} +.datepicker > div { + display: none; +} +.datepicker.days .datepicker-days, +.datepicker.months .datepicker-months, +.datepicker.years .datepicker-years { + display: block; +} +.datepicker table { + margin: 0; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.datepicker table tr td, +.datepicker table tr th { + text-align: center; + width: 30px; + height: 30px; + border-radius: 4px; + border: none; +} +.table-striped .datepicker table tr td, +.table-striped .datepicker table tr th { + background-color: transparent; +} +.datepicker table tr td.day:hover, +.datepicker table tr td.day.focused { + background: #eeeeee; + cursor: pointer; +} +.datepicker table tr td.old, +.datepicker table tr td.new { + color: #999999; +} +.datepicker table tr td.disabled, +.datepicker table tr td.disabled:hover { + background: none; + color: #999999; + cursor: default; +} +.datepicker table tr td.today, +.datepicker table tr td.today:hover, +.datepicker table tr td.today.disabled, +.datepicker table tr td.today.disabled:hover { + color: #000000; + background-color: #ffdb99; + border-color: #ffb733; +} +.datepicker table tr td.today:hover, +.datepicker table tr td.today:hover:hover, +.datepicker table tr td.today.disabled:hover, +.datepicker table tr td.today.disabled:hover:hover, +.datepicker table tr td.today:focus, +.datepicker table tr td.today:hover:focus, +.datepicker table tr td.today.disabled:focus, +.datepicker table tr td.today.disabled:hover:focus, +.datepicker table tr td.today:active, +.datepicker table tr td.today:hover:active, +.datepicker table tr td.today.disabled:active, +.datepicker table tr td.today.disabled:hover:active, +.datepicker table tr td.today.active, +.datepicker table tr td.today:hover.active, +.datepicker table tr td.today.disabled.active, +.datepicker table tr td.today.disabled:hover.active, +.open .dropdown-toggle.datepicker table tr td.today, +.open .dropdown-toggle.datepicker table tr td.today:hover, +.open .dropdown-toggle.datepicker table tr td.today.disabled, +.open .dropdown-toggle.datepicker table tr td.today.disabled:hover { + color: #000000; + background-color: #ffcd70; + border-color: #f59e00; +} +.datepicker table tr td.today:active, +.datepicker table tr td.today:hover:active, +.datepicker table tr td.today.disabled:active, +.datepicker table tr td.today.disabled:hover:active, +.datepicker table tr td.today.active, +.datepicker table tr td.today:hover.active, +.datepicker table tr td.today.disabled.active, +.datepicker table tr td.today.disabled:hover.active, +.open .dropdown-toggle.datepicker table tr td.today, +.open .dropdown-toggle.datepicker table tr td.today:hover, +.open .dropdown-toggle.datepicker table tr td.today.disabled, +.open .dropdown-toggle.datepicker table tr td.today.disabled:hover { + background-image: none; +} +.datepicker table tr td.today.disabled, +.datepicker table tr td.today:hover.disabled, +.datepicker table tr td.today.disabled.disabled, +.datepicker table tr td.today.disabled:hover.disabled, +.datepicker table tr td.today[disabled], +.datepicker table tr td.today:hover[disabled], +.datepicker table tr td.today.disabled[disabled], +.datepicker table tr td.today.disabled:hover[disabled], +fieldset[disabled] .datepicker table tr td.today, +fieldset[disabled] .datepicker table tr td.today:hover, +fieldset[disabled] .datepicker table tr td.today.disabled, +fieldset[disabled] .datepicker table tr td.today.disabled:hover, +.datepicker table tr td.today.disabled:hover, +.datepicker table tr td.today:hover.disabled:hover, +.datepicker table tr td.today.disabled.disabled:hover, +.datepicker table tr td.today.disabled:hover.disabled:hover, +.datepicker table tr td.today[disabled]:hover, +.datepicker table tr td.today:hover[disabled]:hover, +.datepicker table tr td.today.disabled[disabled]:hover, +.datepicker table tr td.today.disabled:hover[disabled]:hover, +fieldset[disabled] .datepicker table tr td.today:hover, +fieldset[disabled] .datepicker table tr td.today:hover:hover, +fieldset[disabled] .datepicker table tr td.today.disabled:hover, +fieldset[disabled] .datepicker table tr td.today.disabled:hover:hover, +.datepicker table tr td.today.disabled:focus, +.datepicker table tr td.today:hover.disabled:focus, +.datepicker table tr td.today.disabled.disabled:focus, +.datepicker table tr td.today.disabled:hover.disabled:focus, +.datepicker table tr td.today[disabled]:focus, +.datepicker table tr td.today:hover[disabled]:focus, +.datepicker table tr td.today.disabled[disabled]:focus, +.datepicker table tr td.today.disabled:hover[disabled]:focus, +fieldset[disabled] .datepicker table tr td.today:focus, +fieldset[disabled] .datepicker table tr td.today:hover:focus, +fieldset[disabled] .datepicker table tr td.today.disabled:focus, +fieldset[disabled] .datepicker table tr td.today.disabled:hover:focus, +.datepicker table tr td.today.disabled:active, +.datepicker table tr td.today:hover.disabled:active, +.datepicker table tr td.today.disabled.disabled:active, +.datepicker table tr td.today.disabled:hover.disabled:active, +.datepicker table tr td.today[disabled]:active, +.datepicker table tr td.today:hover[disabled]:active, +.datepicker table tr td.today.disabled[disabled]:active, +.datepicker table tr td.today.disabled:hover[disabled]:active, +fieldset[disabled] .datepicker table tr td.today:active, +fieldset[disabled] .datepicker table tr td.today:hover:active, +fieldset[disabled] .datepicker table tr td.today.disabled:active, +fieldset[disabled] .datepicker table tr td.today.disabled:hover:active, +.datepicker table tr td.today.disabled.active, +.datepicker table tr td.today:hover.disabled.active, +.datepicker table tr td.today.disabled.disabled.active, +.datepicker table tr td.today.disabled:hover.disabled.active, +.datepicker table tr td.today[disabled].active, +.datepicker table tr td.today:hover[disabled].active, +.datepicker table tr td.today.disabled[disabled].active, +.datepicker table tr td.today.disabled:hover[disabled].active, +fieldset[disabled] .datepicker table tr td.today.active, +fieldset[disabled] .datepicker table tr td.today:hover.active, +fieldset[disabled] .datepicker table tr td.today.disabled.active, +fieldset[disabled] .datepicker table tr td.today.disabled:hover.active { + background-color: #ffdb99; + border-color: #ffb733; +} +.datepicker table tr td.today:hover:hover { + color: #000; +} +.datepicker table tr td.today.active:hover { + color: #fff; +} +.datepicker table tr td.range, +.datepicker table tr td.range:hover, +.datepicker table tr td.range.disabled, +.datepicker table tr td.range.disabled:hover { + background: #eeeeee; + border-radius: 0; +} +.datepicker table tr td.range.today, +.datepicker table tr td.range.today:hover, +.datepicker table tr td.range.today.disabled, +.datepicker table tr td.range.today.disabled:hover { + color: #000000; + background-color: #f7ca77; + border-color: #f1a417; + border-radius: 0; +} +.datepicker table tr td.range.today:hover, +.datepicker table tr td.range.today:hover:hover, +.datepicker table tr td.range.today.disabled:hover, +.datepicker table tr td.range.today.disabled:hover:hover, +.datepicker table tr td.range.today:focus, +.datepicker table tr td.range.today:hover:focus, +.datepicker table tr td.range.today.disabled:focus, +.datepicker table tr td.range.today.disabled:hover:focus, +.datepicker table tr td.range.today:active, +.datepicker table tr td.range.today:hover:active, +.datepicker table tr td.range.today.disabled:active, +.datepicker table tr td.range.today.disabled:hover:active, +.datepicker table tr td.range.today.active, +.datepicker table tr td.range.today:hover.active, +.datepicker table tr td.range.today.disabled.active, +.datepicker table tr td.range.today.disabled:hover.active, +.open .dropdown-toggle.datepicker table tr td.range.today, +.open .dropdown-toggle.datepicker table tr td.range.today:hover, +.open .dropdown-toggle.datepicker table tr td.range.today.disabled, +.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover { + color: #000000; + background-color: #f4bb51; + border-color: #bf800c; +} +.datepicker table tr td.range.today:active, +.datepicker table tr td.range.today:hover:active, +.datepicker table tr td.range.today.disabled:active, +.datepicker table tr td.range.today.disabled:hover:active, +.datepicker table tr td.range.today.active, +.datepicker table tr td.range.today:hover.active, +.datepicker table tr td.range.today.disabled.active, +.datepicker table tr td.range.today.disabled:hover.active, +.open .dropdown-toggle.datepicker table tr td.range.today, +.open .dropdown-toggle.datepicker table tr td.range.today:hover, +.open .dropdown-toggle.datepicker table tr td.range.today.disabled, +.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover { + background-image: none; +} +.datepicker table tr td.range.today.disabled, +.datepicker table tr td.range.today:hover.disabled, +.datepicker table tr td.range.today.disabled.disabled, +.datepicker table tr td.range.today.disabled:hover.disabled, +.datepicker table tr td.range.today[disabled], +.datepicker table tr td.range.today:hover[disabled], +.datepicker table tr td.range.today.disabled[disabled], +.datepicker table tr td.range.today.disabled:hover[disabled], +fieldset[disabled] .datepicker table tr td.range.today, +fieldset[disabled] .datepicker table tr td.range.today:hover, +fieldset[disabled] .datepicker table tr td.range.today.disabled, +fieldset[disabled] .datepicker table tr td.range.today.disabled:hover, +.datepicker table tr td.range.today.disabled:hover, +.datepicker table tr td.range.today:hover.disabled:hover, +.datepicker table tr td.range.today.disabled.disabled:hover, +.datepicker table tr td.range.today.disabled:hover.disabled:hover, +.datepicker table tr td.range.today[disabled]:hover, +.datepicker table tr td.range.today:hover[disabled]:hover, +.datepicker table tr td.range.today.disabled[disabled]:hover, +.datepicker table tr td.range.today.disabled:hover[disabled]:hover, +fieldset[disabled] .datepicker table tr td.range.today:hover, +fieldset[disabled] .datepicker table tr td.range.today:hover:hover, +fieldset[disabled] .datepicker table tr td.range.today.disabled:hover, +fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:hover, +.datepicker table tr td.range.today.disabled:focus, +.datepicker table tr td.range.today:hover.disabled:focus, +.datepicker table tr td.range.today.disabled.disabled:focus, +.datepicker table tr td.range.today.disabled:hover.disabled:focus, +.datepicker table tr td.range.today[disabled]:focus, +.datepicker table tr td.range.today:hover[disabled]:focus, +.datepicker table tr td.range.today.disabled[disabled]:focus, +.datepicker table tr td.range.today.disabled:hover[disabled]:focus, +fieldset[disabled] .datepicker table tr td.range.today:focus, +fieldset[disabled] .datepicker table tr td.range.today:hover:focus, +fieldset[disabled] .datepicker table tr td.range.today.disabled:focus, +fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:focus, +.datepicker table tr td.range.today.disabled:active, +.datepicker table tr td.range.today:hover.disabled:active, +.datepicker table tr td.range.today.disabled.disabled:active, +.datepicker table tr td.range.today.disabled:hover.disabled:active, +.datepicker table tr td.range.today[disabled]:active, +.datepicker table tr td.range.today:hover[disabled]:active, +.datepicker table tr td.range.today.disabled[disabled]:active, +.datepicker table tr td.range.today.disabled:hover[disabled]:active, +fieldset[disabled] .datepicker table tr td.range.today:active, +fieldset[disabled] .datepicker table tr td.range.today:hover:active, +fieldset[disabled] .datepicker table tr td.range.today.disabled:active, +fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:active, +.datepicker table tr td.range.today.disabled.active, +.datepicker table tr td.range.today:hover.disabled.active, +.datepicker table tr td.range.today.disabled.disabled.active, +.datepicker table tr td.range.today.disabled:hover.disabled.active, +.datepicker table tr td.range.today[disabled].active, +.datepicker table tr td.range.today:hover[disabled].active, +.datepicker table tr td.range.today.disabled[disabled].active, +.datepicker table tr td.range.today.disabled:hover[disabled].active, +fieldset[disabled] .datepicker table tr td.range.today.active, +fieldset[disabled] .datepicker table tr td.range.today:hover.active, +fieldset[disabled] .datepicker table tr td.range.today.disabled.active, +fieldset[disabled] .datepicker table tr td.range.today.disabled:hover.active { + background-color: #f7ca77; + border-color: #f1a417; +} +.datepicker table tr td.selected, +.datepicker table tr td.selected:hover, +.datepicker table tr td.selected.disabled, +.datepicker table tr td.selected.disabled:hover { + color: #ffffff; + background-color: #999999; + border-color: #555555; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.datepicker table tr td.selected:hover, +.datepicker table tr td.selected:hover:hover, +.datepicker table tr td.selected.disabled:hover, +.datepicker table tr td.selected.disabled:hover:hover, +.datepicker table tr td.selected:focus, +.datepicker table tr td.selected:hover:focus, +.datepicker table tr td.selected.disabled:focus, +.datepicker table tr td.selected.disabled:hover:focus, +.datepicker table tr td.selected:active, +.datepicker table tr td.selected:hover:active, +.datepicker table tr td.selected.disabled:active, +.datepicker table tr td.selected.disabled:hover:active, +.datepicker table tr td.selected.active, +.datepicker table tr td.selected:hover.active, +.datepicker table tr td.selected.disabled.active, +.datepicker table tr td.selected.disabled:hover.active, +.open .dropdown-toggle.datepicker table tr td.selected, +.open .dropdown-toggle.datepicker table tr td.selected:hover, +.open .dropdown-toggle.datepicker table tr td.selected.disabled, +.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover { + color: #ffffff; + background-color: #858585; + border-color: #373737; +} +.datepicker table tr td.selected:active, +.datepicker table tr td.selected:hover:active, +.datepicker table tr td.selected.disabled:active, +.datepicker table tr td.selected.disabled:hover:active, +.datepicker table tr td.selected.active, +.datepicker table tr td.selected:hover.active, +.datepicker table tr td.selected.disabled.active, +.datepicker table tr td.selected.disabled:hover.active, +.open .dropdown-toggle.datepicker table tr td.selected, +.open .dropdown-toggle.datepicker table tr td.selected:hover, +.open .dropdown-toggle.datepicker table tr td.selected.disabled, +.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover { + background-image: none; +} +.datepicker table tr td.selected.disabled, +.datepicker table tr td.selected:hover.disabled, +.datepicker table tr td.selected.disabled.disabled, +.datepicker table tr td.selected.disabled:hover.disabled, +.datepicker table tr td.selected[disabled], +.datepicker table tr td.selected:hover[disabled], +.datepicker table tr td.selected.disabled[disabled], +.datepicker table tr td.selected.disabled:hover[disabled], +fieldset[disabled] .datepicker table tr td.selected, +fieldset[disabled] .datepicker table tr td.selected:hover, +fieldset[disabled] .datepicker table tr td.selected.disabled, +fieldset[disabled] .datepicker table tr td.selected.disabled:hover, +.datepicker table tr td.selected.disabled:hover, +.datepicker table tr td.selected:hover.disabled:hover, +.datepicker table tr td.selected.disabled.disabled:hover, +.datepicker table tr td.selected.disabled:hover.disabled:hover, +.datepicker table tr td.selected[disabled]:hover, +.datepicker table tr td.selected:hover[disabled]:hover, +.datepicker table tr td.selected.disabled[disabled]:hover, +.datepicker table tr td.selected.disabled:hover[disabled]:hover, +fieldset[disabled] .datepicker table tr td.selected:hover, +fieldset[disabled] .datepicker table tr td.selected:hover:hover, +fieldset[disabled] .datepicker table tr td.selected.disabled:hover, +fieldset[disabled] .datepicker table tr td.selected.disabled:hover:hover, +.datepicker table tr td.selected.disabled:focus, +.datepicker table tr td.selected:hover.disabled:focus, +.datepicker table tr td.selected.disabled.disabled:focus, +.datepicker table tr td.selected.disabled:hover.disabled:focus, +.datepicker table tr td.selected[disabled]:focus, +.datepicker table tr td.selected:hover[disabled]:focus, +.datepicker table tr td.selected.disabled[disabled]:focus, +.datepicker table tr td.selected.disabled:hover[disabled]:focus, +fieldset[disabled] .datepicker table tr td.selected:focus, +fieldset[disabled] .datepicker table tr td.selected:hover:focus, +fieldset[disabled] .datepicker table tr td.selected.disabled:focus, +fieldset[disabled] .datepicker table tr td.selected.disabled:hover:focus, +.datepicker table tr td.selected.disabled:active, +.datepicker table tr td.selected:hover.disabled:active, +.datepicker table tr td.selected.disabled.disabled:active, +.datepicker table tr td.selected.disabled:hover.disabled:active, +.datepicker table tr td.selected[disabled]:active, +.datepicker table tr td.selected:hover[disabled]:active, +.datepicker table tr td.selected.disabled[disabled]:active, +.datepicker table tr td.selected.disabled:hover[disabled]:active, +fieldset[disabled] .datepicker table tr td.selected:active, +fieldset[disabled] .datepicker table tr td.selected:hover:active, +fieldset[disabled] .datepicker table tr td.selected.disabled:active, +fieldset[disabled] .datepicker table tr td.selected.disabled:hover:active, +.datepicker table tr td.selected.disabled.active, +.datepicker table tr td.selected:hover.disabled.active, +.datepicker table tr td.selected.disabled.disabled.active, +.datepicker table tr td.selected.disabled:hover.disabled.active, +.datepicker table tr td.selected[disabled].active, +.datepicker table tr td.selected:hover[disabled].active, +.datepicker table tr td.selected.disabled[disabled].active, +.datepicker table tr td.selected.disabled:hover[disabled].active, +fieldset[disabled] .datepicker table tr td.selected.active, +fieldset[disabled] .datepicker table tr td.selected:hover.active, +fieldset[disabled] .datepicker table tr td.selected.disabled.active, +fieldset[disabled] .datepicker table tr td.selected.disabled:hover.active { + background-color: #999999; + border-color: #555555; +} +.datepicker table tr td.active, +.datepicker table tr td.active:hover, +.datepicker table tr td.active.disabled, +.datepicker table tr td.active.disabled:hover { + color: #ffffff; + background-color: #428bca; + border-color: #357ebd; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.datepicker table tr td.active:hover, +.datepicker table tr td.active:hover:hover, +.datepicker table tr td.active.disabled:hover, +.datepicker table tr td.active.disabled:hover:hover, +.datepicker table tr td.active:focus, +.datepicker table tr td.active:hover:focus, +.datepicker table tr td.active.disabled:focus, +.datepicker table tr td.active.disabled:hover:focus, +.datepicker table tr td.active:active, +.datepicker table tr td.active:hover:active, +.datepicker table tr td.active.disabled:active, +.datepicker table tr td.active.disabled:hover:active, +.datepicker table tr td.active.active, +.datepicker table tr td.active:hover.active, +.datepicker table tr td.active.disabled.active, +.datepicker table tr td.active.disabled:hover.active, +.open .dropdown-toggle.datepicker table tr td.active, +.open .dropdown-toggle.datepicker table tr td.active:hover, +.open .dropdown-toggle.datepicker table tr td.active.disabled, +.open .dropdown-toggle.datepicker table tr td.active.disabled:hover { + color: #ffffff; + background-color: #3276b1; + border-color: #285e8e; +} +.datepicker table tr td.active:active, +.datepicker table tr td.active:hover:active, +.datepicker table tr td.active.disabled:active, +.datepicker table tr td.active.disabled:hover:active, +.datepicker table tr td.active.active, +.datepicker table tr td.active:hover.active, +.datepicker table tr td.active.disabled.active, +.datepicker table tr td.active.disabled:hover.active, +.open .dropdown-toggle.datepicker table tr td.active, +.open .dropdown-toggle.datepicker table tr td.active:hover, +.open .dropdown-toggle.datepicker table tr td.active.disabled, +.open .dropdown-toggle.datepicker table tr td.active.disabled:hover { + background-image: none; +} +.datepicker table tr td.active.disabled, +.datepicker table tr td.active:hover.disabled, +.datepicker table tr td.active.disabled.disabled, +.datepicker table tr td.active.disabled:hover.disabled, +.datepicker table tr td.active[disabled], +.datepicker table tr td.active:hover[disabled], +.datepicker table tr td.active.disabled[disabled], +.datepicker table tr td.active.disabled:hover[disabled], +fieldset[disabled] .datepicker table tr td.active, +fieldset[disabled] .datepicker table tr td.active:hover, +fieldset[disabled] .datepicker table tr td.active.disabled, +fieldset[disabled] .datepicker table tr td.active.disabled:hover, +.datepicker table tr td.active.disabled:hover, +.datepicker table tr td.active:hover.disabled:hover, +.datepicker table tr td.active.disabled.disabled:hover, +.datepicker table tr td.active.disabled:hover.disabled:hover, +.datepicker table tr td.active[disabled]:hover, +.datepicker table tr td.active:hover[disabled]:hover, +.datepicker table tr td.active.disabled[disabled]:hover, +.datepicker table tr td.active.disabled:hover[disabled]:hover, +fieldset[disabled] .datepicker table tr td.active:hover, +fieldset[disabled] .datepicker table tr td.active:hover:hover, +fieldset[disabled] .datepicker table tr td.active.disabled:hover, +fieldset[disabled] .datepicker table tr td.active.disabled:hover:hover, +.datepicker table tr td.active.disabled:focus, +.datepicker table tr td.active:hover.disabled:focus, +.datepicker table tr td.active.disabled.disabled:focus, +.datepicker table tr td.active.disabled:hover.disabled:focus, +.datepicker table tr td.active[disabled]:focus, +.datepicker table tr td.active:hover[disabled]:focus, +.datepicker table tr td.active.disabled[disabled]:focus, +.datepicker table tr td.active.disabled:hover[disabled]:focus, +fieldset[disabled] .datepicker table tr td.active:focus, +fieldset[disabled] .datepicker table tr td.active:hover:focus, +fieldset[disabled] .datepicker table tr td.active.disabled:focus, +fieldset[disabled] .datepicker table tr td.active.disabled:hover:focus, +.datepicker table tr td.active.disabled:active, +.datepicker table tr td.active:hover.disabled:active, +.datepicker table tr td.active.disabled.disabled:active, +.datepicker table tr td.active.disabled:hover.disabled:active, +.datepicker table tr td.active[disabled]:active, +.datepicker table tr td.active:hover[disabled]:active, +.datepicker table tr td.active.disabled[disabled]:active, +.datepicker table tr td.active.disabled:hover[disabled]:active, +fieldset[disabled] .datepicker table tr td.active:active, +fieldset[disabled] .datepicker table tr td.active:hover:active, +fieldset[disabled] .datepicker table tr td.active.disabled:active, +fieldset[disabled] .datepicker table tr td.active.disabled:hover:active, +.datepicker table tr td.active.disabled.active, +.datepicker table tr td.active:hover.disabled.active, +.datepicker table tr td.active.disabled.disabled.active, +.datepicker table tr td.active.disabled:hover.disabled.active, +.datepicker table tr td.active[disabled].active, +.datepicker table tr td.active:hover[disabled].active, +.datepicker table tr td.active.disabled[disabled].active, +.datepicker table tr td.active.disabled:hover[disabled].active, +fieldset[disabled] .datepicker table tr td.active.active, +fieldset[disabled] .datepicker table tr td.active:hover.active, +fieldset[disabled] .datepicker table tr td.active.disabled.active, +fieldset[disabled] .datepicker table tr td.active.disabled:hover.active { + background-color: #428bca; + border-color: #357ebd; +} +.datepicker table tr td span { + display: block; + width: 23%; + height: 54px; + line-height: 54px; + float: left; + margin: 1%; + cursor: pointer; + border-radius: 4px; +} +.datepicker table tr td span:hover { + background: #eeeeee; +} +.datepicker table tr td span.disabled, +.datepicker table tr td span.disabled:hover { + background: none; + color: #999999; + cursor: default; +} +.datepicker table tr td span.active, +.datepicker table tr td span.active:hover, +.datepicker table tr td span.active.disabled, +.datepicker table tr td span.active.disabled:hover { + color: #ffffff; + background-color: #428bca; + border-color: #357ebd; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.datepicker table tr td span.active:hover, +.datepicker table tr td span.active:hover:hover, +.datepicker table tr td span.active.disabled:hover, +.datepicker table tr td span.active.disabled:hover:hover, +.datepicker table tr td span.active:focus, +.datepicker table tr td span.active:hover:focus, +.datepicker table tr td span.active.disabled:focus, +.datepicker table tr td span.active.disabled:hover:focus, +.datepicker table tr td span.active:active, +.datepicker table tr td span.active:hover:active, +.datepicker table tr td span.active.disabled:active, +.datepicker table tr td span.active.disabled:hover:active, +.datepicker table tr td span.active.active, +.datepicker table tr td span.active:hover.active, +.datepicker table tr td span.active.disabled.active, +.datepicker table tr td span.active.disabled:hover.active, +.open .dropdown-toggle.datepicker table tr td span.active, +.open .dropdown-toggle.datepicker table tr td span.active:hover, +.open .dropdown-toggle.datepicker table tr td span.active.disabled, +.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover { + color: #ffffff; + background-color: #3276b1; + border-color: #285e8e; +} +.datepicker table tr td span.active:active, +.datepicker table tr td span.active:hover:active, +.datepicker table tr td span.active.disabled:active, +.datepicker table tr td span.active.disabled:hover:active, +.datepicker table tr td span.active.active, +.datepicker table tr td span.active:hover.active, +.datepicker table tr td span.active.disabled.active, +.datepicker table tr td span.active.disabled:hover.active, +.open .dropdown-toggle.datepicker table tr td span.active, +.open .dropdown-toggle.datepicker table tr td span.active:hover, +.open .dropdown-toggle.datepicker table tr td span.active.disabled, +.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover { + background-image: none; +} +.datepicker table tr td span.active.disabled, +.datepicker table tr td span.active:hover.disabled, +.datepicker table tr td span.active.disabled.disabled, +.datepicker table tr td span.active.disabled:hover.disabled, +.datepicker table tr td span.active[disabled], +.datepicker table tr td span.active:hover[disabled], +.datepicker table tr td span.active.disabled[disabled], +.datepicker table tr td span.active.disabled:hover[disabled], +fieldset[disabled] .datepicker table tr td span.active, +fieldset[disabled] .datepicker table tr td span.active:hover, +fieldset[disabled] .datepicker table tr td span.active.disabled, +fieldset[disabled] .datepicker table tr td span.active.disabled:hover, +.datepicker table tr td span.active.disabled:hover, +.datepicker table tr td span.active:hover.disabled:hover, +.datepicker table tr td span.active.disabled.disabled:hover, +.datepicker table tr td span.active.disabled:hover.disabled:hover, +.datepicker table tr td span.active[disabled]:hover, +.datepicker table tr td span.active:hover[disabled]:hover, +.datepicker table tr td span.active.disabled[disabled]:hover, +.datepicker table tr td span.active.disabled:hover[disabled]:hover, +fieldset[disabled] .datepicker table tr td span.active:hover, +fieldset[disabled] .datepicker table tr td span.active:hover:hover, +fieldset[disabled] .datepicker table tr td span.active.disabled:hover, +fieldset[disabled] .datepicker table tr td span.active.disabled:hover:hover, +.datepicker table tr td span.active.disabled:focus, +.datepicker table tr td span.active:hover.disabled:focus, +.datepicker table tr td span.active.disabled.disabled:focus, +.datepicker table tr td span.active.disabled:hover.disabled:focus, +.datepicker table tr td span.active[disabled]:focus, +.datepicker table tr td span.active:hover[disabled]:focus, +.datepicker table tr td span.active.disabled[disabled]:focus, +.datepicker table tr td span.active.disabled:hover[disabled]:focus, +fieldset[disabled] .datepicker table tr td span.active:focus, +fieldset[disabled] .datepicker table tr td span.active:hover:focus, +fieldset[disabled] .datepicker table tr td span.active.disabled:focus, +fieldset[disabled] .datepicker table tr td span.active.disabled:hover:focus, +.datepicker table tr td span.active.disabled:active, +.datepicker table tr td span.active:hover.disabled:active, +.datepicker table tr td span.active.disabled.disabled:active, +.datepicker table tr td span.active.disabled:hover.disabled:active, +.datepicker table tr td span.active[disabled]:active, +.datepicker table tr td span.active:hover[disabled]:active, +.datepicker table tr td span.active.disabled[disabled]:active, +.datepicker table tr td span.active.disabled:hover[disabled]:active, +fieldset[disabled] .datepicker table tr td span.active:active, +fieldset[disabled] .datepicker table tr td span.active:hover:active, +fieldset[disabled] .datepicker table tr td span.active.disabled:active, +fieldset[disabled] .datepicker table tr td span.active.disabled:hover:active, +.datepicker table tr td span.active.disabled.active, +.datepicker table tr td span.active:hover.disabled.active, +.datepicker table tr td span.active.disabled.disabled.active, +.datepicker table tr td span.active.disabled:hover.disabled.active, +.datepicker table tr td span.active[disabled].active, +.datepicker table tr td span.active:hover[disabled].active, +.datepicker table tr td span.active.disabled[disabled].active, +.datepicker table tr td span.active.disabled:hover[disabled].active, +fieldset[disabled] .datepicker table tr td span.active.active, +fieldset[disabled] .datepicker table tr td span.active:hover.active, +fieldset[disabled] .datepicker table tr td span.active.disabled.active, +fieldset[disabled] .datepicker table tr td span.active.disabled:hover.active { + background-color: #428bca; + border-color: #357ebd; +} +.datepicker table tr td span.old, +.datepicker table tr td span.new { + color: #999999; +} +.datepicker .datepicker-switch { + width: 145px; +} +.datepicker thead tr:first-child th, +.datepicker tfoot tr th { + cursor: pointer; +} +.datepicker thead tr:first-child th:hover, +.datepicker tfoot tr th:hover { + background: #eeeeee; +} +.datepicker .cw { + font-size: 10px; + width: 12px; + padding: 0 2px 0 5px; + vertical-align: middle; +} +.datepicker thead tr:first-child .cw { + cursor: default; + background-color: transparent; +} +.input-group.date .input-group-addon { + cursor: pointer; +} +.input-daterange { + width: 100%; +} +.input-daterange input { + text-align: center; +} +.input-daterange input:first-child { + border-radius: 3px 0 0 3px; +} +.input-daterange input:last-child { + border-radius: 0 3px 3px 0; +} +.input-daterange .input-group-addon { + width: auto; + min-width: 16px; + padding: 4px 5px; + font-weight: normal; + line-height: 1.42857143; + text-align: center; + text-shadow: 0 1px 0 #fff; + vertical-align: middle; + background-color: #eeeeee; + border: solid #cccccc; + border-width: 1px 0; + margin-left: -5px; + margin-right: -5px; +} diff --git a/web/pgadmin/static/css/bootstrap-theme.css b/web/pgadmin/static/css/bootstrap-theme.css index c4cadf15e..b0fdfcbf9 100644 --- a/web/pgadmin/static/css/bootstrap-theme.css +++ b/web/pgadmin/static/css/bootstrap-theme.css @@ -1,6 +1,6 @@ /*! - * Bootstrap v3.3.1 (http://getbootstrap.com) - * Copyright 2011-2014 Twitter, Inc. + * Bootstrap v3.3.4 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */ @@ -63,6 +63,7 @@ background-color: #e0e0e0; border-color: #dbdbdb; } +.btn-default.disabled, .btn-default:disabled, .btn-default[disabled] { background-color: #e0e0e0; @@ -88,6 +89,7 @@ background-color: #265a88; border-color: #245580; } +.btn-primary.disabled, .btn-primary:disabled, .btn-primary[disabled] { background-color: #265a88; @@ -113,6 +115,7 @@ background-color: #419641; border-color: #3e8f3e; } +.btn-success.disabled, .btn-success:disabled, .btn-success[disabled] { background-color: #419641; @@ -138,6 +141,7 @@ background-color: #2aabd2; border-color: #28a4c9; } +.btn-info.disabled, .btn-info:disabled, .btn-info[disabled] { background-color: #2aabd2; @@ -163,6 +167,7 @@ background-color: #eb9316; border-color: #e38d13; } +.btn-warning.disabled, .btn-warning:disabled, .btn-warning[disabled] { background-color: #eb9316; @@ -188,6 +193,7 @@ background-color: #c12e2a; border-color: #b92c28; } +.btn-danger.disabled, .btn-danger:disabled, .btn-danger[disabled] { background-color: #c12e2a; diff --git a/web/pgadmin/static/css/bootstrap-theme.css.map b/web/pgadmin/static/css/bootstrap-theme.css.map index 016a8dabc..5a12d6317 100644 --- a/web/pgadmin/static/css/bootstrap-theme.css.map +++ b/web/pgadmin/static/css/bootstrap-theme.css.map @@ -1 +1 @@ -{"version":3,"sources":["less/theme.less","less/mixins/vendor-prefixes.less","bootstrap-theme.css","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":"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","file":"bootstrap-theme.css","sourcesContent":["\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n .badge {\n text-shadow: none;\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n\n &:disabled,\n &[disabled] {\n background-color: darken(@btn-color, 12%);\n background-image: none;\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: #fff;\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n }\n }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n\n .badge {\n text-shadow: none;\n }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They will be removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility){\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // See https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n",".btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.btn-default:active,\n.btn-primary:active,\n.btn-success:active,\n.btn-info:active,\n.btn-warning:active,\n.btn-danger:active,\n.btn-default.active,\n.btn-primary.active,\n.btn-success.active,\n.btn-info.active,\n.btn-warning.active,\n.btn-danger.active {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-default .badge,\n.btn-primary .badge,\n.btn-success .badge,\n.btn-info .badge,\n.btn-warning .badge,\n.btn-danger .badge {\n text-shadow: none;\n}\n.btn:active,\n.btn.active {\n background-image: none;\n}\n.btn-default {\n background-image: -webkit-linear-gradient(top, #ffffff 0%, #e0e0e0 100%);\n background-image: -o-linear-gradient(top, #ffffff 0%, #e0e0e0 100%);\n background-image: linear-gradient(to bottom, #ffffff 0%, #e0e0e0 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #dbdbdb;\n text-shadow: 0 1px 0 #fff;\n border-color: #ccc;\n}\n.btn-default:hover,\n.btn-default:focus {\n background-color: #e0e0e0;\n background-position: 0 -15px;\n}\n.btn-default:active,\n.btn-default.active {\n background-color: #e0e0e0;\n border-color: #dbdbdb;\n}\n.btn-default:disabled,\n.btn-default[disabled] {\n background-color: #e0e0e0;\n background-image: none;\n}\n.btn-primary {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #245580;\n}\n.btn-primary:hover,\n.btn-primary:focus {\n background-color: #265a88;\n background-position: 0 -15px;\n}\n.btn-primary:active,\n.btn-primary.active {\n background-color: #265a88;\n border-color: #245580;\n}\n.btn-primary:disabled,\n.btn-primary[disabled] {\n background-color: #265a88;\n background-image: none;\n}\n.btn-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #3e8f3e;\n}\n.btn-success:hover,\n.btn-success:focus {\n background-color: #419641;\n background-position: 0 -15px;\n}\n.btn-success:active,\n.btn-success.active {\n background-color: #419641;\n border-color: #3e8f3e;\n}\n.btn-success:disabled,\n.btn-success[disabled] {\n background-color: #419641;\n background-image: none;\n}\n.btn-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #28a4c9;\n}\n.btn-info:hover,\n.btn-info:focus {\n background-color: #2aabd2;\n background-position: 0 -15px;\n}\n.btn-info:active,\n.btn-info.active {\n background-color: #2aabd2;\n border-color: #28a4c9;\n}\n.btn-info:disabled,\n.btn-info[disabled] {\n background-color: #2aabd2;\n background-image: none;\n}\n.btn-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #e38d13;\n}\n.btn-warning:hover,\n.btn-warning:focus {\n background-color: #eb9316;\n background-position: 0 -15px;\n}\n.btn-warning:active,\n.btn-warning.active {\n background-color: #eb9316;\n border-color: #e38d13;\n}\n.btn-warning:disabled,\n.btn-warning[disabled] {\n background-color: #eb9316;\n background-image: none;\n}\n.btn-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #b92c28;\n}\n.btn-danger:hover,\n.btn-danger:focus {\n background-color: #c12e2a;\n background-position: 0 -15px;\n}\n.btn-danger:active,\n.btn-danger.active {\n background-color: #c12e2a;\n border-color: #b92c28;\n}\n.btn-danger:disabled,\n.btn-danger[disabled] {\n background-color: #c12e2a;\n background-image: none;\n}\n.thumbnail,\n.img-thumbnail {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n background-color: #e8e8e8;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n background-color: #2e6da4;\n}\n.navbar-default {\n background-image: -webkit-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: -o-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);\n}\n.navbar-inverse {\n background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222222 100%);\n background-image: -o-linear-gradient(top, #3c3c3c 0%, #222222 100%);\n background-image: linear-gradient(to bottom, #3c3c3c 0%, #222222 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n}\n.navbar-inverse .navbar-brand,\n.navbar-inverse .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n@media (max-width: 767px) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n }\n}\n.alert {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.alert-success {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);\n border-color: #b2dba1;\n}\n.alert-info {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);\n border-color: #9acfea;\n}\n.alert-warning {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);\n border-color: #f5e79e;\n}\n.alert-danger {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);\n border-color: #dca7a7;\n}\n.progress {\n background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);\n}\n.progress-bar {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);\n}\n.progress-bar-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);\n}\n.progress-bar-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);\n}\n.progress-bar-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);\n}\n.progress-bar-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);\n}\n.progress-bar-striped {\n 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);\n 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);\n 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);\n}\n.list-group {\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 #286090;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);\n border-color: #2b669a;\n}\n.list-group-item.active .badge,\n.list-group-item.active:hover .badge,\n.list-group-item.active:focus .badge {\n text-shadow: none;\n}\n.panel {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.panel-default > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n}\n.panel-primary > .panel-heading {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n}\n.panel-success > .panel-heading {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);\n}\n.panel-info > .panel-heading {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);\n}\n.panel-warning > .panel-heading {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);\n}\n.panel-danger > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);\n}\n.well {\n background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);\n border-color: #dcdcdc;\n -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n}\n/*# sourceMappingURL=bootstrap-theme.css.map */","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n"]} \ No newline at end of file +{"version":3,"sources":["less/theme.less","less/mixins/vendor-prefixes.less","bootstrap-theme.css","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":"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","file":"bootstrap-theme.css","sourcesContent":["\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n .badge {\n text-shadow: none;\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners; see https://github.com/twbs/bootstrap/issues/10620\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n\n &.disabled,\n &:disabled,\n &[disabled] {\n background-color: darken(@btn-color, 12%);\n background-image: none;\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered; see https://github.com/twbs/bootstrap/issues/10257\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: #fff;\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n }\n }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n\n .badge {\n text-shadow: none;\n }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They will be removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility){\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n",".btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.btn-default:active,\n.btn-primary:active,\n.btn-success:active,\n.btn-info:active,\n.btn-warning:active,\n.btn-danger:active,\n.btn-default.active,\n.btn-primary.active,\n.btn-success.active,\n.btn-info.active,\n.btn-warning.active,\n.btn-danger.active {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-default .badge,\n.btn-primary .badge,\n.btn-success .badge,\n.btn-info .badge,\n.btn-warning .badge,\n.btn-danger .badge {\n text-shadow: none;\n}\n.btn:active,\n.btn.active {\n background-image: none;\n}\n.btn-default {\n background-image: -webkit-linear-gradient(top, #ffffff 0%, #e0e0e0 100%);\n background-image: -o-linear-gradient(top, #ffffff 0%, #e0e0e0 100%);\n background-image: linear-gradient(to bottom, #ffffff 0%, #e0e0e0 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #dbdbdb;\n text-shadow: 0 1px 0 #fff;\n border-color: #ccc;\n}\n.btn-default:hover,\n.btn-default:focus {\n background-color: #e0e0e0;\n background-position: 0 -15px;\n}\n.btn-default:active,\n.btn-default.active {\n background-color: #e0e0e0;\n border-color: #dbdbdb;\n}\n.btn-default.disabled,\n.btn-default:disabled,\n.btn-default[disabled] {\n background-color: #e0e0e0;\n background-image: none;\n}\n.btn-primary {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #245580;\n}\n.btn-primary:hover,\n.btn-primary:focus {\n background-color: #265a88;\n background-position: 0 -15px;\n}\n.btn-primary:active,\n.btn-primary.active {\n background-color: #265a88;\n border-color: #245580;\n}\n.btn-primary.disabled,\n.btn-primary:disabled,\n.btn-primary[disabled] {\n background-color: #265a88;\n background-image: none;\n}\n.btn-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #3e8f3e;\n}\n.btn-success:hover,\n.btn-success:focus {\n background-color: #419641;\n background-position: 0 -15px;\n}\n.btn-success:active,\n.btn-success.active {\n background-color: #419641;\n border-color: #3e8f3e;\n}\n.btn-success.disabled,\n.btn-success:disabled,\n.btn-success[disabled] {\n background-color: #419641;\n background-image: none;\n}\n.btn-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #28a4c9;\n}\n.btn-info:hover,\n.btn-info:focus {\n background-color: #2aabd2;\n background-position: 0 -15px;\n}\n.btn-info:active,\n.btn-info.active {\n background-color: #2aabd2;\n border-color: #28a4c9;\n}\n.btn-info.disabled,\n.btn-info:disabled,\n.btn-info[disabled] {\n background-color: #2aabd2;\n background-image: none;\n}\n.btn-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #e38d13;\n}\n.btn-warning:hover,\n.btn-warning:focus {\n background-color: #eb9316;\n background-position: 0 -15px;\n}\n.btn-warning:active,\n.btn-warning.active {\n background-color: #eb9316;\n border-color: #e38d13;\n}\n.btn-warning.disabled,\n.btn-warning:disabled,\n.btn-warning[disabled] {\n background-color: #eb9316;\n background-image: none;\n}\n.btn-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #b92c28;\n}\n.btn-danger:hover,\n.btn-danger:focus {\n background-color: #c12e2a;\n background-position: 0 -15px;\n}\n.btn-danger:active,\n.btn-danger.active {\n background-color: #c12e2a;\n border-color: #b92c28;\n}\n.btn-danger.disabled,\n.btn-danger:disabled,\n.btn-danger[disabled] {\n background-color: #c12e2a;\n background-image: none;\n}\n.thumbnail,\n.img-thumbnail {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n background-color: #e8e8e8;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n background-color: #2e6da4;\n}\n.navbar-default {\n background-image: -webkit-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: -o-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);\n}\n.navbar-inverse {\n background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222222 100%);\n background-image: -o-linear-gradient(top, #3c3c3c 0%, #222222 100%);\n background-image: linear-gradient(to bottom, #3c3c3c 0%, #222222 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n}\n.navbar-inverse .navbar-brand,\n.navbar-inverse .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n@media (max-width: 767px) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n }\n}\n.alert {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.alert-success {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);\n border-color: #b2dba1;\n}\n.alert-info {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);\n border-color: #9acfea;\n}\n.alert-warning {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);\n border-color: #f5e79e;\n}\n.alert-danger {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);\n border-color: #dca7a7;\n}\n.progress {\n background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);\n}\n.progress-bar {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);\n}\n.progress-bar-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);\n}\n.progress-bar-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);\n}\n.progress-bar-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);\n}\n.progress-bar-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);\n}\n.progress-bar-striped {\n 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);\n 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);\n 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);\n}\n.list-group {\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 #286090;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);\n border-color: #2b669a;\n}\n.list-group-item.active .badge,\n.list-group-item.active:hover .badge,\n.list-group-item.active:focus .badge {\n text-shadow: none;\n}\n.panel {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.panel-default > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n}\n.panel-primary > .panel-heading {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n}\n.panel-success > .panel-heading {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);\n}\n.panel-info > .panel-heading {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);\n}\n.panel-warning > .panel-heading {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);\n}\n.panel-danger > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);\n}\n.well {\n background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);\n border-color: #dcdcdc;\n -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n}\n/*# sourceMappingURL=bootstrap-theme.css.map */","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n"]} \ No newline at end of file diff --git a/web/pgadmin/static/css/bootstrap-theme.min.css b/web/pgadmin/static/css/bootstrap-theme.min.css index 4c3e7bad7..cefa3d1ae 100644 --- a/web/pgadmin/static/css/bootstrap-theme.min.css +++ b/web/pgadmin/static/css/bootstrap-theme.min.css @@ -1,5 +1,5 @@ /*! - * Bootstrap v3.3.1 (http://getbootstrap.com) - * Copyright 2011-2014 Twitter, Inc. + * Bootstrap v3.3.4 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */.btn-default,.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-default:active,.btn-primary:active,.btn-success:active,.btn-info:active,.btn-warning:active,.btn-danger:active,.btn-default.active,.btn-primary.active,.btn-success.active,.btn-info.active,.btn-warning.active,.btn-danger.active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-default .badge,.btn-primary .badge,.btn-success .badge,.btn-info .badge,.btn-warning .badge,.btn-danger .badge{text-shadow:none}.btn:active,.btn.active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:hover,.btn-default:focus{background-color:#e0e0e0;background-position:0 -15px}.btn-default:active,.btn-default.active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default:disabled,.btn-default[disabled]{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:hover,.btn-primary:focus{background-color:#265a88;background-position:0 -15px}.btn-primary:active,.btn-primary.active{background-color:#265a88;border-color:#245580}.btn-primary:disabled,.btn-primary[disabled]{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:hover,.btn-success:focus{background-color:#419641;background-position:0 -15px}.btn-success:active,.btn-success.active{background-color:#419641;border-color:#3e8f3e}.btn-success:disabled,.btn-success[disabled]{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:hover,.btn-info:focus{background-color:#2aabd2;background-position:0 -15px}.btn-info:active,.btn-info.active{background-color:#2aabd2;border-color:#28a4c9}.btn-info:disabled,.btn-info[disabled]{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:hover,.btn-warning:focus{background-color:#eb9316;background-position:0 -15px}.btn-warning:active,.btn-warning.active{background-color:#eb9316;border-color:#e38d13}.btn-warning:disabled,.btn-warning[disabled]{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:hover,.btn-danger:focus{background-color:#c12e2a;background-position:0 -15px}.btn-danger:active,.btn-danger.active{background-color:#c12e2a;border-color:#b92c28}.btn-danger:disabled,.btn-danger[disabled]{background-color:#c12e2a;background-image:none}.thumbnail,.img-thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-static-top,.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:hover .badge,.list-group-item.active:focus .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} \ No newline at end of file + */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default:disabled,.btn-default[disabled]{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary:disabled,.btn-primary[disabled]{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success:disabled,.btn-success[disabled]{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info:disabled,.btn-info[disabled]{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning:disabled,.btn-warning[disabled]{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger:disabled,.btn-danger[disabled]{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} \ No newline at end of file diff --git a/web/pgadmin/static/css/bootstrap.css b/web/pgadmin/static/css/bootstrap.css index c6f3d2106..fb15e3d69 100644 --- a/web/pgadmin/static/css/bootstrap.css +++ b/web/pgadmin/static/css/bootstrap.css @@ -1,6 +1,6 @@ /*! - * Bootstrap v3.3.1 (http://getbootstrap.com) - * Copyright 2011-2014 Twitter, Inc. + * Bootstrap v3.3.4 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */ @@ -268,7 +268,7 @@ th { font-family: 'Glyphicons Halflings'; src: url('../fonts/glyphicons-halflings-regular.eot'); - src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); + src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); } .glyphicon { position: relative; @@ -883,6 +883,192 @@ th { .glyphicon-tree-deciduous:before { content: "\e200"; } +.glyphicon-cd:before { + content: "\e201"; +} +.glyphicon-save-file:before { + content: "\e202"; +} +.glyphicon-open-file:before { + content: "\e203"; +} +.glyphicon-level-up:before { + content: "\e204"; +} +.glyphicon-copy:before { + content: "\e205"; +} +.glyphicon-paste:before { + content: "\e206"; +} +.glyphicon-alert:before { + content: "\e209"; +} +.glyphicon-equalizer:before { + content: "\e210"; +} +.glyphicon-king:before { + content: "\e211"; +} +.glyphicon-queen:before { + content: "\e212"; +} +.glyphicon-pawn:before { + content: "\e213"; +} +.glyphicon-bishop:before { + content: "\e214"; +} +.glyphicon-knight:before { + content: "\e215"; +} +.glyphicon-baby-formula:before { + content: "\e216"; +} +.glyphicon-tent:before { + content: "\26fa"; +} +.glyphicon-blackboard:before { + content: "\e218"; +} +.glyphicon-bed:before { + content: "\e219"; +} +.glyphicon-apple:before { + content: "\f8ff"; +} +.glyphicon-erase:before { + content: "\e221"; +} +.glyphicon-hourglass:before { + content: "\231b"; +} +.glyphicon-lamp:before { + content: "\e223"; +} +.glyphicon-duplicate:before { + content: "\e224"; +} +.glyphicon-piggy-bank:before { + content: "\e225"; +} +.glyphicon-scissors:before { + content: "\e226"; +} +.glyphicon-bitcoin:before { + content: "\e227"; +} +.glyphicon-btc:before { + content: "\e227"; +} +.glyphicon-xbt:before { + content: "\e227"; +} +.glyphicon-yen:before { + content: "\00a5"; +} +.glyphicon-jpy:before { + content: "\00a5"; +} +.glyphicon-ruble:before { + content: "\20bd"; +} +.glyphicon-rub:before { + content: "\20bd"; +} +.glyphicon-scale:before { + content: "\e230"; +} +.glyphicon-ice-lolly:before { + content: "\e231"; +} +.glyphicon-ice-lolly-tasted:before { + content: "\e232"; +} +.glyphicon-education:before { + content: "\e233"; +} +.glyphicon-option-horizontal:before { + content: "\e234"; +} +.glyphicon-option-vertical:before { + content: "\e235"; +} +.glyphicon-menu-hamburger:before { + content: "\e236"; +} +.glyphicon-modal-window:before { + content: "\e237"; +} +.glyphicon-oil:before { + content: "\e238"; +} +.glyphicon-grain:before { + content: "\e239"; +} +.glyphicon-sunglasses:before { + content: "\e240"; +} +.glyphicon-text-size:before { + content: "\e241"; +} +.glyphicon-text-color:before { + content: "\e242"; +} +.glyphicon-text-background:before { + content: "\e243"; +} +.glyphicon-object-align-top:before { + content: "\e244"; +} +.glyphicon-object-align-bottom:before { + content: "\e245"; +} +.glyphicon-object-align-horizontal:before { + content: "\e246"; +} +.glyphicon-object-align-left:before { + content: "\e247"; +} +.glyphicon-object-align-vertical:before { + content: "\e248"; +} +.glyphicon-object-align-right:before { + content: "\e249"; +} +.glyphicon-triangle-right:before { + content: "\e250"; +} +.glyphicon-triangle-left:before { + content: "\e251"; +} +.glyphicon-triangle-bottom:before { + content: "\e252"; +} +.glyphicon-triangle-top:before { + content: "\e253"; +} +.glyphicon-console:before { + content: "\e254"; +} +.glyphicon-superscript:before { + content: "\e255"; +} +.glyphicon-subscript:before { + content: "\e256"; +} +.glyphicon-menu-left:before { + content: "\e257"; +} +.glyphicon-menu-right:before { + content: "\e258"; +} +.glyphicon-menu-down:before { + content: "\e259"; +} +.glyphicon-menu-up:before { + content: "\e260"; +} * { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; @@ -987,6 +1173,9 @@ hr { overflow: visible; clip: auto; } +[role="button"] { + cursor: pointer; +} h1, h2, h3, @@ -2123,7 +2312,7 @@ th { .table-bordered > thead > tr > td { border-bottom-width: 2px; } -.table-striped > tbody > tr:nth-child(odd) { +.table-striped > tbody > tr:nth-of-type(odd) { background-color: #f9f9f9; } .table-hover > tbody > tr:hover { @@ -2390,10 +2579,13 @@ output { .form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control { - cursor: not-allowed; background-color: #eee; opacity: 1; } +.form-control[disabled], +fieldset[disabled] .form-control { + cursor: not-allowed; +} textarea.form-control { height: auto; } @@ -2410,13 +2602,21 @@ input[type="search"] { input[type="date"].input-sm, input[type="time"].input-sm, input[type="datetime-local"].input-sm, - input[type="month"].input-sm { + input[type="month"].input-sm, + .input-group-sm input[type="date"], + .input-group-sm input[type="time"], + .input-group-sm input[type="datetime-local"], + .input-group-sm input[type="month"] { line-height: 30px; } input[type="date"].input-lg, input[type="time"].input-lg, input[type="datetime-local"].input-lg, - input[type="month"].input-lg { + input[type="month"].input-lg, + .input-group-lg input[type="date"], + .input-group-lg input[type="time"], + .input-group-lg input[type="datetime-local"], + .input-group-lg input[type="month"] { line-height: 46px; } } @@ -2452,6 +2652,7 @@ input[type="search"] { } .radio-inline, .checkbox-inline { + position: relative; display: inline-block; padding-left: 20px; margin-bottom: 0; @@ -2485,6 +2686,7 @@ fieldset[disabled] .checkbox label { cursor: not-allowed; } .form-control-static { + min-height: 34px; padding-top: 7px; padding-bottom: 7px; margin-bottom: 0; @@ -2494,7 +2696,21 @@ fieldset[disabled] .checkbox label { padding-right: 0; padding-left: 0; } -.input-sm, +.input-sm { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-sm { + height: 30px; + line-height: 30px; +} +textarea.input-sm, +select[multiple].input-sm { + height: auto; +} .form-group-sm .form-control { height: 30px; padding: 5px 10px; @@ -2502,36 +2718,58 @@ fieldset[disabled] .checkbox label { line-height: 1.5; border-radius: 3px; } -select.input-sm, select.form-group-sm .form-control { height: 30px; line-height: 30px; } -textarea.input-sm, textarea.form-group-sm .form-control, -select[multiple].input-sm, select[multiple].form-group-sm .form-control { height: auto; } -.input-lg, -.form-group-lg .form-control { +.form-group-sm .form-control-static { + height: 30px; + min-height: 32px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; +} +.input-lg { height: 46px; padding: 10px 16px; font-size: 18px; - line-height: 1.33; + line-height: 1.3333333; border-radius: 6px; } -select.input-lg, -select.form-group-lg .form-control { +select.input-lg { height: 46px; line-height: 46px; } textarea.input-lg, +select[multiple].input-lg { + height: auto; +} +.form-group-lg .form-control { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +select.form-group-lg .form-control { + height: 46px; + line-height: 46px; +} textarea.form-group-lg .form-control, -select[multiple].input-lg, select[multiple].form-group-lg .form-control { height: auto; } +.form-group-lg .form-control-static { + height: 46px; + min-height: 38px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; +} .has-feedback { position: relative; } @@ -2740,7 +2978,7 @@ select[multiple].form-group-lg .form-control { } @media (min-width: 768px) { .form-horizontal .form-group-lg .control-label { - padding-top: 14.3px; + padding-top: 14.333333px; } } @media (min-width: 768px) { @@ -3109,7 +3347,7 @@ fieldset[disabled] .btn-link:focus { .btn-group-lg > .btn { padding: 10px 16px; font-size: 18px; - line-height: 1.33; + line-height: 1.3333333; border-radius: 6px; } .btn-sm, @@ -3149,11 +3387,9 @@ input[type="button"].btn-block { } .collapse { display: none; - visibility: hidden; } .collapse.in { display: block; - visibility: visible; } tr.collapse.in { display: table-row; @@ -3181,10 +3417,11 @@ tbody.collapse.in { height: 0; margin-left: 2px; vertical-align: middle; - border-top: 4px solid; + border-top: 4px dashed; border-right: 4px solid transparent; border-left: 4px solid transparent; } +.dropup, .dropdown { position: relative; } @@ -3303,7 +3540,7 @@ tbody.collapse.in { .navbar-fixed-bottom .dropdown .dropdown-menu { top: auto; bottom: 100%; - margin-bottom: 1px; + margin-bottom: 2px; } @media (min-width: 768px) { .navbar-right .dropdown-menu { @@ -3375,12 +3612,12 @@ tbody.collapse.in { .btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { border-radius: 0; } -.btn-group > .btn-group:first-child > .btn:last-child, -.btn-group > .btn-group:first-child > .dropdown-toggle { +.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { border-top-right-radius: 0; border-bottom-right-radius: 0; } -.btn-group > .btn-group:last-child > .btn:first-child { +.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { border-top-left-radius: 0; border-bottom-left-radius: 0; } @@ -3506,7 +3743,7 @@ tbody.collapse.in { height: 46px; padding: 10px 16px; font-size: 18px; - line-height: 1.33; + line-height: 1.3333333; border-radius: 6px; } select.input-group-lg > .form-control, @@ -3820,11 +4057,9 @@ select[multiple].input-group-sm > .input-group-btn > .btn { } .tab-content > .tab-pane { display: none; - visibility: hidden; } .tab-content > .active { display: block; - visibility: visible; } .nav-tabs .dropdown-menu { margin-top: -1px; @@ -3871,7 +4106,6 @@ select[multiple].input-group-sm > .input-group-btn > .btn { height: auto !important; padding-bottom: 0; overflow: visible !important; - visibility: visible !important; } .navbar-collapse.in { overflow-y: visible; @@ -4120,6 +4354,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn { border-top-right-radius: 0; } .navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { + margin-bottom: 0; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 0; @@ -4595,7 +4830,8 @@ a.label:focus { position: relative; top: -1px; } -.btn-xs .badge { +.btn-xs .badge, +.btn-group-xs > .btn .badge { top: 0; padding: 1px 5px; } @@ -4859,6 +5095,17 @@ a.thumbnail.active { .media:first-child { margin-top: 0; } +.media, +.media-body { + overflow: hidden; + zoom: 1; +} +.media-body { + width: 10000px; +} +.media-object { + display: block; +} .media-right, .media > .pull-right { padding-left: 10px; @@ -5083,7 +5330,11 @@ a.list-group-item-danger.active:focus { font-size: 16px; color: inherit; } -.panel-title > a { +.panel-title > a, +.panel-title > small, +.panel-title > .small, +.panel-title > small > a, +.panel-title > .small > a { color: inherit; } .panel-footer { @@ -5412,10 +5663,10 @@ a.list-group-item-danger.active:focus { height: 100%; border: 0; } -.embed-responsive.embed-responsive-16by9 { +.embed-responsive-16by9 { padding-bottom: 56.25%; } -.embed-responsive.embed-responsive-4by3 { +.embed-responsive-4by3 { padding-bottom: 75%; } .well { @@ -5474,7 +5725,7 @@ button.close { right: 0; bottom: 0; left: 0; - z-index: 1040; + z-index: 1050; display: none; overflow: hidden; -webkit-overflow-scrolling: touch; @@ -5517,10 +5768,12 @@ button.close { box-shadow: 0 3px 9px rgba(0, 0, 0, .5); } .modal-backdrop { - position: absolute; + position: fixed; top: 0; right: 0; + bottom: 0; left: 0; + z-index: 1040; background-color: #000; } .modal-backdrop.fade { @@ -5595,7 +5848,6 @@ button.close { font-size: 12px; font-weight: normal; line-height: 1.4; - visibility: visible; filter: alpha(opacity=0); opacity: 0; } @@ -5957,6 +6209,7 @@ button.close { height: 20px; margin-top: -10px; font-family: serif; + line-height: 1; } .carousel-control .icon-prev:before { content: '\2039'; @@ -6114,7 +6367,6 @@ button.close { } .hidden { display: none !important; - visibility: hidden !important; } .affix { position: fixed; diff --git a/web/pgadmin/static/css/bootstrap.css.map b/web/pgadmin/static/css/bootstrap.css.map index a02f6ba0a..2fd84f36e 100644 --- a/web/pgadmin/static/css/bootstrap.css.map +++ b/web/pgadmin/static/css/bootstrap.css.map @@ -1 +1 @@ -{"version":3,"sources":["bootstrap.css","less/normalize.less","less/print.less","less/glyphicons.less","less/scaffolding.less","less/mixins/vendor-prefixes.less","less/mixins/tab-focus.less","less/mixins/image.less","less/type.less","less/mixins/text-emphasis.less","less/mixins/background-variant.less","less/mixins/text-overflow.less","less/code.less","less/grid.less","less/mixins/grid.less","less/mixins/grid-framework.less","less/tables.less","less/mixins/table-row.less","less/forms.less","less/mixins/forms.less","less/buttons.less","less/mixins/buttons.less","less/mixins/opacity.less","less/component-animations.less","less/dropdowns.less","less/mixins/nav-divider.less","less/mixins/reset-filter.less","less/button-groups.less","less/mixins/border-radius.less","less/input-groups.less","less/navs.less","less/navbar.less","less/mixins/nav-vertical-align.less","less/utilities.less","less/breadcrumbs.less","less/pagination.less","less/mixins/pagination.less","less/pager.less","less/labels.less","less/mixins/labels.less","less/badges.less","less/jumbotron.less","less/thumbnails.less","less/alerts.less","less/mixins/alerts.less","less/progress-bars.less","less/mixins/gradients.less","less/mixins/progress-bar.less","less/media.less","less/list-group.less","less/mixins/list-group.less","less/panels.less","less/mixins/panels.less","less/responsive-embed.less","less/wells.less","less/close.less","less/modals.less","less/tooltip.less","less/popovers.less","less/carousel.less","less/mixins/clearfix.less","less/mixins/center-block.less","less/mixins/hide-text.less","less/responsive-utilities.less","less/mixins/responsive-visibility.less"],"names":[],"mappings":"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AAA;EHsR9C;AGrRmC;EAAW,kBAAA;EHwR9C;AGvRmC;EAAW,kBAAA;EH0R9C;AGzRmC;EAAW,kBAAA;EH4R9C;AG3RmC;EAAW,kBAAA;EH8R9C;AG7RmC;EAAW,kBAAA;EHgS9C;AG/RmC;EAAW,kBAAA;EHkS9C;AGjSmC;EAAW,kBAAA;EHoS9C;AGnSmC;EAAW,kBAAA;EHsS9C;AGrSmC;EAAW,kBAAA;EHwS9C;AGvSmC;EAAW,kBAAA;EH0S9C;AGzSmC;EAAW,kBAAA;EH4S9C;AG3SmC;EAAW,kBAAA;EH8S9C;AG7SmC;EAAW,kBAAA;EHgT9C;AG/SmC;EAAW,kBAAA;EHkT9C;AGjTmC;EAAW,kBAAA;EHoT9C;AGnTmC;EAAW,kBAAA;EHsT9C;AGrTmC;EAAW,kBAAA;EHwT9C;AGvTmC;EAAW,kBAAA;EH0T9C;AGzTmC;EAAW,kBAAA;EH4T9C;AG3TmC;EAAW,kBAAA;EH8T9C;AG7TmC;EAAW,kBAAA;EHgU9C;AG/TmC;EAAW,kBAAA;EHkU9C;AGjUmC;EAAW,kBAAA;EHoU9C;AGnUmC;EAAW,kBAAA;EHsU9C;AGrUmC;EAAW,kBAAA;EHwU9C;AGvUmC;EAAW,kBAAA;EH0U9C;AGzUmC;EAAW,kBAAA;EH4U9C;AG3UmC;EAAW,kBAAA;EH8U9C;AG7UmC;EAAW,kBAAA;EHgV9C;AG/UmC;EAAW,kBAAA;EHkV9C;AGjVmC;EAAW,kBAAA;EHoV9C;AGnVmC;EAAW,kBAAA;EHsV9C;AGrVmC;EAAW,kBAAA;EHwV9C;AGvVmC;EAAW,kBAAA;EH0V9C;AGzVmC;EAAW,kBAAA;EH4V9C;AG3VmC;EAAW,kBAAA;EH8V9C;AG7VmC;EAAW,kBAAA;EHgW9C;AG/VmC;EAAW,kBAAA;EHkW9C;AGjWmC;EAAW,kBAAA;EHoW9C;AGnWmC;EAAW,kBAAA;EHsW9C;AGrWmC;EAAW,kBAAA;EHwW9C;AGvWmC;EAAW,kBAAA;EH0W9C;AGzWmC;EAAW,kBAAA;EH4W9C;AG3WmC;EAAW,kBAAA;EH8W9C;AG7WmC;EAAW,kBAAA;EHgX9C;AG/WmC;EAAW,kBAAA;EHkX9C;AGjXmC;EAAW,kBAAA;EHoX9C;AGnXmC;EAAW,kBAAA;EHsX9C;AGrXmC;EAAW,kBAAA;EHwX9C;AGvXmC;EAAW,kBAAA;EH0X9C;AGzXmC;EAAW,kBAAA;EH4X9C;AG3XmC;EAAW,kBAAA;EH8X9C;AG7XmC;EAAW,kBAAA;EHgY9C;AG/XmC;EAAW,kBAAA;EHkY9C;AGjYmC;EAAW,kBAAA;EHoY9C;AGnYmC;EAAW,kBAAA;EHsY9C;AGrYmC;EAAW,kBAAA;EHwY9C;AGvYmC;EAAW,kBAAA;EH0Y9C;AGzYmC;EAAW,kBAAA;EH4Y9C;AG3YmC;EAAW,kBAAA;EH8Y9C;AG7YmC;EAAW,kBAAA;EHgZ9C;AG/YmC;EAAW,kBAAA;EHkZ9C;AGjZmC;EAAW,kBAAA;EHoZ9C;AGnZmC;EAAW,kBAAA;EHsZ9C;AGrZmC;EAAW,kBAAA;EHwZ9C;AGvZmC;EAAW,kBAAA;EH0Z9C;AGzZmC;EAAW,kBAAA;EH4Z9C;AG3ZmC;EAAW,kBAAA;EH8Z9C;AG7ZmC;EAAW,kBAAA;EHga9C;AG/ZmC;EAAW,kBAAA;EHka9C;AGjamC;EAAW,kBAAA;EHoa9C;AGnamC;EAAW,kBAAA;EHsa9C;AGramC;EAAW,kBAAA;EHwa9C;AGvamC;EAAW,kBAAA;EH0a9C;AGzamC;EAAW,kBAAA;EH4a9C;AG3amC;EAAW,kBAAA;EH8a9C;AG7amC;EAAW,kBAAA;EHgb9C;AG/amC;EAAW,kBAAA;EHkb9C;AGjbmC;EAAW,kBAAA;EHob9C;AGnbmC;EAAW,kBAAA;EHsb9C;AGrbmC;EAAW,kBAAA;EHwb9C;AGvbmC;EAAW,kBAAA;EH0b9C;AGzbmC;EAAW,kBAAA;EH4b9C;AG3bmC;EAAW,kBAAA;EH8b9C;AG7bmC;EAAW,kBAAA;EHgc9C;AG/bmC;EAAW,kBAAA;EHkc9C;AGjcmC;EAAW,kBAAA;EHoc9C;AGncmC;EAAW,kBAAA;EHsc9C;AGrcmC;EAAW,kBAAA;EHwc9C;AGvcmC;EAAW,kBAAA;EH0c9C;AGzcmC;EAAW,kBAAA;EH4c9C;AG3cmC;EAAW,kBAAA;EH8c9C;AG7cmC;EAAW,kBAAA;EHgd9C;AG/cmC;EAAW,kBAAA;EHkd9C;AGjdmC;EAAW,kBAAA;EHod9C;AGndmC;EAAW,kBAAA;EHsd9C;AGrdmC;EAAW,kBAAA;EHwd9C;AGvdmC;EAAW,kBAAA;EH0d9C;AGzdmC;EAAW,kBAAA;EH4d9C;AG3dmC;EAAW,kBAAA;EH8d9C;AG7dmC;EAAW,kBAAA;EHge9C;AG/dmC;EAAW,kBAAA;EHke9C;AGjemC;EAAW,kBAAA;EHoe9C;AGnemC;EAAW,kBAAA;EHse9C;AGremC;EAAW,kBAAA;EHwe9C;AGvemC;EAAW,kBAAA;EH0e9C;AGzemC;EAAW,kBAAA;EH4e9C;AG3emC;EAAW,kBAAA;EH8e9C;AG7emC;EAAW,kBAAA;EHgf9C;AG/emC;EAAW,kBAAA;EHkf9C;AGjfmC;EAAW,kBAAA;EHof9C;AGnfmC;EAAW,kBAAA;EHsf9C;AGrfmC;EAAW,kBAAA;EHwf9C;AGvfmC;EAAW,kBAAA;EH0f9C;AGzfmC;EAAW,kBAAA;EH4f9C;AG3fmC;EAAW,kBAAA;EH8f9C;AG7fmC;EAAW,kBAAA;EHggB9C;AG/fmC;EAAW,kBAAA;EHkgB9C;AGjgBmC;EAAW,kBAAA;EHogB9C;AGngBmC;EAAW,kBAAA;EHsgB9C;AGrgBmC;EAAW,kBAAA;EHwgB9C;AGvgBmC;EAAW,kBAAA;EH0gB9C;AGzgBmC;EAAW,kBAAA;EH4gB9C;AG3gBmC;EAAW,kBAAA;EH8gB9C;AG7gBmC;EAAW,kBAAA;EHghB9C;AG/gBmC;EAAW,kBAAA;EHkhB9C;AGjhBmC;EAAW,kBAAA;EHohB9C;AGnhBmC;EAAW,kBAAA;EHshB9C;AGrhBmC;EAAW,kBAAA;EHwhB9C;AGvhBmC;EAAW,kBAAA;EH0hB9C;AGzhBmC;EAAW,kBAAA;EH4hB9C;AG3hBmC;EAAW,kBAAA;EH8hB9C;AG7hBmC;EAAW,kBAAA;EHgiB9C;AG/hBmC;EAAW,kBAAA;EHkiB9C;AGjiBmC;EAAW,kBAAA;EHoiB9C;AGniBmC;EAAW,kBAAA;EHsiB9C;AGriBmC;EAAW,kBAAA;EHwiB9C;AGviBmC;EAAW,kBAAA;EH0iB9C;AGziBmC;EAAW,kBAAA;EH4iB9C;AG3iBmC;EAAW,kBAAA;EH8iB9C;AG7iBmC;EAAW,kBAAA;EHgjB9C;AG/iBmC;EAAW,kBA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EACE,mBAAA;Efi7CH;Ael7CC;EACE,2BAAA;Efo7CH;Aer7CC;EACE,2BAAA;Efu7CH;Aex7CC;EACE,kBAAA;Ef07CH;Ae37CC;EACE,2BAAA;Ef67CH;Ae97CC;EACE,2BAAA;Efg8CH;Aej8CC;EACE,kBAAA;Efm8CH;Aep8CC;EACE,2BAAA;Efs8CH;Aev8CC;EACE,2BAAA;Efy8CH;Ae18CC;EACE,kBAAA;Ef48CH;Ae78CC;EACE,2BAAA;Ef+8CH;Aeh9CC;EACE,0BAAA;Efk9CH;Aen9CC;EACE,iBAAA;Efq9CH;Aaz9CD;EE9BI;IACE,aAAA;If0/CH;Een/CD;IACE,aAAA;Ifq/CD;Eet/CD;IACE,qBAAA;Ifw/CD;Eez/CD;IACE,qBAAA;If2/CD;Ee5/CD;IACE,YAAA;If8/CD;Ee//CD;IACE,qBAAA;IfigDD;EelgDD;IACE,qBAAA;IfogDD;EergDD;IACE,YAAA;IfugDD;EexgDD;IACE,qBAAA;If0gDD;Ee3gDD;IACE,qBAAA;If6gDD;Ee9gDD;IACE,YAAA;IfghDD;EejhDD;IACE,qBAAA;IfmhDD;EephDD;IACE,oBAAA;IfshDD;EexgDD;IACE,aAAA;If0gDD;Ee3gDD;IACE,qBAAA;If6gDD;Ee9gDD;IACE,qBAAA;IfghDD;EejhDD;IACE,YAAA;IfmhDD;EephDD;IACE,qBAAA;IfshDD;EevhDD;IACE,qBAAA;IfyhDD;Ee1hDD;IACE,YAAA;If4hDD;Ee7hDD;IACE,qBAAA;If+hDD;EehiDD;IACE,qBAAA;IfkiDD;EeniDD;IACE,YAAA;IfqiDD;EetiDD;IACE,qBAAA;IfwiDD;EeziDD;IACE,oBAAA;If2iDD;EeviDD;IACE,aAAA;IfyiDD;EezjDD;IACE,YAAA;If2jDD;Ee5jDD;IACE,oBAAA;If8jDD;Ee/jDD;IACE,oBAAA;IfikDD;EelkDD;IACE,WAAA;IfokDD;EerkDD;IACE,oBAAA;IfukDD;EexkDD;IACE,oBAAA;If0kDD;Ee3kDD;IACE,WAAA;If6kDD;Ee9kDD;IACE,oBAAA;IfglDD;EejlDD;IACE,oBAAA;IfmlDD;EeplDD;IACE,WAAA;IfslDD;EevlDD;IACE,oBAAA;IfylDD;Ee1lDD;IACE,mBAAA;If4lDD;EexlDD;IACE,YAAA;If0lDD;Ee5kDD;IACE,mBAAA;If8kDD;Ee/kDD;IACE,2BAAA;IfilDD;EellDD;IACE,2BAAA;IfolDD;EerlDD;IACE,kBAAA;IfulDD;EexlDD;IACE,2BAAA;If0lDD;Ee3lDD;IACE,2BAAA;If6lDD;Ee9lDD;IACE,kBAAA;IfgmDD;EejmDD;IACE,2BAAA;IfmmDD;EepmDD;IACE,2BAAA;IfsmDD;EevmDD;IACE,kBAAA;IfymDD;Ee1mDD;IACE,2BAAA;If4mDD;Ee7mDD;IACE,0BAAA;If+mDD;EehnDD;IACE,iBAAA;IfknDD;EACF;Aa9mDD;EEvCI;IACE,aAAA;IfwpDH;EejpDD;IACE,aAAA;IfmpDD;EeppDD;IACE,qBAAA;IfspDD;EevpDD;IACE,qBAAA;IfypDD;Ee1pDD;IACE,YAAA;If4pDD;Ee7pDD;IACE,qBAAA;If+pDD;EehqDD;IACE,qBAAA;IfkqDD;EenqDD;IACE,YAAA;IfqqDD;EetqDD;IACE,qBAAA;IfwqDD;EezqDD;IACE,qBAAA;If2qDD;Ee5qDD;IACE,YAAA;If8qDD;Ee/qDD;IACE,qBAAA;IfirDD;EelrDD;IACE,oBAAA;IforDD;EetqDD;IACE,aAAA;IfwqDD;EezqDD;IACE,qBAAA;If2qDD;Ee5qDD;IACE,qBAAA;If8qDD;Ee/qDD;IACE,YAAA;IfirDD;EelrDD;IACE,qBAAA;IforDD;EerrDD;IACE,qBAAA;IfurDD;EexrDD;IACE,YAAA;If0rDD;Ee3rDD;IACE,qBAAA;If6rDD;Ee9rDD;IACE,qBAAA;IfgsDD;EejsDD;IACE,YAAA;IfmsDD;EepsDD;IACE,qBAAA;IfssDD;EevsDD;IACE,oBAAA;IfysDD;EersDD;IACE,aAAA;IfusDD;EevtDD;IACE,YAAA;IfytDD;Ee1tDD;IACE,oBAAA;If4tDD;Ee7tDD;IACE,oBAAA;If+tDD;EehuDD;IACE,WAAA;IfkuDD;EenuDD;IACE,oBAAA;IfquDD;EetuDD;IACE,oBAAA;IfwuDD;EezuDD;IACE,WAAA;If2uDD;Ee5uDD;IACE,oBAAA;If8uDD;Ee/uDD;IACE,oBAAA;IfivDD;EelvDD;IACE,WAAA;IfovDD;EervDD;IACE,oBAAA;IfuvDD;EexvDD;IACE,mBAAA;If0vDD;EetvDD;IACE,YAAA;IfwvDD;Ee1uDD;IACE,mBAAA;If4uDD;Ee7uDD;IACE,2BAAA;If+uDD;EehvDD;IACE,2BAAA;IfkvDD;EenvDD;IACE,kBAAA;IfqvDD;EetvDD;IACE,2BAAA;IfwvDD;EezvDD;IACE,2BAAA;If2vDD;Ee5vDD;IACE,kBAAA;If8vDD;Ee/vDD;IACE,2BAAA;IfiwDD;EelwDD;IACE,2BAAA;IfowDD;EerwDD;IACE,kBAAA;IfuwDD;EexwDD;IACE,2BAAA;If0wDD;Ee3wDD;IACE,0BAAA;If6wDD;Ee9wDD;IACE,iBAAA;IfgxDD;EACF;AarwDD;EE9CI;IACE,aAAA;IfszDH;Ee/yDD;IACE,aAAA;IfizDD;EelzDD;IACE,qBAAA;IfozDD;EerzDD;IACE,qBAAA;IfuzDD;EexzDD;IACE,YAAA;If0zDD;Ee3zDD;IACE,qBAAA;If6zDD;Ee9zDD;IACE,qBAAA;Ifg0DD;Eej0DD;IACE,YAAA;Ifm0DD;Eep0DD;IACE,qBAAA;Ifs0DD;Eev0DD;IACE,qBAAA;Ify0DD;Ee10DD;IACE,YAAA;If40DD;Ee70DD;IACE,qBAAA;If+0DD;Eeh1DD;IACE,oBAAA;Ifk1DD;Eep0DD;IACE,aAAA;Ifs0DD;Eev0DD;IACE,qBAAA;Ify0DD;Ee10DD;IACE,qBAAA;If40DD;Ee70DD;IACE,YAAA;If+0DD;Eeh1DD;IACE,qBAAA;Ifk1DD;Een1DD;IACE,qBAAA;Ifq1DD;Eet1DD;IACE,YAAA;Ifw1DD;Eez1DD;IACE,qBAAA;If21DD;Ee51DD;IACE,qBAAA;If81DD;Ee/1DD;IACE,YAAA;Ifi2DD;Eel2DD;IACE,qBAAA;Ifo2DD;Eer2DD;IACE,oBAAA;Ifu2DD;Een2DD;IACE,aAAA;Ifq2DD;Eer3DD;IACE,YAAA;Ifu3DD;Eex3DD;IACE,oBAAA;If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EACA,uBAAA;ErB+tFD;AqB7tFC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;ErB+tFP;AqB7tFC;;;EAGE,wBAAA;ErB+tFH;AqB1tFG;;;;;;;;;;;;;;;;;;EAME,2BAAA;EACI,uBAAA;ErBwuFT;AoBhtFD;ECnBI,gBAAA;EACA,2BAAA;ErBsuFH;AoBjtFD;ECxDE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErB4wFD;AqB1wFC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;ErB4wFP;AqB1wFC;;;EAGE,wBAAA;ErB4wFH;AqBvwFG;;;;;;;;;;;;;;;;;;EAME,2BAAA;EACI,uBAAA;ErBqxFT;AoB1vFD;ECtBI,gBAAA;EACA,2BAAA;ErBmxFH;AoB1vFD;EC5DE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErByzFD;AqBvzFC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;ErByzFP;AqBvzFC;;;EAGE,wBAAA;ErByzFH;AqBpzFG;;;;;;;;;;;;;;;;;;EAME,2BAAA;EACI,uBAAA;ErBk0FT;AoBnyFD;EC1BI,gBAAA;EACA,2BAAA;ErBg0FH;AoBnyFD;EChEE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErBs2FD;AqBp2FC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;ErBs2FP;AqBp2FC;;;EAGE,wBAAA;ErBs2FH;AqBj2FG;;;;;;;;;;;;;;;;;;EAME,2BAAA;EACI,uBAAA;ErB+2FT;AoB50FD;EC9BI,gBAAA;EACA,2BAAA;ErB62FH;AoB50FD;ECpEE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErBm5FD;AqBj5FC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;ErBm5FP;AqBj5FC;;;EAGE,wBAAA;ErBm5FH;AqB94FG;;;;;;;;;;;;;;;;;;EAME,2BAAA;EACI,uBAAA;ErB45FT;AoBr3FD;EClCI,gBAAA;EACA,2BAAA;ErB05FH;AoBr3FD;ECxEE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErBg8FD;AqB97FC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;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","file":"bootstrap.css","sourcesContent":["/*! normalize.css v3.0.2 | MIT License | git.io/normalize */\nhtml {\n font-family: sans-serif;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n}\nbody {\n margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block;\n vertical-align: baseline;\n}\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n[hidden],\ntemplate {\n display: none;\n}\na {\n background-color: transparent;\n}\na:active,\na:hover {\n outline: 0;\n}\nabbr[title] {\n border-bottom: 1px dotted;\n}\nb,\nstrong {\n font-weight: bold;\n}\ndfn {\n font-style: italic;\n}\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\nmark {\n background: #ff0;\n color: #000;\n}\nsmall {\n font-size: 80%;\n}\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\nsup {\n top: -0.5em;\n}\nsub {\n bottom: -0.25em;\n}\nimg {\n border: 0;\n}\nsvg:not(:root) {\n overflow: hidden;\n}\nfigure {\n margin: 1em 40px;\n}\nhr {\n -moz-box-sizing: content-box;\n box-sizing: content-box;\n height: 0;\n}\npre {\n overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit;\n font: inherit;\n margin: 0;\n}\nbutton {\n overflow: visible;\n}\nbutton,\nselect {\n text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button;\n cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\ninput {\n line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box;\n padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: textfield;\n -moz-box-sizing: content-box;\n -webkit-box-sizing: content-box;\n box-sizing: content-box;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\nlegend {\n border: 0;\n padding: 0;\n}\ntextarea {\n overflow: auto;\n}\noptgroup {\n font-weight: bold;\n}\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\ntd,\nth {\n padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important;\n box-shadow: none !important;\n text-shadow: none !important;\n }\n a,\n a:visited {\n text-decoration: underline;\n }\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n img {\n max-width: 100% !important;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n select {\n background: #fff !important;\n }\n .navbar {\n display: none;\n }\n .btn > .caret,\n .dropup > .btn > .caret {\n border-top-color: #000 !important;\n }\n .label {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('../fonts/glyphicons-halflings-regular.eot');\n src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');\n}\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n content: \"\\2a\";\n}\n.glyphicon-plus:before {\n content: \"\\2b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n content: \"\\270f\";\n}\n.glyphicon-glass:before {\n content: \"\\e001\";\n}\n.glyphicon-music:before {\n content: \"\\e002\";\n}\n.glyphicon-search:before {\n content: \"\\e003\";\n}\n.glyphicon-heart:before {\n content: \"\\e005\";\n}\n.glyphicon-star:before {\n content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n content: \"\\e007\";\n}\n.glyphicon-user:before {\n content: \"\\e008\";\n}\n.glyphicon-film:before {\n content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n content: \"\\e010\";\n}\n.glyphicon-th:before {\n content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n content: \"\\e012\";\n}\n.glyphicon-ok:before {\n content: \"\\e013\";\n}\n.glyphicon-remove:before {\n content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n content: \"\\e016\";\n}\n.glyphicon-off:before {\n content: \"\\e017\";\n}\n.glyphicon-signal:before {\n content: \"\\e018\";\n}\n.glyphicon-cog:before {\n content: \"\\e019\";\n}\n.glyphicon-trash:before {\n content: \"\\e020\";\n}\n.glyphicon-home:before {\n content: \"\\e021\";\n}\n.glyphicon-file:before {\n content: \"\\e022\";\n}\n.glyphicon-time:before {\n content: \"\\e023\";\n}\n.glyphicon-road:before {\n content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n content: \"\\e025\";\n}\n.glyphicon-download:before {\n content: \"\\e026\";\n}\n.glyphicon-upload:before {\n content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n content: \"\\e032\";\n}\n.glyphicon-lock:before {\n content: \"\\e033\";\n}\n.glyphicon-flag:before {\n content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n content: \"\\e040\";\n}\n.glyphicon-tag:before {\n content: \"\\e041\";\n}\n.glyphicon-tags:before {\n content: \"\\e042\";\n}\n.glyphicon-book:before {\n content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n content: \"\\e044\";\n}\n.glyphicon-print:before {\n content: \"\\e045\";\n}\n.glyphicon-camera:before {\n content: \"\\e046\";\n}\n.glyphicon-font:before {\n content: \"\\e047\";\n}\n.glyphicon-bold:before {\n content: \"\\e048\";\n}\n.glyphicon-italic:before {\n content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n content: \"\\e055\";\n}\n.glyphicon-list:before {\n content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n content: \"\\e059\";\n}\n.glyphicon-picture:before {\n content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n content: \"\\e063\";\n}\n.glyphicon-tint:before {\n content: \"\\e064\";\n}\n.glyphicon-edit:before {\n content: \"\\e065\";\n}\n.glyphicon-share:before {\n content: \"\\e066\";\n}\n.glyphicon-check:before {\n content: \"\\e067\";\n}\n.glyphicon-move:before {\n content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n content: \"\\e070\";\n}\n.glyphicon-backward:before {\n content: \"\\e071\";\n}\n.glyphicon-play:before {\n content: \"\\e072\";\n}\n.glyphicon-pause:before {\n content: \"\\e073\";\n}\n.glyphicon-stop:before {\n content: \"\\e074\";\n}\n.glyphicon-forward:before {\n content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n content: \"\\e077\";\n}\n.glyphicon-eject:before {\n content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n content: \"\\e101\";\n}\n.glyphicon-gift:before {\n content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n content: \"\\e103\";\n}\n.glyphicon-fire:before {\n content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n content: \"\\e107\";\n}\n.glyphicon-plane:before {\n content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n content: \"\\e109\";\n}\n.glyphicon-random:before {\n content: \"\\e110\";\n}\n.glyphicon-comment:before {\n content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n content: \"\\e122\";\n}\n.glyphicon-bell:before {\n content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n content: \"\\e134\";\n}\n.glyphicon-globe:before {\n content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n content: \"\\e137\";\n}\n.glyphicon-filter:before {\n content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n content: \"\\e143\";\n}\n.glyphicon-link:before {\n content: \"\\e144\";\n}\n.glyphicon-phone:before {\n content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n content: \"\\e146\";\n}\n.glyphicon-usd:before {\n content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n content: \"\\e149\";\n}\n.glyphicon-sort:before {\n content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n content: \"\\e157\";\n}\n.glyphicon-expand:before {\n content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n content: \"\\e161\";\n}\n.glyphicon-flash:before {\n content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n content: \"\\e164\";\n}\n.glyphicon-record:before {\n content: \"\\e165\";\n}\n.glyphicon-save:before {\n content: \"\\e166\";\n}\n.glyphicon-open:before {\n content: \"\\e167\";\n}\n.glyphicon-saved:before {\n content: \"\\e168\";\n}\n.glyphicon-import:before {\n content: \"\\e169\";\n}\n.glyphicon-export:before {\n content: \"\\e170\";\n}\n.glyphicon-send:before {\n content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n content: \"\\e179\";\n}\n.glyphicon-header:before {\n content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n content: \"\\e183\";\n}\n.glyphicon-tower:before {\n content: \"\\e184\";\n}\n.glyphicon-stats:before {\n content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n content: \"\\e200\";\n}\n* {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n*:before,\n*:after {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 1.42857143;\n color: #333333;\n background-color: #ffffff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\na {\n color: #337ab7;\n text-decoration: none;\n}\na:hover,\na:focus {\n color: #23527c;\n text-decoration: underline;\n}\na:focus {\n outline: thin dotted;\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\nfigure {\n margin: 0;\n}\nimg {\n vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n display: block;\n max-width: 100%;\n height: auto;\n}\n.img-rounded {\n border-radius: 6px;\n}\n.img-thumbnail {\n padding: 4px;\n line-height: 1.42857143;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n border-radius: 4px;\n -webkit-transition: all 0.2s ease-in-out;\n -o-transition: all 0.2s ease-in-out;\n transition: all 0.2s ease-in-out;\n display: inline-block;\n max-width: 100%;\n height: auto;\n}\n.img-circle {\n border-radius: 50%;\n}\nhr {\n margin-top: 20px;\n margin-bottom: 20px;\n border: 0;\n border-top: 1px solid #eeeeee;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n font-family: inherit;\n font-weight: 500;\n line-height: 1.1;\n color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n font-weight: normal;\n line-height: 1;\n color: #777777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n margin-top: 20px;\n margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n margin-top: 10px;\n margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n font-size: 75%;\n}\nh1,\n.h1 {\n font-size: 36px;\n}\nh2,\n.h2 {\n font-size: 30px;\n}\nh3,\n.h3 {\n font-size: 24px;\n}\nh4,\n.h4 {\n font-size: 18px;\n}\nh5,\n.h5 {\n font-size: 14px;\n}\nh6,\n.h6 {\n font-size: 12px;\n}\np {\n margin: 0 0 10px;\n}\n.lead {\n margin-bottom: 20px;\n font-size: 16px;\n font-weight: 300;\n line-height: 1.4;\n}\n@media (min-width: 768px) {\n .lead {\n font-size: 21px;\n }\n}\nsmall,\n.small {\n font-size: 85%;\n}\nmark,\n.mark {\n background-color: #fcf8e3;\n padding: .2em;\n}\n.text-left {\n text-align: left;\n}\n.text-right {\n text-align: right;\n}\n.text-center {\n text-align: center;\n}\n.text-justify {\n text-align: justify;\n}\n.text-nowrap {\n white-space: nowrap;\n}\n.text-lowercase {\n text-transform: lowercase;\n}\n.text-uppercase {\n text-transform: uppercase;\n}\n.text-capitalize {\n text-transform: capitalize;\n}\n.text-muted {\n color: #777777;\n}\n.text-primary {\n color: #337ab7;\n}\na.text-primary:hover {\n color: #286090;\n}\n.text-success {\n color: #3c763d;\n}\na.text-success:hover {\n color: #2b542c;\n}\n.text-info {\n color: #31708f;\n}\na.text-info:hover {\n color: #245269;\n}\n.text-warning {\n color: #8a6d3b;\n}\na.text-warning:hover {\n color: #66512c;\n}\n.text-danger {\n color: #a94442;\n}\na.text-danger:hover {\n color: #843534;\n}\n.bg-primary {\n color: #fff;\n background-color: #337ab7;\n}\na.bg-primary:hover {\n background-color: #286090;\n}\n.bg-success {\n background-color: #dff0d8;\n}\na.bg-success:hover {\n background-color: #c1e2b3;\n}\n.bg-info {\n background-color: #d9edf7;\n}\na.bg-info:hover {\n background-color: #afd9ee;\n}\n.bg-warning {\n background-color: #fcf8e3;\n}\na.bg-warning:hover {\n background-color: #f7ecb5;\n}\n.bg-danger {\n background-color: #f2dede;\n}\na.bg-danger:hover {\n background-color: #e4b9b9;\n}\n.page-header {\n padding-bottom: 9px;\n margin: 40px 0 20px;\n border-bottom: 1px solid #eeeeee;\n}\nul,\nol {\n margin-top: 0;\n margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n margin-bottom: 0;\n}\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n.list-inline {\n padding-left: 0;\n list-style: none;\n margin-left: -5px;\n}\n.list-inline > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n}\ndl {\n margin-top: 0;\n margin-bottom: 20px;\n}\ndt,\ndd {\n line-height: 1.42857143;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .dl-horizontal dt {\n float: left;\n width: 160px;\n clear: left;\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .dl-horizontal dd {\n margin-left: 180px;\n }\n}\nabbr[title],\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted #777777;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\nblockquote {\n padding: 10px 20px;\n margin: 0 0 20px;\n font-size: 17.5px;\n border-left: 5px solid #eeeeee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n display: block;\n font-size: 80%;\n line-height: 1.42857143;\n color: #777777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid #eeeeee;\n border-left: 0;\n text-align: right;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n content: '\\00A0 \\2014';\n}\naddress {\n margin-bottom: 20px;\n font-style: normal;\n line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: #c7254e;\n background-color: #f9f2f4;\n border-radius: 4px;\n}\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: #ffffff;\n background-color: #333333;\n border-radius: 3px;\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n}\npre {\n display: block;\n padding: 9.5px;\n margin: 0 0 10px;\n font-size: 13px;\n line-height: 1.42857143;\n word-break: break-all;\n word-wrap: break-word;\n color: #333333;\n background-color: #f5f5f5;\n border: 1px solid #cccccc;\n border-radius: 4px;\n}\npre code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n}\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n.container {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n@media (min-width: 768px) {\n .container {\n width: 750px;\n }\n}\n@media (min-width: 992px) {\n .container {\n width: 970px;\n }\n}\n@media (min-width: 1200px) {\n .container {\n width: 1170px;\n }\n}\n.container-fluid {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n.row {\n margin-left: -15px;\n margin-right: -15px;\n}\n.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {\n position: relative;\n min-height: 1px;\n padding-left: 15px;\n padding-right: 15px;\n}\n.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {\n float: left;\n}\n.col-xs-12 {\n width: 100%;\n}\n.col-xs-11 {\n width: 91.66666667%;\n}\n.col-xs-10 {\n width: 83.33333333%;\n}\n.col-xs-9 {\n width: 75%;\n}\n.col-xs-8 {\n width: 66.66666667%;\n}\n.col-xs-7 {\n width: 58.33333333%;\n}\n.col-xs-6 {\n width: 50%;\n}\n.col-xs-5 {\n width: 41.66666667%;\n}\n.col-xs-4 {\n width: 33.33333333%;\n}\n.col-xs-3 {\n width: 25%;\n}\n.col-xs-2 {\n width: 16.66666667%;\n}\n.col-xs-1 {\n width: 8.33333333%;\n}\n.col-xs-pull-12 {\n right: 100%;\n}\n.col-xs-pull-11 {\n right: 91.66666667%;\n}\n.col-xs-pull-10 {\n right: 83.33333333%;\n}\n.col-xs-pull-9 {\n right: 75%;\n}\n.col-xs-pull-8 {\n right: 66.66666667%;\n}\n.col-xs-pull-7 {\n right: 58.33333333%;\n}\n.col-xs-pull-6 {\n right: 50%;\n}\n.col-xs-pull-5 {\n right: 41.66666667%;\n}\n.col-xs-pull-4 {\n right: 33.33333333%;\n}\n.col-xs-pull-3 {\n right: 25%;\n}\n.col-xs-pull-2 {\n right: 16.66666667%;\n}\n.col-xs-pull-1 {\n right: 8.33333333%;\n}\n.col-xs-pull-0 {\n right: auto;\n}\n.col-xs-push-12 {\n left: 100%;\n}\n.col-xs-push-11 {\n left: 91.66666667%;\n}\n.col-xs-push-10 {\n left: 83.33333333%;\n}\n.col-xs-push-9 {\n left: 75%;\n}\n.col-xs-push-8 {\n left: 66.66666667%;\n}\n.col-xs-push-7 {\n left: 58.33333333%;\n}\n.col-xs-push-6 {\n left: 50%;\n}\n.col-xs-push-5 {\n left: 41.66666667%;\n}\n.col-xs-push-4 {\n left: 33.33333333%;\n}\n.col-xs-push-3 {\n left: 25%;\n}\n.col-xs-push-2 {\n left: 16.66666667%;\n}\n.col-xs-push-1 {\n left: 8.33333333%;\n}\n.col-xs-push-0 {\n left: auto;\n}\n.col-xs-offset-12 {\n margin-left: 100%;\n}\n.col-xs-offset-11 {\n margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n margin-left: 75%;\n}\n.col-xs-offset-8 {\n margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n margin-left: 50%;\n}\n.col-xs-offset-5 {\n margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n margin-left: 25%;\n}\n.col-xs-offset-2 {\n margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n margin-left: 0%;\n}\n@media (min-width: 768px) {\n .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {\n float: left;\n }\n .col-sm-12 {\n width: 100%;\n }\n .col-sm-11 {\n width: 91.66666667%;\n }\n .col-sm-10 {\n width: 83.33333333%;\n }\n .col-sm-9 {\n width: 75%;\n }\n .col-sm-8 {\n width: 66.66666667%;\n }\n .col-sm-7 {\n width: 58.33333333%;\n }\n .col-sm-6 {\n width: 50%;\n }\n .col-sm-5 {\n width: 41.66666667%;\n }\n .col-sm-4 {\n width: 33.33333333%;\n }\n .col-sm-3 {\n width: 25%;\n }\n .col-sm-2 {\n width: 16.66666667%;\n }\n .col-sm-1 {\n width: 8.33333333%;\n }\n .col-sm-pull-12 {\n right: 100%;\n }\n .col-sm-pull-11 {\n right: 91.66666667%;\n }\n .col-sm-pull-10 {\n right: 83.33333333%;\n }\n .col-sm-pull-9 {\n right: 75%;\n }\n .col-sm-pull-8 {\n right: 66.66666667%;\n }\n .col-sm-pull-7 {\n right: 58.33333333%;\n }\n .col-sm-pull-6 {\n right: 50%;\n }\n .col-sm-pull-5 {\n right: 41.66666667%;\n }\n .col-sm-pull-4 {\n right: 33.33333333%;\n }\n .col-sm-pull-3 {\n right: 25%;\n }\n .col-sm-pull-2 {\n right: 16.66666667%;\n }\n .col-sm-pull-1 {\n right: 8.33333333%;\n }\n .col-sm-pull-0 {\n right: auto;\n }\n .col-sm-push-12 {\n left: 100%;\n }\n .col-sm-push-11 {\n left: 91.66666667%;\n }\n .col-sm-push-10 {\n left: 83.33333333%;\n }\n .col-sm-push-9 {\n left: 75%;\n }\n .col-sm-push-8 {\n left: 66.66666667%;\n }\n .col-sm-push-7 {\n left: 58.33333333%;\n }\n .col-sm-push-6 {\n left: 50%;\n }\n .col-sm-push-5 {\n left: 41.66666667%;\n }\n .col-sm-push-4 {\n left: 33.33333333%;\n }\n .col-sm-push-3 {\n left: 25%;\n }\n .col-sm-push-2 {\n left: 16.66666667%;\n }\n .col-sm-push-1 {\n left: 8.33333333%;\n }\n .col-sm-push-0 {\n left: auto;\n }\n .col-sm-offset-12 {\n margin-left: 100%;\n }\n .col-sm-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-sm-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-sm-offset-9 {\n margin-left: 75%;\n }\n .col-sm-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-sm-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-sm-offset-6 {\n margin-left: 50%;\n }\n .col-sm-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-sm-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-sm-offset-3 {\n margin-left: 25%;\n }\n .col-sm-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-sm-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-sm-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 992px) {\n .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {\n float: left;\n }\n .col-md-12 {\n width: 100%;\n }\n .col-md-11 {\n width: 91.66666667%;\n }\n .col-md-10 {\n width: 83.33333333%;\n }\n .col-md-9 {\n width: 75%;\n }\n .col-md-8 {\n width: 66.66666667%;\n }\n .col-md-7 {\n width: 58.33333333%;\n }\n .col-md-6 {\n width: 50%;\n }\n .col-md-5 {\n width: 41.66666667%;\n }\n .col-md-4 {\n width: 33.33333333%;\n }\n .col-md-3 {\n width: 25%;\n }\n .col-md-2 {\n width: 16.66666667%;\n }\n .col-md-1 {\n width: 8.33333333%;\n }\n .col-md-pull-12 {\n right: 100%;\n }\n .col-md-pull-11 {\n right: 91.66666667%;\n }\n .col-md-pull-10 {\n right: 83.33333333%;\n }\n .col-md-pull-9 {\n right: 75%;\n }\n .col-md-pull-8 {\n right: 66.66666667%;\n }\n .col-md-pull-7 {\n right: 58.33333333%;\n }\n .col-md-pull-6 {\n right: 50%;\n }\n .col-md-pull-5 {\n right: 41.66666667%;\n }\n .col-md-pull-4 {\n right: 33.33333333%;\n }\n .col-md-pull-3 {\n right: 25%;\n }\n .col-md-pull-2 {\n right: 16.66666667%;\n }\n .col-md-pull-1 {\n right: 8.33333333%;\n }\n .col-md-pull-0 {\n right: auto;\n }\n .col-md-push-12 {\n left: 100%;\n }\n .col-md-push-11 {\n left: 91.66666667%;\n }\n .col-md-push-10 {\n left: 83.33333333%;\n }\n .col-md-push-9 {\n left: 75%;\n }\n .col-md-push-8 {\n left: 66.66666667%;\n }\n .col-md-push-7 {\n left: 58.33333333%;\n }\n .col-md-push-6 {\n left: 50%;\n }\n .col-md-push-5 {\n left: 41.66666667%;\n }\n .col-md-push-4 {\n left: 33.33333333%;\n }\n .col-md-push-3 {\n left: 25%;\n }\n .col-md-push-2 {\n left: 16.66666667%;\n }\n .col-md-push-1 {\n left: 8.33333333%;\n }\n .col-md-push-0 {\n left: auto;\n }\n .col-md-offset-12 {\n margin-left: 100%;\n }\n .col-md-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-md-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-md-offset-9 {\n margin-left: 75%;\n }\n .col-md-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-md-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-md-offset-6 {\n margin-left: 50%;\n }\n .col-md-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-md-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-md-offset-3 {\n margin-left: 25%;\n }\n .col-md-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-md-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-md-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 1200px) {\n .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {\n float: left;\n }\n .col-lg-12 {\n width: 100%;\n }\n .col-lg-11 {\n width: 91.66666667%;\n }\n .col-lg-10 {\n width: 83.33333333%;\n }\n .col-lg-9 {\n width: 75%;\n }\n .col-lg-8 {\n width: 66.66666667%;\n }\n .col-lg-7 {\n width: 58.33333333%;\n }\n .col-lg-6 {\n width: 50%;\n }\n .col-lg-5 {\n width: 41.66666667%;\n }\n .col-lg-4 {\n width: 33.33333333%;\n }\n .col-lg-3 {\n width: 25%;\n }\n .col-lg-2 {\n width: 16.66666667%;\n }\n .col-lg-1 {\n width: 8.33333333%;\n }\n .col-lg-pull-12 {\n right: 100%;\n }\n .col-lg-pull-11 {\n right: 91.66666667%;\n }\n .col-lg-pull-10 {\n right: 83.33333333%;\n }\n .col-lg-pull-9 {\n right: 75%;\n }\n .col-lg-pull-8 {\n right: 66.66666667%;\n }\n .col-lg-pull-7 {\n right: 58.33333333%;\n }\n .col-lg-pull-6 {\n right: 50%;\n }\n .col-lg-pull-5 {\n right: 41.66666667%;\n }\n .col-lg-pull-4 {\n right: 33.33333333%;\n }\n .col-lg-pull-3 {\n right: 25%;\n }\n .col-lg-pull-2 {\n right: 16.66666667%;\n }\n .col-lg-pull-1 {\n right: 8.33333333%;\n }\n .col-lg-pull-0 {\n right: auto;\n }\n .col-lg-push-12 {\n left: 100%;\n }\n .col-lg-push-11 {\n left: 91.66666667%;\n }\n .col-lg-push-10 {\n left: 83.33333333%;\n }\n .col-lg-push-9 {\n left: 75%;\n }\n .col-lg-push-8 {\n left: 66.66666667%;\n }\n .col-lg-push-7 {\n left: 58.33333333%;\n }\n .col-lg-push-6 {\n left: 50%;\n }\n .col-lg-push-5 {\n left: 41.66666667%;\n }\n .col-lg-push-4 {\n left: 33.33333333%;\n }\n .col-lg-push-3 {\n left: 25%;\n }\n .col-lg-push-2 {\n left: 16.66666667%;\n }\n .col-lg-push-1 {\n left: 8.33333333%;\n }\n .col-lg-push-0 {\n left: auto;\n }\n .col-lg-offset-12 {\n margin-left: 100%;\n }\n .col-lg-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-lg-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-lg-offset-9 {\n margin-left: 75%;\n }\n .col-lg-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-lg-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-lg-offset-6 {\n margin-left: 50%;\n }\n .col-lg-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-lg-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-lg-offset-3 {\n margin-left: 25%;\n }\n .col-lg-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-lg-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-lg-offset-0 {\n margin-left: 0%;\n }\n}\ntable {\n background-color: transparent;\n}\ncaption {\n padding-top: 8px;\n padding-bottom: 8px;\n color: #777777;\n text-align: left;\n}\nth {\n text-align: left;\n}\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n padding: 8px;\n line-height: 1.42857143;\n vertical-align: top;\n border-top: 1px solid #dddddd;\n}\n.table > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid #dddddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n border-top: 0;\n}\n.table > tbody + tbody {\n border-top: 2px solid #dddddd;\n}\n.table .table {\n background-color: #ffffff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n padding: 5px;\n}\n.table-bordered {\n border: 1px solid #dddddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n border: 1px solid #dddddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-child(odd) {\n background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-column;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-cell;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n background-color: #ebcccc;\n}\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%;\n}\n@media screen and (max-width: 767px) {\n .table-responsive {\n width: 100%;\n margin-bottom: 15px;\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid #dddddd;\n }\n .table-responsive > .table {\n margin-bottom: 0;\n }\n .table-responsive > .table > thead > tr > th,\n .table-responsive > .table > tbody > tr > th,\n .table-responsive > .table > tfoot > tr > th,\n .table-responsive > .table > thead > tr > td,\n .table-responsive > .table > tbody > tr > td,\n .table-responsive > .table > tfoot > tr > td {\n white-space: nowrap;\n }\n .table-responsive > .table-bordered {\n border: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:first-child,\n .table-responsive > .table-bordered > tbody > tr > th:first-child,\n .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n .table-responsive > .table-bordered > thead > tr > td:first-child,\n .table-responsive > .table-bordered > tbody > tr > td:first-child,\n .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:last-child,\n .table-responsive > .table-bordered > tbody > tr > th:last-child,\n .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n .table-responsive > .table-bordered > thead > tr > td:last-child,\n .table-responsive > .table-bordered > tbody > tr > td:last-child,\n .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n }\n .table-responsive > .table-bordered > tbody > tr:last-child > th,\n .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n .table-responsive > .table-bordered > tbody > tr:last-child > td,\n .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n border-bottom: 0;\n }\n}\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n min-width: 0;\n}\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: 20px;\n font-size: 21px;\n line-height: inherit;\n color: #333333;\n border: 0;\n border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n display: inline-block;\n max-width: 100%;\n margin-bottom: 5px;\n font-weight: bold;\n}\ninput[type=\"search\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9;\n line-height: normal;\n}\ninput[type=\"file\"] {\n display: block;\n}\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\nselect[multiple],\nselect[size] {\n height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n outline: thin dotted;\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\noutput {\n display: block;\n padding-top: 7px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n}\n.form-control {\n display: block;\n width: 100%;\n height: 34px;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n background-color: #ffffff;\n background-image: none;\n border: 1px solid #cccccc;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n border-color: #66afe9;\n outline: 0;\n -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n}\n.form-control::-moz-placeholder {\n color: #999999;\n opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n color: #999999;\n}\n.form-control::-webkit-input-placeholder {\n color: #999999;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n cursor: not-allowed;\n background-color: #eeeeee;\n opacity: 1;\n}\ntextarea.form-control {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"],\n input[type=\"time\"],\n input[type=\"datetime-local\"],\n input[type=\"month\"] {\n line-height: 34px;\n }\n input[type=\"date\"].input-sm,\n input[type=\"time\"].input-sm,\n input[type=\"datetime-local\"].input-sm,\n input[type=\"month\"].input-sm {\n line-height: 30px;\n }\n input[type=\"date\"].input-lg,\n input[type=\"time\"].input-lg,\n input[type=\"datetime-local\"].input-lg,\n input[type=\"month\"].input-lg {\n line-height: 46px;\n }\n}\n.form-group {\n margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n min-height: 20px;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-left: -20px;\n margin-top: 4px \\9;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n cursor: not-allowed;\n}\n.form-control-static {\n padding-top: 7px;\n padding-bottom: 7px;\n margin-bottom: 0;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n padding-left: 0;\n padding-right: 0;\n}\n.input-sm,\n.form-group-sm .form-control {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-sm,\nselect.form-group-sm .form-control {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-sm,\ntextarea.form-group-sm .form-control,\nselect[multiple].input-sm,\nselect[multiple].form-group-sm .form-control {\n height: auto;\n}\n.input-lg,\n.form-group-lg .form-control {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.33;\n border-radius: 6px;\n}\nselect.input-lg,\nselect.form-group-lg .form-control {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-lg,\ntextarea.form-group-lg .form-control,\nselect[multiple].input-lg,\nselect[multiple].form-group-lg .form-control {\n height: auto;\n}\n.has-feedback {\n position: relative;\n}\n.has-feedback .form-control {\n padding-right: 42.5px;\n}\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: 34px;\n height: 34px;\n line-height: 34px;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback {\n width: 46px;\n height: 46px;\n line-height: 46px;\n}\n.input-sm + .form-control-feedback {\n width: 30px;\n height: 30px;\n line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n color: #3c763d;\n}\n.has-success .form-control {\n border-color: #3c763d;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-success .form-control:focus {\n border-color: #2b542c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n color: #3c763d;\n border-color: #3c763d;\n background-color: #dff0d8;\n}\n.has-success .form-control-feedback {\n color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n color: #8a6d3b;\n}\n.has-warning .form-control {\n border-color: #8a6d3b;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-warning .form-control:focus {\n border-color: #66512c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n color: #8a6d3b;\n border-color: #8a6d3b;\n background-color: #fcf8e3;\n}\n.has-warning .form-control-feedback {\n color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n color: #a94442;\n}\n.has-error .form-control {\n border-color: #a94442;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-error .form-control:focus {\n border-color: #843534;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n color: #a94442;\n border-color: #a94442;\n background-color: #f2dede;\n}\n.has-error .form-control-feedback {\n color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n top: 0;\n}\n.help-block {\n display: block;\n margin-top: 5px;\n margin-bottom: 10px;\n color: #737373;\n}\n@media (min-width: 768px) {\n .form-inline .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-static {\n display: inline-block;\n }\n .form-inline .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .form-inline .input-group .input-group-addon,\n .form-inline .input-group .input-group-btn,\n .form-inline .input-group .form-control {\n width: auto;\n }\n .form-inline .input-group > .form-control {\n width: 100%;\n }\n .form-inline .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio,\n .form-inline .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio label,\n .form-inline .checkbox label {\n padding-left: 0;\n }\n .form-inline .radio input[type=\"radio\"],\n .form-inline .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .form-inline .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n margin-top: 0;\n margin-bottom: 0;\n padding-top: 7px;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n min-height: 27px;\n}\n.form-horizontal .form-group {\n margin-left: -15px;\n margin-right: -15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .control-label {\n text-align: right;\n margin-bottom: 0;\n padding-top: 7px;\n }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n right: 15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-lg .control-label {\n padding-top: 14.3px;\n }\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-sm .control-label {\n padding-top: 6px;\n }\n}\n.btn {\n display: inline-block;\n margin-bottom: 0;\n font-weight: normal;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none;\n border: 1px solid transparent;\n white-space: nowrap;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n border-radius: 4px;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n outline: thin dotted;\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n color: #333333;\n text-decoration: none;\n}\n.btn:active,\n.btn.active {\n outline: 0;\n background-image: none;\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n cursor: not-allowed;\n pointer-events: none;\n opacity: 0.65;\n filter: alpha(opacity=65);\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-default {\n color: #333333;\n background-color: #ffffff;\n border-color: #cccccc;\n}\n.btn-default:hover,\n.btn-default:focus,\n.btn-default.focus,\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n color: #333333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n background-image: none;\n}\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus,\n.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n background-color: #ffffff;\n border-color: #cccccc;\n}\n.btn-default .badge {\n color: #ffffff;\n background-color: #333333;\n}\n.btn-primary {\n color: #ffffff;\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary:hover,\n.btn-primary:focus,\n.btn-primary.focus,\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n color: #ffffff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n background-image: none;\n}\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary .badge {\n color: #337ab7;\n background-color: #ffffff;\n}\n.btn-success {\n color: #ffffff;\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success:hover,\n.btn-success:focus,\n.btn-success.focus,\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n color: #ffffff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n background-image: none;\n}\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success .badge {\n color: #5cb85c;\n background-color: #ffffff;\n}\n.btn-info {\n color: #ffffff;\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info:hover,\n.btn-info:focus,\n.btn-info.focus,\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n color: #ffffff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n background-image: none;\n}\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info .badge {\n color: #5bc0de;\n background-color: #ffffff;\n}\n.btn-warning {\n color: #ffffff;\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning:hover,\n.btn-warning:focus,\n.btn-warning.focus,\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n color: #ffffff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n background-image: none;\n}\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning .badge {\n color: #f0ad4e;\n background-color: #ffffff;\n}\n.btn-danger {\n color: #ffffff;\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger:hover,\n.btn-danger:focus,\n.btn-danger.focus,\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n color: #ffffff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n background-image: none;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger .badge {\n color: #d9534f;\n background-color: #ffffff;\n}\n.btn-link {\n color: #337ab7;\n font-weight: normal;\n border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n background-color: transparent;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n color: #23527c;\n text-decoration: underline;\n background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n color: #777777;\n text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.33;\n border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n padding: 1px 5px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-block {\n display: block;\n width: 100%;\n}\n.btn-block + .btn-block {\n margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n.fade {\n opacity: 0;\n -webkit-transition: opacity 0.15s linear;\n -o-transition: opacity 0.15s linear;\n transition: opacity 0.15s linear;\n}\n.fade.in {\n opacity: 1;\n}\n.collapse {\n display: none;\n visibility: hidden;\n}\n.collapse.in {\n display: block;\n visibility: visible;\n}\ntr.collapse.in {\n display: table-row;\n}\ntbody.collapse.in {\n display: table-row-group;\n}\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n -webkit-transition-property: height, visibility;\n transition-property: height, visibility;\n -webkit-transition-duration: 0.35s;\n transition-duration: 0.35s;\n -webkit-transition-timing-function: ease;\n transition-timing-function: ease;\n}\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: 4px solid;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n}\n.dropdown {\n position: relative;\n}\n.dropdown-toggle:focus {\n outline: 0;\n}\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0;\n list-style: none;\n font-size: 14px;\n text-align: left;\n background-color: #ffffff;\n border: 1px solid #cccccc;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 4px;\n -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n background-clip: padding-box;\n}\n.dropdown-menu.pull-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu .divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: 1.42857143;\n color: #333333;\n white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n text-decoration: none;\n color: #262626;\n background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n color: #ffffff;\n text-decoration: none;\n outline: 0;\n background-color: #337ab7;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n color: #777777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none;\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n cursor: not-allowed;\n}\n.open > .dropdown-menu {\n display: block;\n}\n.open > a {\n outline: 0;\n}\n.dropdown-menu-right {\n left: auto;\n right: 0;\n}\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: 12px;\n line-height: 1.42857143;\n color: #777777;\n white-space: nowrap;\n}\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: 990;\n}\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n border-top: 0;\n border-bottom: 4px solid;\n content: \"\";\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 1px;\n}\n@media (min-width: 768px) {\n .navbar-right .dropdown-menu {\n left: auto;\n right: 0;\n }\n .navbar-right .dropdown-menu-left {\n left: 0;\n right: auto;\n }\n}\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n margin-left: -1px;\n}\n.btn-toolbar {\n margin-left: -5px;\n}\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child > .btn:last-child,\n.btn-group > .btn-group:first-child > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn-group:last-child > .btn:first-child {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n.btn-group.open .dropdown-toggle {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn .caret {\n margin-left: 0;\n}\n.btn-lg .caret {\n border-width: 5px 5px 0;\n border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n border-top-right-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n border-bottom-left-radius: 4px;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n.input-group {\n position: relative;\n display: table;\n border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n}\n.input-group .form-control {\n position: relative;\n z-index: 2;\n float: left;\n width: 100%;\n margin-bottom: 0;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.33;\n border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle;\n}\n.input-group-addon {\n padding: 6px 12px;\n font-size: 14px;\n font-weight: normal;\n line-height: 1;\n color: #555555;\n text-align: center;\n background-color: #eeeeee;\n border: 1px solid #cccccc;\n border-radius: 4px;\n}\n.input-group-addon.input-sm {\n padding: 5px 10px;\n font-size: 12px;\n border-radius: 3px;\n}\n.input-group-addon.input-lg {\n padding: 10px 16px;\n font-size: 18px;\n border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n.input-group-btn {\n position: relative;\n font-size: 0;\n white-space: nowrap;\n}\n.input-group-btn > .btn {\n position: relative;\n}\n.input-group-btn > .btn + .btn {\n margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n margin-left: -1px;\n}\n.nav {\n margin-bottom: 0;\n padding-left: 0;\n list-style: none;\n}\n.nav > li {\n position: relative;\n display: block;\n}\n.nav > li > a {\n position: relative;\n display: block;\n padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.nav > li.disabled > a {\n color: #777777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n color: #777777;\n text-decoration: none;\n background-color: transparent;\n cursor: not-allowed;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n background-color: #eeeeee;\n border-color: #337ab7;\n}\n.nav .nav-divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.nav > li > a > img {\n max-width: none;\n}\n.nav-tabs {\n border-bottom: 1px solid #dddddd;\n}\n.nav-tabs > li {\n float: left;\n margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n margin-right: 2px;\n line-height: 1.42857143;\n border: 1px solid transparent;\n border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n border-color: #eeeeee #eeeeee #dddddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n color: #555555;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n border-bottom-color: transparent;\n cursor: default;\n}\n.nav-tabs.nav-justified {\n width: 100%;\n border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n float: none;\n}\n.nav-tabs.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-tabs.nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs.nav-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n border: 1px solid #dddddd;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li > a {\n border-bottom: 1px solid #dddddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs.nav-justified > .active > a,\n .nav-tabs.nav-justified > .active > a:hover,\n .nav-tabs.nav-justified > .active > a:focus {\n border-bottom-color: #ffffff;\n }\n}\n.nav-pills > li {\n float: left;\n}\n.nav-pills > li > a {\n border-radius: 4px;\n}\n.nav-pills > li + li {\n margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n color: #ffffff;\n background-color: #337ab7;\n}\n.nav-stacked > li {\n float: none;\n}\n.nav-stacked > li + li {\n margin-top: 2px;\n margin-left: 0;\n}\n.nav-justified {\n width: 100%;\n}\n.nav-justified > li {\n float: none;\n}\n.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs-justified {\n border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n border: 1px solid #dddddd;\n}\n@media (min-width: 768px) {\n .nav-tabs-justified > li > a {\n border-bottom: 1px solid #dddddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs-justified > .active > a,\n .nav-tabs-justified > .active > a:hover,\n .nav-tabs-justified > .active > a:focus {\n border-bottom-color: #ffffff;\n }\n}\n.tab-content > .tab-pane {\n display: none;\n visibility: hidden;\n}\n.tab-content > .active {\n display: block;\n visibility: visible;\n}\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar {\n position: relative;\n min-height: 50px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n .navbar {\n border-radius: 4px;\n }\n}\n@media (min-width: 768px) {\n .navbar-header {\n float: left;\n }\n}\n.navbar-collapse {\n overflow-x: visible;\n padding-right: 15px;\n padding-left: 15px;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);\n -webkit-overflow-scrolling: touch;\n}\n.navbar-collapse.in {\n overflow-y: auto;\n}\n@media (min-width: 768px) {\n .navbar-collapse {\n width: auto;\n border-top: 0;\n box-shadow: none;\n }\n .navbar-collapse.collapse {\n display: block !important;\n visibility: visible !important;\n height: auto !important;\n padding-bottom: 0;\n overflow: visible !important;\n }\n .navbar-collapse.in {\n overflow-y: visible;\n }\n .navbar-fixed-top .navbar-collapse,\n .navbar-static-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n padding-left: 0;\n padding-right: 0;\n }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n .navbar-fixed-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n max-height: 200px;\n }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .container > .navbar-header,\n .container-fluid > .navbar-header,\n .container > .navbar-collapse,\n .container-fluid > .navbar-collapse {\n margin-right: 0;\n margin-left: 0;\n }\n}\n.navbar-static-top {\n z-index: 1000;\n border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n .navbar-static-top {\n border-radius: 0;\n }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n@media (min-width: 768px) {\n .navbar-fixed-top,\n .navbar-fixed-bottom {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0;\n border-width: 1px 0 0;\n}\n.navbar-brand {\n float: left;\n padding: 15px 15px;\n font-size: 18px;\n line-height: 20px;\n height: 50px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n text-decoration: none;\n}\n.navbar-brand > img {\n display: block;\n}\n@media (min-width: 768px) {\n .navbar > .container .navbar-brand,\n .navbar > .container-fluid .navbar-brand {\n margin-left: -15px;\n }\n}\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: 15px;\n padding: 9px 10px;\n margin-top: 8px;\n margin-bottom: 8px;\n background-color: transparent;\n background-image: none;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.navbar-toggle:focus {\n outline: 0;\n}\n.navbar-toggle .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n margin-top: 4px;\n}\n@media (min-width: 768px) {\n .navbar-toggle {\n display: none;\n }\n}\n.navbar-nav {\n margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: 20px;\n}\n@media (max-width: 767px) {\n .navbar-nav .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n }\n .navbar-nav .open .dropdown-menu > li > a,\n .navbar-nav .open .dropdown-menu .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n .navbar-nav .open .dropdown-menu > li > a {\n line-height: 20px;\n }\n .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-nav .open .dropdown-menu > li > a:focus {\n background-image: none;\n }\n}\n@media (min-width: 768px) {\n .navbar-nav {\n float: left;\n margin: 0;\n }\n .navbar-nav > li {\n float: left;\n }\n .navbar-nav > li > a {\n padding-top: 15px;\n padding-bottom: 15px;\n }\n}\n.navbar-form {\n margin-left: -15px;\n margin-right: -15px;\n padding: 10px 15px;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n margin-top: 8px;\n margin-bottom: 8px;\n}\n@media (min-width: 768px) {\n .navbar-form .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .navbar-form .form-control-static {\n display: inline-block;\n }\n .navbar-form .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .navbar-form .input-group .input-group-addon,\n .navbar-form .input-group .input-group-btn,\n .navbar-form .input-group .form-control {\n width: auto;\n }\n .navbar-form .input-group > .form-control {\n width: 100%;\n }\n .navbar-form .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio,\n .navbar-form .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio label,\n .navbar-form .checkbox label {\n padding-left: 0;\n }\n .navbar-form .radio input[type=\"radio\"],\n .navbar-form .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .navbar-form .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n@media (max-width: 767px) {\n .navbar-form .form-group {\n margin-bottom: 5px;\n }\n .navbar-form .form-group:last-child {\n margin-bottom: 0;\n }\n}\n@media (min-width: 768px) {\n .navbar-form {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n}\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.navbar-btn {\n margin-top: 8px;\n margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n margin-top: 14px;\n margin-bottom: 14px;\n}\n.navbar-text {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n .navbar-text {\n float: left;\n margin-left: 15px;\n margin-right: 15px;\n }\n}\n@media (min-width: 768px) {\n .navbar-left {\n float: left !important;\n }\n .navbar-right {\n float: right !important;\n margin-right: -15px;\n }\n .navbar-right ~ .navbar-right {\n margin-right: 0;\n }\n}\n.navbar-default {\n background-color: #f8f8f8;\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n color: #777777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n color: #5e5e5e;\n background-color: transparent;\n}\n.navbar-default .navbar-text {\n color: #777777;\n}\n.navbar-default .navbar-nav > li > a {\n color: #777777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n color: #333333;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n color: #555555;\n background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n color: #cccccc;\n background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n border-color: #dddddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n background-color: #dddddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n background-color: #888888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n background-color: #e7e7e7;\n color: #555555;\n}\n@media (max-width: 767px) {\n .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n color: #777777;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #333333;\n background-color: transparent;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #555555;\n background-color: #e7e7e7;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #cccccc;\n background-color: transparent;\n }\n}\n.navbar-default .navbar-link {\n color: #777777;\n}\n.navbar-default .navbar-link:hover {\n color: #333333;\n}\n.navbar-default .btn-link {\n color: #777777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n color: #333333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n color: #cccccc;\n}\n.navbar-inverse {\n background-color: #222222;\n border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n color: #ffffff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n color: #ffffff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n color: #ffffff;\n background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n color: #444444;\n background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n border-color: #333333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n background-color: #333333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n background-color: #ffffff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n background-color: #080808;\n color: #ffffff;\n}\n@media (max-width: 767px) {\n .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n border-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n color: #9d9d9d;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #ffffff;\n background-color: transparent;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #ffffff;\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #444444;\n background-color: transparent;\n }\n}\n.navbar-inverse .navbar-link {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n color: #ffffff;\n}\n.navbar-inverse .btn-link {\n color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n color: #ffffff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n color: #444444;\n}\n.breadcrumb {\n padding: 8px 15px;\n margin-bottom: 20px;\n list-style: none;\n background-color: #f5f5f5;\n border-radius: 4px;\n}\n.breadcrumb > li {\n display: inline-block;\n}\n.breadcrumb > li + li:before {\n content: \"/\\00a0\";\n padding: 0 5px;\n color: #cccccc;\n}\n.breadcrumb > .active {\n color: #777777;\n}\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: 20px 0;\n border-radius: 4px;\n}\n.pagination > li {\n display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n position: relative;\n float: left;\n padding: 6px 12px;\n line-height: 1.42857143;\n text-decoration: none;\n color: #337ab7;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n margin-left: -1px;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n margin-left: 0;\n border-bottom-left-radius: 4px;\n border-top-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n border-bottom-right-radius: 4px;\n border-top-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n color: #23527c;\n background-color: #eeeeee;\n border-color: #dddddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n z-index: 2;\n color: #ffffff;\n background-color: #337ab7;\n border-color: #337ab7;\n cursor: default;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n color: #777777;\n background-color: #ffffff;\n border-color: #dddddd;\n cursor: not-allowed;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n padding: 10px 16px;\n font-size: 18px;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n border-bottom-left-radius: 6px;\n border-top-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n border-bottom-right-radius: 6px;\n border-top-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n padding: 5px 10px;\n font-size: 12px;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n border-bottom-left-radius: 3px;\n border-top-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n border-bottom-right-radius: 3px;\n border-top-right-radius: 3px;\n}\n.pager {\n padding-left: 0;\n margin: 20px 0;\n list-style: none;\n text-align: center;\n}\n.pager li {\n display: inline;\n}\n.pager li > a,\n.pager li > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.pager .next > a,\n.pager .next > span {\n float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n color: #777777;\n background-color: #ffffff;\n cursor: not-allowed;\n}\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: #ffffff;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n color: #ffffff;\n text-decoration: none;\n cursor: pointer;\n}\n.label:empty {\n display: none;\n}\n.btn .label {\n position: relative;\n top: -1px;\n}\n.label-default {\n background-color: #777777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n background-color: #5e5e5e;\n}\n.label-primary {\n background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n background-color: #286090;\n}\n.label-success {\n background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n background-color: #449d44;\n}\n.label-info {\n background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n background-color: #31b0d5;\n}\n.label-warning {\n background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n background-color: #ec971f;\n}\n.label-danger {\n background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n background-color: #c9302c;\n}\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: 12px;\n font-weight: bold;\n color: #ffffff;\n line-height: 1;\n vertical-align: baseline;\n white-space: nowrap;\n text-align: center;\n background-color: #777777;\n border-radius: 10px;\n}\n.badge:empty {\n display: none;\n}\n.btn .badge {\n position: relative;\n top: -1px;\n}\n.btn-xs .badge {\n top: 0;\n padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n color: #ffffff;\n text-decoration: none;\n cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n color: #337ab7;\n background-color: #ffffff;\n}\n.list-group-item > .badge {\n float: right;\n}\n.list-group-item > .badge + .badge {\n margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n margin-left: 3px;\n}\n.jumbotron {\n padding: 30px 15px;\n margin-bottom: 30px;\n color: inherit;\n background-color: #eeeeee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n color: inherit;\n}\n.jumbotron p {\n margin-bottom: 15px;\n font-size: 21px;\n font-weight: 200;\n}\n.jumbotron > hr {\n border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n border-radius: 6px;\n}\n.jumbotron .container {\n max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n .jumbotron {\n padding: 48px 0;\n }\n .container .jumbotron,\n .container-fluid .jumbotron {\n padding-left: 60px;\n padding-right: 60px;\n }\n .jumbotron h1,\n .jumbotron .h1 {\n font-size: 63px;\n }\n}\n.thumbnail {\n display: block;\n padding: 4px;\n margin-bottom: 20px;\n line-height: 1.42857143;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n border-radius: 4px;\n -webkit-transition: border 0.2s ease-in-out;\n -o-transition: border 0.2s ease-in-out;\n transition: border 0.2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n margin-left: auto;\n margin-right: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n border-color: #337ab7;\n}\n.thumbnail .caption {\n padding: 9px;\n color: #333333;\n}\n.alert {\n padding: 15px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.alert h4 {\n margin-top: 0;\n color: inherit;\n}\n.alert .alert-link {\n font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n margin-bottom: 0;\n}\n.alert > p + p {\n margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n}\n.alert-success {\n background-color: #dff0d8;\n border-color: #d6e9c6;\n color: #3c763d;\n}\n.alert-success hr {\n border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n color: #2b542c;\n}\n.alert-info {\n background-color: #d9edf7;\n border-color: #bce8f1;\n color: #31708f;\n}\n.alert-info hr {\n border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n color: #245269;\n}\n.alert-warning {\n background-color: #fcf8e3;\n border-color: #faebcc;\n color: #8a6d3b;\n}\n.alert-warning hr {\n border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n color: #66512c;\n}\n.alert-danger {\n background-color: #f2dede;\n border-color: #ebccd1;\n color: #a94442;\n}\n.alert-danger hr {\n border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n.progress {\n overflow: hidden;\n height: 20px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: 12px;\n line-height: 20px;\n color: #ffffff;\n text-align: center;\n background-color: #337ab7;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n -webkit-transition: width 0.6s ease;\n -o-transition: width 0.6s ease;\n transition: width 0.6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n 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);\n 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);\n 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);\n background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n -webkit-animation: progress-bar-stripes 2s linear infinite;\n -o-animation: progress-bar-stripes 2s linear infinite;\n animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n 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);\n 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);\n 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);\n}\n.progress-bar-info {\n background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n 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);\n 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);\n 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);\n}\n.progress-bar-warning {\n background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n 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);\n 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);\n 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);\n}\n.progress-bar-danger {\n background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n 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);\n 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);\n 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);\n}\n.media {\n margin-top: 15px;\n}\n.media:first-child {\n margin-top: 0;\n}\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n.media-middle {\n vertical-align: middle;\n}\n.media-bottom {\n vertical-align: bottom;\n}\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n.list-group {\n margin-bottom: 20px;\n padding-left: 0;\n}\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n margin-bottom: -1px;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n}\n.list-group-item:first-child {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n}\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\na.list-group-item {\n color: #555555;\n}\na.list-group-item .list-group-item-heading {\n color: #333333;\n}\na.list-group-item:hover,\na.list-group-item:focus {\n text-decoration: none;\n color: #555555;\n background-color: #f5f5f5;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n background-color: #eeeeee;\n color: #777777;\n cursor: not-allowed;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n color: #777777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n z-index: 2;\n color: #ffffff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n color: #c7ddef;\n}\n.list-group-item-success {\n color: #3c763d;\n background-color: #dff0d8;\n}\na.list-group-item-success {\n color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-success:hover,\na.list-group-item-success:focus {\n color: #3c763d;\n background-color: #d0e9c6;\n}\na.list-group-item-success.active,\na.list-group-item-success.active:hover,\na.list-group-item-success.active:focus {\n color: #fff;\n background-color: #3c763d;\n border-color: #3c763d;\n}\n.list-group-item-info {\n color: #31708f;\n background-color: #d9edf7;\n}\na.list-group-item-info {\n color: #31708f;\n}\na.list-group-item-info .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-info:hover,\na.list-group-item-info:focus {\n color: #31708f;\n background-color: #c4e3f3;\n}\na.list-group-item-info.active,\na.list-group-item-info.active:hover,\na.list-group-item-info.active:focus {\n color: #fff;\n background-color: #31708f;\n border-color: #31708f;\n}\n.list-group-item-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n}\na.list-group-item-warning {\n color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-warning:hover,\na.list-group-item-warning:focus {\n color: #8a6d3b;\n background-color: #faf2cc;\n}\na.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus {\n color: #fff;\n background-color: #8a6d3b;\n border-color: #8a6d3b;\n}\n.list-group-item-danger {\n color: #a94442;\n background-color: #f2dede;\n}\na.list-group-item-danger {\n color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-danger:hover,\na.list-group-item-danger:focus {\n color: #a94442;\n background-color: #ebcccc;\n}\na.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus {\n color: #fff;\n background-color: #a94442;\n border-color: #a94442;\n}\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n.panel {\n margin-bottom: 20px;\n background-color: #ffffff;\n border: 1px solid transparent;\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.panel-body {\n padding: 15px;\n}\n.panel-heading {\n padding: 10px 15px;\n border-bottom: 1px solid transparent;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n color: inherit;\n}\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: 16px;\n color: inherit;\n}\n.panel-title > a {\n color: inherit;\n}\n.panel-footer {\n padding: 10px 15px;\n background-color: #f5f5f5;\n border-top: 1px solid #dddddd;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n border-top: 0;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n border-bottom: 0;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n border-top-width: 0;\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n padding-left: 15px;\n padding-right: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n border-bottom-left-radius: 3px;\n border-bottom-right-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n border-top: 1px solid #dddddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n border-bottom: 0;\n}\n.panel > .table-responsive {\n border: 0;\n margin-bottom: 0;\n}\n.panel-group {\n margin-bottom: 20px;\n}\n.panel-group .panel {\n margin-bottom: 0;\n border-radius: 4px;\n}\n.panel-group .panel + .panel {\n margin-top: 5px;\n}\n.panel-group .panel-heading {\n border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n border-top: 1px solid #dddddd;\n}\n.panel-group .panel-footer {\n border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n border-bottom: 1px solid #dddddd;\n}\n.panel-default {\n border-color: #dddddd;\n}\n.panel-default > .panel-heading {\n color: #333333;\n background-color: #f5f5f5;\n border-color: #dddddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #dddddd;\n}\n.panel-default > .panel-heading .badge {\n color: #f5f5f5;\n background-color: #333333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #dddddd;\n}\n.panel-primary {\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n color: #ffffff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n color: #337ab7;\n background-color: #ffffff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #337ab7;\n}\n.panel-success {\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n color: #dff0d8;\n background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #d6e9c6;\n}\n.panel-info {\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n color: #d9edf7;\n background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #bce8f1;\n}\n.panel-warning {\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n color: #fcf8e3;\n background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #faebcc;\n}\n.panel-danger {\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n color: #f2dede;\n background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n height: 100%;\n width: 100%;\n border: 0;\n}\n.embed-responsive.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n.embed-responsive.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border: 1px solid #e3e3e3;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.well blockquote {\n border-color: #ddd;\n border-color: rgba(0, 0, 0, 0.15);\n}\n.well-lg {\n padding: 24px;\n border-radius: 6px;\n}\n.well-sm {\n padding: 9px;\n border-radius: 3px;\n}\n.close {\n float: right;\n font-size: 21px;\n font-weight: bold;\n line-height: 1;\n color: #000000;\n text-shadow: 0 1px 0 #ffffff;\n opacity: 0.2;\n filter: alpha(opacity=20);\n}\n.close:hover,\n.close:focus {\n color: #000000;\n text-decoration: none;\n cursor: pointer;\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\nbutton.close {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n}\n.modal-open {\n overflow: hidden;\n}\n.modal {\n display: none;\n overflow: hidden;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n -webkit-overflow-scrolling: touch;\n outline: 0;\n}\n.modal.fade .modal-dialog {\n -webkit-transform: translate(0, -25%);\n -ms-transform: translate(0, -25%);\n -o-transform: translate(0, -25%);\n transform: translate(0, -25%);\n -webkit-transition: -webkit-transform 0.3s ease-out;\n -moz-transition: -moz-transform 0.3s ease-out;\n -o-transition: -o-transform 0.3s ease-out;\n transition: transform 0.3s ease-out;\n}\n.modal.in .modal-dialog {\n -webkit-transform: translate(0, 0);\n -ms-transform: translate(0, 0);\n -o-transform: translate(0, 0);\n transform: translate(0, 0);\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n.modal-content {\n position: relative;\n background-color: #ffffff;\n border: 1px solid #999999;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n background-clip: padding-box;\n outline: 0;\n}\n.modal-backdrop {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n background-color: #000000;\n}\n.modal-backdrop.fade {\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.modal-backdrop.in {\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\n.modal-header {\n padding: 15px;\n border-bottom: 1px solid #e5e5e5;\n min-height: 16.42857143px;\n}\n.modal-header .close {\n margin-top: -2px;\n}\n.modal-title {\n margin: 0;\n line-height: 1.42857143;\n}\n.modal-body {\n position: relative;\n padding: 15px;\n}\n.modal-footer {\n padding: 15px;\n text-align: right;\n border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0;\n}\n.modal-footer .btn-group .btn + .btn {\n margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n margin-left: 0;\n}\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n@media (min-width: 768px) {\n .modal-dialog {\n width: 600px;\n margin: 30px auto;\n }\n .modal-content {\n -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n }\n .modal-sm {\n width: 300px;\n }\n}\n@media (min-width: 992px) {\n .modal-lg {\n width: 900px;\n }\n}\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n visibility: visible;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 12px;\n font-weight: normal;\n line-height: 1.4;\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.tooltip.in {\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.tooltip.top {\n margin-top: -3px;\n padding: 5px 0;\n}\n.tooltip.right {\n margin-left: 3px;\n padding: 0 5px;\n}\n.tooltip.bottom {\n margin-top: 3px;\n padding: 5px 0;\n}\n.tooltip.left {\n margin-left: -3px;\n padding: 0 5px;\n}\n.tooltip-inner {\n max-width: 200px;\n padding: 3px 8px;\n color: #ffffff;\n text-align: center;\n text-decoration: none;\n background-color: #000000;\n border-radius: 4px;\n}\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000000;\n}\n.tooltip.top-left .tooltip-arrow {\n bottom: 0;\n right: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000000;\n}\n.tooltip.top-right .tooltip-arrow {\n bottom: 0;\n left: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000000;\n}\n.tooltip.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -5px;\n border-width: 5px 5px 5px 0;\n border-right-color: #000000;\n}\n.tooltip.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -5px;\n border-width: 5px 0 5px 5px;\n border-left-color: #000000;\n}\n.tooltip.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n top: 0;\n right: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n top: 0;\n left: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000000;\n}\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: none;\n max-width: 276px;\n padding: 1px;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n font-weight: normal;\n line-height: 1.42857143;\n text-align: left;\n background-color: #ffffff;\n background-clip: padding-box;\n border: 1px solid #cccccc;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n white-space: normal;\n}\n.popover.top {\n margin-top: -10px;\n}\n.popover.right {\n margin-left: 10px;\n}\n.popover.bottom {\n margin-top: 10px;\n}\n.popover.left {\n margin-left: -10px;\n}\n.popover-title {\n margin: 0;\n padding: 8px 14px;\n font-size: 14px;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-radius: 5px 5px 0 0;\n}\n.popover-content {\n padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover > .arrow {\n border-width: 11px;\n}\n.popover > .arrow:after {\n border-width: 10px;\n content: \"\";\n}\n.popover.top > .arrow {\n left: 50%;\n margin-left: -11px;\n border-bottom-width: 0;\n border-top-color: #999999;\n border-top-color: rgba(0, 0, 0, 0.25);\n bottom: -11px;\n}\n.popover.top > .arrow:after {\n content: \" \";\n bottom: 1px;\n margin-left: -10px;\n border-bottom-width: 0;\n border-top-color: #ffffff;\n}\n.popover.right > .arrow {\n top: 50%;\n left: -11px;\n margin-top: -11px;\n border-left-width: 0;\n border-right-color: #999999;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n.popover.right > .arrow:after {\n content: \" \";\n left: 1px;\n bottom: -10px;\n border-left-width: 0;\n border-right-color: #ffffff;\n}\n.popover.bottom > .arrow {\n left: 50%;\n margin-left: -11px;\n border-top-width: 0;\n border-bottom-color: #999999;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n top: -11px;\n}\n.popover.bottom > .arrow:after {\n content: \" \";\n top: 1px;\n margin-left: -10px;\n border-top-width: 0;\n border-bottom-color: #ffffff;\n}\n.popover.left > .arrow {\n top: 50%;\n right: -11px;\n margin-top: -11px;\n border-right-width: 0;\n border-left-color: #999999;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n.popover.left > .arrow:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: #ffffff;\n bottom: -10px;\n}\n.carousel {\n position: relative;\n}\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n}\n.carousel-inner > .item {\n display: none;\n position: relative;\n -webkit-transition: 0.6s ease-in-out left;\n -o-transition: 0.6s ease-in-out left;\n transition: 0.6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n .carousel-inner > .item {\n transition: transform 0.6s ease-in-out;\n backface-visibility: hidden;\n perspective: 1000;\n }\n .carousel-inner > .item.next,\n .carousel-inner > .item.active.right {\n transform: translate3d(100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.prev,\n .carousel-inner > .item.active.left {\n transform: translate3d(-100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.next.left,\n .carousel-inner > .item.prev.right,\n .carousel-inner > .item.active {\n transform: translate3d(0, 0, 0);\n left: 0;\n }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n display: block;\n}\n.carousel-inner > .active {\n left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n}\n.carousel-inner > .next {\n left: 100%;\n}\n.carousel-inner > .prev {\n left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n left: 0;\n}\n.carousel-inner > .active.left {\n left: -100%;\n}\n.carousel-inner > .active.right {\n left: 100%;\n}\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: 15%;\n opacity: 0.5;\n filter: alpha(opacity=50);\n font-size: 20px;\n color: #ffffff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-control.left {\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n}\n.carousel-control.right {\n left: auto;\n right: 0;\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n}\n.carousel-control:hover,\n.carousel-control:focus {\n outline: 0;\n color: #ffffff;\n text-decoration: none;\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n z-index: 5;\n display: inline-block;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n width: 20px;\n height: 20px;\n margin-top: -10px;\n font-family: serif;\n}\n.carousel-control .icon-prev:before {\n content: '\\2039';\n}\n.carousel-control .icon-next:before {\n content: '\\203a';\n}\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n}\n.carousel-indicators li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid #ffffff;\n border-radius: 10px;\n cursor: pointer;\n background-color: #000 \\9;\n background-color: rgba(0, 0, 0, 0);\n}\n.carousel-indicators .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: #ffffff;\n}\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #ffffff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-caption .btn {\n text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-prev,\n .carousel-control .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -15px;\n font-size: 30px;\n }\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .icon-prev {\n margin-left: -15px;\n }\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-next {\n margin-right: -15px;\n }\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n .carousel-indicators {\n bottom: 20px;\n }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-footer:before,\n.modal-footer:after {\n content: \" \";\n display: table;\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-footer:after {\n clear: both;\n}\n.center-block {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n.hidden {\n display: none !important;\n visibility: hidden !important;\n}\n.affix {\n position: fixed;\n}\n@-ms-viewport {\n width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n@media (max-width: 767px) {\n .visible-xs {\n display: block !important;\n }\n table.visible-xs {\n display: table;\n }\n tr.visible-xs {\n display: table-row !important;\n }\n th.visible-xs,\n td.visible-xs {\n display: table-cell !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-block {\n display: block !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline {\n display: inline !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm {\n display: block !important;\n }\n table.visible-sm {\n display: table;\n }\n tr.visible-sm {\n display: table-row !important;\n }\n th.visible-sm,\n td.visible-sm {\n display: table-cell !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-block {\n display: block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline {\n display: inline !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md {\n display: block !important;\n }\n table.visible-md {\n display: table;\n }\n tr.visible-md {\n display: table-row !important;\n }\n th.visible-md,\n td.visible-md {\n display: table-cell !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-block {\n display: block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline {\n display: inline !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg {\n display: block !important;\n }\n table.visible-lg {\n display: table;\n }\n tr.visible-lg {\n display: table-row !important;\n }\n th.visible-lg,\n td.visible-lg {\n display: table-cell !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-block {\n display: block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline {\n display: inline !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline-block {\n display: inline-block !important;\n }\n}\n@media (max-width: 767px) {\n .hidden-xs {\n display: none !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .hidden-sm {\n display: none !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .hidden-md {\n display: none !important;\n }\n}\n@media (min-width: 1200px) {\n .hidden-lg {\n display: none !important;\n }\n}\n.visible-print {\n display: none !important;\n}\n@media print {\n .visible-print {\n display: block !important;\n }\n table.visible-print {\n display: table;\n }\n tr.visible-print {\n display: table-row !important;\n }\n th.visible-print,\n td.visible-print {\n display: table-cell !important;\n }\n}\n.visible-print-block {\n display: none !important;\n}\n@media print {\n .visible-print-block {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n}\n@media print {\n .visible-print-inline {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n}\n@media print {\n .visible-print-inline-block {\n display: inline-block !important;\n }\n}\n@media print {\n .hidden-print {\n display: none !important;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */","/*! normalize.css v3.0.2 | MIT License | git.io/normalize */\n\n//\n// 1. Set default font family to sans-serif.\n// 2. Prevent iOS text size adjust after orientation change, without disabling\n// user zoom.\n//\n\nhtml {\n font-family: sans-serif; // 1\n -ms-text-size-adjust: 100%; // 2\n -webkit-text-size-adjust: 100%; // 2\n}\n\n//\n// Remove default margin.\n//\n\nbody {\n margin: 0;\n}\n\n// HTML5 display definitions\n// ==========================================================================\n\n//\n// Correct `block` display not defined for any HTML5 element in IE 8/9.\n// Correct `block` display not defined for `details` or `summary` in IE 10/11\n// and Firefox.\n// Correct `block` display not defined for `main` in IE 11.\n//\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\n\n//\n// 1. Correct `inline-block` display not defined in IE 8/9.\n// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n//\n\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block; // 1\n vertical-align: baseline; // 2\n}\n\n//\n// Prevent modern browsers from displaying `audio` without controls.\n// Remove excess height in iOS 5 devices.\n//\n\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n\n//\n// Address `[hidden]` styling not present in IE 8/9/10.\n// Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.\n//\n\n[hidden],\ntemplate {\n display: none;\n}\n\n// Links\n// ==========================================================================\n\n//\n// Remove the gray background color from active links in IE 10.\n//\n\na {\n background-color: transparent;\n}\n\n//\n// Improve readability when focused and also mouse hovered in all browsers.\n//\n\na:active,\na:hover {\n outline: 0;\n}\n\n// Text-level semantics\n// ==========================================================================\n\n//\n// Address styling not present in IE 8/9/10/11, Safari, and Chrome.\n//\n\nabbr[title] {\n border-bottom: 1px dotted;\n}\n\n//\n// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n//\n\nb,\nstrong {\n font-weight: bold;\n}\n\n//\n// Address styling not present in Safari and Chrome.\n//\n\ndfn {\n font-style: italic;\n}\n\n//\n// Address variable `h1` font-size and margin within `section` and `article`\n// contexts in Firefox 4+, Safari, and Chrome.\n//\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n//\n// Address styling not present in IE 8/9.\n//\n\nmark {\n background: #ff0;\n color: #000;\n}\n\n//\n// Address inconsistent and variable font size in all browsers.\n//\n\nsmall {\n font-size: 80%;\n}\n\n//\n// Prevent `sub` and `sup` affecting `line-height` in all browsers.\n//\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsup {\n top: -0.5em;\n}\n\nsub {\n bottom: -0.25em;\n}\n\n// Embedded content\n// ==========================================================================\n\n//\n// Remove border when inside `a` element in IE 8/9/10.\n//\n\nimg {\n border: 0;\n}\n\n//\n// Correct overflow not hidden in IE 9/10/11.\n//\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\n// Grouping content\n// ==========================================================================\n\n//\n// Address margin not present in IE 8/9 and Safari.\n//\n\nfigure {\n margin: 1em 40px;\n}\n\n//\n// Address differences between Firefox and other browsers.\n//\n\nhr {\n -moz-box-sizing: content-box;\n box-sizing: content-box;\n height: 0;\n}\n\n//\n// Contain overflow in all browsers.\n//\n\npre {\n overflow: auto;\n}\n\n//\n// Address odd `em`-unit font size rendering in all browsers.\n//\n\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\n// Forms\n// ==========================================================================\n\n//\n// Known limitation: by default, Chrome and Safari on OS X allow very limited\n// styling of `select`, unless a `border` property is set.\n//\n\n//\n// 1. Correct color not being inherited.\n// Known issue: affects color of disabled elements.\n// 2. Correct font properties not being inherited.\n// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n//\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit; // 1\n font: inherit; // 2\n margin: 0; // 3\n}\n\n//\n// Address `overflow` set to `hidden` in IE 8/9/10/11.\n//\n\nbutton {\n overflow: visible;\n}\n\n//\n// Address inconsistent `text-transform` inheritance for `button` and `select`.\n// All other form control elements do not inherit `text-transform` values.\n// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n// Correct `select` style inheritance in Firefox.\n//\n\nbutton,\nselect {\n text-transform: none;\n}\n\n//\n// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n// and `video` controls.\n// 2. Correct inability to style clickable `input` types in iOS.\n// 3. Improve usability and consistency of cursor style between image-type\n// `input` and others.\n//\n\nbutton,\nhtml input[type=\"button\"], // 1\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button; // 2\n cursor: pointer; // 3\n}\n\n//\n// Re-set default cursor for disabled elements.\n//\n\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\n\n//\n// Remove inner padding and border in Firefox 4+.\n//\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\n\n//\n// Address Firefox 4+ setting `line-height` on `input` using `!important` in\n// the UA stylesheet.\n//\n\ninput {\n line-height: normal;\n}\n\n//\n// It's recommended that you don't attempt to style these elements.\n// Firefox's implementation doesn't respect box-sizing, padding, or width.\n//\n// 1. Address box sizing set to `content-box` in IE 8/9/10.\n// 2. Remove excess padding in IE 8/9/10.\n//\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box; // 1\n padding: 0; // 2\n}\n\n//\n// Fix the cursor style for Chrome's increment/decrement buttons. For certain\n// `font-size` values of the `input`, it causes the cursor style of the\n// decrement button to change from `default` to `text`.\n//\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n//\n// 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n// 2. Address `box-sizing` set to `border-box` in Safari and Chrome\n// (include `-moz` to future-proof).\n//\n\ninput[type=\"search\"] {\n -webkit-appearance: textfield; // 1\n -moz-box-sizing: content-box;\n -webkit-box-sizing: content-box; // 2\n box-sizing: content-box;\n}\n\n//\n// Remove inner padding and search cancel button in Safari and Chrome on OS X.\n// Safari (but not Chrome) clips the cancel button when the search input has\n// padding (and `textfield` appearance).\n//\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// Define consistent border, margin, and padding.\n//\n\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\n\n//\n// 1. Correct `color` not being inherited in IE 8/9/10/11.\n// 2. Remove padding so people aren't caught out if they zero out fieldsets.\n//\n\nlegend {\n border: 0; // 1\n padding: 0; // 2\n}\n\n//\n// Remove default vertical scrollbar in IE 8/9/10/11.\n//\n\ntextarea {\n overflow: auto;\n}\n\n//\n// Don't inherit the `font-weight` (applied by a rule above).\n// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n//\n\noptgroup {\n font-weight: bold;\n}\n\n// Tables\n// ==========================================================================\n\n//\n// Remove most spacing between table cells.\n//\n\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\n\ntd,\nth {\n padding: 0;\n}\n","/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request: h5bp.com/r\n// ==========================================================================\n\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important; // Black prints faster: h5bp.com/s\n box-shadow: none !important;\n text-shadow: none !important;\n }\n\n a,\n a:visited {\n text-decoration: underline;\n }\n\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n\n // Don't show links that are fragment identifiers,\n // or use the `javascript:` pseudo protocol\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n\n thead {\n display: table-header-group; // h5bp.com/t\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n img {\n max-width: 100% !important;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Bootstrap specific changes start\n //\n // Chrome (OSX) fix for https://github.com/twbs/bootstrap/issues/11245\n // Once fixed, we can just straight up remove this.\n select {\n background: #fff !important;\n }\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .btn,\n .dropup > .btn {\n > .caret {\n border-top-color: #000 !important;\n }\n }\n .label {\n border: 1px solid #000;\n }\n\n .table {\n border-collapse: collapse !important;\n\n td,\n th {\n background-color: #fff !important;\n }\n }\n .table-bordered {\n th,\n td {\n border: 1px solid #ddd !important;\n }\n }\n\n // Bootstrap specific changes end\n}\n","//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n// Star\n\n// Import the fonts\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('@{icon-font-path}@{icon-font-name}.eot');\n src: url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype'),\n url('@{icon-font-path}@{icon-font-name}.woff') format('woff'),\n url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype'),\n url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg');\n}\n\n// Catchall baseclass\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk { &:before { content: \"\\2a\"; } }\n.glyphicon-plus { &:before { content: \"\\2b\"; } }\n.glyphicon-euro,\n.glyphicon-eur { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil { &:before { content: \"\\270f\"; } }\n.glyphicon-glass { &:before { content: \"\\e001\"; } }\n.glyphicon-music { &:before { content: \"\\e002\"; } }\n.glyphicon-search { &:before { content: \"\\e003\"; } }\n.glyphicon-heart { &:before { content: \"\\e005\"; } }\n.glyphicon-star { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty { &:before { content: \"\\e007\"; } }\n.glyphicon-user { &:before { content: \"\\e008\"; } }\n.glyphicon-film { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large { &:before { content: \"\\e010\"; } }\n.glyphicon-th { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list { &:before { content: \"\\e012\"; } }\n.glyphicon-ok { &:before { content: \"\\e013\"; } }\n.glyphicon-remove { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out { &:before { content: \"\\e016\"; } }\n.glyphicon-off { &:before { content: \"\\e017\"; } }\n.glyphicon-signal { &:before { content: \"\\e018\"; } }\n.glyphicon-cog { &:before { content: \"\\e019\"; } }\n.glyphicon-trash { &:before { content: \"\\e020\"; } }\n.glyphicon-home { &:before { content: \"\\e021\"; } }\n.glyphicon-file { &:before { content: \"\\e022\"; } }\n.glyphicon-time { &:before { content: \"\\e023\"; } }\n.glyphicon-road { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt { &:before { content: \"\\e025\"; } }\n.glyphicon-download { &:before { content: \"\\e026\"; } }\n.glyphicon-upload { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt { &:before { content: \"\\e032\"; } }\n.glyphicon-lock { &:before { content: \"\\e033\"; } }\n.glyphicon-flag { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode { &:before { content: \"\\e040\"; } }\n.glyphicon-tag { &:before { content: \"\\e041\"; } }\n.glyphicon-tags { &:before { content: \"\\e042\"; } }\n.glyphicon-book { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark { &:before { content: \"\\e044\"; } }\n.glyphicon-print { &:before { content: \"\\e045\"; } }\n.glyphicon-camera { &:before { content: \"\\e046\"; } }\n.glyphicon-font { &:before { content: \"\\e047\"; } }\n.glyphicon-bold { &:before { content: \"\\e048\"; } }\n.glyphicon-italic { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify { &:before { content: \"\\e055\"; } }\n.glyphicon-list { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video { &:before { content: \"\\e059\"; } }\n.glyphicon-picture { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust { &:before { content: \"\\e063\"; } }\n.glyphicon-tint { &:before { content: \"\\e064\"; } }\n.glyphicon-edit { &:before { content: \"\\e065\"; } }\n.glyphicon-share { &:before { content: \"\\e066\"; } }\n.glyphicon-check { &:before { content: \"\\e067\"; } }\n.glyphicon-move { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward { &:before { content: \"\\e070\"; } }\n.glyphicon-backward { &:before { content: \"\\e071\"; } }\n.glyphicon-play { &:before { content: \"\\e072\"; } }\n.glyphicon-pause { &:before { content: \"\\e073\"; } }\n.glyphicon-stop { &:before { content: \"\\e074\"; } }\n.glyphicon-forward { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward { &:before { content: \"\\e077\"; } }\n.glyphicon-eject { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign { &:before { content: \"\\e101\"; } }\n.glyphicon-gift { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf { &:before { content: \"\\e103\"; } }\n.glyphicon-fire { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign { &:before { content: \"\\e107\"; } }\n.glyphicon-plane { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar { &:before { content: \"\\e109\"; } }\n.glyphicon-random { &:before { content: \"\\e110\"; } }\n.glyphicon-comment { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn { &:before { content: \"\\e122\"; } }\n.glyphicon-bell { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down { &:before { content: \"\\e134\"; } }\n.glyphicon-globe { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks { &:before { content: \"\\e137\"; } }\n.glyphicon-filter { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty { &:before { content: \"\\e143\"; } }\n.glyphicon-link { &:before { content: \"\\e144\"; } }\n.glyphicon-phone { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin { &:before { content: \"\\e146\"; } }\n.glyphicon-usd { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp { &:before { content: \"\\e149\"; } }\n.glyphicon-sort { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked { &:before { content: \"\\e157\"; } }\n.glyphicon-expand { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in { &:before { content: \"\\e161\"; } }\n.glyphicon-flash { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window { &:before { content: \"\\e164\"; } }\n.glyphicon-record { &:before { content: \"\\e165\"; } }\n.glyphicon-save { &:before { content: \"\\e166\"; } }\n.glyphicon-open { &:before { content: \"\\e167\"; } }\n.glyphicon-saved { &:before { content: \"\\e168\"; } }\n.glyphicon-import { &:before { content: \"\\e169\"; } }\n.glyphicon-export { &:before { content: \"\\e170\"; } }\n.glyphicon-send { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery { &:before { content: \"\\e179\"; } }\n.glyphicon-header { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt { &:before { content: \"\\e183\"; } }\n.glyphicon-tower { &:before { content: \"\\e184\"; } }\n.glyphicon-stats { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1 { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1 { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1 { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous { &:before { content: \"\\e200\"; } }\n","//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n//\n// Heads up! This reset may cause conflicts with some third-party widgets.\n// For recommendations on resolving such conflicts, see\n// http://getbootstrap.com/getting-started/#third-box-sizing\n* {\n .box-sizing(border-box);\n}\n*:before,\n*:after {\n .box-sizing(border-box);\n}\n\n\n// Body reset\n\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0,0,0,0);\n}\n\nbody {\n font-family: @font-family-base;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @text-color;\n background-color: @body-bg;\n}\n\n// Reset fonts for relevant elements\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\n\n// Links\n\na {\n color: @link-color;\n text-decoration: none;\n\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n }\n\n &:focus {\n .tab-focus();\n }\n}\n\n\n// Figures\n//\n// We reset this here because previously Normalize had no `figure` margins. This\n// ensures we don't break anyone's use of the element.\n\nfigure {\n margin: 0;\n}\n\n\n// Images\n\nimg {\n vertical-align: middle;\n}\n\n// Responsive images (ensure images don't scale beyond their parents)\n.img-responsive {\n .img-responsive();\n}\n\n// Rounded corners\n.img-rounded {\n border-radius: @border-radius-large;\n}\n\n// Image thumbnails\n//\n// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.\n.img-thumbnail {\n padding: @thumbnail-padding;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(all .2s ease-in-out);\n\n // Keep them at most 100% wide\n .img-responsive(inline-block);\n}\n\n// Perfect circle\n.img-circle {\n border-radius: 50%; // set radius in percents\n}\n\n\n// Horizontal rules\n\nhr {\n margin-top: @line-height-computed;\n margin-bottom: @line-height-computed;\n border: 0;\n border-top: 1px solid @hr-border;\n}\n\n\n// Only display content to screen readers\n//\n// See: http://a11yproject.com/posts/how-to-hide-content/\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0,0,0,0);\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n }\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They will be removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility){\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // See https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// WebKit-style focus\n\n.tab-focus() {\n // Default\n outline: thin dotted;\n // WebKit\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n.img-responsive(@display: block) {\n display: @display;\n max-width: 100%; // Part 1: Set a maximum relative to the parent\n height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size. Note that the\n// spelling of `min--moz-device-pixel-ratio` is intentional.\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n background-image: url(\"@{file-1x}\");\n\n @media\n only screen and (-webkit-min-device-pixel-ratio: 2),\n only screen and ( min--moz-device-pixel-ratio: 2),\n only screen and ( -o-min-device-pixel-ratio: 2/1),\n only screen and ( min-device-pixel-ratio: 2),\n only screen and ( min-resolution: 192dpi),\n only screen and ( min-resolution: 2dppx) {\n background-image: url(\"@{file-2x}\");\n background-size: @width-1x @height-1x;\n }\n}\n","//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n font-family: @headings-font-family;\n font-weight: @headings-font-weight;\n line-height: @headings-line-height;\n color: @headings-color;\n\n small,\n .small {\n font-weight: normal;\n line-height: 1;\n color: @headings-small-color;\n }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n margin-top: @line-height-computed;\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 65%;\n }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n margin-top: (@line-height-computed / 2);\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 75%;\n }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n margin-bottom: @line-height-computed;\n font-size: floor((@font-size-base * 1.15));\n font-weight: 300;\n line-height: 1.4;\n\n @media (min-width: @screen-sm-min) {\n font-size: (@font-size-base * 1.5);\n }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: (12px small font / 14px base font) * 100% = about 85%\nsmall,\n.small {\n font-size: floor((100% * @font-size-small / @font-size-base));\n}\n\nmark,\n.mark {\n background-color: @state-warning-bg;\n padding: .2em;\n}\n\n// Alignment\n.text-left { text-align: left; }\n.text-right { text-align: right; }\n.text-center { text-align: center; }\n.text-justify { text-align: justify; }\n.text-nowrap { white-space: nowrap; }\n\n// Transformation\n.text-lowercase { text-transform: lowercase; }\n.text-uppercase { text-transform: uppercase; }\n.text-capitalize { text-transform: capitalize; }\n\n// Contextual colors\n.text-muted {\n color: @text-muted;\n}\n.text-primary {\n .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n // Given the contrast here, this is the only class to have its color inverted\n // automatically.\n color: #fff;\n .bg-variant(@brand-primary);\n}\n.bg-success {\n .bg-variant(@state-success-bg);\n}\n.bg-info {\n .bg-variant(@state-info-bg);\n}\n.bg-warning {\n .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n padding-bottom: ((@line-height-computed / 2) - 1);\n margin: (@line-height-computed * 2) 0 @line-height-computed;\n border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// -------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n margin-top: 0;\n margin-bottom: (@line-height-computed / 2);\n ul,\n ol {\n margin-bottom: 0;\n }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n .list-unstyled();\n margin-left: -5px;\n\n > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n }\n}\n\n// Description Lists\ndl {\n margin-top: 0; // Remove browser default\n margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n line-height: @line-height-base;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n.dl-horizontal {\n dd {\n &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n }\n\n @media (min-width: @grid-float-breakpoint) {\n dt {\n float: left;\n width: (@dl-horizontal-offset - 20);\n clear: left;\n text-align: right;\n .text-overflow();\n }\n dd {\n margin-left: @dl-horizontal-offset;\n }\n }\n}\n\n\n// Misc\n// -------------------------\n\n// Abbreviations and acronyms\nabbr[title],\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted @abbr-border-color;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\n\n// Blockquotes\nblockquote {\n padding: (@line-height-computed / 2) @line-height-computed;\n margin: 0 0 @line-height-computed;\n font-size: @blockquote-font-size;\n border-left: 5px solid @blockquote-border-color;\n\n p,\n ul,\n ol {\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n // Note: Deprecated small and .small as of v3.1.0\n // Context: https://github.com/twbs/bootstrap/issues/11660\n footer,\n small,\n .small {\n display: block;\n font-size: 80%; // back to default font-size\n line-height: @line-height-base;\n color: @blockquote-small-color;\n\n &:before {\n content: '\\2014 \\00A0'; // em dash, nbsp\n }\n }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid @blockquote-border-color;\n border-left: 0;\n text-align: right;\n\n // Account for citation\n footer,\n small,\n .small {\n &:before { content: ''; }\n &:after {\n content: '\\00A0 \\2014'; // nbsp, em dash\n }\n }\n}\n\n// Addresses\naddress {\n margin-bottom: @line-height-computed;\n font-style: normal;\n line-height: @line-height-base;\n}\n","// Typography\n\n.text-emphasis-variant(@color) {\n color: @color;\n a&:hover {\n color: darken(@color, 10%);\n }\n}\n","// Contextual backgrounds\n\n.bg-variant(@color) {\n background-color: @color;\n a&:hover {\n background-color: darken(@color, 10%);\n }\n}\n","// Text overflow\n// Requires inline-block or block for proper styling\n\n.text-overflow() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: @code-color;\n background-color: @code-bg;\n border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: @kbd-color;\n background-color: @kbd-bg;\n border-radius: @border-radius-small;\n box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);\n\n kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n }\n}\n\n// Blocks of code\npre {\n display: block;\n padding: ((@line-height-computed - 1) / 2);\n margin: 0 0 (@line-height-computed / 2);\n font-size: (@font-size-base - 1); // 14px to 13px\n line-height: @line-height-base;\n word-break: break-all;\n word-wrap: break-word;\n color: @pre-color;\n background-color: @pre-bg;\n border: 1px solid @pre-border-color;\n border-radius: @border-radius-base;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: @pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n .container-fixed();\n\n @media (min-width: @screen-sm-min) {\n width: @container-sm;\n }\n @media (min-width: @screen-md-min) {\n width: @container-md;\n }\n @media (min-width: @screen-lg-min) {\n width: @container-lg;\n }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n .make-row();\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid(xs);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n .make-grid(sm);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n .make-grid(md);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n .make-grid(lg);\n}\n","// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n// Centered container element\n.container-fixed(@gutter: @grid-gutter-width) {\n margin-right: auto;\n margin-left: auto;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n margin-left: (@gutter / -2);\n margin-right: (@gutter / -2);\n &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n float: left;\n width: percentage((@columns / @grid-columns));\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n margin-left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-push(@columns) {\n left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-pull(@columns) {\n right: percentage((@columns / @grid-columns));\n}\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-sm-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-offset(@columns) {\n @media (min-width: @screen-sm-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-push(@columns) {\n @media (min-width: @screen-sm-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-pull(@columns) {\n @media (min-width: @screen-sm-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-md-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-offset(@columns) {\n @media (min-width: @screen-md-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-push(@columns) {\n @media (min-width: @screen-md-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-pull(@columns) {\n @media (min-width: @screen-md-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-lg-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-offset(@columns) {\n @media (min-width: @screen-lg-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-push(@columns) {\n @media (min-width: @screen-lg-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-pull(@columns) {\n @media (min-width: @screen-lg-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n // Common styles for all sizes of grid columns, widths 1-12\n .col(@index) { // initial\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n position: relative;\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-left: (@grid-gutter-width / 2);\n padding-right: (@grid-gutter-width / 2);\n }\n }\n .col(1); // kickstart it\n}\n\n.float-grid-columns(@class) {\n .col(@index) { // initial\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n float: left;\n }\n }\n .col(1); // kickstart it\n}\n\n.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {\n .col-@{class}-@{index} {\n width: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {\n .col-@{class}-push-@{index} {\n left: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {\n .col-@{class}-push-0 {\n left: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {\n .col-@{class}-pull-@{index} {\n right: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {\n .col-@{class}-pull-0 {\n right: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = offset) {\n .col-@{class}-offset-@{index} {\n margin-left: percentage((@index / @grid-columns));\n }\n}\n\n// Basic looping in LESS\n.loop-grid-columns(@index, @class, @type) when (@index >= 0) {\n .calc-grid-column(@index, @class, @type);\n // next iteration\n .loop-grid-columns((@index - 1), @class, @type);\n}\n\n// Create grid for specific class\n.make-grid(@class) {\n .float-grid-columns(@class);\n .loop-grid-columns(@grid-columns, @class, width);\n .loop-grid-columns(@grid-columns, @class, pull);\n .loop-grid-columns(@grid-columns, @class, push);\n .loop-grid-columns(@grid-columns, @class, offset);\n}\n","//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n background-color: @table-bg;\n}\ncaption {\n padding-top: @table-cell-padding;\n padding-bottom: @table-cell-padding;\n color: @text-muted;\n text-align: left;\n}\nth {\n text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: @line-height-computed;\n // Cells\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-cell-padding;\n line-height: @line-height-base;\n vertical-align: top;\n border-top: 1px solid @table-border-color;\n }\n }\n }\n // Bottom align for column headings\n > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid @table-border-color;\n }\n // Remove top border from thead by default\n > caption + thead,\n > colgroup + thead,\n > thead:first-child {\n > tr:first-child {\n > th,\n > td {\n border-top: 0;\n }\n }\n }\n // Account for multiple tbody instances\n > tbody + tbody {\n border-top: 2px solid @table-border-color;\n }\n\n // Nesting\n .table {\n background-color: @body-bg;\n }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-condensed-cell-padding;\n }\n }\n }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n border: 1px solid @table-border-color;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n border: 1px solid @table-border-color;\n }\n }\n }\n > thead > tr {\n > th,\n > td {\n border-bottom-width: 2px;\n }\n }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n > tbody > tr:nth-child(odd) {\n background-color: @table-bg-accent;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n > tbody > tr:hover {\n background-color: @table-bg-hover;\n }\n}\n\n\n// Table cell sizing\n//\n// Reset default table behavior\n\ntable col[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9/10 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-column;\n}\ntable {\n td,\n th {\n &[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9/10 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-cell;\n }\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%; // Workaround for IE9 bug (see https://github.com/twbs/bootstrap/issues/14837)\n\n @media screen and (max-width: @screen-xs-max) {\n width: 100%;\n margin-bottom: (@line-height-computed * 0.75);\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid @table-border-color;\n\n // Tighten up spacing\n > .table {\n margin-bottom: 0;\n\n // Ensure the content doesn't wrap\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n white-space: nowrap;\n }\n }\n }\n }\n\n // Special overrides for the bordered tables\n > .table-bordered {\n border: 0;\n\n // Nuke the appropriate borders so that the parent can handle them\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n\n // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n // chances are there will be only one `tr` in a `thead` and that would\n // remove the border altogether.\n > tbody,\n > tfoot {\n > tr:last-child {\n > th,\n > td {\n border-bottom: 0;\n }\n }\n }\n\n }\n }\n}\n","// Tables\n\n.table-row-variant(@state; @background) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table > thead > tr,\n .table > tbody > tr,\n .table > tfoot > tr {\n > td.@{state},\n > th.@{state},\n &.@{state} > td,\n &.@{state} > th {\n background-color: @background;\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover > tbody > tr {\n > td.@{state}:hover,\n > th.@{state}:hover,\n &.@{state}:hover > td,\n &:hover > .@{state},\n &.@{state}:hover > th {\n background-color: darken(@background, 5%);\n }\n }\n}\n","//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n // Chrome and Firefox set a `min-width: min-content;` on fieldsets,\n // so we reset that to ensure it behaves more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359.\n min-width: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: @line-height-computed;\n font-size: (@font-size-base * 1.5);\n line-height: inherit;\n color: @legend-color;\n border: 0;\n border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n display: inline-block;\n max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)\n margin-bottom: 5px;\n font-weight: bold;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\n// Override content-box in Normalize (* isn't specific enough)\ninput[type=\"search\"] {\n .box-sizing(border-box);\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9; // IE8-9\n line-height: normal;\n}\n\n// Set the height of file controls to match text inputs\ninput[type=\"file\"] {\n display: block;\n}\n\n// Make range inputs behave like textual form controls\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\n\n// Make multiple select elements height not fixed\nselect[multiple],\nselect[size] {\n height: auto;\n}\n\n// Focus for file, radio, and checkbox\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n .tab-focus();\n}\n\n// Adjust output element\noutput {\n display: block;\n padding-top: (@padding-base-vertical + 1);\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n}\n\n\n// Common form controls\n//\n// Shared size and type resets for form controls. Apply `.form-control` to any\n// of the following form controls:\n//\n// select\n// textarea\n// input[type=\"text\"]\n// input[type=\"password\"]\n// input[type=\"datetime\"]\n// input[type=\"datetime-local\"]\n// input[type=\"date\"]\n// input[type=\"month\"]\n// input[type=\"time\"]\n// input[type=\"week\"]\n// input[type=\"number\"]\n// input[type=\"email\"]\n// input[type=\"url\"]\n// input[type=\"search\"]\n// input[type=\"tel\"]\n// input[type=\"color\"]\n\n.form-control {\n display: block;\n width: 100%;\n height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n background-color: @input-bg;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid @input-border;\n border-radius: @input-border-radius;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n // Customize the `:focus` state to imitate native WebKit styles.\n .form-control-focus();\n\n // Placeholder\n .placeholder();\n\n // Disabled and read-only inputs\n //\n // HTML5 says that controls under a fieldset > legend:first-child won't be\n // disabled if the fieldset is disabled. Due to implementation difficulty, we\n // don't honor that edge case; we style them as disabled anyway.\n &[disabled],\n &[readonly],\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n background-color: @input-bg-disabled;\n opacity: 1; // iOS fix for unreadable disabled content\n }\n\n // Reset height for `textarea`s\n textarea& {\n height: auto;\n }\n}\n\n\n// Search inputs in iOS\n//\n// This overrides the extra rounded corners on search inputs in iOS so that our\n// `.form-control` class can properly style them. Note that this cannot simply\n// be added to `.form-control` as it's not specific enough. For details, see\n// https://github.com/twbs/bootstrap/issues/11586.\n\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n\n\n// Special styles for iOS temporal inputs\n//\n// In Mobile Safari, setting `display: block` on temporal inputs causes the\n// text within the input to become vertically misaligned. As a workaround, we\n// set a pixel line-height that matches the given height of the input, but only\n// for Safari.\n\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"],\n input[type=\"time\"],\n input[type=\"datetime-local\"],\n input[type=\"month\"] {\n line-height: @input-height-base;\n }\n input[type=\"date\"].input-sm,\n input[type=\"time\"].input-sm,\n input[type=\"datetime-local\"].input-sm,\n input[type=\"month\"].input-sm {\n line-height: @input-height-small;\n }\n input[type=\"date\"].input-lg,\n input[type=\"time\"].input-lg,\n input[type=\"datetime-local\"].input-lg,\n input[type=\"month\"].input-lg {\n line-height: @input-height-large;\n }\n}\n\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n margin-bottom: 15px;\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n\n label {\n min-height: @line-height-computed; // Ensure the input doesn't jump when there is no text\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n }\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-left: -20px;\n margin-top: 4px \\9;\n}\n\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing\n}\n\n// Radios and checkboxes on same line\n.radio-inline,\n.checkbox-inline {\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px; // space out consecutive inline controls\n}\n\n// Apply same disabled cursor tweak as for inputs\n// Some special care is needed because