[
  {
    "path": ".gitignore",
    "content": "# python pyc pyo\n*.pyc\n*.pyo\n\n# log\n*.log\n\n# out\n*.out\n\n# pid \n*.pid\n\n# pycharm\n.idea\n\n# datax\ndatax\n\n# create table sql\n*/migrations\n"
  },
  {
    "path": "FirstBlood/__init__.py",
    "content": "from __future__ import absolute_import\r\n\r\n# This will make sure the app is always imported when\r\n# Django starts so that shared_task will use this app.\r\nfrom .celery import app as celery_app"
  },
  {
    "path": "FirstBlood/celery.py",
    "content": "#!/usr/bin/python env\r\n# -*- coding: UTF-8 -*-\r\n# Description:                    \r\n# Author:           黄小雪\r\n# Date:             2017年03月25日\r\n# Company:          东方银谷\r\n\r\n\r\nfrom __future__ import absolute_import\r\nimport os\r\nfrom celery import Celery\r\nfrom django.conf import settings\r\n\r\n# set the default Django settings module for the 'celery' program.\r\nos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'FirstBlood.settings')\r\napp = Celery('FirstBlood')\r\n\r\n# Using a string here means the worker will not have to\r\n# pickle the object when using Windows.\r\napp.config_from_object('django.conf:settings')\r\napp.autodiscover_tasks(lambda: settings.INSTALLED_APPS)\r\n\r\n\r\n@app.task(bind=True)\r\ndef debug_task(self):\r\n    print('Request: {0!r}'.format(self.request))"
  },
  {
    "path": "FirstBlood/settings.py",
    "content": "# -*-coding:utf-8-*-\n\"\"\"\nDjango settings for FirstBlood project.\n\nGenerated by 'django-admin startproject' using Django 1.9.5.\n\nFor more information on this file, see\nhttps://docs.djangoproject.com/en/1.9/topics/settings/\n\nFor the full list of settings and their values, see\nhttps://docs.djangoproject.com/en/1.9/ref/settings/\n\"\"\"\n\nimport os\n\n# Build paths inside the project like this: os.path.join(BASE_DIR, ...)\nBASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\n\n\n# Quick-start development settings - unsuitable for production\n# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/\n\n# SECURITY WARNING: keep the secret key used in production secret!\nSECRET_KEY = 'on9c1o9$*rvub+_(z!_n!b$!2mwo1h8(pd_h#n_q$=2s84+^9('\n\n# SECURITY WARNING: don't run with debug turned on in production!\nDEBUG = True\n\nALLOWED_HOSTS = ['*']\n\n\n# 根据系统变量判断生产、测试环境来加载配置文件\nSYSTEM_ENVIRONMENT_VARIABLES = 'development_environment'\n\n# Application definition\n\nINSTALLED_APPS = [\n    'datax_web',\n    'batch_job',\n    'djcelery',\n    'django.contrib.admin',\n    'django.contrib.auth',\n    'django.contrib.contenttypes',\n    'django.contrib.sessions',\n    'django.contrib.messages',\n    'django.contrib.staticfiles',\n]\n\nMIDDLEWARE_CLASSES = [\n    'django.middleware.security.SecurityMiddleware',\n    'django.contrib.sessions.middleware.SessionMiddleware',\n    'django.middleware.common.CommonMiddleware',\n    'django.middleware.csrf.CsrfViewMiddleware',\n    'django.contrib.auth.middleware.AuthenticationMiddleware',\n    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',\n    'django.contrib.messages.middleware.MessageMiddleware',\n    'django.middleware.clickjacking.XFrameOptionsMiddleware',\n]\n\nROOT_URLCONF = 'FirstBlood.urls'\n\nTEMPLATES = [\n    {\n        'BACKEND': 'django.template.backends.django.DjangoTemplates',\n        'DIRS': [os.path.join(BASE_DIR, 'templates')],\n        'APP_DIRS': True,\n        'OPTIONS': {\n            'context_processors': [\n                'django.template.context_processors.debug',\n                'django.template.context_processors.request',\n                'django.contrib.auth.context_processors.auth',\n                'django.contrib.messages.context_processors.messages',\n            ],\n        },\n    },\n]\n\nWSGI_APPLICATION = 'FirstBlood.wsgi.application'\n\n\n# Database\n# https://docs.djangoproject.com/en/1.9/ref/settings/#databases\n\n\n# 测试环境\nDATABASES = {\n    'default': {\n        'ENGINE': 'django.db.backends.mysql',  # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.\n        'NAME': 'FirstBlood',  # Or path to database file if using sqlite3.\n        'USER': 'root',  # Not used with sqlite3.\n        'PASSWORD': '123.com',  # Not used with sqlite3.\n        'HOST': '127.0.0.1',  # Set to empty string for localhost. Not used with sqlite3.\n        'PORT': '3306',  # Set to empty string for default. Not used with sqlite3.\n        'STORAGE_ENGINE': 'MYISAM'\n        # 'OPTIONS': {\"init_command\": \"SET foreign_key_checks = 0;\",},\n    }\n}\nCELERYD_CONCURRENCY = 3\n\n\n# Password validation\n# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators\n\nAUTH_PASSWORD_VALIDATORS = [\n    {\n        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',\n    },\n]\n\n\n# Internationalization\n# https://docs.djangoproject.com/en/1.9/topics/i18n/\n\nLANGUAGE_CODE = 'en-us'\n\nTIME_ZONE = 'Asia/Shanghai'\n\nUSE_I18N = True\n\nUSE_L10N = True\n\nUSE_TZ = False\n\n\n# redis celery\n# CELERY STUFF\nimport djcelery\ndjcelery.setup_loader()\nBROKER_URL = 'redis://localhost:6379'\nCELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler' # 定时任务\nCELERY_RESULT_BACKEND = 'djcelery.backends.database:DatabaseBackend'\n# CELERY_RESULT_BACKEND = 'redis://localhost:6379'\nCELERY_ACCEPT_CONTENT = ['application/json']\nCELERY_TASK_SERIALIZER = 'json'\nCELERY_RESULT_SERIALIZER = 'json'\nCELERY_TIMEZONE = 'Asia/Shanghai'\nCELERY_ENABLE_UTC=False\n# CELERYD_CONCURRENCY = 10\nCELERYD_MAX_TASKS_PER_CHILD = 1 #  每个worker最多执行3个任务就会被销毁，可防止内存泄露\n\n\n# Static files (CSS, JavaScript, Images)\n# https://docs.djangoproject.com/en/1.9/howto/static-files/\n\nSTATIC_URL = '/static/'\n\nSTATICFILES_DIRS = [\n    os.path.join(BASE_DIR, \"static\"),\n]\n\nLOG_FILE_DIR = os.path.join(BASE_DIR, \"log/\")\n\n\nLOGGING = {\n    'version': 1,\n    'disable_existing_loggers': True,\n    'formatters': {\n        'standard': {\n                'format': '%(levelname)s %(asctime)s %(message)s'\n                },\n    },\n    'filters': {\n    },\n    'handlers': {\n        'mail_admins': {\n            'level': 'ERROR',\n            'class': 'django.utils.log.AdminEmailHandler',\n            'formatter':'standard',\n        },\n        'datax_web_handler': {\n            'level':'DEBUG',\n            'class':'logging.handlers.RotatingFileHandler',\n            'filename':'%s%s' % (LOG_FILE_DIR, 'datax_web.log'),\n            'formatter':'standard',\n        },\n        'batch_job_handler': {\n            'level':'DEBUG',\n            'class':'logging.handlers.RotatingFileHandler',\n            'filename':'%s%s' % (LOG_FILE_DIR, 'batch_job.log'),\n            'formatter':'standard',\n        },\n    },\n    'loggers': {\n        'django.request': {\n            'handlers': ['mail_admins'],\n            'level': 'ERROR',\n            'propagate': True,\n        },\n        'datax_web':{\n            'handlers': ['datax_web_handler'],\n            'level': 'INFO',\n            'propagate': False\n        },\n        'batch_job':{\n            'handlers': ['batch_job_handler'],\n            'level': 'INFO',\n            'propagate': False\n        },\n    }\n}"
  },
  {
    "path": "FirstBlood/urls.py",
    "content": "# -*- coding: UTF-8 -*-\n\"\"\"FirstBlood URL Configuration\n\nThe `urlpatterns` list routes URLs to views. For more information please see:\n    https://docs.djangoproject.com/en/1.9/topics/http/urls/\nExamples:\nFunction views\n    1. Add an import:  from my_app import views\n    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')\nClass-based views\n    1. Add an import:  from other_app.views import Home\n    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')\nIncluding another URLconf\n    1. Import the include() function: from django.conf.urls import url, include\n    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))\n\"\"\"\nfrom django.views.static import serve\nfrom django.conf.urls import include, url\nfrom django.conf import settings\nfrom django.contrib import admin\nadmin.autodiscover()\nfrom django.contrib.auth.views import (logout,login,password_change,password_change_done)\nfrom views import *\n\nurlpatterns = [\n    url(r'^admin/', admin.site.urls),\n\n    url(r'^index/$', index),  # 首页\n    url(r'^$', index, name='index'),\n    url(r'^accounts/login/$', login, {'template_name': 'registered/login.html'}, name='django.contrib.auth.views.login'),\n    url(r'^accounts/logout/$', logout, name='django.contrib.auth.views.logout'),\n    url(r'^password_change/$', password_change, {\n        'post_change_redirect': '/password_change_done/',\n        'template_name': 'registered/password_change.html'},\n        name='django.contrib.auth.views.password_change'),\n    url(r'^password_change_done/$', password_change_done, {\n        'template_name': 'registered/password_change_done.html'},\n        name='django.contrib.auth.views.password_change_done'),\n    url(r'^get_username/$', get_username),  # 获取当前登陆用户名\n    url(r'^check_permission/$', check_permission),  # 检测用户权限\n    url(r'^static/(?P<path>.*)$', serve, {'document_root': settings.STATIC_ROOT}),\n\n    # 数据同步\n    url(r'^datax_web/', include('datax_web.urls')),\n    # 批处理作业\n    url(r'^batch_job/', include('batch_job.urls')),\n]\n"
  },
  {
    "path": "FirstBlood/views.py",
    "content": "# -*- coding: UTF-8 -*-\nfrom django.contrib.auth.decorators import permission_required\nfrom django.contrib.auth.decorators import login_required\nfrom django.shortcuts import render\nfrom django.template import RequestContext\nfrom django.http import HttpResponse\nfrom django.contrib import auth\nfrom controller.core.public import Currency\nimport json\n\n# Create your views here.\n\n\n@login_required\ndef index(request):\n    # 首页\n    nowuser = auth.get_user(request)\n    return render(request, 'index.html', locals())\n\n\ndef page_not_found(request):\n    return render(\"404.html\")\n\n\ndef permission_denied(request):\n    return render(\"403.html\")\n\n\n@login_required\ndef get_username(request):\n    # 获取当前登陆的用户名\n    nowuser = auth.get_user(request)\n    username = nowuser.get_username()\n    response = HttpResponse()\n    response.write(json.dumps(username))\n    return response\n\n\n@login_required\ndef check_permission(request):\n    # 检测用户权限\n    nowuser = auth.get_user(request)\n    cur = Currency(request)\n    permission = cur.rq_post('permission')\n    status = 0 if nowuser.has_perm(permission) else 1\n    response = HttpResponse()\n    response.write(json.dumps({'status': status}))\n    return response"
  },
  {
    "path": "FirstBlood/wsgi.py",
    "content": "\"\"\"\nWSGI config for FirstBlood project.\n\nIt exposes the WSGI callable as a module-level variable named ``application``.\n\nFor more information on this file, see\nhttps://docs.djangoproject.com/en/1.9/howto/deployment/wsgi/\n\"\"\"\n\nimport os\n\nfrom django.core.wsgi import get_wsgi_application\n\nos.environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"FirstBlood.settings\")\n\napplication = get_wsgi_application()\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2022 盲僧\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "精简版ETL数据转换工具\n==========\n## 功能\n    1.数据同步（目前只支持MySQL）\n    2.执行SQL脚本 （后期开发）\n    3.定时执行\n    \n## 安装（两种方法）\n### 1.Docker 镜像安装\n#### 系统已打包成docker镜像，3个多G，可以直接使用\n    1.1 拉取镜像\n    docker pull hanson001/first_blood:v1\n    1.2 运行容器\n    docker run -itd --privileged -p 10028:22 -p 9028:9000 -p 3328:3306 -p 8080:8080 --name FirstBlood_test  hanson001/first_blood:v1 /usr/sbin/init\n\n    10028映射centos系统ssh连接端口，用户名root 密码 123.com\n    3328映射MySQL数据库端口，用户名root 密码123.com\n    8080映射内部websocket端口\n    9028映射内部系统访问端口，登录地址：http://服务器IP:9028 用户名 admim 密码123456.com\n    \n### 2.源码配置安装\n#### 准备环境\n    1.python 环境 2.7\n    2.安装requirements.txt里的依赖包，若运行时还报缺少模块的错误，再安装缺少的模块。\n    3.创建日志目录\n      cd <项目路径/FirstBlood>\n      mkdir log\n\n#### 建表\n    整个项目所需要的表，关于用户认证、权限控制等等使用django自带的，而项目其它功能模块使用原生SQL语句创建。\n    涉及到项目功能模块增删改查，全部使用原生SQL语句。\n    涉及到用户认证、权限控制等等，使用Django的orm。\n\n    1.create_table.sql 执行建表语句，创建项目中各个模块所需要的表\n    2.执行 python manage.py migrate，创建项目用户认证、权限控制所需要的表（Django自带）\n\n#### 运行其它服务\n    由于项目使用到定时任务和异步实时查询日志功能，所以需要使用到celery和websockted。\n    这两个服务的启动和运行全部交给supervisord托管，所以需要配置好supervisord配置文件。\n    supervisord配置文件分两个，dev为开发环境的配置文件，pro为生产环境的配置文件。\n    里面的路径需要根据自己实际的环境配置。\n\n    1.配置完成后执行以下命令，启动celery和websocketed服务\n      supervisord -c 项目路径/FirstBlood/supervisord/FirstBlood_pro.conf （开发环境使用FirstBlood_dev.conf文件）\n\n    2.根据配置文件里的日志路径查看是否报错，有报错百度、Google。\n      如果错误不影响功能的使用，则忽略。\n\n#### settings配置文件\n    由于项目的settings配置文件，需要根据开发环境、生产环境来连接不同环境的数据库，所以需要在开发环境添加变量。\n    settings文件里就可以通过development_environment变量，选择是连接生产数据库，还是开发环境数据库。\n    1.1 修改 bash_profile 文件\n        vim ~/.bash_profile\n        # 程序根据不同环境变量加载测试或生产的配置文件\n        development_environment=1\n        export development_environment\n\n#### 下载阿里开发数据同步工具datax\n    5.1 下载datax工具，放在项目目录下\n        项目路径/FirstBlood/datax\n\n    5.2 创建日志目录\n        由于项目的数据同步，底层使用的datax，而datax产生的日志文件名是固定长度，且以datax的 json配置文件名命名，\n        当配置文件名超过日志文件名的固定长度时，datax将会以固定长度截取配置文件名，来命名日志文件名称。所以无法以\n        datax的自生的日志来实时显示同步日志。所以需要新创建日志目录 web_log，以任务ID+13位时间戳命名日志文件名，\n        将datax产生的日志导入web_log目录里。\n\n        操作命令：\n        cd 项目路径/FirstBlood/datax/\n        mkdir web_log\n\n## 启动\n    以上步骤执行完成后，就可以运行项目。若有错误，百度Google。\n\n## 使用\n    大部分功能操作参照博客\n    databaseinfo 表，需要预先导入生产库的表信息\n"
  },
  {
    "path": "batch_job/__init__.py",
    "content": ""
  },
  {
    "path": "batch_job/admin.py",
    "content": "# -*- coding: utf-8 -*-\nfrom __future__ import unicode_literals\n\nfrom django.contrib import admin\n\n# Register your models here.\n"
  },
  {
    "path": "batch_job/apps.py",
    "content": "# -*- coding: utf-8 -*-\nfrom __future__ import unicode_literals\n\nfrom django.apps import AppConfig\n\n\nclass BatchJobConfig(AppConfig):\n    name = 'batch_job'\n"
  },
  {
    "path": "batch_job/conf/__init__.py",
    "content": "#!/usr/bin/python3\r\n# -*- coding: utf-8 -*-\r\n# @Function:\r\n# @Time    : 2018/7/20 15:34\r\n# @Author  : Hanson\r\n# @Email   : 229396865@qq.com\r\n# @File    : __init__.py.py\r\n# @Software: PyCharm\r\n# @Company : 东方银谷"
  },
  {
    "path": "batch_job/conf/config.py",
    "content": "#!/usr/bin/python3\r\n# -*- coding: utf-8 -*-\r\n# @Function: 批处理作业配置文件\r\n# @Time    : 2018/7/20 15:35\r\n# @Author  : Hanson\r\n# @Email   : @qq.com\r\n# @File    : config.py\r\n# @Software: PyCharm\r\n# @Company : 东方银谷\r\n\r\n# 最大任务个数\r\nmaxtasksperchild = 20\r\n\r\nquery_batch_job_by_name_sql = \"SELECT * FROM FirstBlood.batch_job bj WHERE bj.`name` = '%s';\"\r\n\r\nquery_batch_job_sql1 = \"SELECT * FROM FirstBlood.batch_job bj WHERE bj.`name` = '%s' and bj.id!=%s;\"\r\n\r\ninsert_batch_job_sql = \"insert into FirstBlood.`batch_job` (`name`, `description`) values ('%s', '%s');\"\r\n\r\ninsert_batch_job_details_sql = \"insert into FirstBlood.`batch_job_details` (`batch_job_id`, `subjob_id`, `type`) values\"\r\n\r\nquery_batch_job_sql2 = \"\"\"\r\nSELECT\r\n\tbj.*,\r\n\tdp.task,\r\n\tdp.enabled,\r\n\tconcat(dc.`minute`,' ',dc.`hour`,' ',dc.day_of_week,' ',dc.day_of_month, ' ',dc.month_of_year, ' (m/h/d/dM/MY)') crontab\r\nFROM\r\n\tFirstBlood.batch_job bj\r\nLEFT JOIN FirstBlood.djcelery_periodictask dp ON CONCAT(\"[\",bj.id,\"]\")=dp.args\r\nLEFT JOIN FirstBlood.djcelery_crontabschedule dc on dp.crontab_id=dc.id\r\nORDER BY bj.id\r\n\"\"\"\r\n\r\nquery_batch_job_sql3 = \"\"\"\r\nSELECT\r\n\tbj.*,\r\n\tdp.task,\r\n\tdp.enabled,\r\n\tdp.crontab_id,\r\n\tconcat(dc.`minute`,' ',dc.`hour`,' ',dc.day_of_week,' ',dc.day_of_month, ' ',dc.month_of_year, ' (m/h/d/dM/MY)') crontab\r\nFROM\r\n\tFirstBlood.batch_job bj\r\nLEFT JOIN FirstBlood.djcelery_periodictask dp ON CONCAT(\"[\",bj.id,\"]\")=dp.args\r\nLEFT JOIN FirstBlood.djcelery_crontabschedule dc on dp.crontab_id=dc.id\r\nWHERE bj.id = %s\r\n\"\"\"\r\n\r\nquery_batch_job_sub_job_by_id_sql = \"\"\"\r\nSELECT\r\n  bjd.*,\r\n  dj.`name`,\r\n  dj.description\r\nFROM\r\n  FirstBlood.batch_job_details bjd\r\nLEFT JOIN FirstBlood.datax_job dj on bjd.subjob_id=dj.id\r\nWHERE\r\n  bjd.batch_job_id = %s\r\n\"\"\"\r\n\r\nupdate_batch_job_by_id_sql = \"\"\"\r\nupdate FirstBlood.batch_job set\r\n    `name` = '%s',\r\n    `description` = '%s'\r\nwhere\r\n   id = %s\r\n\"\"\"\r\n\r\ndelete_batch_job_details_by_id_sql = \"\"\"\r\ndelete from FirstBlood.batch_job_details where batch_job_id =%s;\r\n\"\"\"\r\n\r\ninsert_batch_job_instance_sql = \"\"\"\r\ninsert into FirstBlood.batch_job_instance (\r\n    `instance_id`,\r\n    `name`,\r\n    `description`,\r\n    `trigger_mode`\r\n)\r\nvalues (%s, '%s', '%s', %s);\r\n\"\"\"\r\n\r\nupdate_batch_job_instance_by_id_sql = \"\"\"\r\nupdate FirstBlood.batch_job_instance set `status`=%s, `result`=%s, `end_time`='%s' where instance_id=%s;\r\n\"\"\"\r\n\r\n\r\ninsert_batch_job_instance_details_sql = \"\"\"\r\ninsert into FirstBlood.batch_job_instance_details (\r\n    `instance_id`,\r\n    `subjob_instance_id`,\r\n    `type`\r\n)\r\nvalues (%s, %s, %s);\r\n\"\"\"\r\n\r\nselect_batch_job_instance_sql = \"select * from FirstBlood.batch_job_instance bji\"\r\ncount_batch_job_instance_sql = \"select count(1) count from FirstBlood.batch_job_instance bji\"\r\nselect_batch_job_instance_by_id_sql = \"select * from FirstBlood.batch_job_instance bji where bji.instance_id=%s\"\r\n\r\n# 根据ID获取子作业类型为数据同步的信息\r\nselect_sub_job_datax_instance_by_id_sql = \"\"\"\r\nselect\r\n    bjid.instance_id,\r\n    bjid.subjob_instance_id,\r\n    bjid.type,\r\n    dji.`name`,\r\n    dji.description,\r\n    dji.trigger_mode,\r\n    dji.`status`,\r\n    dji.result,\r\n    dji.start_time,\r\n    dji.end_time\r\nfrom\r\n  FirstBlood.batch_job_instance_details bjid\r\nLEFT JOIN FirstBlood.datax_job_instance  dji on bjid.subjob_instance_id=dji.instance_id\r\nwhere\r\n  bjid.instance_id=%s and bjid.type=1\r\n\"\"\""
  },
  {
    "path": "batch_job/models.py",
    "content": "# -*- coding: utf-8 -*-\nfrom __future__ import unicode_literals\n\nfrom django.db import models\n\n# Create your models here.\nclass BatchJobPermission(models.Model):\n    \"\"\"\n    批处理作业权限\n    \"\"\"\n    class Meta:\n        db_table = 'batch_job_permission'\n        permissions = (\n            (\"viewBatchJob\", u\"查看批处理作业\"),\n            (\"editBatchJob\", u\"修改批处理祖业\")\n        )\n"
  },
  {
    "path": "batch_job/tests.py",
    "content": "# -*- coding: utf-8 -*-\nfrom __future__ import unicode_literals\n\nfrom django.test import TestCase\n\n# Create your tests here.\n\nimport requests\nimport json\nimport pprint\n# url1 = 'http://httpbin.org/get?name=gemey&age=22'\n# url2 = 'http://192.168.190.132:9000/batch_job/get_batch_job_instance/?username=admin&password=123456.com&limit=10&offset=0&name=test2&description=&status=&result=&trigger_mode='\nurl3 = 'http://172.24.132.144:9000/batch_job/get_batch_job_instance/?limit=10&offset=0&name=big_data&description=&status=&result=&trigger_mode='\n\nresponse = requests.get(url3)\npprint.pprint(json.loads(response.text))\n\n"
  },
  {
    "path": "batch_job/urls.py",
    "content": "# -*- coding: UTF-8 -*-\nfrom django.conf.urls import url\nimport views\n\nurlpatterns = [\n    # Examples:\n    # url(r'^$', 'YinguOnline.views.home', name='home'),\n    # url(r'^blog/', include('blog.urls')),\n\n   url(r'^index/$', views.index),  # 首页\n   url(r'^add_batch_job/$', views.add_batch_job),  # 新增批处理作业\n   url(r'^update_batch_job/(?P<id>\\d+)/$', views.update_batch_job),  # 更新批处理作业\n   url(r'^batch_job_instance/$', views.batch_job_instance),  # 批处理作业执行历史\n   url(r'^batch_job_instance_details/(?P<id>\\d+)/$', views.batch_job_instance_details),  # 批处理作业详情执行历史\n   url(r'^get_task_template/$', views.get_task_template),  # 获取任务模板\n   url(r'^get_crontab/$', views.get_crontab),  # 获取crontab\n   url(r'^add_crontab/$', views.add_crontab),  # 新增 crontab  定时时间\n   url(r'^add_batch_job_data/$', views.add_batch_job_data),  # 提交新增或更新批处理作业数据\n   # url(r'^add_job_data/$', views.add_job_data),  # 新增或修改任务数据\n   url(r'^get_batch_job_data/$', views.get_batch_job_data),  # 获取批处理作业数据\n   url(r'^get_batch_job_data_by_id/$', views.get_batch_job_data_by_id),  # 根据ID获取需要更新的任务数据\n   url(r'^get_batch_job_sub_job_by_id/$', views.get_batch_job_sub_job_by_id),  # 根据ID获取需要更新的子作业数据\n   url(r'^get_batch_job_instance/$', views.get_batch_job_instance),  # 获取批处理作业实例数据\n   url(r'^get_batch_job_instance_data_by_id/$', views.get_batch_job_instance_data_by_id),  # 根据ID获取批处理作业实例数据\n   url(r'^get_batch_job_sub_job_instance_data_by_id/$',\n       views.get_batch_job_sub_job_instance_data_by_id),  # 根据ID获取批处理作业子作业实例数据\n   url(r'^run_batch_job_task/$', views.run_batch_job_task),  # 运行批处理任务\n   # url(r'^get_database/$', views.get_database),  # 获取数据库信息\n]\n\n\n"
  },
  {
    "path": "batch_job/views.py",
    "content": "# -*- coding: utf-8 -*-\nfrom __future__ import unicode_literals\n\nfrom django.contrib.auth.decorators import permission_required\nfrom django.contrib.auth.decorators import login_required\nfrom django.core.exceptions import PermissionDenied\nfrom django.shortcuts import render\nfrom django.http import HttpResponse\nfrom functools import wraps\nfrom controller.core.public import (Currency, DatetimeHelp)\nfrom controller.core import query_sql\nfrom controller.public import dataconn\nfrom djcelery import loaders\nfrom djcelery.models import PeriodicTask, CrontabSchedule\nfrom djcelery.schedulers import ModelEntry\n# from multiprocessing import Manager,Pool\nimport multiprocessing as mp\nfrom anyjson import loads, dumps\nfrom celery import shared_task\nfrom celery import registry\nfrom celery import schedules\nfrom conf import config\nfrom datax_web.conf import config as datax_web_config\nfrom datax_web.views import run as datax_web_run\nfrom datax_web.views import Datax\nfrom datax_web.views import JobData as DataxJobData\nimport commands\nimport logging\nimport sys\nimport json\nreload(sys)\nsys.setdefaultencoding(\"utf-8\")\n# Create your views here.\n\n\nlogger = logging.getLogger('batch_job')\n_SUCCESS = dict(status=0, msg=u'检测成功')\n_str = (str, unicode)\n# 操作类型\n_OPERATION_TYPE = (1, 2)  # 1:新增批处理作业  2:修改批处理作业\n# 触发模式\n_TRIGGER_MODE = (1, 2)  # 1:自动  2:手动\n_TRIGGER_MODE_STR = u'TRIGGER_MODE = (1, 2)  # 1:自动  2:手动'\n# 子作业类型\n_SUBJOB_TYPE = (1, 2, 3)  # 1 数据同步 2 SQL脚本 3 备份。 主要用于后期扩展\n# 执行状态\n_STATUS = (0, 1)  # 状态 0 正在执行 1 执行完成\n\n\ndef verification(CheckClass):\n    \"\"\"\n    装饰器用于检测用户提交的信息是否合法.\n    check_class 检测类\n    Decorator for views that checks that the user submitted information,\n    redirecting to the log-in page if necessary. The test should be a callable\n    that takes the user object and returns True if the user passes.\n    \"\"\"\n\n    def decorator(view_func):\n        @wraps(view_func)\n        def _wrapped_view(request, *args, **kwargs):\n            response = HttpResponse()\n            ccl = CheckClass(request)\n            result = ccl.total_check()\n            if result['status']:\n                response.write(json.dumps(result))\n                return response\n\n            return view_func(request, *args, **kwargs)\n        return _wrapped_view\n    return decorator\n\n\nclass BatchJobData(object):\n    \"\"\"\n    新增、更新、手工运行任务时处理数据\n    \"\"\"\n    def __init__(self, data):\n        # id 为 batch_job_id\n        self._batch_job_id = data.get('_id', None)\n        self.name = data.get('name', '')\n        self.description = data.get('description', '')\n        self.task_template = data.get('task_template', '')\n        self.is_enable = data.get('is_enable', '')\n        self.crontab = data.get('crontab', '')\n        self.batch_job_details = data.get('batch_job_details', [])\n        self.trigger_mode = data.get('trigger_mode', '')\n        self.operation_type = data.get('operation_type', '')\n\n        self.dtconn = dataconn.DatabaseConnection(logger)\n        self.dtsf = dataconn.DataTransform()\n        self.dh = DatetimeHelp()\n        self.__timestamp1 = self.dh.timestamp1\n\n\n    @property\n    def timestamp1(self):\n        return self.__timestamp1\n\n    def _get_schedule_dict(self):\n        schedule = CrontabSchedule.objects.get(pk=self.crontab)\n        return {\n            'crontab': schedule,\n            'kwargs': dumps({}),\n            'task': self.task_template,\n            'enabled': self.is_enable,\n            'name': self.name\n        }\n\n    @property\n    def schedule_dict(self):\n        return self._get_schedule_dict()\n\n    # def get_batch_job_id(self):\n    #     \"\"\"\n    #     新建批处理任务数据时 batch_id 为 插入数据后的返回id\n    #     更新或手动运行任务时 batch_id 为 页面体检的id\n    #     :return: batch_id\n    #     \"\"\"\n    #     return self._batch_job_id or self.dtconn.ygol.insert_id\n\n    @property\n    def batch_job_id(self):\n        \"\"\"\n        新建批处理任务数据时 batch_id 为 插入数据后的返回id\n        更新或手动运行任务时 batch_id 为 页面体检的id\n        :return: batch_id\n        \"\"\"\n        return self._batch_job_id\n\n    @batch_job_id.setter\n    def batch_job_id(self, batch_job_id):\n        self._batch_job_id = batch_job_id\n\n    def get_insert_datax_job_sql(self):\n        # 在 batch_job表里创建新的任务  -  新增SQL\n        return config.insert_batch_job_sql % (self.name, self.description)\n\n    def get_update_batch_job_by_id_sql(self):\n        # 获取batch_job表里更新任务  - 更新SQL\n        return config.update_batch_job_by_id_sql % (self.name, self.description, self.batch_job_id)\n\n    def get_insert_batch_job_details_sql(self):\n        # 拼接插入批处理作业详情表SQL  insert into  values ('user_id', 1), ('card_name', 1)\n        values_list = [\"('%s', %s, %s)\" % (self.batch_job_id, subjob['subjob_id'], subjob['type']) for subjob in self.batch_job_details]\n        return config.insert_batch_job_details_sql + ','.join(values_list)\n\n    def get_delete_batch_job_details_by_id_sql(self):\n        # 获取根据ID删除batch_job_details 表的sql\n        return config.delete_batch_job_details_by_id_sql % self.batch_job_id\n\n    def create(self):\n        # batch_job表里创建新的任务\n        result = _SUCCESS.copy()\n        sql1 = self.get_insert_datax_job_sql()\n        self.dtconn.ygol.transaction_start()\n        self.dtconn.ygol.transaction_execute(sql1)\n        if self.dtconn.ygol.status:\n            msg = u'batch_job表里创建新的任务，SQL：%s 插入数据失败。 -  Msg: %s' % \\\n                  (sql1, self.dtconn.ygol.msg)\n            logger.error(msg)\n            result = dict(status=500, msg=msg)\n        else:\n            self.batch_job_id = self.dtconn.ygol.insert_id\n            sql2 = self.get_insert_batch_job_details_sql()\n            self.dtconn.ygol.transaction_execute(sql2)\n            if self.dtconn.ygol.status:\n                msg = u'创建批处理作业详情，SQL：%s 插入数据失败。 -  Msg: %s' % \\\n                      (sql2, self.dtconn.ygol.msg)\n                logger.error(msg)\n                result = dict(status=500, msg=msg)\n        self.dtconn.ygol.transaction_commit_and_close()\n        return result\n\n    def create_PeriodicTask(self):\n        \"\"\"\n        创建定时任务\n\n            在 PeriodicTask表里创建新的定时任务，并在表的args字段里保存批处理作业表的batch_job_id。这样，\n            就可以把批处理作业和定时调度关联起来。\n        :return:\n        \"\"\"\n        obj = PeriodicTask.objects.create(**self.schedule_dict)\n        obj.args = dumps([self.batch_job_id])\n        obj.save()\n        return obj\n\n    def update(self):\n        # 更新任务\n        result = _SUCCESS.copy()\n        sql1 = self.get_update_batch_job_by_id_sql()\n        self.dtconn.ygol.transaction_start()\n        self.dtconn.ygol.transaction_execute(sql1)\n        if self.dtconn.ygol.status:\n            msg = u'batch_job表，SQL：%s 更新数据失败。 -  Msg: %s' % \\\n                  (sql1, self.dtconn.ygol.msg)\n            logger.error(msg)\n            result = dict(status=500, msg=msg)\n        else:\n            sql2 = self.get_delete_batch_job_details_by_id_sql()\n            sql3 = self.get_insert_batch_job_details_sql()\n            self.dtconn.ygol.transaction_execute(sql2)\n            self.dtconn.ygol.transaction_execute(sql3)\n            if self.dtconn.ygol.status:\n                msg = u'batch_job_details表里更新列 - SQL2：%s - SQL3: %s -' \\\n                      u' 更新数据失败。 -  Msg: %s' % \\\n                      (sql2, sql3, self.dtconn.ygol.msg)\n                logger.error(msg)\n                result = dict(status=500, msg=msg)\n        self.dtconn.ygol.transaction_commit_and_close()\n        return result\n\n    def update_PeriodicTask(self):\n        # 更新PeriodicTask\n        obj = PeriodicTask.objects.get(args=\"[%s]\" % self.batch_job_id)\n        for k, v in self.schedule_dict.items():\n            setattr(obj, k, v)\n        obj.save()\n        return obj\n\n    def get_batch_job_by_id(self, batch_job_id):\n        # 根据批处理作业id，获取批处理作业信息\n        sql = config.query_batch_job_sql3 % batch_job_id\n        source_data = self.dtconn.ygol.getsingle(sql)\n        return self.dtsf.get_row_by_dict_to_user(source_data)\n\n    def get_batch_job_details_by_id(self, batch_job_id):\n        # 根据批处理作业id，获取批处理作业子作业batch_job_details表信息\n        sql = config.query_batch_job_sub_job_by_id_sql % batch_job_id\n        source_data = self.dtconn.ygol.getall(sql)\n        return map(self.dtsf.get_row_by_dict_to_user, source_data)\n\n\nclass BatchJobInstanceData(object):\n    \"\"\"\n    批处理作业实例数据处理\n    data 为批处理作业更新页面提及的任务数据\n\n    数据格式：\n            {u'_id': u'30',\n             u'batch_job_details': [{u'batch_job_id': u'30',\n                                     u'create_time': u'2018-07-24 21:18:31',\n                                     u'description': u'\\u6570\\u636e\\u540c\\u6b65\\u6d4b\\u8bd5',\n                                     u'id': u'37',\n                                     u'modify_time': u'2018-07-24 21:18:31',\n                                     u'name': u'test',\n                                     u'subjob_id': u'28',\n                                     u'type': u'1'}],\n             u'crontab': u'2',\n             u'description': u'DIY\\u6d4b\\u8bd5\\u7ec4\\u88c5\\u673a1',\n             u'is_enable': False,\n             u'name': u'test1',\n             u'operation_type': 2,\n             u'task_template': u'celery.chunks',\n             u'trigger_mode': 2}\n\n             _id：batch_job_id 批处理作业表 id\n    \"\"\"\n    def __init__(self, data):\n        self._batch_job_id = data.get('_id', None)\n        self.name = data.get('name', '')\n        self.description = data.get('description', '')\n        self._trigger_mode = data.get('trigger_mode', None)\n\n        self.dtconn = dataconn.DatabaseConnection(logger)\n        self.dtsf = dataconn.DataTransform()\n        self.dh = DatetimeHelp()\n        self.__timestamp1 = self.dh.timestamp1\n\n        self._batch_job_instance_id = None\n        self.batch_job_instance_id = self._batch_job_id\n\n    @property\n    def batch_job_instance_id(self):\n        \"\"\"\n        批处理作业实例ID\n        由批处理作业ID + 时间戳组成\n        :return: 30 + 1532522114566 = 301532522114566\n        \"\"\"\n        return self._batch_job_instance_id\n\n    @batch_job_instance_id.setter\n    def batch_job_instance_id(self, batch_job_id):\n        self._batch_job_instance_id = '%s%s' % (batch_job_id, self.__timestamp1)\n\n    @property\n    def trigger_mode(self):\n        return self._trigger_mode\n\n    @trigger_mode.setter\n    def trigger_mode(self, val):\n        if val not in _TRIGGER_MODE:\n            msg = u'触发模式值错误 - trigger_mode：%s - %s' % (val, _TRIGGER_MODE_STR)\n            logger.error(msg)\n        else:\n            self._trigger_mode = val\n\n    def get_insert_batch_job_instance_sql(self):\n        return config.insert_batch_job_instance_sql % (\n            self.batch_job_instance_id,\n            self.name,\n            self.description,\n            self.trigger_mode\n        )\n\n    def get_update_batch_job_instance_by_id_sql(self, result):\n        return config.update_batch_job_instance_by_id_sql % (\n            _STATUS[1],\n            result,\n            self.dh.nowtimestrf1,\n            self.batch_job_instance_id\n        )\n\n    @staticmethod\n    def get_select_batch_job_instance_by_id_sql(batch_job_instance_id):\n        return config.select_batch_job_instance_by_id_sql % batch_job_instance_id\n\n    def get_batch_job_instance_by_id(self, batch_job_instance_id):\n        sql = self.get_select_batch_job_instance_by_id_sql(batch_job_instance_id)\n        souce_data = self.dtconn.ygol.getsingle(sql)\n        return self.dtsf.get_row_by_dict_to_user(souce_data)\n\n    def start_log(self):\n        # 开始记录任务日志到batch_job_instance\n        sql = self.get_insert_batch_job_instance_sql()\n        self.dtconn.ygol.insert(sql)\n        if self.dtconn.ygol.status:\n            logger.error(u'记录任务日志到batch_job_instance 失败 - SQL: %s - msg: %s' %\n                         (sql, self.dtconn.ygol.msg))\n\n    def record_result_log(self, result):\n        # 记录任务执行结果 datax_job_instance\n        sql = self.get_update_batch_job_instance_by_id_sql(result)\n        self.dtconn.ygol.update(sql)\n        if self.dtconn.ygol.status:\n            logger.error(u'记录任务执行结果 batch_job_instance 失败 - SQL: %s - msg: %s' %\n                         (sql, self.dtconn.ygol.msg))\n\n\nclass BatchJobSubjobInstanceData(object):\n    \"\"\"\n    批处理作业中的子任务实例数据处理\n    data 格式\n     u'batch_job_details': [{u'batch_job_id': u'30',\n                         u'create_time': u'2018-07-24 21:18:31',\n                         u'description': u'\\u6570\\u636e\\u540c\\u6b65\\u6d4b\\u8bd5',\n                         u'id': u'37',\n                         u'modify_time': u'2018-07-24 21:18:31',\n                         u'name': u'test',\n                         u'subjob_id': u'28',\n                         u'type': u'1'}],\n\n    \"\"\"\n    def __init__(self, data):\n        # id 为 子作业实例ID\n        self._subjob_instance_id = None\n        self._batch_job_instance_id = None\n        self.subjob_id = data.get('subjob_id')\n        self.type = data.get('type')\n\n        self.dtconn = dataconn.DatabaseConnection(logger)\n        self.dtsf = dataconn.DataTransform()\n        self.dh = DatetimeHelp()\n        self.__timestamp1 = self.dh.timestamp1\n\n    @property\n    def subjob_instance_id(self):\n        return self._subjob_instance_id\n\n    @subjob_instance_id.setter\n    def subjob_instance_id(self, subjob_instance_id):\n        self._subjob_instance_id = subjob_instance_id\n\n    @property\n    def batch_job_instance_id(self):\n        return self._batch_job_instance_id\n\n    @batch_job_instance_id.setter\n    def batch_job_instance_id(self, batch_job_instance_id):\n        self._batch_job_instance_id = batch_job_instance_id\n\n    def get_insert_batch_job_instance_details_sql_sql(self, _type):\n        return config.insert_batch_job_instance_details_sql % (\n            self.batch_job_instance_id,\n            self.subjob_instance_id,\n            _type\n        )\n\n    def start_subjob_log(self, _type):\n        # 开始记录子任务日志到batch_job_instance_details\n        sql = self.get_insert_batch_job_instance_details_sql_sql(_type)\n        self.dtconn.ygol.insert(sql)\n        if self.dtconn.ygol.status:\n            logger.error(u'记录子任务日志到batch_job_instance_details 失败 - SQL: %s - msg: %s' %\n                         (sql, self.dtconn.ygol.msg))\n\n    @classmethod\n    def run_sub_job(cls, _type, subjob_id, results, batch_job_instance_id, trigger_mode):\n        \"\"\"\n        执行批处理作业中的子作业\n        :param _type: 子作业类型\n        :param subjob_id: 子作业id\n        :param results: 保存所有的子作业执行结果\n        :param batch_job_instance_id: 批处理作业实例ID\n        :return: None\n        \"\"\"\n        result = None\n\n        if _type == _SUBJOB_TYPE[0]:\n            dataxjd = DataxJobData({})\n            dataxjob_data = dataxjd.get_job_data_by_id(subjob_id)\n            dataxjob_writer_column = dataxjd.get_datax_job_writer_column_by_id(subjob_id)\n            writer_column_id = [dt['name'] for dt in dataxjob_writer_column]\n            dataxjob_data['_id'] = subjob_id\n            dataxjob_data['trigger_mode'] = trigger_mode\n            dataxjob_data['writer_column_id'] = writer_column_id\n            bjsid = cls(dataxjob_data)\n            dx = Datax(dataxjob_data)\n            dx.jd.create_file(dx.job_json_file, dx.get_job_json())\n            dx.jd.start_log()  # 记录datax_job 实例同步日志\n            bjsid.batch_job_instance_id = batch_job_instance_id\n            bjsid.subjob_instance_id = dx.jd.datax_job_instance_id\n            bjsid.start_subjob_log(_type)  # 记录子作业日志\n            (status, output) = commands.getstatusoutput(dx.cmd)\n            result = 1 if status else 0\n            dx.jd.record_result_log(result)\n\n        results.append(result)\n\n    @staticmethod\n    def get_select_sub_job_datax_instance_by_id_sql(batch_job_instance_id):\n        return config.select_sub_job_datax_instance_by_id_sql % batch_job_instance_id\n\n    @staticmethod\n    def get_sub_job_datax_instance_data_by_id(batch_job_instance_id):\n        dtconn = dataconn.DatabaseConnection(logger)\n        dtsf = dataconn.DataTransform()\n        sql = BatchJobSubjobInstanceData.get_select_sub_job_datax_instance_by_id_sql(batch_job_instance_id)\n        source_data = dtconn.ygol.getall(sql)\n        return map(dtsf.get_row_by_dict_to_user, source_data)\n\n\nclass CheckBatchJob(object):\n    \"\"\"\n    检测新增、更新、手工运行批处理作业提交的信息\n    :return  result\n             格式：   {'status': 1, 'msg': '操作类型错误'}\n    total_check 启动所有检测，返回检测状态和错误消息\n    \"\"\"\n    _SUCCESS = _SUCCESS.copy()\n    _OPERATION_TYPE_ERROR1 = dict(status=1, msg=u'操作类型不能为空')\n    _OPERATION_TYPE_ERROR2 = dict(status=2, msg=u'操作类型错误')\n    _DESCRIPTION_ERROR1 = dict(status=3, msg=u'任务描述不能为空')\n    _NAME_ERROR1 = dict(status=4, msg=u'任务名称不能为空')\n    _NAME_ERROR2 = dict(status=5, msg=u'任务名称已存在')\n    _TASK_TEMPLATE_ERROR1 = dict(status=6, msg=u'任务模板不能为空')\n    _TASK_TEMPLATE_ERROR2 = dict(status=6, msg=u'任务模板不存在')\n    _IS_ENABLE_ERROR1 = dict(status=7, msg=u'是否启用值错误')\n    _BATCH_JOB_DETAILS_ERROR1 = dict(status=8, msg=u'批处理作业详情不能为空')\n    _BATCH_JOB_DETAILS_ERROR2 = dict(status=9, msg=u'批处理作业详情，子作业 %s %s 类型错误')\n    _BATCH_JOB_DETAILS_ERROR3 = dict(status=10, msg=u'批处理作业详情，子作业 %s %s ID %s 不存在')\n    _TRIGGER_MODE_ERROR1 = dict(status=11, msg=u'触发模式 不存在')\n    _TRIGGER_MODE_ERROR2 = dict(status=12, msg=u'触发模式值错误')\n    _CRONTAB_ERROR = dict(status=13, msg=u'执行时间错误')\n    _BATCH_JOB_ID_ERROR1 = dict(status=14, msg=u'batch_job_id 不能为空')\n    _BATCH_JOB_ID_ERROR2 = dict(status=15, msg=u'batch_job_id 不存在')\n\n    def __init__(self, request):\n        cur = Currency(request)\n        data = cur.rq_post_json('data')\n        self.dtconn = dataconn.DatabaseConnection(logger)\n        self.jd = BatchJobData(data)\n\n        self.error_msg = []\n        self.result = self._SUCCESS\n\n    def check_operation_type(self):\n        # 检测操作类型\n        operation_type = self.jd.operation_type\n        if not operation_type:\n            self.result = self._OPERATION_TYPE_ERROR1\n        else:\n            if operation_type not in _OPERATION_TYPE:\n                self.result = self._OPERATION_TYPE_ERROR2\n\n    def check_name_by_operation_type(self):\n        # 根据操作类型 检测任务名称\n        name = self.jd.name\n        if self.jd.operation_type == _OPERATION_TYPE[0]:\n            sql = config.query_batch_job_by_name_sql % name\n            self.check_name(name, sql)\n\n        if self.jd.operation_type == _OPERATION_TYPE[1]:\n            sql = config.query_batch_job_sql1 % (name, self.jd.batch_job_id)\n            self.check_name(name, sql)\n\n    def check_name(self, name, sql):\n        # 新增、更新、运行批处理作业时，检测名称\n        if name:\n            data = self.dtconn.ygol.getsingle(sql)\n            if self.dtconn.ygol.status:\n                _msg = u'检测任务名称时数据库错误。 - Msg: %s' % self.dtconn.ygol.msg\n                logger.error(_msg)\n                self.result = dict(status=500, msg=_msg)\n            else:\n                if data:\n                    self.result = self._NAME_ERROR2\n        else:\n            self.result = self._NAME_ERROR1\n\n    def check_description(self):\n        # 检测任务描述\n        description = self.jd.description\n        if not description:\n            self.result = self._DESCRIPTION_ERROR1\n\n    def check_task_template(self):\n        # 检测任务模板\n        loaders.autodiscover()\n        tasks = list(sorted(registry.tasks.regular().keys()))\n        if self.jd.task_template:\n            if self.jd.task_template not in tasks:\n                self.result = self._TASK_TEMPLATE_ERROR1\n        else:\n            self.result = self._TASK_TEMPLATE_ERROR2\n\n    def check_is_enable(self):\n        # 检测“是否启用”\n        is_enable = self.jd.is_enable\n        if not isinstance(is_enable, bool):\n            self.result = self._IS_ENABLE_ERROR1\n\n    def check_crontab(self):\n        crontab = self.jd.crontab\n        crons = CrontabSchedule.objects.values('id')\n        try:\n            if long(crontab) not in [c['id'] for c in crons]:\n                self.result = self._CRONTAB_ERROR\n        except Exception, e:\n            self.result = self._CRONTAB_ERROR\n\n    def check_batch_job_details(self):\n        \"\"\"\n        检查批处理作业详情\n        先验证子作业类型，再验证子作业是否存在\n        :return:\n        \"\"\"\n        data = self.jd.batch_job_details\n        if data:\n            for dt in data:\n                try:\n                    _type = int(dt['type'])\n                except Exception as e:\n                    msg = self._BATCH_JOB_DETAILS_ERROR2.get('msg') % (dt['name'], dt['description'])\n                    status = self._BATCH_JOB_DETAILS_ERROR2.get('status')\n                    self.result = dict(status=status, msg=msg)\n                    break\n                else:\n                    if _type not in _SUBJOB_TYPE:\n                        msg = self._BATCH_JOB_DETAILS_ERROR2.get('msg') % (dt['name'], dt['description'])\n                        status = self._BATCH_JOB_DETAILS_ERROR2.get('status')\n                        self.result = dict(status=status, msg=msg)\n                        break\n                    else:\n                        msg = self._BATCH_JOB_DETAILS_ERROR3.get('msg') % (dt['name'], dt['description'], dt['subjob_id'])\n                        status = self._BATCH_JOB_DETAILS_ERROR3.get('status')\n                        # 数据同步\n                        if _type == _SUBJOB_TYPE[0]:\n                            sql = datax_web_config.query_datax_job_by_id_sql % dt['subjob_id']\n                            data = self.dtconn.ygol.getsingle(sql)\n                            if self.dtconn.ygol.status:\n                                _msg = u'检测datax_job_id 错误 - SQL: %s。 - Msg: %s' % (sql, self.dtconn.ygol.msg)\n                                logger.error(_msg)\n                                self.result = dict(status=500, msg=_msg)\n                            else:\n                                if not data:\n                                    self.result = dict(status=status, msg=msg)\n        else:\n            self.result = self._BATCH_JOB_DETAILS_ERROR1\n\n    def check_batch_job_id(self):\n        # 检测批处理作业ID\n        if self.jd.operation_type == _OPERATION_TYPE[1]:\n            _id = self.jd.batch_job_id\n            if isinstance(_id, _str) and _id and _id.isdigit():\n                sql = config.query_batch_job_sql3 % _id\n                data = self.dtconn.ygol.getsingle(sql)\n                if self.dtconn.ygol.status:\n                    _msg = u'检测batch_job_id 错误 - SQL: %s。 - Msg: %s' % (sql, self.dtconn.ygol.msg)\n                    logger.error(_msg)\n                    self.result = dict(status=500, msg=_msg)\n                else:\n                    if not data:\n                        self.result = self._BATCH_JOB_ID_ERROR2\n            else:\n                self.result = self._BATCH_JOB_ID_ERROR1\n\n    def check_trigger_mode(self):\n        # 检测触发模式\n        trigger_mode = self.jd.trigger_mode\n        if self.jd.operation_type == _OPERATION_TYPE[1]:\n            if not trigger_mode:\n                self.result = self._TRIGGER_MODE_ERROR1\n            else:\n                if trigger_mode not in _TRIGGER_MODE:\n                    self.result = self._TRIGGER_MODE_ERROR2\n\n\n    def total_check(self):\n        check_func = ['check_operation_type', 'check_name_by_operation_type',\n                      'check_description', 'check_trigger_mode', 'check_task_template',\n                      'check_is_enable', 'check_crontab', 'check_batch_job_details',\n                      'check_batch_job_id'\n                      ]\n\n        for func_name in check_func:\n            getattr(self, func_name)()\n            if self.result['status']:\n                break\n\n        return self.result\n\n\nclass BatchJobInstanceSql(object):\n    # datax job instance 查询sql\n    _table_bji = {\n        'name': {'data_type': 'str', 'val': ''},\n        'description': {'data_type': 'str', 'val': ''},\n        'status': {'data_type': 'str', 'val': ''},\n        'result': {'data_type': 'str', 'val': ''},\n        'trigger_mode': {'data_type': 'str', 'val': ''},\n    }\n\n    _order_by = [{'table': 'bji', 'field': 'start_time', 'rule': 'DESC'}]\n\n    def __init__(self, request):\n        self.cur = Currency(request)\n        self.rq_get = self.cur.rq_get\n\n        self._offset = int(self.rq_get('offset'))\n        self._limit = int(self.rq_get('limit'))\n        self._SQL = config.select_batch_job_instance_sql\n        self._TOTAL_SQL = config.count_batch_job_instance_sql\n        self._set_table(self._table_bji)\n\n    def _set_table(self, table):\n        for field, attr in table.items():\n            val = self.rq_get(field)\n            attr['val'] = val\n        return table\n\n    @property\n    def tables(self):\n        _tables = {'bji': self._table_bji}\n        return _tables\n\n    @property\n    def cvtpara(self):\n        _cvtpara = {\n            'offset': self._offset,\n            'limit': self._limit,\n            'sql': self._SQL,\n            'total_sql': self._TOTAL_SQL,\n            'order_by': self._order_by,\n            'order_rule': self._order_by\n        }\n        return _cvtpara\n\n\nclass PaginatorBatchJobInstance(dataconn.DatabaseConnection, query_sql.Q_Data):\n    # 分页访问数据\n    def __init__(self, qs):\n        super(PaginatorBatchJobInstance, self).__init__(logger)\n        query_sql.Q_Data.__init__(self, qs)\n\n    @property\n    def rows(self):\n        return self._get_rows(self.ygol)\n\n    @property\n    def total(self):\n        return self._get_total(self.ygol)\n\n\n@login_required\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\ndef index(request):\n    # 批处理作业首页\n    return render(request, 'batch_job/index.html', locals())\n\n@login_required\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\n@permission_required('batch_job.editBatchJob', raise_exception=PermissionDenied)\ndef add_batch_job(request):\n    # 新建批处理作业\n    return render(request, 'batch_job/add_batch_job.html', locals())\n\n@login_required\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\ndef update_batch_job(request, id):\n    # 更新批处理作业\n    return render(request, 'batch_job/update_batch_job.html', locals())\n\n@login_required\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\ndef batch_job_instance(request):\n    # 批处理作业执行历史\n    return render(request, 'batch_job/batch_job_instance.html', locals())\n\n\n@login_required\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\ndef batch_job_instance_details(request, id):\n    # 批处理作业详情执行历史\n    return render(request, 'batch_job/batch_job_instance_details.html', locals())\n\n\n@login_required\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\ndef get_task_template(request):\n    # 任务模板\n    irrelevant_tasks = ['FirstBlood.celery.debug_task',\n                         'celery.backend_cleanup',\n                         'celery.chain',\n                         'celery.chord',\n                         'celery.chord_unlock',\n                         'celery.chunks',\n                         'celery.group',\n                         'celery.map',\n                         'celery.starmap',\n                         'run',\n                         u'run_batch_job']\n\n    loaders.autodiscover()\n    response = HttpResponse()\n    tasks = list(sorted(registry.tasks.regular().keys()))\n    for t in irrelevant_tasks:\n        tasks.remove(t)\n    response.write(json.dumps(tasks))\n    return response\n\n\n@login_required\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\ndef get_crontab(request):\n    # 获取 crontab 定时时间\n    response = HttpResponse()\n    data = CrontabSchedule.objects.values()\n    response.write(json.dumps(list(data)))\n    return response\n\n\n@login_required\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\n@permission_required('batch_job.editBatchJob', raise_exception=PermissionDenied)\ndef add_crontab(request):\n    # 新增 crontab 定时时间\n    response = HttpResponse()\n    cur = Currency(request)\n    rq_post = getattr(cur, 'rq_post')\n    jdata = rq_post('data')\n    data = json.loads(jdata)\n    ndata = dict([(k, v.replace(' ', '')) for k, v in data.items()])  # Remove all spaces\n    crobj = schedules.crontab(**ndata)\n    to_model_schedule = ModelEntry.to_model_schedule\n    model_schedule, model_field = to_model_schedule(crobj)\n    response.write(json.dumps(ndata))\n    return response\n\n\n@login_required\n@verification(CheckBatchJob)\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\n@permission_required('batch_job.editBatchJob', raise_exception=PermissionDenied)\ndef add_batch_job_data(request):\n    # 新增或者修改任务数据\n    response = HttpResponse()\n    cur = Currency(request)\n    data = cur.rq_post_json('data')\n    jd = BatchJobData(data)\n\n    if jd.operation_type == _OPERATION_TYPE[0]:\n        result = jd.create()  # 新批处理作业\n        jd.create_PeriodicTask()  # 创建定时任务\n    else:\n        result = jd.update()\n        jd.update_PeriodicTask()\n    response.write(json.dumps(result))\n    return response\n\n\n@login_required\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\ndef get_batch_job_data(request):\n    # 获取批处理作业数据\n    sql = config.query_batch_job_sql2\n    dtconn = dataconn.DatabaseConnection(logger)\n    dtsf = dataconn.DataTransform()\n    source_data = dtconn.ygol.getall(sql)\n    data = [dtsf.get_row_by_dict_to_user(dt) for dt in source_data]\n    response = HttpResponse()\n    response.write(json.dumps(data))\n    return response\n\n\n@login_required\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\ndef get_batch_job_data_by_id(request):\n    \"\"\"\n    根据ID获取批处理作业数据\n    :param request: id\n    :return:\n    \"\"\"\n    cur = Currency(request)\n    _id = cur.rq_post('_id')\n    sql = config.query_batch_job_sql3 % _id\n    dtconn = dataconn.DatabaseConnection(logger)\n    dtsf = dataconn.DataTransform()\n    source_data = dtconn.ygol.getsingle(sql)\n    response = HttpResponse()\n    response.write(json.dumps(dtsf.get_row_by_dict_to_user(source_data)))\n    return response\n\n\n@login_required\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\ndef get_batch_job_sub_job_by_id(request):\n    \"\"\"\n    根据ID获取批处理作业中的子作业数据\n\n    扩展：\n         目前子作业只包含数据同步，后期加入了SQL脚本、SQL备份等等之后，\n         需要先判断子作业的类型，再根据类型去相关表里查询子作业的详细信息。\n         例如：如果有同步类型的子作业，就需要根据同步作业表查询同步的任务详情。\n              如果有备份类型的，就去备份表里查询备份任务详情。\n    :param request: id\n    :return:\n    \"\"\"\n    cur = Currency(request)\n    _id = cur.rq_post('_id')\n    sql = config.query_batch_job_sub_job_by_id_sql % _id\n    dtconn = dataconn.DatabaseConnection(logger)\n    dtsf = dataconn.DataTransform()\n    source_data = dtconn.ygol.getall(sql)\n    data = [dtsf.get_row_by_dict_to_user(dt) for dt in source_data]\n    response = HttpResponse()\n    response.write(json.dumps(data))\n    return response\n\n\n@login_required\n@verification(CheckBatchJob)\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\n@permission_required('batch_job.editBatchJob', raise_exception=PermissionDenied)\ndef run_batch_job_task(request):\n    # 执行批处理作业\n    response = HttpResponse()\n    cur = Currency(request)\n    rq_post = getattr(cur, 'rq_post')\n    jdata = rq_post('data')\n    data = json.loads(jdata)\n    # run_batch_job(**data)\n    run_batch_job.delay(**data)\n    response.write(json.dumps({'status': 0, 'msg': u'操作成功'}))\n    return response\n\n\ndef _process_run_sub_job(_type, subjob_id, results, batch_job_instance_id, trigger_mode):\n    # 多进程执行批处理任务的子任务\n    BatchJobSubjobInstanceData.run_sub_job(_type, subjob_id, results, batch_job_instance_id, trigger_mode)\n\n\n@shared_task(name='run_batch_job')\ndef run_batch_job(**data):\n    \"\"\"\n    异步执行批处理作业任务\n    :param data:\n            {u'_id': u'30',\n             u'batch_job_details': [{u'batch_job_id': u'30',\n                                     u'create_time': u'2018-07-24 21:18:31',\n                                     u'description': u'\\u6570\\u636e\\u540c\\u6b65\\u6d4b\\u8bd5',\n                                     u'id': u'37',\n                                     u'modify_time': u'2018-07-24 21:18:31',\n                                     u'name': u'test',\n                                     u'subjob_id': u'28',\n                                     u'type': u'1'}],\n             u'crontab': u'2',\n             u'description': u'DIY\\u6d4b\\u8bd5\\u7ec4\\u88c5\\u673a1',\n             u'is_enable': False,\n             u'name': u'test1',\n             u'operation_type': 2,\n             u'task_template': u'celery.chunks',\n             u'trigger_mode': 2}\n\n             _id：batch_job_id 批处理作业表 id\n    :return:\n    \"\"\"\n    bjid = BatchJobInstanceData(data)\n    bjid.start_log()\n\n    curr_proc = mp.current_process()\n    # celery 里执行任务时，默认守护进程无法开启多进程，需要先将当前进程设置为非守护进程, 启动执行再改为守护进程\n    curr_proc.daemon = False\n    manager = mp.Manager()\n    results = manager.list()  # 记录所有子作业的执行结果\n    p = mp.Pool(config.maxtasksperchild)\n    curr_proc.daemon = True\n\n    batch_job_details = data.get('batch_job_details')\n    for sj in batch_job_details:\n        _type = int(sj.get('type'))\n        subjob_id = sj.get('subjob_id')\n        p.apply_async(_process_run_sub_job, args=(_type, subjob_id, results,\n                                                  bjid.batch_job_instance_id,\n                                                  bjid.trigger_mode))\n\n    p.close()\n    p.join()\n    batch_job_result = 0 if 1 not in results else 1\n    bjid.record_result_log(batch_job_result)\n\n\n@shared_task(name='batch_job_periodictask')\ndef batch_job_periodictask(batch_job_id):\n    \"\"\"\n    定时执行批处理作业\n                        通过batch_job_id查询批处理作业的信息来执行任务。\n\n    :param batch_job_id: 批处理作业ID，也就是batch_job表id\n    :return: None\n    \"\"\"\n    bjd = BatchJobData({})\n    batch_job_data = bjd.get_batch_job_by_id(batch_job_id)\n\n    bjid = BatchJobInstanceData(batch_job_data)\n    bjid.batch_job_instance_id = batch_job_id\n    bjid.trigger_mode = _TRIGGER_MODE[0]  # 触发模式：自动\n    bjid.start_log()\n\n    curr_proc = mp.current_process()\n    # celery 里执行任务时，默认守护进程无法开启多进程，需要先将当前进程设置为非守护进程, 启动执行后再改为守护进程\n    curr_proc.daemon = False\n    manager = mp.Manager()\n    results = manager.list()  # 记录所有子作业的执行结果\n    p = mp.Pool(config.maxtasksperchild)\n    curr_proc.daemon = True\n\n    batch_job_details = bjd.get_batch_job_details_by_id(batch_job_id)\n    for sj in batch_job_details:\n        _type = int(sj.get('type'))\n        subjob_id = sj.get('subjob_id')\n        p.apply_async(_process_run_sub_job, args=(_type, subjob_id, results,\n                                                  bjid.batch_job_instance_id,\n                                                  bjid.trigger_mode))\n\n    p.close()\n    p.join()\n    batch_job_result = 0 if 1 not in results else 1\n    bjid.record_result_log(batch_job_result)\n\n\n# @login_required\n# @permission_required('change.view_delivery', raise_exception=PermissionDenied)\n# @permission_required('change.edit_delivery', raise_exception=PermissionDenied)\ndef get_batch_job_instance(request):\n    # 分页查询批处理作业实例\n    dsql = BatchJobInstanceSql(request)\n    cvtpara = dsql.cvtpara\n    tables = dsql.tables\n    qs = query_sql.Q_Sql(cvtpara, **tables)\n    pd = PaginatorBatchJobInstance(qs)\n    response = HttpResponse()\n    response.write(json.dumps({'rows': pd.rows, 'total': pd.total}))\n    return response\n\n\n@login_required\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\ndef get_batch_job_instance_data_by_id(request):\n    # 根据ID获取批处理作业数据\n    cur = Currency(request)\n    batch_job_instance_id = cur.rq_post('instance_id')\n    bjid = BatchJobInstanceData({})\n    data = bjid.get_batch_job_instance_by_id(batch_job_instance_id)\n    response = HttpResponse()\n    response.write(json.dumps(data))\n    return response\n\n\n@login_required\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\ndef get_batch_job_sub_job_instance_data_by_id(request):\n    # 根据ID获取批处理作业数据\n    cur = Currency(request)\n    batch_job_instance_id = cur.rq_get('instance_id')\n    # if _type == 1: 数据同步类型为1\n    data = BatchJobSubjobInstanceData.get_sub_job_datax_instance_data_by_id(batch_job_instance_id)\n    response = HttpResponse()\n    response.write(json.dumps(data))\n    return response"
  },
  {
    "path": "controller/__init__.py",
    "content": ""
  },
  {
    "path": "controller/core/__init__.py",
    "content": ""
  },
  {
    "path": "controller/core/access.py",
    "content": "# -*- coding: UTF-8 -*-\r\n# Description:                    \r\n# Author:           黄小雪\r\n# Date:             2017年09月07日\r\n# Company:          东方银谷\r\nfrom public import *\r\nfrom django.http import HttpResponse\r\nfrom business_query.configuration.sqlList import *\r\nfrom dtmt.query import DatabaseConnection\r\nfrom functools import wraps\r\nimport json\r\nimport logging\r\n\r\n\r\ndef verification(check_class):\r\n    \"\"\"\r\n    装饰器用于检测用户提交的信息是否合法.\r\n    check_class 检测类\r\n    Decorator for views that checks that the user submitted information,\r\n    redirecting to the log-in page if necessary. The test should be a callable\r\n    that takes the user object and returns True if the user passes.\r\n    \"\"\"\r\n\r\n    def decorator(view_func):\r\n        @wraps(view_func)\r\n        def _wrapped_view(request, *args, **kwargs):\r\n            response = HttpResponse()\r\n            ccl = check_class(request)\r\n            check_status, error_msg = ccl.total_check()\r\n            if check_status:\r\n                response.write(json.dumps({'status': check_status, 'msg': error_msg}))\r\n                return response\r\n\r\n            return view_func(request, *args, **kwargs)\r\n        return _wrapped_view\r\n    return decorator\r\n\r\n\r\nclass Check_IBQ(object):\r\n    \"\"\"\r\n    检测投资批量查询提交的信息\r\n    error_msg 存放所有错误消息\r\n    check_status 错误状态 1 错误，0 正常，主要用于前端的JavaScript进行判断\r\n    total_check 启动所有检测，返回检测状态和错误消息\r\n    \"\"\"\r\n    def __init__(self, request):\r\n        cur = Currency(request)\r\n        rq_post = getattr(cur, 'rq_post')\r\n        jdata = rq_post('data')\r\n        data = json.loads(jdata)\r\n        self.data = data\r\n        self.conf = investment_batch_query_conf\r\n        self.error_msg = []\r\n\r\n    def check_data(self):\r\n        # 检测脚本名称\r\n        isdigit = [d for d in self.data if str(d).isdigit()]\r\n        if not isdigit:\r\n            self.error_msg.append(u'请输入手机号')\r\n        else:\r\n            if len(self.data) > self.conf['maxNum']:\r\n                self.error_msg.append(u'每次查询量不能超过%s' % self.conf['maxNum'])\r\n\r\n    def total_check(self):\r\n        self.check_data()\r\n        status = 1 if self.error_msg else 0\r\n\r\n        return status, self.error_msg\r\n\r\n\r\nclass Check_PCI(object):\r\n    \"\"\"\r\n    普惠离职员工客户信息查询\r\n    error_msg 存放所有错误消息\r\n    check_status 错误状态 1 错误，0 正常，主要用于前端的JavaScript进行判断\r\n    total_check 启动所有检测，返回检测状态和错误消息\r\n    \"\"\"\r\n    def __init__(self, request):\r\n        cur = Currency(request)\r\n        rq_post = getattr(cur, 'rq_post')\r\n        jdata = rq_post('data')\r\n        data = json.loads(jdata)\r\n        self.logger = logging.getLogger('business_query')\r\n        self.dc = DatabaseConnection(self.logger)\r\n        self.data = data\r\n        self.conf = puhuiCustomerInfoConf\r\n        self.error_msg = []\r\n\r\n    def check_data(self):\r\n        # 检测脚本名称\r\n        isdigit = [d for d in self.data if str(d)]\r\n        if not isdigit:\r\n            self.error_msg.append(u'请输入工号')\r\n        else:\r\n            if len(self.data) > self.conf['maxNum']:\r\n                self.error_msg.append(u'每次查询量不能超过%s' % self.conf['maxNum'])\r\n\r\n    def checkDateMaxNum(self):\r\n        # 每天最多查询5次\r\n        res = self.dc._r.hmget('puhuiCustomerInfo', 'count')[0]\r\n        count = int(res) if res else 0\r\n        if count >= 5:\r\n            self.error_msg.append(u'今天已查询5次，欢迎明天再来查询！')\r\n\r\n    def total_check(self):\r\n        self.check_data()\r\n        self.checkDateMaxNum()\r\n        status = 1 if self.error_msg else 0\r\n\r\n        return status, self.error_msg\r\n\r\n\r\nclass Check_people_upload(object):\r\n    \"\"\"\r\n    检测人力上传的文件\r\n    错误码 错误消息\r\n    1     上传文件为空\r\n    2     只能上传excel文件\r\n    \"\"\"\r\n    def __init__(self, request):\r\n        self.fileobj = request.FILES.get('file', None)\r\n        self.error_msg = []\r\n        self.error_code = []\r\n\r\n    def check_file_exists(self):\r\n        \"\"\"\r\n        检测文件是否存在\r\n        :return:\r\n        \"\"\"\r\n        if self.fileobj is None:\r\n            self.error_msg.append(u'上传文件为空')\r\n            self.error_code.append(1)\r\n\r\n    def check_filename(self):\r\n        \"\"\"\r\n        检测文件名后缀必须为xlsx、xls\r\n        :return:\r\n        \"\"\"\r\n        legal_file_suffixes = ['xlsx', 'xls']\r\n        if self.fileobj.name.split('.')[-1] not in legal_file_suffixes:\r\n            self.error_msg.append(u'只能上传excel文件')\r\n            self.error_code.append(2)\r\n\r\n    def total_check(self):\r\n        self.check_file_exists()\r\n        if 1 not in self.error_code:\r\n            self.check_filename()\r\n        status = 1 if self.error_msg else 0\r\n        return status, self.error_msg"
  },
  {
    "path": "controller/core/excel.py",
    "content": "#! /usr/bin/env python\r\n# -*-coding:utf-8-*-\r\n##################################################\r\n# Function:        银谷在线注册统计及出借统计脚本\r\n# Usage:                python start.py\r\n# Author:               黄小雪\r\n# Date:\t\t\t\t   2016年7月19日\r\n# Company:\r\n# Version:        1.2\r\n##################################################\r\n\r\nimport xlwt\r\nimport xlrd\r\nfrom unicode_width import *\r\nfrom openpyxl import Workbook\r\nfrom openpyxl.utils import get_column_letter\r\nfrom openpyxl.styles import Font, Alignment\r\n\r\n\r\ndef set_style(name, height, bold=False):\r\n    # 设置单元格样式\r\n    style = xlwt.XFStyle()  # 初始化样式\r\n\r\n    font = xlwt.Font()  # 为样式创建字体\r\n    font.name = name  # 'Times New Roman'\r\n    font.bold = bold\r\n    font.color_index = 4\r\n    font.height = height\r\n\r\n    al = xlwt.Alignment()\r\n    al.horz = xlwt.Alignment.HORZ_CENTER  # 设置水平居中\r\n    al.vert = xlwt.Alignment.VERT_CENTER  # 设置垂直居中\r\n\r\n    style.font = font\r\n    style.alignment = al\r\n    return style\r\n\r\n\r\ndef get_table(file, table=False):\r\n    # 获取表格数据\r\n    data = xlrd.open_workbook(file)\r\n    sheets = False\r\n    if table:\r\n        table = data.sheets()[0]\r\n    else:\r\n        sheets = data.sheets()\r\n\r\n    return table or sheets\r\n\r\n\r\ndef sheet_write(f, sheet_name, row0, rows, width):\r\n    # 写入工作簿\r\n    sheet = f.add_sheet(sheet_name, cell_overwrite_ok=True)  # 创建sheet\r\n\r\n    # 生成第一行\r\n    for i in range(0, len(row0)):\r\n        sheet.write(0, i, row0[i], set_style('Times New Roman', 220, True))\r\n        sheet.col(i).width = 256 * width[i]\r\n\r\n    for j in range(0, len(rows)):\r\n        row = rows[j]\r\n        for i in range(0, len(row)):\r\n            sheet.write(j + 1, i, row[i], set_style('Times New Roman', 220, False))\r\n\r\n\r\nclass Openpyxl(object):\r\n    # openpyxl 生成excel文件\r\n    def __init__(self, filename):\r\n        self.ft1 = Font(name='Calibri', bold=True)\r\n        self.ft2 = Font(name='Calibri')\r\n        self.al = Alignment(horizontal='center', vertical='center')\r\n        self.filename = filename\r\n        self.wb = Workbook()\r\n\r\n    def __set_width(self, rows, ws):\r\n        widths = get_width(*rows)\r\n        for i in xrange(len(widths)):\r\n            ws.column_dimensions[get_column_letter(i + 1)].width = widths[i]\r\n\r\n    def __get_new_ws(self, title):\r\n        new_ws = self.wb.get_active_sheet()\r\n\r\n        if len(new_ws.get_cell_collection()) == 0:\r\n            new_ws.title = title\r\n        else:\r\n            new_ws = self.wb.create_sheet(title=title)\r\n\r\n        return new_ws\r\n\r\n    def add_sheet(self, title, rows):\r\n        new_ws = self.__get_new_ws(title)\r\n\r\n        for i in range(len(rows)):\r\n            row = rows[i]\r\n            for j in range(len(row)):\r\n                new_ws.cell(row=i + 1, column=j + 1).value = row[j]\r\n\r\n                if i == 0:\r\n                    new_ws.cell(row=i + 1, column=j + 1).font = self.ft1\r\n                else:\r\n                    new_ws.cell(row=i + 1, column=j + 1).font = self.ft2\r\n                new_ws.cell(row=i + 1, column=j + 1).alignment = self.al\r\n\r\n        self.__set_width(rows, new_ws)\r\n\r\n    def save(self):\r\n        self.wb.save(filename=self.filename)\r\n"
  },
  {
    "path": "controller/core/local_mysql.py",
    "content": "#! /usr/bin/env python\r\n# -*-coding:utf-8-*-\r\n##################################################\r\n# Function:        银谷在线注册统计及出借统计脚本\r\n# Usage:                python start.py\r\n# Author:               黄小雪\r\n# Date:                 2016年7月19日\r\n# Company:\r\n# Version:        1.2\r\n##################################################\r\n\r\n\r\nfrom controller.public.mysql_helper import Business\r\n\r\n\r\nBusiness(host, user, passwd, db)"
  },
  {
    "path": "controller/core/mailtable.py",
    "content": "#!/usr/bin/python env\r\n# -*- coding: UTF-8 -*-\r\n# Description:                    \r\n# Author:           黄小雪\r\n# Date:             2017年07月04日\r\n# Company:          东方银谷\r\n\r\n\r\nclass MailTable(object):\r\n    \"\"\"\r\n    邮件html表格\r\n    \"\"\"\r\n    def __init__(self):\r\n        pass\r\n\r\n    @property\r\n    def style(self):\r\n        _style = \"\"\"\r\n        <style type=\"text/css\">\r\n        table.imagetable {\r\n            font-family: verdana,arial,sans-serif;\r\n            font-size:11px;\r\n            color:#333333;\r\n            border-width: 1px;\r\n            border-color: #999999;\r\n            border-collapse: collapse;\r\n        }\r\n        table.imagetable th {\r\n            background:#b5cfd2 url('cell-blue.jpg');\r\n            border-width: 1px;\r\n            padding: 8px;\r\n            border-style: solid;\r\n            border-color: #999999;\r\n            white-space:nowrap;\r\n        }\r\n        table.imagetable td {\r\n            background:#dcddc0 url('cell-grey.jpg');\r\n            border-width: 1px;\r\n            padding: 8px;\r\n            border-style: solid;\r\n            border-color: #999999;\r\n            white-space:nowrap;\r\n        }\r\n        </style>\r\n        \"\"\"\r\n        return _style\r\n\r\n    def table(self, caption, rows):\r\n        row0 = rows[0]\r\n        tr0 = self._tr0_list(row0)\r\n        total_tr_list = [self._tr_list(row) for row in rows[1:]]\r\n        tr_body = ''.join(total_tr_list)\r\n        _table = \"\"\"\r\n        <table class=\"imagetable\">\r\n        <caption align=\"top\">%s</caption>\r\n        %s\r\n        %s\r\n        </table>\r\n        \"\"\" % (caption, tr0, tr_body)\r\n        return _table\r\n\r\n    def _tr_list(self, row):\r\n        _tr_list = ['<td>%s</td>' % r for r in row]\r\n        _tr = '<tr>%s</tr>' % ''.join(_tr_list)\r\n        return _tr\r\n\r\n    def _tr0_list(self, row):\r\n        _tr_list = ['<th>%s</th>' % r for r in row]\r\n        _tr = '<tr>%s</tr>' % ''.join(_tr_list)\r\n        return _tr\r\n\r\n"
  },
  {
    "path": "controller/core/public.py",
    "content": "# -*- coding: UTF-8 -*-\r\nimport datetime\r\nimport time\r\nimport json\r\n\r\nclass Currency(object):\r\n    #  通用帮助\r\n    def __init__(self, request):\r\n        self.request = request\r\n\r\n    def rq_get(self, key):\r\n        return self.request.GET.get(key, '').strip()\r\n\r\n    def rq_post(self, key):\r\n        return self.request.POST.get(key, '').strip()\r\n\r\n    def rq_get_json(self, key):\r\n        return json.loads(self.rq_get(key))\r\n\r\n    def rq_post_json(self, key):\r\n        return json.loads(self.rq_post(key))\r\n\r\nclass DatetimeHelp(object):\r\n    # 日期时间帮助\r\n    def __init__(self):\r\n        pass\r\n\r\n    @property\r\n    def now_time(self):\r\n        return datetime.datetime.now()\r\n\r\n    def strptime(self, value, format):\r\n        return datetime.datetime.strptime(value, format)\r\n\r\n    @property\r\n    def nowtimestrf1(self):\r\n        return self.now_time.strftime(u'%Y-%m-%d %H:%M:%S')\r\n\r\n    @property\r\n    def nowtimestrf2(self):\r\n        return self.now_time.strftime(u'%Y年%m月%d日 %H点%M分%S秒')\r\n\r\n    @property\r\n    def nowtimestrf3(self):\r\n        return self.now_time.strftime(u'%Y%m%d%H%M%S')\r\n\r\n    @property\r\n    def nowtimestrf4(self):\r\n        return self.now_time.strftime(u'%Y%m%d')\r\n\r\n    @property\r\n    def nowtimestrf5(self):\r\n        return self.now_time.strftime(u'%Y-%m-%d')\r\n\r\n    @property\r\n    def nowtimestrf6(self):\r\n        return self.now_time.strftime(u'%Y年%m月%d日')\r\n\r\n    @property\r\n    def yesterday(self):\r\n        yd = self.now_time - datetime.timedelta(days=1)\r\n        return yd\r\n\r\n    @property\r\n    def yesterdaystrf4(self):\r\n        return self.yesterday.strftime(u'%Y%m%d')\r\n\r\n    @property\r\n    def yesterdaystrf5(self):\r\n        return self.yesterday.strftime(u'%Y-%m-%d')\r\n\r\n    @property\r\n    def yesterdaystrf6(self):\r\n        return self.yesterday.strftime(u'%Y年%m月%d日')\r\n\r\n    @property\r\n    def timestamp1(self):\r\n        \"\"\"返回当前时间的13位毫秒时间戳\r\n        :return: 13 位的毫秒时间戳  1456402864242\r\n        \"\"\"\r\n        return self.datetime_to_timestamp(self.now_time)\r\n\r\n    @staticmethod\r\n    def datetime_to_timestamp(datetime_obj):\r\n        \"\"\"将本地(local) datetime 格式的时间 (含毫秒) 转为毫秒时间戳\r\n        :param datetime_obj: {datetime}2016-02-25 20:21:04.242000\r\n        :return: 13 位的毫秒时间戳  1456402864242\r\n        \"\"\"\r\n        local_timestamp = long(time.mktime(datetime_obj.timetuple()) * 1000.0 + datetime_obj.microsecond / 1000.0)\r\n        return local_timestamp\r\n\r\n\r\nif __name__ == '__main__':\r\n    dth = DatetimeHelp()\r\n    print dth.timestamp1\r\n"
  },
  {
    "path": "controller/core/query_sql.py",
    "content": "#!/usr/bin/python env\r\n# -*- coding: UTF-8 -*-\r\n# Description:                    \r\n# Author:           黄小雪\r\n# Date:             2017年03月29日\r\n# Company:          东方银谷\r\nfrom controller.core.public import *\r\nimport decimal\r\n\r\n\r\nclass Q_Sql(object):\r\n    \"\"\"\r\n    # 查询sql\r\n    table_a = {\r\n        'delivery_id': {'data_type': 'str', 'val':''},\r\n        'customer': {'data_type': 'str', 'val':''},\r\n        'customer_cn': {'data_type': 'str', 'val':''},\r\n        'employee': {'data_type': 'str', 'val':''},\r\n        'employee_cn': {'data_type': 'str', 'val':''},\r\n        'former_employee': {'data_type': 'str', 'val':''},\r\n        'former_employee_cn': {'data_type': 'str', 'val':''},\r\n        'result': {'data_type': 'str', 'val':''},\r\n        'start_time': {'data_type': 'datetime', 'val':''},\r\n        'end_time': {'data_type': 'datetime', 'val':''},\r\n    }\r\n\r\n    table_b = {\r\n        'large_area': {'data_type': 'str', 'val': '北区'},\r\n        'store': {'data_type': 'str', 'val': '安阳一部'},\r\n        'emp_num': {'data_type': 'str', 'val': 'CF400721'}\r\n    }\r\n\r\n    table_c ={ ... ... }\r\n    ...\r\n    ...\r\n\r\n    tables = {'a':table_a, 'b':table_b, 'c':table_c ... ...}\r\n\r\n    \"\"\"\r\n\r\n    def __init__(self,  cvtpara, **tables):\r\n        self._offset = cvtpara['offset']\r\n        self._limit = cvtpara['limit']\r\n        self.tables = tables\r\n\r\n        self._SQL = cvtpara['sql']\r\n        self._TOTAL_SQL = cvtpara['total_sql']\r\n        self._order_by = self._set_order_by(cvtpara['order_by'])\r\n\r\n        self._para = []\r\n        self._condition = []\r\n        self._condition_sql = ''\r\n\r\n        self._data()\r\n        self._set_condition()\r\n\r\n    def _data(self):\r\n        # 获取数据\r\n        for t, table in self.tables.items():\r\n            self._set_data(t, table)\r\n\r\n    def _set_data(self, t, table):\r\n        # 设置查询条件\r\n        for field, attr in table.items():\r\n\r\n            if attr['val']:\r\n                if attr['data_type'] == 'str':\r\n                    self._set_str(t, field, **attr)\r\n\r\n                if attr['data_type'] == 'datetime':\r\n                    self._set_datetime(t, field, **attr)\r\n\r\n    def _set_str(self, t, field, **attr):\r\n        val = attr['val']\r\n        self._condition.append('%s.%s = %%s' % (t, field))\r\n        self._para.append(val)\r\n\r\n    def _set_datetime(self, t, field, **attr):\r\n        val = attr['val']\r\n        tfield = field.split('_', 1)[1]  # 获取时间字段名称\r\n        judge = field.split('_', 1)[0]  # 判断是开始还是结束时间 'start' or 'end'\r\n        if judge == 'start':\r\n            self._condition.append('%s.%s >= %%s' % (t, tfield))\r\n            self._para.append(val)\r\n        elif judge == 'end':\r\n            self._condition.append('%s.%s <= %%s' % (t, tfield))\r\n            self._para.append('%s 23:59:59' % val)\r\n\r\n    def _set_order_by(self, order_by):\r\n        _order_by_str = ''\r\n        _fields = []\r\n\r\n        if order_by:\r\n            for dt in order_by:\r\n                _table = dt['table']\r\n                _field = dt['field']\r\n                _rule = dt['rule']\r\n\r\n                _field = '%s.%s %s' % (_table, _field, _rule)\r\n                _fields.append(_field)\r\n\r\n            _fields_str = ','.join(_fields)\r\n            _order_by_str = 'ORDER BY %s' % _fields_str\r\n\r\n        return _order_by_str\r\n\r\n    def _set_condition(self):\r\n        if self._condition:\r\n            and_sql = '\\nand '.join(self._condition)\r\n            self._condition_sql = 'where \\n%s' % and_sql\r\n\r\n    @property\r\n    def para(self):\r\n        import copy\r\n        _para = copy.deepcopy(self._para)\r\n        _para.append(self._offset)\r\n        _para.append(self._limit)\r\n        return _para\r\n\r\n    @property\r\n    def total_para(self):\r\n        return self._para\r\n\r\n    @property\r\n    def sql(self):\r\n        _sql = '\\n'.join([self._SQL, self._condition_sql,\r\n                      self._order_by, 'limit %s,%s'])\r\n        return _sql\r\n\r\n    @property\r\n    def total_sql(self):\r\n        _total_sql = '\\n'.join([self._TOTAL_SQL, self._condition_sql])\r\n        return _total_sql\r\n\r\n\r\nclass Q_Data(object):\r\n    # 设置投资数据\r\n    def __init__(self, qs):\r\n        self._sql = qs.sql\r\n        self._para = qs.para\r\n        self._total_sql = qs.total_sql\r\n        self._total_para = qs.total_para\r\n\r\n    def _get_data(self, databases_c):\r\n        return databases_c.getall(self._sql, self._para)\r\n\r\n    def _data_clean(self, data):\r\n        res = {}\r\n        for key,val in data.items():\r\n            res[key] = self._data_conversion(val)\r\n        return res\r\n\r\n    def _data_conversion(self, val):\r\n        # 数据转换\r\n        new_val = None\r\n        if isinstance(val, datetime.datetime):\r\n            new_val = val.strftime('%Y-%m-%d %H:%M:%S')\r\n\r\n        if isinstance(val, decimal.Decimal):\r\n            new_val = float(val)\r\n\r\n        return new_val or val\r\n\r\n    def _get_rows(self, databases_c):\r\n        # rows [{key1: val1, key2: val2, ... ...}]\r\n        rows = []\r\n        data = self._get_data(databases_c)\r\n        for dt in data:\r\n            row = self._data_clean(dt)\r\n            rows.append(row)\r\n\r\n        return rows\r\n\r\n    def _get_total(self, databases_c):\r\n        total_data = databases_c.getall(self._total_sql, self._total_para)\r\n        total = total_data[0]['count']\r\n        return total\r\n\r\n\r\nclass Download_Sql(Q_Sql):\r\n    \"\"\"\r\n    导出文件的sql\r\n    查询数据时使用重写的sql和total_para去查询\r\n    主要是去掉offset limit，导出数据时不需要分页查询\r\n    \"\"\"\r\n    def __init__(self, cvtpara, **tables):\r\n        super(Download_Sql, self).__init__(cvtpara, **tables)\r\n\r\n    @property\r\n    def sql(self):\r\n        _sql = '\\n'.join([self._SQL, self._condition_sql,\r\n                        self._order_by])\r\n        return _sql\r\n\r\n    @property\r\n    def para(self):\r\n        return self._para"
  },
  {
    "path": "controller/core/unicode_width.py",
    "content": "#!/usr/bin/env python\r\n#-*-coding:utf-8-*-\r\n\r\n\r\ndef get_max_length(arg):\r\n    length = str_len(arg[0]) + 2\r\n    return length\r\n\r\n\r\ndef sort_arg(arg):\r\n    arg = list(arg)\r\n    arg.sort(cmp=cmp_length)\r\n    return arg\r\n\r\n\r\ndef cmp_length(a, b):\r\n    la = str_len(a)\r\n    lb = str_len(b)\r\n\r\n    if la > lb:\r\n        return -1\r\n    elif la < lb:\r\n        return 1\r\n    else:\r\n        return 0\r\n\r\n\r\ndef str_len(string):\r\n    try:\r\n        string = u'%s' % string\r\n        row_l=len(string)\r\n        utf8_l=len(string.encode('utf-8'))\r\n        return (utf8_l-row_l)/2+row_l\r\n    except:\r\n        return row_l\r\n\r\n\r\ndef get_width(*var):\r\n    out = zip(*var)\r\n    res = map(sort_arg, out)\r\n    width = map(get_max_length, res)\r\n    return width\r\n\r\n\r\n"
  },
  {
    "path": "controller/public/__init__.py",
    "content": ""
  },
  {
    "path": "controller/public/dataconn.py",
    "content": "#!/usr/bin/python env\r\n# -*- coding: UTF-8 -*-\r\n# Description:                    \r\n# Author:           黄小雪\r\n# Date:             2018年01月04日\r\n# Company:          东方银谷\r\nimport re\r\nimport datetime\r\nimport decimal\r\nfrom django.conf import settings\r\nfrom mysql_helper import BusinessMysql\r\nfrom sqlserver_helper import BusinessSqlserver\r\n\r\n\r\n# 业绩平台数据库\r\n_database = settings.DATABASES['default']\r\n# 数据库用户名密码SQL\r\ndtbsif_sql = 'select * from FirstBlood.databaseinfo '\r\n\r\n\r\nclass DatabaseConnection(object):\r\n    # 数据库连接\r\n    def __init__(self, logger):\r\n        self._logger = logger\r\n        self.ygol = BusinessMysql(_database['HOST'], _database['USER'],\r\n                                  _database['PASSWORD'], _database['NAME'])\r\n\r\n    def get_dtbs_conn(self, name):\r\n        # 获取数据库连接\r\n        datainfo = self.get_datainfo(name)\r\n        businessType = {'mysql': BusinessMysql, 'sqlserver': BusinessSqlserver}\r\n        business = businessType[datainfo['type']]\r\n        return business(datainfo['host'], datainfo['user'], datainfo['passwd'], datainfo['db'])\r\n\r\n    def get_dtbs_conn_by_id(self, _id):\r\n        \"\"\"\r\n        根据数据库信息表的id获取数据库连接\r\n        :param _id:  数据库表主键id\r\n        :return: 数据库连接对象\r\n        \"\"\"\r\n        datainfo = self.get_datainfo_by_id(_id)\r\n        businessType = {'mysql': BusinessMysql, 'sqlserver': BusinessSqlserver}\r\n        business = businessType[datainfo['type']]\r\n        return business(datainfo['host'], datainfo['user'], datainfo['passwd'], datainfo['db'])\r\n\r\n    def get_datainfo(self, name):\r\n        # 获取数据库信息\r\n        conditions_sql = \"where `name`='%s'\" % name\r\n        data = self.ygol.getsingle(dtbsif_sql + conditions_sql)\r\n        if self.ygol.status:\r\n            self._logger.error(u'根据数据库信息表的名称，获取数据库信息失败. - Msg:' % self.ygol.msg)\r\n        return data\r\n\r\n    def get_datainfo_by_id(self, _id):\r\n        # 根据数据库信息表的主键id，获取数据库信息\r\n        conditions_sql = \"where `id`=%s\" % _id\r\n        data = self.ygol.getsingle(dtbsif_sql + conditions_sql)\r\n        if self.ygol.status:\r\n            self._logger.error(u'根据数据库信息表的主键id，获取数据库信息失败. - Msg:' % self.ygol.msg)\r\n        return data\r\n\r\n\r\nclass DataTransform(object):\r\n    \"\"\"\r\n    数据转换\r\n    \"\"\"\r\n    def __init__(self):\r\n        self._ILLEGAL_CHARACTERS_RE = re.compile(r'[\\000-\\010]|[\\013-\\014]|[\\016-\\037]')\r\n\r\n    def get_row_by_list(self, dt, database_type):\r\n        special_characters_conversion = self.special_characters(database_type)\r\n\r\n        row = []\r\n        for val in dt:\r\n            if isinstance(val, long):\r\n                val = '%s' % str(val)\r\n            if isinstance(val, str) or isinstance(val, unicode):\r\n                if next(self._ILLEGAL_CHARACTERS_RE.finditer(val), None):\r\n                    val = re.sub(self._ILLEGAL_CHARACTERS_RE, \"\", val)\r\n            if isinstance(val, bool):\r\n                val = 'true' if val else 'false'\r\n            if isinstance(val, str):\r\n                val = \"'%s'\" % special_characters_conversion(val)\r\n            if isinstance(val, unicode):\r\n                val = \"'%s'\" % special_characters_conversion(val)\r\n            if isinstance(val, datetime.datetime):\r\n                val = \"'%s'\" % val\r\n            if isinstance(val, datetime.date):\r\n                val = \"'%s'\" % val\r\n            if val is None:\r\n                val = 'null'\r\n            row.append(val)\r\n\r\n        return row\r\n\r\n    def get_row_by_dict(self, dt, database_type):\r\n        special_characters_conversion = self.special_characters(database_type)\r\n\r\n        row = {}\r\n        for key, val in dt.items():\r\n            if isinstance(val, long):\r\n                val = '%s' % str(val)\r\n            if isinstance(val, str) or isinstance(val, unicode):\r\n                if next(self._ILLEGAL_CHARACTERS_RE.finditer(val), None):\r\n                    val = re.sub(self._ILLEGAL_CHARACTERS_RE, \"\", val)\r\n            if isinstance(val, bool):\r\n                val = 'true' if val else 'false'\r\n            if isinstance(val, str):\r\n                val = \"%s\" % special_characters_conversion(val)\r\n            if isinstance(val, unicode):\r\n                val = \"%s\" % special_characters_conversion(val)\r\n            if isinstance(val, datetime.datetime):\r\n                val = \"%s\" % val\r\n            if isinstance(val, datetime.date):\r\n                val = \"%s\" % val\r\n            if val is None:\r\n                val = 'null'\r\n            if isinstance(val, decimal.Decimal):\r\n                val = float(val)\r\n            row[key] = val\r\n\r\n        return row\r\n\r\n    def get_row_by_dict_to_user(self, dt):\r\n        # 返给用户的数据，人性化展示\r\n        row = {}\r\n        for key, val in dt.items():\r\n            if isinstance(val, long):\r\n                val = '%s' % str(val)\r\n            if isinstance(val, str) or isinstance(val, unicode):\r\n                if next(self._ILLEGAL_CHARACTERS_RE.finditer(val), None):\r\n                    val = re.sub(self._ILLEGAL_CHARACTERS_RE, \"\", val)\r\n            if isinstance(val, bool):\r\n                val = 'true' if val else 'false'\r\n            if isinstance(val, datetime.datetime):\r\n                val = \"%s\" % val\r\n            if isinstance(val, datetime.date):\r\n                val = \"%s\" % val\r\n            if val is None:\r\n                val = 'null'\r\n            if isinstance(val, decimal.Decimal):\r\n                val = float(val)\r\n            row[key] = val\r\n\r\n        return row\r\n\r\n    def get_row_by_list_to_excel(self, dt):\r\n        # 列表数据，用于生成excel文件\r\n        row = []\r\n        for val in dt:\r\n            if isinstance(val, long):\r\n                val = str(val)\r\n            if isinstance(val, str) or isinstance(val, unicode):\r\n                if next(self._ILLEGAL_CHARACTERS_RE.finditer(val), None):\r\n                    val = re.sub(self._ILLEGAL_CHARACTERS_RE, \"\", val)\r\n            row.append(val)\r\n\r\n        return row\r\n\r\n    @staticmethod\r\n    def special_characters_mysql(string):\r\n        double_slash = re.compile(r'\\\\')\r\n        single_quotes = re.compile(r'\\'')\r\n        double_quotation_marks = re.compile(r'\\\"')\r\n\r\n        string = re.sub(double_slash, \"\\\\\\\\\", string)\r\n        string = re.sub(single_quotes, \"\\\\'\", string)\r\n        string = re.sub(double_quotation_marks, \"\\\\\\\"\", string)\r\n        return string\r\n\r\n    @staticmethod\r\n    def special_characters_sqlserver(string):\r\n        string = string.replace(\"'\", \"''\")\r\n        string = string.replace('\"', '\"\"')\r\n        return string\r\n\r\n    def special_characters(self, database_type):\r\n        # 特殊字符转义\r\n        func = {'mysql': self.special_characters_mysql, 'sqlserver': self.special_characters_sqlserver}\r\n        return func[database_type]\r\n"
  },
  {
    "path": "controller/public/log.py",
    "content": "#!/usr/bin/python env\r\n# -*- coding: UTF-8 -*-\r\n# Description:      日志记录\r\n# Author:           黄小雪\r\n# Date:             2017年02月15日\r\n# Company:          东方银谷\r\n\r\nimport logging\r\n\r\n# 开发一个日志系统， 既要把日志输出到控制台， 还要写入日志文件\r\nclass Logger(object):\r\n    # 用字典保存日志级别\r\n    _format_dict = {\r\n        1: logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'),\r\n        2: logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'),\r\n        3: logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'),\r\n        4: logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'),\r\n        5: logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')\r\n    }\r\n\r\n    def __init__(self, logname, loglevel, logger):\r\n        '''\r\n           指定保存日志的文件路径，日志级别，以及调用文件\r\n           将日志存入到指定的文件中\r\n        '''\r\n\r\n        # 创建一个logger\r\n        self.logger = logging.getLogger(logger)\r\n        self.logger.setLevel(logging.DEBUG)\r\n\r\n        # 创建一个handler，用于写入日志文件\r\n        fh = logging.FileHandler(logname)\r\n        fh.setLevel(logging.DEBUG)\r\n\r\n        # 再创建一个handler，用于输出到控制台\r\n        ch = logging.StreamHandler()\r\n        ch.setLevel(logging.DEBUG)\r\n\r\n        # 定义handler的输出格式\r\n        # formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')\r\n        formatter = self._format_dict[int(loglevel)]\r\n        fh.setFormatter(formatter)\r\n        ch.setFormatter(formatter)\r\n\r\n        # 给logger添加handler\r\n        self.logger.addHandler(fh)\r\n        self.logger.addHandler(ch)\r\n\r\n    def getlog(self):\r\n        return self.logger\r\n\r\n\r\n"
  },
  {
    "path": "controller/public/mailclass.py",
    "content": "#! /usr/bin/env python\r\n# -*- coding: UTF-8 -*-\r\n##################################################\r\n# Function:    银谷在线注册统计及出借统计脚本\r\n# Usage:                python start.py\r\n# Author:               黄小雪\r\n# Date:\t\t\t\t   2016年7月19日\r\n# Company:\r\n# Version:        1.2\r\n##################################################\r\n\r\nimport os\r\nimport sys\r\nimport xlrd\r\nimport smtplib\r\nimport datetime\r\nfrom email.header import Header\r\nfrom email.mime.text import MIMEText\r\nfrom email.mime.image import MIMEImage\r\nfrom email.mime.multipart import MIMEMultipart\r\nfrom email.utils import parseaddr, formataddr\r\n\r\nreload(sys)\r\nsys.setdefaultencoding(\"utf-8\")\r\n\r\n\r\nclass MailHelper(object):\r\n    # 发html邮件\r\n    def __init__(self, mail_host, mail_user, mail_pass,\r\n                 sender, sender_zh_name, receivers, cc):\r\n\r\n        # 第三方 SMTP 服务\r\n        self.mail_host = mail_host  # 设置服务器\r\n        self.mail_user = mail_user  # 用户名\r\n        self.mail_pass = mail_pass  # 口令\r\n\r\n        self.sender = sender\r\n        self.sender_zh_name = sender_zh_name\r\n        self.receivers = receivers  # 接收邮件，可设置为你的QQ邮箱或者其他邮箱\r\n        self.cc = cc  # 抄送\r\n\r\n        self.message = MIMEMultipart()  # 设置附件\r\n        self.status = 0  # 执行状态\r\n        self.msg = ''  # 错误消息\r\n\r\n    def add_attch(self, res_file):\r\n        # 添加附件\r\n        # 附件为绝对路径 /opt/script/yingu_rt/res/充值提现明细.xls\r\n\r\n        # 附件\r\n        att1 = MIMEText(open(res_file, 'rb').read(), 'base64', 'utf-8')\r\n        att1[\"Content-Type\"] = 'application/octet-stream'\r\n        # 这里的filename可以任意写，写什么名字，邮件中显示什么名字\r\n        att1[\"Content-Disposition\"] = 'attachment; filename=%s' % Header(res_file.split('/')[-1], 'UTF-8')\r\n        self.message.attach(att1)\r\n\r\n    def insert_img(self, file):\r\n        # 插入图片\r\n        # 指定图片为当前目录\r\n        fp = open(file, 'rb')\r\n        msgImage = MIMEImage(fp.read())\r\n        fp.close()\r\n\r\n        # 定义图片 ID，在 HTML 文本中引用\r\n        msgImage.add_header('Content-ID', '<image1>')\r\n        self.message.attach(msgImage)\r\n\r\n    def add_content(self, content, subject):\r\n        self.message['Subject'] = Header(subject, 'utf-8')\r\n        self.message['From'] = self._format_addr(u'%s <%s>'% (self.sender_zh_name, self.sender))\r\n        self.message['To'] = ''.join(self._cvt_receivers(self.receivers))\r\n        self.message['Cc'] = ''.join(self._cvt_receivers(self.cc))\r\n        head_content = \"\"\"\"\"\"\r\n        mail_msg = ''.join([head_content, content])\r\n        self.message.attach(MIMEText(mail_msg, 'html', 'utf-8'))\r\n\r\n    def _cvt_receivers(self, receivers):\r\n        # 收件人乱码处理\r\n        return [self._cvt_user(u) for u in receivers]\r\n\r\n    def _cvt_user(self, user):\r\n        return ''.join(['<', user, '>'])\r\n\r\n    def send_htm(self):\r\n        # 发送邮件\r\n        # 创建一个带附件的实例\r\n\r\n        try:\r\n            smtpObj = smtplib.SMTP()\r\n            smtpObj.connect(self.mail_host, 25)  # 25 为 SMTP 端口号\r\n            smtpObj.login(self.mail_user, self.mail_pass)\r\n            smtpObj.sendmail(self.sender, self.receivers + self.cc, self.message.as_string())\r\n        except smtplib.SMTPException, e:\r\n            self.status = 1\r\n            self.msg = u\"%s\" % e\r\n\r\n    @staticmethod\r\n    def _format_addr(s):\r\n        name, addr = parseaddr(s)\r\n        return formataddr((Header(name, 'utf-8').encode(),\r\n                           addr.encode('utf-8') if isinstance(addr, unicode) else addr))\r\n"
  },
  {
    "path": "controller/public/mysql_helper.py",
    "content": "#!/usr/bin/python env\r\n# -*- coding: UTF-8 -*-\r\n# Description:\r\n# Author:           黄小雪\r\n# Date:             2017年07月12日\r\n# Company:          东方银谷\r\nimport MySQLdb\r\n\r\n\r\nclass MysqlHelper(object):\r\n    \"\"\"\r\n    数据访问层\r\n    status：查询状态,0 查询正常，1 查询失败,默认为0\r\n    \"\"\"\r\n    def __init__(self, host, user, passwd, db):\r\n        self.__host = host\r\n        self.__user = user\r\n        self.__passwd = passwd\r\n        self.__db = db\r\n        self.row0 = None\r\n        self.rowcount = None\r\n        self.msg = ''\r\n        self.status = 0\r\n\r\n    def __conn(self):\r\n        try:\r\n            conn = MySQLdb.connect(host=self.__host, user=self.__user,\r\n                                   passwd=self.__passwd, db=self.__db,\r\n                                   init_command=\"set names utf8;set net_write_timeout=3600;\",\r\n                                   charset='utf8',\r\n                                   # cursorclass=MySQLdb.cursors.SSCursor\r\n                                   )\r\n        except Exception, e:\r\n            self.msg = '%s' % e\r\n            self.status = 1\r\n            conn = None\r\n        return conn\r\n\r\n    def getall(self, sql, paramters=None):\r\n        conn = self.__conn()\r\n        if not conn:\r\n            return None\r\n        try:\r\n            cur = conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)  # 返回字典\r\n            cur.execute(sql, paramters)\r\n            data = cur.fetchall()\r\n            self.rowcount = cur.rowcount\r\n            self.row0 = [d[0] for d in cur.description]\r\n        except Exception, e:\r\n            self.msg = '%s' % e\r\n            self.status = 1\r\n            data = None\r\n        finally:\r\n            cur.close()\r\n            conn.commit()\r\n            conn.close()\r\n        return data\r\n\r\n    def getallmany(self, sql, paramters=None):\r\n        conn = self.__conn()\r\n        if not conn:\r\n            return None\r\n        try:\r\n            cur = conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)  # 返回字典\r\n            cur.executemany(sql, paramters)\r\n            data = cur.fetchall()\r\n        except Exception, e:\r\n            self.msg = '%s' % e\r\n            self.status = 1\r\n            data = None\r\n        finally:\r\n            cur.close()\r\n            conn.commit()\r\n            conn.close()\r\n        return data\r\n\r\n    def getsingle(self, sql, paramters=None):\r\n        conn = self.__conn()\r\n        if not conn:\r\n            return None\r\n        try:\r\n            cur = conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)  # 返回字典\r\n            cur.execute(sql, paramters)\r\n            data = cur.fetchone()\r\n        except Exception, e:\r\n            self.msg = '%s' % e\r\n            self.status = 1\r\n            data = None\r\n        finally:\r\n            cur.close()\r\n            conn.commit()\r\n            conn.close()\r\n        return data\r\n\r\n    def insertmany(self, sql, paramters=None):\r\n        conn = self.__conn()\r\n        if not conn:\r\n            return None\r\n        try:\r\n            cur = conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)  # 返回字典\r\n            cur.executemany(sql, paramters)\r\n        except Exception, e:\r\n            self.msg = '%s' % e\r\n            self.status = 1\r\n        finally:\r\n            cur.close()\r\n            conn.commit()\r\n            conn.close()\r\n        return None\r\n\r\n    def insert(self, sql, paramters=None):\r\n        conn = self.__conn()\r\n        if not conn:\r\n            return None\r\n        try:\r\n            cur = conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)  # 返回字典\r\n            cur.execute(sql, paramters)\r\n            setattr(self, 'insert_id', conn.insert_id())\r\n        except Exception, e:\r\n            self.msg = '%s' % e\r\n            self.status = 1\r\n        finally:\r\n            cur.close()\r\n            conn.commit()\r\n            conn.close()\r\n        return None\r\n\r\n    def getall_list(self, sql, paramters=None):\r\n        # 返回列表形式结果\r\n        conn = self.__conn()\r\n        if not conn:\r\n            return None\r\n        try:\r\n            cur = conn.cursor()  # 返回列表\r\n            cur.execute(sql, paramters)\r\n            data = cur.fetchall()\r\n            self.rowcount = cur.rowcount\r\n            self.row0 = [d[0] for d in cur.description]\r\n        except Exception, e:\r\n            self.msg = '%s' % e\r\n            self.status = 1\r\n            data = None\r\n        finally:\r\n            cur.close()\r\n            conn.commit()\r\n            conn.close()\r\n        return data\r\n\r\n    def getall_list_sqls(self, sqls, paramters=None):\r\n        \"\"\"\r\n            执行多个sql语句，返回列表形式结果\r\n            sqls = [sql1, sql2, ... ...]\r\n        \"\"\"\r\n\r\n        conn = self.__conn()\r\n        if not conn:\r\n            return None\r\n        try:\r\n            cur = conn.cursor()  # 返回列表\r\n            for sql in sqls:\r\n                cur.execute(sql, paramters)\r\n            data = cur.fetchall()\r\n            self.rowcount = cur.rowcount\r\n            self.row0 = [d[0] for d in cur.description]\r\n        except Exception, e:\r\n            self.msg = '%s' % e\r\n            self.status = 1\r\n            data = None\r\n        finally:\r\n            cur.close()\r\n            conn.commit()\r\n            conn.close()\r\n        return data\r\n\r\n    def delete(self, sql, paramters=None):\r\n        conn = self.__conn()\r\n        if not conn:\r\n            return None\r\n        try:\r\n            cur = conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)  # 返回字典\r\n            cur.execute(sql, paramters)\r\n        except Exception, e:\r\n            self.msg = '%s' % e\r\n            self.status = 1\r\n        finally:\r\n            cur.close()\r\n            conn.commit()\r\n            conn.close()\r\n        return None\r\n\r\n    def update(self, sql, paramters=None):\r\n        conn = self.__conn()\r\n        if not conn:\r\n            return None\r\n        try:\r\n            cur = conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)  # 返回字典\r\n            cur.execute(sql, paramters)\r\n        except Exception, e:\r\n            self.msg = '%s' % e\r\n            self.status = 1\r\n        finally:\r\n            cur.close()\r\n            conn.commit()\r\n            conn.close()\r\n        return None\r\n\r\n    def dict_generator(self, sql, paramters=None):\r\n        \"\"\"\r\n        以生成器方式获取数据，用于数据量大的时候\r\n        :param sql:\r\n        :param paramters:\r\n        :return:\r\n        \"\"\"\r\n        conn = self.__conn()\r\n        try:\r\n            if conn:\r\n                cur = conn.cursor(cursorclass=MySQLdb.cursors.SSDictCursor)  # 流式数据返回字典\r\n                cur.execute(sql, paramters)\r\n                self.rowcount = cur.rowcount\r\n                self.row0 = [d[0] for d in cur.description]\r\n                data = cur.fetchone()\r\n                while data:\r\n                    yield data\r\n                    data = cur.fetchone()\r\n                cur.close()\r\n                conn.commit()\r\n                conn.close()\r\n        except Exception, e:\r\n            self.msg = '%s' % e\r\n            self.status = 1\r\n\r\n    def tuple_generator(self, sql, paramters=None):\r\n        \"\"\"\r\n        以生成器方式获取数据，用于数据量大的时候\r\n        :param sql: SQL语句\r\n        :param paramters:\r\n        :param size: 每次提取的行数，默认1000。\r\n        :return: 以生成器的方式返回数据\r\n                 数据格式 row1 = [v1,v2, ...]\r\n                         data = (row1, row2, ...)\r\n        \"\"\"\r\n        conn = self.__conn()\r\n        try:\r\n            if conn:\r\n                # SSCursor 查询结果缓存在server端\r\n                cur = conn.cursor(cursorclass=MySQLdb.cursors.SSCursor)  # 返回元组\r\n                cur.execute(sql, paramters)\r\n                self.rowcount = cur.rowcount\r\n                self.row0 = [d[0] for d in cur.description]\r\n                data = cur.fetchone()\r\n                while data:\r\n                    yield data\r\n                    data = cur.fetchone()\r\n                cur.close()\r\n                conn.commit()\r\n                conn.close()\r\n        except Exception, e:\r\n            self.msg = '%s' % e\r\n            self.status = 1\r\n\r\n    def transaction_start(self):\r\n        conn = self.__conn()\r\n        if not conn:\r\n            return None\r\n        try:\r\n            cur = conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)  # 返回字典\r\n            setattr(self, 'conn', conn)\r\n            setattr(self, 'cur', cur)\r\n        except Exception, e:\r\n            self.msg = 'transaction_start - %s' % e\r\n            self.status = 1\r\n            conn.commit()\r\n            conn.close()\r\n        return None\r\n\r\n    def transaction_execute(self, sql, paramters=None):\r\n        # 事务 insert update delete\r\n        if hasattr(self, 'cur') and hasattr(self, 'conn'):\r\n            try:\r\n                self.cur.execute(sql, paramters)\r\n                setattr(self, 'insert_id', self.conn.insert_id())\r\n            except Exception, e:\r\n                self.msg = 'transaction_insert - %s' % e\r\n                self.status = 1\r\n            return None\r\n\r\n    def transaction_commit_and_close(self):\r\n        # 执行成功提交事务，失败回滚，最后关闭连接\r\n        if hasattr(self, 'cur') and hasattr(self, 'conn'):\r\n            self.cur.close()\r\n            if self.status:\r\n                self.conn.rollback()\r\n            else:\r\n                self.conn.commit()\r\n            self.conn.close()\r\n        return None\r\n\r\n\r\nclass BusinessMysql(MysqlHelper):\r\n    # 业务处理层\r\n    def __init__(self, host, user, passwd, db):\r\n        super(BusinessMysql, self).__init__(host, user, passwd, db)\r\n\r\n    def search(self, sql, para=None):\r\n        return self.getsingle(sql, para)"
  },
  {
    "path": "controller/public/pagination.py",
    "content": "#!/usr/bin/env python\r\n# -*- coding: UTF-8 -*-\r\n\r\nfrom django.core.paginator import Paginator\r\n\r\n\r\nclass Paginator_help:\r\n    # 分页\r\n\r\n    def __init__(self, page_num, queryset, PAGE_SIZE, current_page_total, request):\r\n        self.page_num = self.check_page_num(page_num)  # 当前页码\r\n        self.current_page_total = current_page_total  # 当前页下标\r\n        self.queryset = queryset  # 需要分页的对象集合\r\n        self.PAGE_SIZE = PAGE_SIZE  # 每页显示多少条\r\n        self.pages = self.get_Paginator_obj()  # 获取分页对象\r\n        self.page_range = self.get_page_range()  # 获取当前页的页面下标\r\n        self.qstr = self.get_qstr(request)\r\n        self.current_page = self.get_current_page()  # 获取当前页对象\r\n\r\n    def get_Paginator_obj(self):\r\n        # 获取分页对象\r\n        pages = Paginator(self.queryset, self.PAGE_SIZE)\r\n        return pages\r\n\r\n    def check_page_num(self, page_num):\r\n        # 检查页码\r\n        if page_num <= 0:\r\n            page_num = 1\r\n        return page_num\r\n\r\n    def get_current_page(self):\r\n        # 获取当前页对象\r\n        current_page = self.pages.page(self.page_num)\r\n        return current_page\r\n\r\n    def get_qstr(self, request):\r\n        qstr = '&'.join(['%s=%s' % (k, v) for k, v in request.GET.items() if k != 'p'])\r\n        return qstr\r\n\r\n    def calculate_begin_end(self):\r\n        # 计算当前页下标的取值范围\r\n        page_total = self.pages.num_pages\r\n        begin = 0\r\n        end = 0\r\n        if page_total <= self.current_page_total:\r\n            begin = 0\r\n            end = page_total\r\n        else:\r\n            if self.page_num <= self.current_page_total / 2:\r\n                begin = 0\r\n                end = self.current_page_total\r\n            else:\r\n                begin = self.page_num - self.current_page_total / 2\r\n                end = self.page_num + self.current_page_total / 2\r\n                if (self.current_page_total % 2) != 0:  # 如果分页下标为奇数\r\n                    end += 1\r\n                if end > page_total:\r\n                    end = page_total\r\n                    begin = page_total - self.current_page_total\r\n        return begin, end\r\n\r\n    def get_page_range(self):\r\n        # 获取当前页的页面下标\r\n        begin, end = self.calculate_begin_end()\r\n\r\n        # 草了，1.9的Paginator分页类的page_range方法得到的尽然是xrange,用[begin:end]切片报错\r\n        page_range = [i for i in self.pages.page_range]\r\n        page_range = page_range[begin:end]\r\n\r\n        return page_range\r\n\r\n\r\nclass Paginator_ajax(object):\r\n    # bootstrap-table 插件 后端分页\r\n\r\n    def __init__(self, offset, queryset, PAGE_SIZE):\r\n        self.page_num = offset/PAGE_SIZE + 1  # 当前页码\r\n        self.queryset = queryset  # 需要分页的对象集合\r\n        self.PAGE_SIZE = PAGE_SIZE  # 每页显示多少条\r\n        self.pages = self.get_Paginator_obj  # 获取分页对象\r\n        self.current_page = self.get_current_page  # 获取当前页对象\r\n        self.total = self.pages.count # queryset 对象集合的总数\r\n        self.rows = self._get_rows\r\n\r\n\r\n    @property\r\n    def get_current_page(self):\r\n        # 获取当前页对象\r\n        return self.pages.page(self.page_num)\r\n\r\n    @property\r\n    def get_Paginator_obj(self):\r\n        # 获取分页对象\r\n        return Paginator(self.queryset, self.PAGE_SIZE)\r\n\r\n    @property\r\n    def _get_rows(self):\r\n        return list(self.current_page)\r\n\r\n    @property\r\n    def data(self):\r\n        return {'total': self.total, 'rows': self.rows}\r\n\r\n\r\nclass Paginator_sql(object):\r\n    # bootstrap-table 插件 后端分页\r\n    # sql 连接远程数据库查询 分页\r\n    def __init__(self, offset, queryset, PAGE_SIZE):\r\n\r\n        self.offset = offset # 偏移量\r\n        self.PAGE_SIZE = PAGE_SIZE  # 每页显示多少条\r\n\r\n        self.page_num = offset/PAGE_SIZE + 1  # 当前页码\r\n        self.queryset = queryset  # 需要分页的对象集合\r\n        self.pages = self.get_Paginator_obj  # 获取分页对象\r\n        self.current_page = self.get_current_page  # 获取当前页对象\r\n        self.total = self.pages.count # queryset 对象集合的总数\r\n        self.rows = self._get_rows\r\n\r\n\r\n    @property\r\n    def get_current_page(self):\r\n        # 获取当前页对象\r\n        return self.pages.page(self.page_num)\r\n\r\n    @property\r\n    def get_Paginator_obj(self):\r\n        # 获取分页对象\r\n        return Paginator(self.queryset, self.PAGE_SIZE)\r\n\r\n    @property\r\n    def _get_rows(self):\r\n        return list(self.current_page)\r\n\r\n    @property\r\n    def data(self):\r\n        return {'total': self.total, 'rows': self.rows}"
  },
  {
    "path": "controller/public/sqlserver_helper.py",
    "content": "#!/usr/bin/python env\r\n# -*- coding: UTF-8 -*-\r\n# Description:                    \r\n# Author:           黄小雪\r\n# Date:             2017年11月03日\r\n# Company:          东方银谷\r\n\r\nimport pymssql\r\n\r\nclass SqlserverHelper(object):\r\n    \"\"\"\r\n    数据访问层\r\n    status：查询状态,0 查询正常，1 查询失败,默认为 0\r\n    \"\"\"\r\n    def __init__(self, host, user, passwd, db):\r\n        self.__host = host\r\n        self.__user = user\r\n        self.__passwd = passwd\r\n        self.__db = db\r\n        self.row0 = None\r\n        self.rowcount = None\r\n        self.msg = ''\r\n        self.status = 0\r\n\r\n    def __conn(self):\r\n        try:\r\n            conn = pymssql.connect(server=self.__host, user=self.__user,\r\n                                   password=self.__passwd, database=self.__db,\r\n                                   # init_command=\"set names utf8\",\r\n                                   charset='utf8')\r\n        except Exception, e:\r\n            self.msg = '%s' % e\r\n            self.status = 1\r\n            conn = None\r\n        return conn\r\n\r\n    def getall(self, sql, paramters=None):\r\n        conn = self.__conn()\r\n        if not conn:\r\n            return None\r\n        try:\r\n            cur = conn.cursor(as_dict=True)  # 返回字典\r\n            cur.execute(sql, paramters)\r\n            data = cur.fetchall()\r\n            self.rowcount = cur.rowcount\r\n            self.row0 = [d[0] for d in cur.description]\r\n        except Exception, e:\r\n            self.msg = '%s' % e\r\n            self.status = 1\r\n            data = None\r\n        finally:\r\n            cur.close()\r\n            conn.commit()\r\n            conn.close()\r\n        return data\r\n\r\n    def getallmany(self, sql, paramters=None):\r\n        conn = self.__conn()\r\n        if not conn:\r\n            return None\r\n        try:\r\n            cur = conn.cursor(as_dict=True)  # 返回字典\r\n            cur.executemany(sql, paramters)\r\n            data = cur.fetchall()\r\n        except Exception, e:\r\n            self.msg = '%s' % e\r\n            self.status = 1\r\n            data = None\r\n        finally:\r\n            cur.close()\r\n            conn.commit()\r\n            conn.close()\r\n        return data\r\n\r\n    def getsingle(self, sql, paramters=None):\r\n        conn = self.__conn()\r\n        if not conn:\r\n            return None\r\n        try:\r\n            cur = conn.cursor(as_dict=True)  # 返回字典\r\n            cur.execute(sql, paramters)\r\n            data = cur.fetchone()\r\n        except Exception, e:\r\n            self.msg = '%s' % e\r\n            self.status = 1\r\n            data = None\r\n        finally:\r\n            cur.close()\r\n            conn.commit()\r\n            conn.close()\r\n        return data\r\n\r\n    def insertmany(self, sql, paramters=None):\r\n        conn = self.__conn()\r\n        if not conn:\r\n            return None\r\n        try:\r\n            cur = conn.cursor(as_dict=True)  # 返回字典\r\n            cur.executemany(sql, paramters)\r\n        except Exception, e:\r\n            self.msg = '%s' % e\r\n            self.status = 1\r\n        finally:\r\n            cur.close()\r\n            conn.commit()\r\n            conn.close()\r\n        return None\r\n\r\n    def insert(self, sql, paramters=None):\r\n        conn = self.__conn()\r\n        if not conn:\r\n            return None\r\n        try:\r\n            cur = conn.cursor(as_dict=True)  # 返回字典\r\n            cur.execute(sql, paramters)\r\n        except Exception, e:\r\n            self.msg = '%s' % e\r\n            self.status = 1\r\n        finally:\r\n            cur.close()\r\n            conn.commit()\r\n            conn.close()\r\n        return None\r\n\r\n    def getall_list(self, sql, paramters=None):\r\n        # 返回列表形式结果\r\n        conn = self.__conn()\r\n        if not conn:\r\n            return None\r\n        try:\r\n            cur = conn.cursor()  # 返回列表\r\n            cur.execute(sql, paramters)\r\n            data = cur.fetchall()\r\n            self.rowcount = cur.rowcount\r\n            self.row0 = [d[0] for d in cur.description]\r\n        except Exception, e:\r\n            self.msg = '%s' % e\r\n            self.status = 1\r\n            data = None\r\n        finally:\r\n            cur.close()\r\n            conn.commit()\r\n            conn.close()\r\n        return data\r\n\r\n    def getall_list_sqls(self, sqls, paramters=None):\r\n        \"\"\"\r\n            执行多个sql语句，返回列表形式结果\r\n            sqls = [sql1, sql2, ... ...]\r\n        \"\"\"\r\n\r\n        conn = self.__conn()\r\n        if not conn:\r\n            return None\r\n        try:\r\n            cur = conn.cursor()  # 返回列表\r\n            for sql in sqls:\r\n                cur.execute(sql, paramters)\r\n            data = cur.fetchall()\r\n            self.rowcount = cur.rowcount\r\n            self.row0 = [d[0] for d in cur.description]\r\n        except Exception, e:\r\n            self.msg = '%s' % e\r\n            self.status = 1\r\n            data = None\r\n        finally:\r\n            cur.close()\r\n            conn.commit()\r\n            conn.close()\r\n        return data\r\n\r\n    def delete(self, sql, paramters=None):\r\n        conn = self.__conn()\r\n        if not conn:\r\n            return None\r\n        try:\r\n            cur = conn.cursor(as_dict=True)  # 返回字典\r\n            cur.execute(sql, paramters)\r\n        except Exception, e:\r\n            self.msg = '%s' % e\r\n            self.status = 1\r\n        finally:\r\n            cur.close()\r\n            conn.commit()\r\n            conn.close()\r\n        return None\r\n\r\n    def dict_generator(self, sql, paramters=None):\r\n        \"\"\"\r\n        以生成器方式获取数据，用于数据量大的时候\r\n        :param sql:\r\n        :param paramters:\r\n        :return:\r\n        \"\"\"\r\n        conn = self.__conn()\r\n        try:\r\n            if conn:\r\n                cur = conn.cursor(as_dict=True)  # 返回字典\r\n                cur.execute(sql, paramters)\r\n                self.rowcount = cur.rowcount\r\n                self.row0 = [d[0] for d in cur.description]\r\n                data = cur.fetchone()\r\n                while data:\r\n                    yield data\r\n                    data = cur.fetchone()\r\n                cur.close()\r\n                conn.commit()\r\n                conn.close()\r\n        except Exception, e:\r\n            self.msg = '%s' % e\r\n            self.status = 1\r\n\r\n    def tuple_generator(self, sql, paramters=None):\r\n        \"\"\"\r\n        以生成器方式获取数据，用于数据量大的时候\r\n        :param sql:\r\n        :param paramters:\r\n        :return:\r\n        \"\"\"\r\n        conn = self.__conn()\r\n        try:\r\n            if conn:\r\n                cur = conn.cursor()  # 返回字典\r\n                cur.execute(sql, paramters)\r\n                self.rowcount = cur.rowcount\r\n                self.row0 = [d[0] for d in cur.description]\r\n                data = cur.fetchone()\r\n                while data:\r\n                    yield data\r\n                    data = cur.fetchone()\r\n                cur.close()\r\n                conn.commit()\r\n                conn.close()\r\n        except Exception, e:\r\n            self.msg = '%s' % e\r\n            self.status = 1\r\n\r\n\r\nclass BusinessSqlserver(SqlserverHelper):\r\n    # 业务处理层\r\n    def __init__(self, host, user, passwd, db):\r\n        super(BusinessSqlserver, self).__init__(host, user, passwd, db)\r\n\r\n    def search(self, sql, para=None):\r\n        return self.getsingle(sql, para)"
  },
  {
    "path": "create_table.sql",
    "content": "/*\r\n* 创建数据库\r\n*/\r\ncreate database FirstBlood default character set utf8 collate utf8_bin;\r\n\r\n/* 进入数据库 */\r\nuse FirstBlood;\r\n\r\n\r\n/*\r\n* 数据库信息\r\n*/\r\nCREATE TABLE `databaseinfo` (\r\n  `id` int(11) NOT NULL AUTO_INCREMENT,\r\n  `name` varchar(255) DEFAULT NULL COMMENT '名称',\r\n  `description` varchar(255) DEFAULT NULL COMMENT '描述',\r\n  `host` varchar(255) DEFAULT NULL COMMENT '主机',\r\n  `user` varchar(255) DEFAULT NULL COMMENT '用户',\r\n  `passwd` varchar(255) DEFAULT NULL COMMENT '密码',\r\n  `db` varchar(255) DEFAULT NULL COMMENT '数据库',\r\n  `type` varchar(255) DEFAULT NULL COMMENT '类型',\r\n  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\r\n  `modify_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',\r\n  PRIMARY KEY (`id`),\r\n  UNIQUE KEY `databaseinfo_host_c254f05e_uniq` (`host`),\r\n  UNIQUE KEY `databaseinfo_name_a3bc8190_uniq` (`name`)\r\n) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8 COMMENT='数据库信息';\r\n\r\n\r\n/*\r\n* 数据同步任务\r\n*/\r\ndrop table if exists `datax_job`;\r\nCREATE TABLE `datax_job` (\r\n  `id` int(11) NOT NULL AUTO_INCREMENT,\r\n  `name` varchar(255) DEFAULT NULL COMMENT '名称',\r\n  `description` varchar(255) DEFAULT NULL COMMENT '描述',\r\n  `querySql` longtext COLLATE utf8_bin NOT NULL COMMENT '查询SQL语句',\r\n  `reader_databaseinfo_id` int(11) NOT NULL COMMENT '读取数据库',\r\n  `writer_table` varchar(255) DEFAULT NULL COMMENT '写入表名',\r\n  `writer_databaseinfo_id` int(11) NOT NULL COMMENT '写入数据库',\r\n  `writer_preSql` longtext COLLATE utf8_bin NOT NULL COMMENT '写入数据前执行的SQL语句',\r\n  `writer_postSql` longtext COLLATE utf8_bin NOT NULL COMMENT '写入数据后执行的SQL语句',\r\n  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\r\n  `modify_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',\r\n  PRIMARY KEY (`id`),\r\n  UNIQUE KEY `datax_job_name_uniq` (`name`)\r\n) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8 COMMENT='datax数据同步任务';\r\n\r\n\r\n/*\r\n* 写入表的列信息\r\n*/\r\ndrop table if exists `datax_job_writer_column`;\r\nCREATE TABLE `datax_job_writer_column` (\r\n  `id` int(11) NOT NULL AUTO_INCREMENT,\r\n  `name` varchar(255) DEFAULT NULL COMMENT '列名',\r\n  `datax_job_id` int(11) NOT NULL COMMENT '数据同步任务ID',\r\n  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\r\n  `modify_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',\r\n  PRIMARY KEY (`id`)\r\n) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8 COMMENT='写入表的列信息';\r\n\r\n\r\n/*\r\n* 数据同步任务实例\r\n*/\r\ndrop table if exists `datax_job_instance`;\r\nCREATE TABLE `datax_job_instance` (\r\n  `id` int(11) NOT NULL AUTO_INCREMENT,\r\n  `instance_id` bigint(20) NOT NULL COMMENT '任务实例ID',\r\n  `name` varchar(255) DEFAULT NULL COMMENT '名称',\r\n  `description` varchar(255) DEFAULT NULL COMMENT '描述',\r\n  `querySql` longtext COLLATE utf8_bin NOT NULL COMMENT '查询SQL语句',\r\n  `reader_databaseinfo_host` varchar(255) NOT NULL COMMENT '读取数据库IP',\r\n  `reader_databaseinfo_description` varchar(255) NOT NULL COMMENT '读取数据库描述',\r\n  `writer_table` varchar(255) DEFAULT NULL COMMENT '写入表名',\r\n  `writer_databaseinfo_host` varchar(255) NOT NULL COMMENT '写入数据库IP',\r\n  `writer_databaseinfo_description` varchar(255) NOT NULL COMMENT '写入数据库描述',\r\n  `writer_preSql` longtext COLLATE utf8_bin NOT NULL COMMENT '写入数据前执行的SQL语句',\r\n  `writer_postSql` longtext COLLATE utf8_bin NOT NULL COMMENT '写入数据后执行的SQL语句',\r\n  `trigger_mode` int(2) DEFAULT '1' COMMENT '触发模式 1 自动 2 手动（默认自动）',\r\n  `status` int(2) DEFAULT '0' COMMENT '状态 0 正在执行 1 执行完成',\r\n  `result` int(2) DEFAULT '2' COMMENT '执行结果 0 成功 1 失败 2 未知',\r\n  `start_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '开始时间',\r\n  `end_time` datetime DEFAULT NULL COMMENT '结束时间',\r\n  PRIMARY KEY (`id`),\r\n  UNIQUE KEY `datax_job_instance_id_uniq` (`instance_id`)\r\n) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8 COMMENT='datax数据同步任务实例';\r\n\r\n\r\n/*\r\n* 批处理作业\r\n*/\r\ndrop table if exists `batch_job`;\r\nCREATE TABLE `batch_job` (\r\n  `id` int(11) NOT NULL AUTO_INCREMENT,\r\n  `name` varchar(255) DEFAULT NULL COMMENT '名称',\r\n  `description` varchar(255) DEFAULT NULL COMMENT '描述',\r\n  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\r\n  `modify_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',\r\n  PRIMARY KEY (`id`),\r\n  UNIQUE KEY `batch_job_name_uniq` (`name`)\r\n) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8 COMMENT='批处理作业';\r\n\r\n\r\n/*\r\n* 批处理作业详情\r\n*/\r\ndrop table if exists `batch_job_details`;\r\nCREATE TABLE `batch_job_details` (\r\n  `id` int(11) NOT NULL AUTO_INCREMENT,\r\n  `batch_job_id` int(11) NOT NULL COMMENT '批处理作业ID',\r\n  `subjob_id` int(11) NOT NULL COMMENT '子作业ID',\r\n  `type` int(2) NOT NUll COMMENT '类型 1 数据同步 2 SQL脚本 3 备份。 主要用于后期扩展',\r\n  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\r\n  `modify_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',\r\n  PRIMARY KEY (`id`)\r\n) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8 COMMENT='批处理作业详情';\r\n\r\n\r\n/*\r\n* 批处理作业执行实例\r\n*/\r\ndrop table if exists `batch_job_instance`;\r\nCREATE TABLE `batch_job_instance` (\r\n  `id` int(11) NOT NULL AUTO_INCREMENT,\r\n  `instance_id` bigint(20) NOT NULL COMMENT '实例ID',\r\n  `name` varchar(255) DEFAULT NULL COMMENT '名称',\r\n  `description` varchar(255) DEFAULT NULL COMMENT '描述',\r\n  `trigger_mode` int(2) DEFAULT '1' COMMENT '触发模式 1 自动 2 手动（默认自动）',\r\n  `status` int(2) DEFAULT '0' COMMENT '状态 0 正在执行 1 执行完成',\r\n  `result` int(2) DEFAULT '2' COMMENT '执行结果 0 成功 1 失败 2 未知',\r\n  `start_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '开始时间',\r\n  `end_time` datetime DEFAULT NULL COMMENT '结束时间',\r\n  PRIMARY KEY (`id`),\r\n  UNIQUE KEY `batch_job_instance_id_uniq` (`instance_id`)\r\n) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8 COMMENT='批处理作业执行实例';\r\n\r\n\r\n/*\r\n* 批处理作业执行实例详情\r\n*/\r\ndrop table if exists `batch_job_instance_details`;\r\nCREATE TABLE `batch_job_instance_details` (\r\n  `id` int(11) NOT NULL AUTO_INCREMENT,\r\n  `instance_id` bigint(20) NOT NULL COMMENT '实例ID',\r\n  `subjob_instance_id` bigint(20) NOT NULL COMMENT '子作业实例ID',\r\n  `type` int(2) NOT NUll COMMENT '类型 1 数据同步 2 SQL脚本 3 备份。 主要用于后期扩展',\r\n  PRIMARY KEY (`id`)\r\n) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8 COMMENT='批处理作业执行实例详情';\r\n\r\n"
  },
  {
    "path": "datax_web/__init__.py",
    "content": ""
  },
  {
    "path": "datax_web/admin.py",
    "content": "from django.contrib import admin\n\n# Register your models here.\n"
  },
  {
    "path": "datax_web/apps.py",
    "content": "from __future__ import unicode_literals\n\nfrom django.apps import AppConfig\n\n\nclass DataxWebConfig(AppConfig):\n    name = 'datax_web'\n"
  },
  {
    "path": "datax_web/conf/__init__.py",
    "content": ""
  },
  {
    "path": "datax_web/conf/config.py",
    "content": "#!/usr/bin/python env\r\n# -*- coding: UTF-8 -*-\r\nimport sys\r\nimport os\r\nreload(sys)\r\nsys.setdefaultencoding(\"utf-8\")\r\n\r\n_parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\r\n_FirstBlood_dir = os.path.dirname(_parentdir)\r\nsys.path.append(_parentdir)\r\nsys.path.append(_FirstBlood_dir)\r\n\r\n_log_file_dir = _FirstBlood_dir + '/log/'\r\nimg_dir = _FirstBlood_dir + '/static/img/'\r\n\r\n# datax job 路径\r\ndatax_dir = _FirstBlood_dir + '/datax'\r\ndatax_job_dir = '/tmp'\r\ndatax_log_dir = datax_dir + '/web_log'\r\n\r\n# 数据申请定时任务执行日志\r\nscheduled_tasks_log_file = _log_file_dir + u'scheduled_tasks.log'\r\n# 日志主键\r\nprimary_key = 'task_instance_id'\r\n# 定时任务实例状态 1:开始执行 2:正在执行 3:执行完成\r\nstatus = [1, 2, 3]\r\n\r\n# 响应类型\r\nRESPONSE_TYPE = dict(small=1, large=2, html=3)\r\n# 操作类型\r\nOPERATION_TYPE = ['add', 'mod']\r\n# 触发模式\r\nTRIGGER_MODE = [1, 2]  # 1 自动  2 手动\r\n# 数据库类型\r\nDATABASE_TYPE = 'mysql'\r\n\r\n# 以名称查询任务\r\nquery_datax_job_by_name_sql = \"SELECT * FROM FirstBlood.datax_job dj WHERE dj.`name` = '%s';\"\r\n# 以名称和ID查询任务\r\nquery_datax_job_sql2 = \"SELECT * FROM FirstBlood.datax_job dj WHERE dj.`name` = '%s' and dj.id!=%s;\"\r\n# 以ID查询任务\r\nquery_datax_job_by_id_sql = \"\"\"\r\nSELECT\r\n\tdj.*,\r\n\t( SELECT GROUP_CONCAT( djwc.`name` SEPARATOR '\\n' ) FROM FirstBlood.datax_job_writer_column djwc WHERE djwc.datax_job_id = dj.id ) writer_column_id \r\nFROM\r\n\tFirstBlood.datax_job dj \r\nWHERE\r\n\tdj.id = %s;\r\n\"\"\"\r\n# 以ID查询数据同步任务需要写入的列\r\nquery_datax_job_writer_column_by_id_sql = \"\"\"\r\nSELECT\r\n  * \r\nFROM\r\n\tFirstBlood.datax_job_writer_column\r\nWHERE\r\n\tdatax_job_id = %s\r\norder by id;\r\n\"\"\"\r\n\r\n# 查询所有任务\r\nquery_datax_job_sql = \"\"\"\r\nSELECT\r\n\tdj.id,\r\n\tdj.`name`,\r\n\tdj.description,\r\n\tdj.querySql,\r\n\tconcat(rdbi.description,'  ', rdbi.`host`) reader_databaseinfo_id,\r\n\tdj.writer_table,\r\n\tconcat(wdbi.description,'  ', wdbi.`host`) writer_databaseinfo_id,\r\n\tdj.create_time,\r\n\tdj.modify_time\r\nFROM\r\n\tFirstBlood.datax_job dj\r\nLEFT JOIN FirstBlood.databaseinfo rdbi on dj.reader_databaseinfo_id=rdbi.id\r\nLEFT JOIN FirstBlood.databaseinfo wdbi on dj.writer_databaseinfo_id=wdbi.id\r\n\"\"\"\r\n\r\ninsert_datax_job_sql = \"\"\"\r\nINSERT INTO FirstBlood.datax_job (\r\n    `name`,\r\n    `description`,\r\n    `querySql`,\r\n    `reader_databaseinfo_id`,\r\n    `writer_table`,\r\n    `writer_databaseinfo_id`,\r\n    `writer_preSql`,\r\n    `writer_postSql`\r\n) VALUES\r\n  ('%s','%s','%s',%s,'%s',%s,'%s','%s')\r\n\"\"\"\r\n\r\ninsert_datax_job_writer_column_sql = \"\"\"\r\nINSERT INTO FirstBlood.datax_job_writer_column (`name`, `datax_job_id`) VALUES\r\n\"\"\"\r\n\r\nupdate_datax_job_by_id_sql = \"\"\"\r\nupdate FirstBlood.datax_job set\r\n    `name` = '%s',\r\n    `description` = '%s',\r\n    `querySql` = '%s',\r\n    `reader_databaseinfo_id` = %s,\r\n    `writer_table` = '%s',\r\n    `writer_databaseinfo_id` = %s,\r\n    `writer_preSql` = '%s',\r\n    `writer_postSql` = '%s'\r\nwhere\r\n   id = %s\r\n\"\"\"\r\n\r\ndelete_datax_job_writer_column_by_id_sql = \"\"\"\r\ndelete from FirstBlood.datax_job_writer_column where datax_job_id =%s;\r\n\"\"\"\r\n\r\ninsert_datax_job_instance_sql = \"\"\"\r\ninsert into FirstBlood.datax_job_instance (\r\n    `instance_id`,\r\n    `name`,\r\n    `description`,\r\n    `querySql`,\r\n    `reader_databaseinfo_host`,\r\n    `reader_databaseinfo_description`,\r\n    `writer_table`,\r\n    `writer_databaseinfo_host`,\r\n    `writer_databaseinfo_description`,\r\n    `trigger_mode`,\r\n    `writer_preSql`,\r\n    `writer_postSql`\r\n)\r\nvalues (%s, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %s, '%s', '%s');\r\n\"\"\"\r\n\r\n\r\nupdate_datax_job_instance_by_instance_id_sql = \"\"\"\r\nupdate FirstBlood.datax_job_instance set `status`=%s, `result`=%s, `end_time`='%s' where instance_id=%s;\r\n\"\"\"\r\n\r\nselect_datax_job_instance_sql = \"\"\"\r\nselect\r\n  dji.id,\r\n  dji.instance_id,\r\n  dji.`name`,\r\n  dji.description,\r\n  dji.querySql,\r\n  concat(dji.reader_databaseinfo_description,' ',dji.reader_databaseinfo_host) 'reader_databaseinfo_host',\r\n  dji.writer_table,\r\n  concat(dji.writer_databaseinfo_description,' ',dji.writer_databaseinfo_host) 'writer_databaseinfo_host',\r\n  dji.writer_preSql,\r\n  dji.writer_postSql,\r\n  dji.trigger_mode,\r\n  dji.`status`,\r\n  dji.result,\r\n  dji.start_time,\r\n  dji.end_time\r\nFROM\r\n\tFirstBlood.datax_job_instance dji\r\n\"\"\"\r\n\r\ncount_datax_job_instance_sql = \"\"\"\r\nSELECT\r\n\tcount(1) count\r\nFROM\r\n\tFirstBlood.datax_job_instance dji\r\n\"\"\"\r\n\r\nselect_datax_job_instance_by_id_sql = select_datax_job_instance_sql + \"\\n where dji.id = %s\"\r\n\r\n\r\ndatax_job_template = \"\"\"\r\n{\r\n    \"job\": {\r\n        \"content\": [\r\n            {\r\n                \"reader\": {\r\n                    \"name\": \"mysqlreader\",\r\n                    \"parameter\": {\r\n                        \"connection\": [\r\n                            {\r\n                                \"jdbcUrl\": [\"%s\"],\r\n                                \"querySql\": [\"%s\"],\r\n                            }\r\n                        ],\r\n                        \"password\": \"%s\",\r\n                        \"username\": \"%s\",\r\n                        \"where\": \"\"\r\n                    }\r\n                },\r\n                \"writer\": {\r\n                    \"name\": \"mysqlwriter\",\r\n                    \"parameter\": {\r\n                        \"column\": %s,\r\n                        \"connection\": [\r\n                            {\r\n                                \"jdbcUrl\": \"%s\",\r\n                                \"table\": [\"%s\"]\r\n                            }\r\n                        ],\r\n                        \"password\": \"%s\",\r\n                        \"preSql\": [%s],\r\n                        \"postSql\": [%s],\r\n                        \"session\": [],\r\n                        \"username\": \"%s\",\r\n                        \"writeMode\": \"insert\"\r\n                    }\r\n                }\r\n            }\r\n        ],\r\n        \"setting\": {\r\n            \"speed\": {\r\n                      \"record\": \"1000\"\r\n            }\r\n        }\r\n    }\r\n}\r\n\"\"\""
  },
  {
    "path": "datax_web/models.py",
    "content": "from __future__ import unicode_literals\n\nfrom django.db import models\n\n# Create your models here.\n"
  },
  {
    "path": "datax_web/tests.py",
    "content": "# -*- coding: UTF-8 -*-\nfrom django.test import TestCase\n\n# Create your tests here.\n\n#!/usr/bin/python\n\n# Copyright 2013 Joe Walnes and the websocketd team.\n# All rights reserved.\n# Use of this source code is governed by a BSD-style\n# license that can be found in the LICENSE file.\n\nimport time\nfrom sys import stdin, stdout\n\ndef follow(thefile):\n    thefile.seek(0,2)\n    while True:\n        line = thefile.readline()\n        if not line:\n            time.sleep(1)\n            continue\n        yield line\n\nlog_dir = '/opt/django/FirstBlood/datax/web_log/%s.json.log'\n\nfile_id = stdin.readline().strip()\nlogfile = log_dir % file_id\nprint('Hello fuck %s!' % logfile)\nstdout.flush() # Remember to flush\n\n\n# For each line FOO received on STDIN, respond with \"Hello FOO!\".\nlogfile_open = open(logfile, 'r')\nloglines = follow(logfile_open)\nprint 'ok'\nfor line in loglines:\n    print line,\n    stdout.flush() # Remember to flush\n"
  },
  {
    "path": "datax_web/urls.py",
    "content": "# -*- coding: UTF-8 -*-\nfrom django.conf.urls import url\nimport views\n\nurlpatterns = [\n    # Examples:\n    # url(r'^$', 'YinguOnline.views.home', name='home'),\n    # url(r'^blog/', include('blog.urls')),\n\n   url(r'^index/$', views.index),  # 数据同步\n   url(r'^add_job/$', views.add_job),  # 新增任务\n   url(r'^monitor_job/$', views.monitor_job),  # 任务执行实例\n   url(r'^monitor_job_detail/(?P<id>\\d+)/$', views.monitor_job_detail),  # 任务执行详情\n   url(r'^update_job/(?P<id>\\d+)/$', views.update_job),  # 更新任务\n   url(r'^get_database/$', views.get_database),  # 获取数据库信息\n   url(r'^add_job_data/$', views.add_job_data),  # 新增或修改任务数据\n   url(r'^get_job_data/$', views.get_job_data),  # 获取任务数据\n   url(r'^get_update_job_data/$', views.get_update_job_data),  # 获取需要更新的任务数据\n   url(r'^get_datax_job_instance/$', views.get_datax_job_instance),  # 获取任务实例数据\n   url(r'^get_datax_job_instance_by_id/$', views.get_datax_job_instance_by_id),  # 根据ID获取任务实例数据\n   url(r'^run_job/$', views.run_job),  # 运行 任务\n   url(r'^get_database/$', views.get_database),  # 获取数据库信息\n]\n\n\n"
  },
  {
    "path": "datax_web/views.py",
    "content": "# -*- coding: UTF-8 -*-\nfrom django.contrib.auth.decorators import permission_required\nfrom django.contrib.auth.decorators import login_required\nfrom django.core.exceptions import PermissionDenied\nfrom django.shortcuts import render\nfrom django.http import HttpResponse\nfrom functools import wraps\nfrom controller.core.public import (Currency, DatetimeHelp)\nfrom controller.core import query_sql\nfrom controller.public import dataconn\nfrom celery import shared_task\nfrom conf import config\nimport commands\nimport logging\nimport sys\nimport json\nreload(sys)\nsys.setdefaultencoding(\"utf-8\")\n\n\nlogger = logging.getLogger('datax_web')\n_SUCCESS = dict(status=0, msg=u'检测成功')\n_str = (str, unicode)\n\ndef verification(check_class):\n    \"\"\"\n    装饰器用于检测用户提交的信息是否合法.\n    check_class 检测类\n    Decorator for views that checks that the user submitted information,\n    redirecting to the log-in page if necessary. The test should be a callable\n    that takes the user object and returns True if the user passes.\n    \"\"\"\n\n    def decorator(view_func):\n        @wraps(view_func)\n        def _wrapped_view(request, *args, **kwargs):\n            response = HttpResponse()\n            ccl = check_class(request)\n            result = ccl.total_check()\n            if result['status']:\n                response.write(json.dumps(result))\n                return response\n\n            return view_func(request, *args, **kwargs)\n        return _wrapped_view\n    return decorator\n\n\nclass JobData(object):\n    \"\"\"\n    新增或更新定时任务时处理数据\n    data 数据格式\n\n    {u'_id': u'28',\n     u'description': u'\\u6570\\u636e\\u540c\\u6b65\\u6d4b\\u8bd5',\n     u'name': u'test',\n     u'operation_type': u'mod',\n     u'querySql': u'select * from `admin-service`.as_user_info limit 10;',\n     u'reader_databaseinfo_id': u'1',\n     u'trigger_mode': 2,\n     u'writer_column_id': [u'*'],\n     u'writer_databaseinfo_id': u'22',\n     u'writer_postSql': u'',\n     u'writer_preSql': u'truncate table `admin-service`.as_user_info;',\n     u'writer_table': u'`admin-service`.as_user_info'}\n\n     _id: datax_job_id\n    \"\"\"\n    def __init__(self, data):\n        # id 为 datax_job_id\n        self.id = data.get('_id', 0)\n        self.name = data.get('name', '')\n        self.description = data.get('description', '')\n        self.querySql = data.get('querySql', '')\n        self.reader_databaseinfo_id = data.get('reader_databaseinfo_id', '')\n        self.writer_table = data.get('writer_table', '')\n        self.writer_column = data.get('writer_column_id', [])\n        self.writer_databaseinfo_id = data.get('writer_databaseinfo_id', '')\n        self.writer_preSql = data.get('writer_preSql', '')\n        self.writer_postSql = data.get('writer_postSql', '')\n        self.operation_type = data.get('operation_type', '')\n        self.trigger_mode = data.get('trigger_mode', '')\n\n        self.dtconn = dataconn.DatabaseConnection(logger)\n        self.dtsf = dataconn.DataTransform()\n        self.dh = DatetimeHelp()\n        self.__timestamp1 = self.dh.timestamp1\n\n        self.reader_dtbs = self._get_reader_dtbs() if self.reader_databaseinfo_id else None\n        self.writer_dtbs = self._get_writer_dtbs() if self.writer_databaseinfo_id else None\n\n    @property\n    def timestamp1(self):\n        return self.__timestamp1\n\n    def _get_reader_dtbs(self):\n        return self.dtconn.get_datainfo_by_id(self.reader_databaseinfo_id)\n\n    def _get_writer_dtbs(self):\n        return self.dtconn.get_datainfo_by_id(self.writer_databaseinfo_id)\n\n    def get_insert_datax_job_sql(self):\n        # 在 datax_job表里创建新的任务  -  新增SQL\n        querySql = self.dtsf.special_characters_mysql(self.querySql)\n        writer_preSql = self.dtsf.special_characters_mysql(self.writer_preSql)\n        writer_postSql = self.dtsf.special_characters_mysql(self.writer_postSql)\n\n        return config.insert_datax_job_sql % (\n            self.name, self.description, querySql, self.reader_databaseinfo_id,\n            self.writer_table, self.writer_databaseinfo_id, writer_preSql, writer_postSql\n        )\n\n    def get_update_datax_job_by_id_sql(self):\n        # 在 datax_job表里更新任务  - 更新SQL\n        querySql = self.dtsf.special_characters_mysql(self.querySql)\n        writer_preSql = self.dtsf.special_characters_mysql(self.writer_preSql)\n        writer_postSql = self.dtsf.special_characters_mysql(self.writer_postSql)\n\n        return config.update_datax_job_by_id_sql % (\n            self.name, self.description, querySql, self.reader_databaseinfo_id,\n            self.writer_table, self.writer_databaseinfo_id, writer_preSql, writer_postSql,\n            self.id\n        )\n\n    def get_insert_datax_job_writer_column_sql(self):\n        # 拼接写入列SQL  insert into  values ('user_id', 1), ('card_name', 1)\n        datax_job_id = self.id or self.dtconn.ygol.insert_id\n        values_list =   [\"('%s', %s)\" % (column, datax_job_id) for column in self.writer_column]\n        return config.insert_datax_job_writer_column_sql + ','.join(values_list)\n\n    def get_delete_datax_job_writer_column_by_id_sql(self):\n        # 获取删除写入列SQL ， 根据ID删除\n        return config.delete_datax_job_writer_column_by_id_sql % self.id\n\n    def get_insert_datax_job_instance_sql(self):\n        querySql = self.dtsf.special_characters_mysql(self.querySql)\n        writer_preSql = self.dtsf.special_characters_mysql(self.writer_preSql)\n        writer_postSql = self.dtsf.special_characters_mysql(self.writer_postSql)\n\n        return config.insert_datax_job_instance_sql % (\n            self.datax_job_instance_id,\n            self.name,\n            self.description,\n            querySql,\n            self.reader_dtbs['host'],\n            self.reader_dtbs['description'],\n            self.writer_table,\n            self.writer_dtbs['host'],\n            self.writer_dtbs['description'],\n            self.trigger_mode,\n            writer_preSql,\n            writer_postSql\n        )\n\n    def get_update_datax_job_instance_by_instance_id_sql(self, result):\n        return config.update_datax_job_instance_by_instance_id_sql % (\n            1, result, self.dh.now_time, self.datax_job_instance_id\n        )\n\n    @property\n    def datax_job_instance_id(self):\n        return '%s%s' % (self.id, self.__timestamp1)\n\n    def start_log(self):\n        # 开始记录任务日志到datax_job_instance\n        sql = self.get_insert_datax_job_instance_sql()\n        self.dtconn.ygol.insert(sql)\n        if self.dtconn.ygol.status:\n            logger.error(u'记录任务日志到datax_job_instance 失败 - SQL: %s - msg: %s' %\n                         (sql, self.dtconn.ygol.msg))\n\n    def record_result_log(self, result):\n        # 记录任务执行结果 datax_job_instance\n        sql = self.get_update_datax_job_instance_by_instance_id_sql(result)\n        self.dtconn.ygol.update(sql)\n        if self.dtconn.ygol.status:\n            logger.error(u'记录任务执行结果 datax_job_instance 失败 - SQL: %s - msg: %s' %\n                         (sql, self.dtconn.ygol.msg))\n\n    def create(self):\n        # datax_job表里创建新的任务\n        result = _SUCCESS.copy()\n        sql1 = self.get_insert_datax_job_sql()\n        self.dtconn.ygol.transaction_start()\n        self.dtconn.ygol.transaction_execute(sql1)\n        if self.dtconn.ygol.status:\n            msg = u'datax_job表里创建新的任务，SQL：%s 插入数据失败。 -  Msg: %s' % \\\n                  (sql1, self.dtconn.ygol.msg)\n            logger.error(msg)\n            result = dict(status=500, msg=msg)\n        else:\n            sql2 = self.get_insert_datax_job_writer_column_sql()\n            self.dtconn.ygol.transaction_execute(sql2)\n            if self.dtconn.ygol.status:\n                msg = u'datax_job_writer_column表里创建新的列，SQL：%s 插入数据失败。 -  Msg: %s' % \\\n                      (sql2, self.dtconn.ygol.msg)\n                logger.error(msg)\n                result = dict(status=500, msg=msg)\n        self.dtconn.ygol.transaction_commit_and_close()\n        return result\n\n    def update(self):\n        # 更新任务\n        result = _SUCCESS.copy()\n        sql1 = self.get_update_datax_job_by_id_sql()\n        self.dtconn.ygol.transaction_start()\n        self.dtconn.ygol.transaction_execute(sql1)\n        if self.dtconn.ygol.status:\n            msg = u'datax_job表，SQL：%s 更新数据失败。 -  Msg: %s' % \\\n                  (sql1, self.dtconn.ygol.msg)\n            logger.error(msg)\n            result = dict(status=500, msg=msg)\n        else:\n            sql2 = self.get_delete_datax_job_writer_column_by_id_sql()\n            sql3 = self.get_insert_datax_job_writer_column_sql()\n            self.dtconn.ygol.transaction_execute(sql2)\n            self.dtconn.ygol.transaction_execute(sql3)\n            if self.dtconn.ygol.status:\n                msg = u'datax_job_writer_column表里更新列 - SQL2：%s - SQL3: %s -' \\\n                      u' 更新数据失败。 -  Msg: %s' % \\\n                      (sql2, sql3, self.dtconn.ygol.msg)\n                logger.error(msg)\n                result = dict(status=500, msg=msg)\n        self.dtconn.ygol.transaction_commit_and_close()\n        return result\n\n    def get_job_data(self):\n        # 获取任务数据\n        source_data = self.dtconn.ygol.getall(config.query_datax_job_sql)\n        if self.dtconn.ygol.status:\n            logger.error(u'获取datax_job信息失败 %s' % self.dtconn.ygol.msg)\n            return []\n        else:\n            return [self.dtsf.get_row_by_dict_to_user(dt) for dt in source_data]\n\n    def get_job_data_by_id(self, _id):\n        \"\"\"\n        根据ID获取任务数据\n        :param _id: datax_job_id\n        :return: datax_job\n        \"\"\"\n        source_data = self.dtconn.ygol.getsingle(config.query_datax_job_by_id_sql % _id)\n        if self.dtconn.ygol.status:\n            logger.error(u'根据ID %s 获取任务数据信息失败 %s' % (self.id, self.dtconn.ygol.msg))\n            return None\n        else:\n            return self.dtsf.get_row_by_dict_to_user(source_data)\n\n\n    def get_datax_job_writer_column_by_id(self, _id):\n        \"\"\"\n        根据ID获取任务需要写入的列\n        :param _id: datax_job_id\n        :return: datax_job_writer_column\n        \"\"\"\n        source_data = self.dtconn.ygol.getall(config.query_datax_job_writer_column_by_id_sql % _id)\n        if self.dtconn.ygol.status:\n            logger.error(u'根据ID %s 获取任务数据信息失败 %s' % (self.id, self.dtconn.ygol.msg))\n            return None\n        else:\n            return [self.dtsf.get_row_by_dict_to_user(dt) for dt in source_data]\n\n    @staticmethod\n    def create_file(file, content):\n        # 创建文件\n        with open(file, 'w') as f:\n            f.write(content)\n\n\nclass CheckJob(object):\n    \"\"\"\n    检测新增任务提交的信息\n    :return  result\n             格式：   {'status': 1, 'msg': '操作类型错误'}\n    total_check 启动所有检测，返回检测状态和错误消息\n    \"\"\"\n    _SUCCESS = _SUCCESS.copy()\n    _OPERATION_TYPE_ERROR1 = dict(status=1, msg=u'操作类型不能为空')\n    _OPERATION_TYPE_ERROR2 = dict(status=2, msg=u'操作类型错误')\n    _DESCRIPTION_ERROR1 = dict(status=3, msg=u'任务描述不能为空')\n    _NAME_ERROR1 = dict(status=4, msg=u'任务名称不能为空')\n    _NAME_ERROR2 = dict(status=5, msg=u'任务名称已存在')\n    _QUERY_SQL_ERROR1 = dict(status=6, msg=u'查询SQL语句不能为空')\n    _READER_DATABASEINFO_ID_ERROR1 = dict(status=7, msg=u'读取数据库不能为空，必须为数字')\n    _READER_DATABASEINFO_ID_ERROR2 = dict(status=8, msg=u'读取数据库ID不存在')\n    _WRITER_TABLE_ERROR1 = dict(status=10, msg=u'写入表不能为空')\n    _WRITER_COLUMN_ERROR1 = dict(status=11, msg=u'写入列不能为空')\n    _WRITER_DATABASEINFO_ID_ERROR1 = dict(status=12, msg=u'写入数据库不能为空')\n    _WRITER_DATABASEINFO_ID_ERROR2 = dict(status=13, msg=u'写入数据库ID不存在')\n    _DATAX_JOB_ID_ERROR1 = dict(status=1, msg=u'datax_job_id 不能为空')\n    _DATAX_JOB_ID_ERROR2 = dict(status=2, msg=u'datax_job_id 不存在')\n    _TRIGGER_MODE_ERROR1 = dict(status=2, msg=u'触发模式 不存在')\n    _TRIGGER_MODE_ERROR2 = dict(status=2, msg=u'触发模式值错误')\n\n\n    def __init__(self, request):\n\n        \"\"\"\n        RESPONSE_TYPE 返回给用户数据的方式\n        1：20万行以内的数据，以excel方式返回\n        2：超过20万行的数据，需要分批处理\n        3：小量的数据以HTML表格的方式返回'\n        \"\"\"\n        cur = Currency(request)\n        data = cur.rq_post_json('data')\n        self.dtconn = dataconn.DatabaseConnection(logger)\n        self.jd = JobData(data)\n\n        self.error_msg = []\n        self.result = self._SUCCESS\n\n    def check_operation_type(self):\n        # 检测操作类型\n        operation_type = self.jd.operation_type\n        if not operation_type:\n            self.result = self._OPERATION_TYPE_ERROR1\n        else:\n            if operation_type not in config.OPERATION_TYPE:\n                self.result = self._OPERATION_TYPE_ERROR2\n\n    def check_name_by_operation_type(self):\n        # 根据操作类型add/mod 检测任务名称\n        name = self.jd.name\n        if self.jd.operation_type == config.OPERATION_TYPE[0]:\n            sql = config.query_datax_job_by_name_sql % name\n            self.check_name(name, sql)\n\n        if self.jd.operation_type == config.OPERATION_TYPE[1]:\n            sql = config.query_datax_job_sql2 % (name, self.jd.id)\n            self.check_name(name, sql)\n\n    def check_name(self, name, sql):\n        # 修改任务时，检测任务名称\n        if name:\n            data = self.dtconn.ygol.getsingle(sql)\n            if self.dtconn.ygol.status:\n                _msg = u'检测任务名称时数据库错误。 - Msg: %s' % self.dtconn.ygol.msg\n                logger.error(_msg)\n                self.result = dict(status=500, msg=_msg)\n            else:\n                if data:\n                    self.result = self._NAME_ERROR2\n        else:\n            self.result = self._NAME_ERROR1\n\n    def check_description(self):\n        # 检测任务描述\n        description = self.jd.description\n        if not description:\n            self.result = self._DESCRIPTION_ERROR1\n\n    def check_querySql(self):\n        # 检测查询SQL语句\n        querySql = self.jd.querySql\n        if not querySql:\n            self.result = self._DESCRIPTION_ERROR1\n\n    def check_reader_databaseinfo_id(self):\n        # 检测读取数据库\n        kwargs = {\n            '_id': self.jd.reader_databaseinfo_id,\n            'operation_type': u'读取',\n            'ERROR1': self._READER_DATABASEINFO_ID_ERROR1,\n            'ERROR2': self._READER_DATABASEINFO_ID_ERROR2,\n        }\n        self.check_databaseinfo_id(**kwargs)\n\n    def check_writer_table(self):\n        # 检测写入表\n        writer_table = self.jd.writer_table\n        if not writer_table:\n            self.result = self._WRITER_TABLE_ERROR1\n\n    def check_writer_column(self):\n        # 检测写入列\n        writer_column = self.jd.writer_column\n        if not writer_column:\n            self.result = self._WRITER_COLUMN_ERROR1\n\n    def check_writer_databaseinfo_id(self):\n        # 检测写入数据库\n        kwargs = {\n            '_id': self.jd.writer_databaseinfo_id,\n            'operation_type': u'写入',\n            'ERROR1': self._WRITER_DATABASEINFO_ID_ERROR1,\n            'ERROR2': self._WRITER_DATABASEINFO_ID_ERROR2,\n        }\n        self.check_databaseinfo_id(**kwargs)\n\n    def check_databaseinfo_id(self, _id, operation_type, ERROR1, ERROR2):\n        # 检测数据库ID\n        if _id and _id.isdigit():\n            data = self.dtconn.get_datainfo_by_id(int(_id))\n            if self.dtconn.ygol.status:\n                _msg = u'检测%s数据库错误。 - Msg: %s' % (operation_type, self.dtconn.ygol.msg)\n                logger.error(_msg)\n                self.result = dict(status=500, msg=_msg)\n            else:\n                if not data:\n                    self.result = ERROR2\n        else:\n            self.result = ERROR1\n\n    def check_datax_job_id(self):\n        # 检测任务ID\n        if self.jd.operation_type == config.OPERATION_TYPE[1]:\n            _id = self.jd.id\n            if isinstance(_id, _str) and _id and _id.isdigit():\n                sql = config.query_datax_job_by_id_sql % _id\n                data = self.dtconn.ygol.getsingle(sql)\n                if self.dtconn.ygol.status:\n                    _msg = u'检测datax_job_id 错误 - SQL: %s。 - Msg: %s' % (sql, self.dtconn.ygol.msg)\n                    logger.error(_msg)\n                    self.result = dict(status=500, msg=_msg)\n                else:\n                    if not data:\n                        self.result = self._DATAX_JOB_ID_ERROR2\n            else:\n                self.result = self._DATAX_JOB_ID_ERROR1\n\n\n    def check_trigger_mode(self):\n        # 检测触发模式\n        trigger_mode = self.jd.trigger_mode\n        if self.jd.operation_type == config.OPERATION_TYPE[1]:\n            if not trigger_mode:\n                self.result = self._TRIGGER_MODE_ERROR1\n            else:\n                if trigger_mode not in config.TRIGGER_MODE:\n                    self.result = self._TRIGGER_MODE_ERROR2\n\n\n    def total_check(self):\n        check_func = ['check_operation_type', 'check_datax_job_id',\n                      'check_description', 'check_name_by_operation_type',\n                      'check_querySql', 'check_reader_databaseinfo_id',\n                      'check_writer_table', 'check_writer_column',\n                      'check_writer_databaseinfo_id', 'check_trigger_mode'\n                      ]\n\n        for func_name in check_func:\n            getattr(self, func_name)()\n            if self.result['status']:\n                break\n\n        return self.result\n\n\nclass Datax(object):\n    \"\"\"\n    处理和datax相关的操作\n    \"\"\"\n    def __init__(self, data):\n        self.jd = JobData(data)\n\n    def get_reader(self):\n        return dict(\n            jdbcUrl = 'jdbc:mysql://%s/%s' % (self.jd.reader_dtbs['host'], self.jd.reader_dtbs['db']),\n            querySql = self.jd.querySql,\n            password = self.jd.reader_dtbs['passwd'],\n            username = self.jd.reader_dtbs['user']\n        )\n\n    def get_writer(self):\n        return dict(\n            column = \"[%s]\" % ','.join(['\"%s\"' % str(c) for c in self.jd.writer_column]),\n            jdbcUrl = 'jdbc:mysql://%s/%s' % (self.jd.writer_dtbs['host'], self.jd.writer_dtbs['db']),\n            table = self.jd.writer_table,\n            password = self.jd.writer_dtbs['passwd'],\n            preSql = ','.join(map(lambda x:'\"%s\"' % x, self.jd.writer_preSql.split(';'))),\n            postSql = ','.join(map(lambda x:'\"%s\"' % x, self.jd.writer_postSql.split(';'))),\n            username = self.jd.writer_dtbs['user']\n        )\n\n    def get_job_json(self):\n        reader = self.get_reader()\n        writer = self.get_writer()\n        return config.datax_job_template % (\n            reader['jdbcUrl'], reader['querySql'], reader['password'], reader['username'],\n            writer['column'], writer['jdbcUrl'], writer['table'], writer['password'],\n            writer['preSql'], writer['postSql'], writer['username']\n        )\n\n    @property\n    def job_json_file_name(self):\n        return u'%s.json' % self.jd.datax_job_instance_id\n\n    @property\n    def job_json_file(self):\n        return config.datax_job_dir + '/' + self.job_json_file_name\n\n    @staticmethod\n    def create_file(file, content):\n        # 创建文件\n        with open(file, 'w') as f:\n            f.write(content)\n\n    @property\n    def cmd(self):\n        return 'python %s/bin/datax.py %s > %s/%s.log' % \\\n              (config.datax_dir, self.job_json_file, config.datax_log_dir, self.job_json_file_name)\n\n@shared_task(name='run')\ndef run(**data):\n    # 执行任务\n    dx = Datax(data)\n    dx.jd.create_file(dx.job_json_file, dx.get_job_json())\n    dx.jd.start_log()\n    (status, output) = commands.getstatusoutput(dx.cmd)\n    if status:\n        logger.error(\"status:%s output:%s\" % (status, output))\n    result = 1 if status else 0\n    dx.jd.record_result_log(result)\n\n\n@login_required\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\ndef index(request):\n    # 数据同步\n    return render(request, 'datax_web/index.html', locals())\n\n\n@login_required\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\n@permission_required('batch_job.editBatchJob', raise_exception=PermissionDenied)\ndef add_job(request):\n    # 新增任务\n    return render(request, 'datax_web/add_job.html', locals())\n\n\n@login_required\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\ndef update_job(request, id):\n    # 更新任务\n    return render(request, 'datax_web/update_job.html', locals())\n\n\n@login_required\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\ndef monitor_job(request):\n    # 任务执行实例\n    return render(request, 'datax_web/monitor_job.html', locals())\n\n\n@login_required\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\ndef monitor_job_detail(request, id):\n    # 任务执行详情\n    return render(request, 'datax_web/monitor_job_detail.html', locals())\n\n\n@login_required\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\ndef get_database(request):\n    # 获取 数据库信息\n    def _data_processing(dt):\n        # 清除数据里的密码，并对数据格式化\n        del dt['passwd']\n        return dtsf.get_row_by_dict_to_user(dt)\n    response = HttpResponse()\n    dtconn = dataconn.DatabaseConnection(logger)\n    data = dtconn.ygol.getall(dataconn.dtbsif_sql)\n    dtsf = dataconn.DataTransform()\n    if dtconn.ygol.status:\n        logger.error(u'获取数据库信息失败 %s' % dtconn.ygol.msg)\n    response.write(json.dumps(map(_data_processing, data)))\n    return response\n\n\n@login_required\n@verification(CheckJob)\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\n@permission_required('batch_job.editBatchJob', raise_exception=PermissionDenied)\ndef add_job_data(request):\n    # 新增或者修改任务数据\n    response = HttpResponse()\n    cur = Currency(request)\n    data = cur.rq_post_json('data')\n    jd = JobData(data)\n\n    if jd.operation_type == config.OPERATION_TYPE[0]:\n        result = jd.create()  # 新增\n    else:\n        result = jd.update()  # 更新\n    response.write(json.dumps(result))\n    return response\n\n\n@login_required\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\ndef get_job_data(request):\n    # 获取 任务列表数据\n    response = HttpResponse()\n    jd = JobData({})\n    response.write(json.dumps(jd.get_job_data()))\n    return response\n\n\n@login_required\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\ndef get_update_job_data(request):\n    # 获取 更新任务数据\n    response = HttpResponse()\n    cur = Currency(request)\n    _id = cur.rq_post_json('_id')\n    jd = JobData({})\n    response.write(json.dumps(jd.get_job_data_by_id(_id)))\n    return response\n\n\n@login_required\n@verification(CheckJob)\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\n@permission_required('batch_job.editBatchJob', raise_exception=PermissionDenied)\ndef run_job(request):\n    # 执行任务\n    response = HttpResponse()\n    cur = Currency(request)\n    data = cur.rq_post_json('data')\n    # run(**data)\n    run.delay(**data)\n    response.write(json.dumps(_SUCCESS))\n    return response\n\n\nclass DataxJobInstanceSql(object):\n    # datax job instance 查询sql\n    _table_dji = {\n        'name': {'data_type': 'str', 'val': ''},\n        'description': {'data_type': 'str', 'val': ''},\n        'reader_databaseinfo_host': {'data_type': 'str', 'val': ''},\n        'writer_table': {'data_type': 'str', 'val': ''},\n        'writer_databaseinfo_host': {'data_type': 'str', 'val': ''},\n        'status': {'data_type': 'str', 'val': ''},\n        'result': {'data_type': 'str', 'val': ''},\n        'trigger_mode': {'data_type': 'str', 'val': ''},\n    }\n\n    _order_by = [{'table': 'dji', 'field': 'start_time', 'rule': 'DESC'}]\n\n    def __init__(self, request):\n        self.cur = Currency(request)\n        self.rq_get = self.cur.rq_get\n\n        self._offset = int(self.rq_get('offset'))\n        self._limit = int(self.rq_get('limit'))\n        self._SQL = config.select_datax_job_instance_sql\n        self._TOTAL_SQL = config.count_datax_job_instance_sql\n        self._set_table(self._table_dji)\n\n    def _set_table(self, table):\n        for field, attr in table.items():\n            val = self.rq_get(field)\n            attr['val'] = val\n        return table\n\n    @property\n    def tables(self):\n        _tables = {'dji': self._table_dji}\n        return _tables\n\n    @property\n    def cvtpara(self):\n        _cvtpara = {\n            'offset': self._offset,\n            'limit': self._limit,\n            'sql': self._SQL,\n            'total_sql': self._TOTAL_SQL,\n            'order_by': self._order_by,\n            'order_rule': self._order_by\n        }\n        return _cvtpara\n\n\nclass PaginatorData(dataconn.DatabaseConnection, query_sql.Q_Data):\n    # 分页访问数据\n    def __init__(self, qs):\n        super(PaginatorData, self).__init__(logger)\n        query_sql.Q_Data.__init__(self, qs)\n\n    @property\n    def rows(self):\n        return self._get_rows(self.ygol)\n\n    @property\n    def total(self):\n        return self._get_total(self.ygol)\n\n\n@login_required\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\ndef get_datax_job_instance(request):\n    # 分页查询任务实例\n    dsql = DataxJobInstanceSql(request)\n    cvtpara = dsql.cvtpara\n    tables = dsql.tables\n    qs = query_sql.Q_Sql(cvtpara, **tables)\n    pd = PaginatorData(qs)\n    response = HttpResponse()\n    response.write(json.dumps({'rows': pd.rows, 'total': pd.total}))\n    return response\n\n\n@login_required\n@permission_required('batch_job.viewBatchJob', raise_exception=PermissionDenied)\ndef get_datax_job_instance_by_id(request):\n    # 根据ID查询任务实例\n    cur = Currency(request)\n    _id = cur.rq_post('_id')\n    conn = dataconn.DatabaseConnection(logger)\n    dtf = dataconn.DataTransform()\n    sql = config.select_datax_job_instance_by_id_sql % _id\n    source_data = conn.ygol.getsingle(sql)\n    response = HttpResponse()\n    response.write(json.dumps(dtf.get_row_by_dict_to_user(source_data)))\n    return response\n"
  },
  {
    "path": "manage.py",
    "content": "#!/usr/bin/env python\nimport os\nimport sys\n\nif __name__ == \"__main__\":\n    os.environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"FirstBlood.settings\")\n\n    from django.core.management import execute_from_command_line\n\n    execute_from_command_line(sys.argv)\n"
  },
  {
    "path": "requirements.txt",
    "content": "celery==3.1.25\ncelery-with-redis==3.0\nDjango==1.11.14\ndjango-celery==3.2.1\npymssql==2.1.4\nredis==2.10.6\nsupervisor==3.3.4\n\n"
  },
  {
    "path": "static/css/login.css",
    "content": "\r\nbody{background: url(/static/img/login_bg.jpg) 0 -200px no-repeat #000;\r\nbackground-size: cover;margin:0; color:#FFF}\r\n*{-webkit-box-sizing:border-box;box-sizing:border-box;}\r\na{-webkit-transition: All 1s ease;text-decoration: none;\r\n\tcolor: #dfc684;}\r\ninput , button{border:0;background:none;color: #dfc684;}\r\n#login-box{position:absolute; width:500px; left:30%; top:29%;}\r\n.login-box-wh{height:53px;width:800px;margin-bottom:16px;}\r\n.to-index{padding-left:16px;overflow:hidden; position:absolute;left:69px;}\r\n.to-index-m{width:360px; height:53px;\tmargin-top:-53px;margin-left:-16px;position:absolute;z-index:-1;background:yellow;transition:margin 0.8s;-moz-transition:margin 0.8s; -webkit-transition:margin 0.8s 0.3s; }\r\n.login-box-wh:hover .to-index-m{margin-top:0;}\r\n.login-box-wh:hover a{color:#f00}\r\n.box-mov{width: 53px;height: 53px;float: left; display: inline-block;opacity: .72;filter: alpha(opacity=72);background: url(/static/img/icons.png) -212px 0 #000; margin-right: 16px;position: relative;overflow:hidden;z-index:0;}\r\n.box-mov-s{width: 53px;height: 53px;z-index:1;position:absolute;background:#ff0;margin-left:-53px;\r\nbackground:yellow;\r\ntransition:margin 0.8s;-moz-transition:margin 0.8s; -webkit-transition:margin 0.8s; }\r\n.login-box-wh:hover .box-mov-s{margin:0;}\r\n.box-mov-d{width: 53px;height: 53px;z-index:2;position:absolute;background:url(/static/img/icons.png) -212px -53px;);opacity:0; }\r\n.login-box-wh:hover .box-mov-d {opacity:1;}\r\n.text-box{width:360px; height:53px;background:#000;opacity: .72; float:left;line-height:53px;}\r\n#vdcode{width:270px;}\r\n.text-box-login{}\r\n.text-box-login-btn{width:360px; height:53px;background:#000;opacity: .72; float:left;line-height:53px;-webkit-box-sizing:border-box; position:absolute;left:69px;overflow:hidden; }\r\n.login-btn-m{width:360px; height:53px;margin-top:-53px; position:absolute;z-index:1;background:yellow;transition:margin 0.8s;-moz-transition:margin 0.8s; -webkit-transition:margin 0.8s 0.3s;}\r\n.text-box-login:hover .login-btn-m{margin-top:0}\r\n.login-btn{width:100%;height:100%; cursor:pointer;font-size:16px;position:absolute;z-index:5;transition: 0.8s;-moz-transition: 0.8s; -webkit-transition: 0.8s 0.3s;}\r\n.login-btn:hover{color:#f00;}\r\n input{height:100%;width:100%;padding:8px 0 8px 8px;background:none;color:#fff;}\r\ninput:focus {\r\n    outline:none;\r\n}"
  },
  {
    "path": "static/js/csrf.js",
    "content": "function getCookie(name) {\r\n    var cookieValue = null;\r\n    if (document.cookie && document.cookie != '') {\r\n        var cookies = document.cookie.split(';');\r\n        for (var i = 0; i < cookies.length; i++) {\r\n            var cookie = jQuery.trim(cookies[i]);\r\n            // Does this cookie string begin with the name we want?\r\n            if (cookie.substring(0, name.length + 1) == (name + '=')) {\r\n                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));\r\n                break;\r\n            }\r\n        }\r\n    }\r\n    return cookieValue;\r\n}\r\nvar csrftoken = getCookie('csrftoken');\r\nfunction csrfSafeMethod(method) {\r\n    // these HTTP methods do not require CSRF protection\r\n    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));\r\n}\r\n$.ajaxSetup({\r\n    beforeSend: function(xhr, settings) {\r\n        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {\r\n            xhr.setRequestHeader(\"X-CSRFToken\", csrftoken);\r\n        }\r\n    }\r\n});"
  },
  {
    "path": "static/plugins/bootstarp-table/bootstrap-table-zh-CN.js",
    "content": "/**\n * Bootstrap Table Chinese translation\n * Author: Zhixin Wen<wenzhixin2010@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['zh-CN'] = {\n        formatLoadingMessage: function () {\n            return '正在努力地加载数据中，请稍候……';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return '每页显示 ' + pageNumber + ' 条记录';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return '显示第 ' + pageFrom + ' 到第 ' + pageTo + ' 条记录，总共 ' + totalRows + ' 条记录';\n        },\n        formatSearch: function () {\n            return '搜索';\n        },\n        formatNoMatches: function () {\n            return '没有找到匹配的记录';\n        },\n        formatPaginationSwitch: function () {\n            return '隐藏/显示分页';\n        },\n        formatRefresh: function () {\n            return '刷新';\n        },\n        formatToggle: function () {\n            return '切换';\n        },\n        formatColumns: function () {\n            return '列';\n        },\n        formatExport: function () {\n            return '导出数据';\n        },\n        formatClearFilters: function () {\n            return '清空过滤';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['zh-CN']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/plugins/datatables/css/jquery.dataTables.css",
    "content": "/*\n * Table styles\n */\ntable.dataTable {\n  width: 100%;\n  margin: 0 auto;\n  clear: both;\n  border-collapse: separate;\n  border-spacing: 0;\n  /*\n   * Header and footer styles\n   */\n  /*\n   * Body styles\n   */\n}\ntable.dataTable thead th,\ntable.dataTable tfoot th {\n  font-weight: bold;\n}\ntable.dataTable thead th,\ntable.dataTable thead td {\n  padding: 10px 18px;\n  border-bottom: 1px solid #111;\n}\ntable.dataTable thead th:active,\ntable.dataTable thead td:active {\n  outline: none;\n}\ntable.dataTable tfoot th,\ntable.dataTable tfoot td {\n  padding: 10px 18px 6px 18px;\n  border-top: 1px solid #111;\n}\ntable.dataTable thead .sorting,\ntable.dataTable thead .sorting_asc,\ntable.dataTable thead .sorting_desc {\n  cursor: pointer;\n  *cursor: hand;\n}\ntable.dataTable thead .sorting,\ntable.dataTable thead .sorting_asc,\ntable.dataTable thead .sorting_desc,\ntable.dataTable thead .sorting_asc_disabled,\ntable.dataTable thead .sorting_desc_disabled {\n  background-repeat: no-repeat;\n  background-position: center right;\n}\ntable.dataTable thead .sorting {\n  background-image: url(\"../images/sort_both.png\");\n}\ntable.dataTable thead .sorting_asc {\n  background-image: url(\"../images/sort_asc.png\");\n}\ntable.dataTable thead .sorting_desc {\n  background-image: url(\"../images/sort_desc.png\");\n}\ntable.dataTable thead .sorting_asc_disabled {\n  background-image: url(\"../images/sort_asc_disabled.png\");\n}\ntable.dataTable thead .sorting_desc_disabled {\n  background-image: url(\"../images/sort_desc_disabled.png\");\n}\ntable.dataTable tbody tr {\n  background-color: #ffffff;\n}\ntable.dataTable tbody tr.selected {\n  background-color: #B0BED9;\n}\ntable.dataTable tbody th,\ntable.dataTable tbody td {\n  padding: 8px 10px;\n}\ntable.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td {\n  border-top: 1px solid #ddd;\n}\ntable.dataTable.row-border tbody tr:first-child th,\ntable.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th,\ntable.dataTable.display tbody tr:first-child td {\n  border-top: none;\n}\ntable.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td {\n  border-top: 1px solid #ddd;\n  border-right: 1px solid #ddd;\n}\ntable.dataTable.cell-border tbody tr th:first-child,\ntable.dataTable.cell-border tbody tr td:first-child {\n  border-left: 1px solid #ddd;\n}\ntable.dataTable.cell-border tbody tr:first-child th,\ntable.dataTable.cell-border tbody tr:first-child td {\n  border-top: none;\n}\ntable.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd {\n  background-color: #f9f9f9;\n}\ntable.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected {\n  background-color: #acbad4;\n}\ntable.dataTable.hover tbody tr:hover, table.dataTable.display tbody tr:hover {\n  background-color: #f6f6f6;\n}\ntable.dataTable.hover tbody tr:hover.selected, table.dataTable.display tbody tr:hover.selected {\n  background-color: #aab7d1;\n}\ntable.dataTable.order-column tbody tr > .sorting_1,\ntable.dataTable.order-column tbody tr > .sorting_2,\ntable.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1,\ntable.dataTable.display tbody tr > .sorting_2,\ntable.dataTable.display tbody tr > .sorting_3 {\n  background-color: #fafafa;\n}\ntable.dataTable.order-column tbody tr.selected > .sorting_1,\ntable.dataTable.order-column tbody tr.selected > .sorting_2,\ntable.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1,\ntable.dataTable.display tbody tr.selected > .sorting_2,\ntable.dataTable.display tbody tr.selected > .sorting_3 {\n  background-color: #acbad5;\n}\ntable.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 {\n  background-color: #f1f1f1;\n}\ntable.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 {\n  background-color: #f3f3f3;\n}\ntable.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 {\n  background-color: whitesmoke;\n}\ntable.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 {\n  background-color: #a6b4cd;\n}\ntable.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 {\n  background-color: #a8b5cf;\n}\ntable.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 {\n  background-color: #a9b7d1;\n}\ntable.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 {\n  background-color: #fafafa;\n}\ntable.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 {\n  background-color: #fcfcfc;\n}\ntable.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 {\n  background-color: #fefefe;\n}\ntable.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 {\n  background-color: #acbad5;\n}\ntable.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 {\n  background-color: #aebcd6;\n}\ntable.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 {\n  background-color: #afbdd8;\n}\ntable.dataTable.display tbody tr:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1 {\n  background-color: #eaeaea;\n}\ntable.dataTable.display tbody tr:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2 {\n  background-color: #ececec;\n}\ntable.dataTable.display tbody tr:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3 {\n  background-color: #efefef;\n}\ntable.dataTable.display tbody tr:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1 {\n  background-color: #a2aec7;\n}\ntable.dataTable.display tbody tr:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2 {\n  background-color: #a3b0c9;\n}\ntable.dataTable.display tbody tr:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3 {\n  background-color: #a5b2cb;\n}\ntable.dataTable.no-footer {\n  border-bottom: 1px solid #111;\n}\ntable.dataTable.nowrap th, table.dataTable.nowrap td {\n  white-space: nowrap;\n}\ntable.dataTable.compact thead th,\ntable.dataTable.compact thead td {\n  padding: 4px 17px 4px 4px;\n}\ntable.dataTable.compact tfoot th,\ntable.dataTable.compact tfoot td {\n  padding: 4px;\n}\ntable.dataTable.compact tbody th,\ntable.dataTable.compact tbody td {\n  padding: 4px;\n}\ntable.dataTable th.dt-left,\ntable.dataTable td.dt-left {\n  text-align: left;\n}\ntable.dataTable th.dt-center,\ntable.dataTable td.dt-center,\ntable.dataTable td.dataTables_empty {\n  text-align: center;\n}\ntable.dataTable th.dt-right,\ntable.dataTable td.dt-right {\n  text-align: right;\n}\ntable.dataTable th.dt-justify,\ntable.dataTable td.dt-justify {\n  text-align: justify;\n}\ntable.dataTable th.dt-nowrap,\ntable.dataTable td.dt-nowrap {\n  white-space: nowrap;\n}\ntable.dataTable thead th.dt-head-left,\ntable.dataTable thead td.dt-head-left,\ntable.dataTable tfoot th.dt-head-left,\ntable.dataTable tfoot td.dt-head-left {\n  text-align: left;\n}\ntable.dataTable thead th.dt-head-center,\ntable.dataTable thead td.dt-head-center,\ntable.dataTable tfoot th.dt-head-center,\ntable.dataTable tfoot td.dt-head-center {\n  text-align: center;\n}\ntable.dataTable thead th.dt-head-right,\ntable.dataTable thead td.dt-head-right,\ntable.dataTable tfoot th.dt-head-right,\ntable.dataTable tfoot td.dt-head-right {\n  text-align: right;\n}\ntable.dataTable thead th.dt-head-justify,\ntable.dataTable thead td.dt-head-justify,\ntable.dataTable tfoot th.dt-head-justify,\ntable.dataTable tfoot td.dt-head-justify {\n  text-align: justify;\n}\ntable.dataTable thead th.dt-head-nowrap,\ntable.dataTable thead td.dt-head-nowrap,\ntable.dataTable tfoot th.dt-head-nowrap,\ntable.dataTable tfoot td.dt-head-nowrap {\n  white-space: nowrap;\n}\ntable.dataTable tbody th.dt-body-left,\ntable.dataTable tbody td.dt-body-left {\n  text-align: left;\n}\ntable.dataTable tbody th.dt-body-center,\ntable.dataTable tbody td.dt-body-center {\n  text-align: center;\n}\ntable.dataTable tbody th.dt-body-right,\ntable.dataTable tbody td.dt-body-right {\n  text-align: right;\n}\ntable.dataTable tbody th.dt-body-justify,\ntable.dataTable tbody td.dt-body-justify {\n  text-align: justify;\n}\ntable.dataTable tbody th.dt-body-nowrap,\ntable.dataTable tbody td.dt-body-nowrap {\n  white-space: nowrap;\n}\n\ntable.dataTable,\ntable.dataTable th,\ntable.dataTable td {\n  -webkit-box-sizing: content-box;\n  box-sizing: content-box;\n}\n\n/*\n * Control feature layout\n */\n.dataTables_wrapper {\n  position: relative;\n  clear: both;\n  *zoom: 1;\n  zoom: 1;\n}\n.dataTables_wrapper .dataTables_length {\n  float: left;\n}\n.dataTables_wrapper .dataTables_filter {\n  float: right;\n  text-align: right;\n}\n.dataTables_wrapper .dataTables_filter input {\n  margin-left: 0.5em;\n}\n.dataTables_wrapper .dataTables_info {\n  clear: both;\n  float: left;\n  padding-top: 0.755em;\n}\n.dataTables_wrapper .dataTables_paginate {\n  float: right;\n  text-align: right;\n  padding-top: 0.25em;\n}\n.dataTables_wrapper .dataTables_paginate .paginate_button {\n  box-sizing: border-box;\n  display: inline-block;\n  min-width: 1.5em;\n  padding: 0.5em 1em;\n  margin-left: 2px;\n  text-align: center;\n  text-decoration: none !important;\n  cursor: pointer;\n  *cursor: hand;\n  color: #333 !important;\n  border: 1px solid transparent;\n  border-radius: 2px;\n}\n.dataTables_wrapper .dataTables_paginate .paginate_button.current, .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {\n  color: #333 !important;\n  border: 1px solid #979797;\n  background-color: white;\n  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, #dcdcdc));\n  /* Chrome,Safari4+ */\n  background: -webkit-linear-gradient(top, white 0%, #dcdcdc 100%);\n  /* Chrome10+,Safari5.1+ */\n  background: -moz-linear-gradient(top, white 0%, #dcdcdc 100%);\n  /* FF3.6+ */\n  background: -ms-linear-gradient(top, white 0%, #dcdcdc 100%);\n  /* IE10+ */\n  background: -o-linear-gradient(top, white 0%, #dcdcdc 100%);\n  /* Opera 11.10+ */\n  background: linear-gradient(to bottom, white 0%, #dcdcdc 100%);\n  /* W3C */\n}\n.dataTables_wrapper .dataTables_paginate .paginate_button.disabled, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active {\n  cursor: default;\n  color: #666 !important;\n  border: 1px solid transparent;\n  background: transparent;\n  box-shadow: none;\n}\n.dataTables_wrapper .dataTables_paginate .paginate_button:hover {\n  color: white !important;\n  border: 1px solid #111;\n  background-color: #585858;\n  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));\n  /* Chrome,Safari4+ */\n  background: -webkit-linear-gradient(top, #585858 0%, #111 100%);\n  /* Chrome10+,Safari5.1+ */\n  background: -moz-linear-gradient(top, #585858 0%, #111 100%);\n  /* FF3.6+ */\n  background: -ms-linear-gradient(top, #585858 0%, #111 100%);\n  /* IE10+ */\n  background: -o-linear-gradient(top, #585858 0%, #111 100%);\n  /* Opera 11.10+ */\n  background: linear-gradient(to bottom, #585858 0%, #111 100%);\n  /* W3C */\n}\n.dataTables_wrapper .dataTables_paginate .paginate_button:active {\n  outline: none;\n  background-color: #2b2b2b;\n  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));\n  /* Chrome,Safari4+ */\n  background: -webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\n  /* Chrome10+,Safari5.1+ */\n  background: -moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\n  /* FF3.6+ */\n  background: -ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\n  /* IE10+ */\n  background: -o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\n  /* Opera 11.10+ */\n  background: linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);\n  /* W3C */\n  box-shadow: inset 0 0 3px #111;\n}\n.dataTables_wrapper .dataTables_paginate .ellipsis {\n  padding: 0 1em;\n}\n.dataTables_wrapper .dataTables_processing {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  width: 100%;\n  height: 40px;\n  margin-left: -50%;\n  margin-top: -25px;\n  padding-top: 20px;\n  text-align: center;\n  font-size: 1.2em;\n  background-color: white;\n  background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0)));\n  background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n}\n.dataTables_wrapper .dataTables_length,\n.dataTables_wrapper .dataTables_filter,\n.dataTables_wrapper .dataTables_info,\n.dataTables_wrapper .dataTables_processing,\n.dataTables_wrapper .dataTables_paginate {\n  color: #333;\n}\n.dataTables_wrapper .dataTables_scroll {\n  clear: both;\n}\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody {\n  *margin-top: -1px;\n  -webkit-overflow-scrolling: touch;\n}\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td {\n  vertical-align: middle;\n}\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th > div.dataTables_sizing,\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td > div.dataTables_sizing {\n  height: 0;\n  overflow: hidden;\n  margin: 0 !important;\n  padding: 0 !important;\n}\n.dataTables_wrapper.no-footer .dataTables_scrollBody {\n  border-bottom: 1px solid #111;\n}\n.dataTables_wrapper.no-footer div.dataTables_scrollHead table,\n.dataTables_wrapper.no-footer div.dataTables_scrollBody table {\n  border-bottom: none;\n}\n.dataTables_wrapper:after {\n  visibility: hidden;\n  display: block;\n  content: \"\";\n  clear: both;\n  height: 0;\n}\n\n@media screen and (max-width: 767px) {\n  .dataTables_wrapper .dataTables_info,\n  .dataTables_wrapper .dataTables_paginate {\n    float: none;\n    text-align: center;\n  }\n  .dataTables_wrapper .dataTables_paginate {\n    margin-top: 0.5em;\n  }\n}\n@media screen and (max-width: 640px) {\n  .dataTables_wrapper .dataTables_length,\n  .dataTables_wrapper .dataTables_filter {\n    float: none;\n    text-align: center;\n  }\n  .dataTables_wrapper .dataTables_filter {\n    margin-top: 0.5em;\n  }\n}\n"
  },
  {
    "path": "static/plugins/datatables/css/jquery.dataTables_themeroller.css",
    "content": "/*\n * Table styles\n */\ntable.dataTable {\n  width: 100%;\n  margin: 0 auto;\n  clear: both;\n  border-collapse: separate;\n  border-spacing: 0;\n  /*\n   * Header and footer styles\n   */\n  /*\n   * Body styles\n   */\n}\ntable.dataTable thead th,\ntable.dataTable thead td,\ntable.dataTable tfoot th,\ntable.dataTable tfoot td {\n  padding: 4px 10px;\n}\ntable.dataTable thead th,\ntable.dataTable tfoot th {\n  font-weight: bold;\n}\ntable.dataTable thead th:active,\ntable.dataTable thead td:active {\n  outline: none;\n}\ntable.dataTable thead .sorting_asc,\ntable.dataTable thead .sorting_desc,\ntable.dataTable thead .sorting {\n  cursor: pointer;\n  *cursor: hand;\n}\ntable.dataTable thead th div.DataTables_sort_wrapper {\n  position: relative;\n  padding-right: 10px;\n}\ntable.dataTable thead th div.DataTables_sort_wrapper span {\n  position: absolute;\n  top: 50%;\n  margin-top: -8px;\n  right: -5px;\n}\ntable.dataTable thead th.ui-state-default {\n  border-right-width: 0;\n}\ntable.dataTable thead th.ui-state-default:last-child {\n  border-right-width: 1px;\n}\ntable.dataTable tbody tr {\n  background-color: #ffffff;\n}\ntable.dataTable tbody tr.selected {\n  background-color: #B0BED9;\n}\ntable.dataTable tbody th,\ntable.dataTable tbody td {\n  padding: 8px 10px;\n}\ntable.dataTable th.center,\ntable.dataTable td.center,\ntable.dataTable td.dataTables_empty {\n  text-align: center;\n}\ntable.dataTable th.right,\ntable.dataTable td.right {\n  text-align: right;\n}\ntable.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td {\n  border-top: 1px solid #ddd;\n}\ntable.dataTable.row-border tbody tr:first-child th,\ntable.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th,\ntable.dataTable.display tbody tr:first-child td {\n  border-top: none;\n}\ntable.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td {\n  border-top: 1px solid #ddd;\n  border-right: 1px solid #ddd;\n}\ntable.dataTable.cell-border tbody tr th:first-child,\ntable.dataTable.cell-border tbody tr td:first-child {\n  border-left: 1px solid #ddd;\n}\ntable.dataTable.cell-border tbody tr:first-child th,\ntable.dataTable.cell-border tbody tr:first-child td {\n  border-top: none;\n}\ntable.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd {\n  background-color: #f9f9f9;\n}\ntable.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected {\n  background-color: #abb9d3;\n}\ntable.dataTable.hover tbody tr:hover,\ntable.dataTable.hover tbody tr.odd:hover,\ntable.dataTable.hover tbody tr.even:hover, table.dataTable.display tbody tr:hover,\ntable.dataTable.display tbody tr.odd:hover,\ntable.dataTable.display tbody tr.even:hover {\n  background-color: whitesmoke;\n}\ntable.dataTable.hover tbody tr:hover.selected,\ntable.dataTable.hover tbody tr.odd:hover.selected,\ntable.dataTable.hover tbody tr.even:hover.selected, table.dataTable.display tbody tr:hover.selected,\ntable.dataTable.display tbody tr.odd:hover.selected,\ntable.dataTable.display tbody tr.even:hover.selected {\n  background-color: #a9b7d1;\n}\ntable.dataTable.order-column tbody tr > .sorting_1,\ntable.dataTable.order-column tbody tr > .sorting_2,\ntable.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1,\ntable.dataTable.display tbody tr > .sorting_2,\ntable.dataTable.display tbody tr > .sorting_3 {\n  background-color: #f9f9f9;\n}\ntable.dataTable.order-column tbody tr.selected > .sorting_1,\ntable.dataTable.order-column tbody tr.selected > .sorting_2,\ntable.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1,\ntable.dataTable.display tbody tr.selected > .sorting_2,\ntable.dataTable.display tbody tr.selected > .sorting_3 {\n  background-color: #acbad4;\n}\ntable.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 {\n  background-color: #f1f1f1;\n}\ntable.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 {\n  background-color: #f3f3f3;\n}\ntable.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 {\n  background-color: whitesmoke;\n}\ntable.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 {\n  background-color: #a6b3cd;\n}\ntable.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 {\n  background-color: #a7b5ce;\n}\ntable.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 {\n  background-color: #a9b6d0;\n}\ntable.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 {\n  background-color: #f9f9f9;\n}\ntable.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 {\n  background-color: #fbfbfb;\n}\ntable.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 {\n  background-color: #fdfdfd;\n}\ntable.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 {\n  background-color: #acbad4;\n}\ntable.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 {\n  background-color: #adbbd6;\n}\ntable.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 {\n  background-color: #afbdd8;\n}\ntable.dataTable.display tbody tr:hover > .sorting_1,\ntable.dataTable.display tbody tr.odd:hover > .sorting_1,\ntable.dataTable.display tbody tr.even:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1,\ntable.dataTable.order-column.hover tbody tr.odd:hover > .sorting_1,\ntable.dataTable.order-column.hover tbody tr.even:hover > .sorting_1 {\n  background-color: #eaeaea;\n}\ntable.dataTable.display tbody tr:hover > .sorting_2,\ntable.dataTable.display tbody tr.odd:hover > .sorting_2,\ntable.dataTable.display tbody tr.even:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2,\ntable.dataTable.order-column.hover tbody tr.odd:hover > .sorting_2,\ntable.dataTable.order-column.hover tbody tr.even:hover > .sorting_2 {\n  background-color: #ebebeb;\n}\ntable.dataTable.display tbody tr:hover > .sorting_3,\ntable.dataTable.display tbody tr.odd:hover > .sorting_3,\ntable.dataTable.display tbody tr.even:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3,\ntable.dataTable.order-column.hover tbody tr.odd:hover > .sorting_3,\ntable.dataTable.order-column.hover tbody tr.even:hover > .sorting_3 {\n  background-color: #eeeeee;\n}\ntable.dataTable.display tbody tr:hover.selected > .sorting_1,\ntable.dataTable.display tbody tr.odd:hover.selected > .sorting_1,\ntable.dataTable.display tbody tr.even:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1,\ntable.dataTable.order-column.hover tbody tr.odd:hover.selected > .sorting_1,\ntable.dataTable.order-column.hover tbody tr.even:hover.selected > .sorting_1 {\n  background-color: #a1aec7;\n}\ntable.dataTable.display tbody tr:hover.selected > .sorting_2,\ntable.dataTable.display tbody tr.odd:hover.selected > .sorting_2,\ntable.dataTable.display tbody tr.even:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2,\ntable.dataTable.order-column.hover tbody tr.odd:hover.selected > .sorting_2,\ntable.dataTable.order-column.hover tbody tr.even:hover.selected > .sorting_2 {\n  background-color: #a2afc8;\n}\ntable.dataTable.display tbody tr:hover.selected > .sorting_3,\ntable.dataTable.display tbody tr.odd:hover.selected > .sorting_3,\ntable.dataTable.display tbody tr.even:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3,\ntable.dataTable.order-column.hover tbody tr.odd:hover.selected > .sorting_3,\ntable.dataTable.order-column.hover tbody tr.even:hover.selected > .sorting_3 {\n  background-color: #a4b2cb;\n}\ntable.dataTable.nowrap th, table.dataTable.nowrap td {\n  white-space: nowrap;\n}\ntable.dataTable.compact thead th,\ntable.dataTable.compact thead td {\n  padding: 5px 9px;\n}\ntable.dataTable.compact tfoot th,\ntable.dataTable.compact tfoot td {\n  padding: 5px 9px 3px 9px;\n}\ntable.dataTable.compact tbody th,\ntable.dataTable.compact tbody td {\n  padding: 4px 5px;\n}\ntable.dataTable th.dt-left,\ntable.dataTable td.dt-left {\n  text-align: left;\n}\ntable.dataTable th.dt-center,\ntable.dataTable td.dt-center,\ntable.dataTable td.dataTables_empty {\n  text-align: center;\n}\ntable.dataTable th.dt-right,\ntable.dataTable td.dt-right {\n  text-align: right;\n}\ntable.dataTable th.dt-justify,\ntable.dataTable td.dt-justify {\n  text-align: justify;\n}\ntable.dataTable th.dt-nowrap,\ntable.dataTable td.dt-nowrap {\n  white-space: nowrap;\n}\ntable.dataTable thead th.dt-head-left,\ntable.dataTable thead td.dt-head-left,\ntable.dataTable tfoot th.dt-head-left,\ntable.dataTable tfoot td.dt-head-left {\n  text-align: left;\n}\ntable.dataTable thead th.dt-head-center,\ntable.dataTable thead td.dt-head-center,\ntable.dataTable tfoot th.dt-head-center,\ntable.dataTable tfoot td.dt-head-center {\n  text-align: center;\n}\ntable.dataTable thead th.dt-head-right,\ntable.dataTable thead td.dt-head-right,\ntable.dataTable tfoot th.dt-head-right,\ntable.dataTable tfoot td.dt-head-right {\n  text-align: right;\n}\ntable.dataTable thead th.dt-head-justify,\ntable.dataTable thead td.dt-head-justify,\ntable.dataTable tfoot th.dt-head-justify,\ntable.dataTable tfoot td.dt-head-justify {\n  text-align: justify;\n}\ntable.dataTable thead th.dt-head-nowrap,\ntable.dataTable thead td.dt-head-nowrap,\ntable.dataTable tfoot th.dt-head-nowrap,\ntable.dataTable tfoot td.dt-head-nowrap {\n  white-space: nowrap;\n}\ntable.dataTable tbody th.dt-body-left,\ntable.dataTable tbody td.dt-body-left {\n  text-align: left;\n}\ntable.dataTable tbody th.dt-body-center,\ntable.dataTable tbody td.dt-body-center {\n  text-align: center;\n}\ntable.dataTable tbody th.dt-body-right,\ntable.dataTable tbody td.dt-body-right {\n  text-align: right;\n}\ntable.dataTable tbody th.dt-body-justify,\ntable.dataTable tbody td.dt-body-justify {\n  text-align: justify;\n}\ntable.dataTable tbody th.dt-body-nowrap,\ntable.dataTable tbody td.dt-body-nowrap {\n  white-space: nowrap;\n}\n\ntable.dataTable,\ntable.dataTable th,\ntable.dataTable td {\n  -webkit-box-sizing: content-box;\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n}\n\n/*\n * Control feature layout\n */\n.dataTables_wrapper {\n  position: relative;\n  clear: both;\n  *zoom: 1;\n  zoom: 1;\n}\n.dataTables_wrapper .dataTables_length {\n  float: left;\n}\n.dataTables_wrapper .dataTables_filter {\n  float: right;\n  text-align: right;\n}\n.dataTables_wrapper .dataTables_filter input {\n  margin-left: 0.5em;\n}\n.dataTables_wrapper .dataTables_info {\n  clear: both;\n  float: left;\n  padding-top: 0.55em;\n}\n.dataTables_wrapper .dataTables_paginate {\n  float: right;\n  text-align: right;\n}\n.dataTables_wrapper .dataTables_paginate .fg-button {\n  box-sizing: border-box;\n  display: inline-block;\n  min-width: 1.5em;\n  padding: 0.5em;\n  margin-left: 2px;\n  text-align: center;\n  text-decoration: none !important;\n  cursor: pointer;\n  *cursor: hand;\n  color: #333 !important;\n  border: 1px solid transparent;\n}\n.dataTables_wrapper .dataTables_paginate .fg-button:active {\n  outline: none;\n}\n.dataTables_wrapper .dataTables_paginate .fg-button:first-child {\n  border-top-left-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.dataTables_wrapper .dataTables_paginate .fg-button:last-child {\n  border-top-right-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n.dataTables_wrapper .dataTables_processing {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  width: 100%;\n  height: 40px;\n  margin-left: -50%;\n  margin-top: -25px;\n  padding-top: 20px;\n  text-align: center;\n  font-size: 1.2em;\n  background-color: white;\n  background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0)));\n  /* Chrome,Safari4+ */\n  background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  /* Chrome10+,Safari5.1+ */\n  background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  /* FF3.6+ */\n  background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  /* IE10+ */\n  background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  /* Opera 11.10+ */\n  background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  /* W3C */\n}\n.dataTables_wrapper .dataTables_length,\n.dataTables_wrapper .dataTables_filter,\n.dataTables_wrapper .dataTables_info,\n.dataTables_wrapper .dataTables_processing,\n.dataTables_wrapper .dataTables_paginate {\n  color: #333;\n}\n.dataTables_wrapper .dataTables_scroll {\n  clear: both;\n}\n.dataTables_wrapper .dataTables_scrollBody {\n  *margin-top: -1px;\n  -webkit-overflow-scrolling: touch;\n}\n.dataTables_wrapper .ui-widget-header {\n  font-weight: normal;\n}\n.dataTables_wrapper .ui-toolbar {\n  padding: 8px;\n}\n.dataTables_wrapper:after {\n  visibility: hidden;\n  display: block;\n  content: \"\";\n  clear: both;\n  height: 0;\n}\n\n@media screen and (max-width: 767px) {\n  .dataTables_wrapper .dataTables_length,\n  .dataTables_wrapper .dataTables_filter,\n  .dataTables_wrapper .dataTables_info,\n  .dataTables_wrapper .dataTables_paginate {\n    float: none;\n    text-align: center;\n  }\n  .dataTables_wrapper .dataTables_filter,\n  .dataTables_wrapper .dataTables_paginate {\n    margin-top: 0.5em;\n  }\n}\n"
  },
  {
    "path": "static/plugins/datatables/js/jquery.dataTables.js",
    "content": "/*! DataTables 1.10.12\n * ©2008-2015 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * @summary     DataTables\n * @description Paginate, search and order HTML tables\n * @version     1.10.12\n * @file        jquery.dataTables.js\n * @author      SpryMedia Ltd (www.sprymedia.co.uk)\n * @contact     www.sprymedia.co.uk/contact\n * @copyright   Copyright 2008-2015 SpryMedia Ltd.\n *\n * This source file is free software, available under the following license:\n *   MIT license - http://datatables.net/license\n *\n * This source file is distributed in the hope that it will be useful, but\n * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.\n *\n * For details please refer to: http://www.datatables.net\n */\n\n/*jslint evil: true, undef: true, browser: true */\n/*globals $,require,jQuery,define,_selector_run,_selector_opts,_selector_first,_selector_row_indexes,_ext,_Api,_api_register,_api_registerPlural,_re_new_lines,_re_html,_re_formatted_numeric,_re_escape_regex,_empty,_intVal,_numToDecimal,_isNumber,_isHtml,_htmlNumeric,_pluck,_pluck_order,_range,_stripHtml,_unique,_fnBuildAjax,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAjaxDataSrc,_fnAddColumn,_fnColumnOptions,_fnAdjustColumnSizing,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnVisbleColumns,_fnGetColumns,_fnColumnTypes,_fnApplyColumnDefs,_fnHungarianMap,_fnCamelToHungarian,_fnLanguageCompat,_fnBrowserDetect,_fnAddData,_fnAddTr,_fnNodeToDataIndex,_fnNodeToColumnIndex,_fnGetCellData,_fnSetCellData,_fnSplitObjNotation,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnGetDataMaster,_fnClearTable,_fnDeleteIndex,_fnInvalidate,_fnGetRowElements,_fnCreateTr,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAddOptionsHtml,_fnDetectHeader,_fnGetUniqueThs,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnFilterCreateSearch,_fnEscapeRegex,_fnFilterData,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnInfoMacros,_fnInitialise,_fnInitComplete,_fnLengthChange,_fnFeatureHtmlLength,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnFeatureHtmlTable,_fnScrollDraw,_fnApplyToChildren,_fnCalculateColumnWidths,_fnThrottle,_fnConvertToWidth,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/\n\n(function( factory ) {\n\t\"use strict\";\n\n\tif ( typeof define === 'function' && define.amd ) {\n\t\t// AMD\n\t\tdefine( ['jquery'], function ( $ ) {\n\t\t\treturn factory( $, window, document );\n\t\t} );\n\t}\n\telse if ( typeof exports === 'object' ) {\n\t\t// CommonJS\n\t\tmodule.exports = function (root, $) {\n\t\t\tif ( ! root ) {\n\t\t\t\t// CommonJS environments without a window global must pass a\n\t\t\t\t// root. This will give an error otherwise\n\t\t\t\troot = window;\n\t\t\t}\n\n\t\t\tif ( ! $ ) {\n\t\t\t\t$ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window\n\t\t\t\t\trequire('jquery') :\n\t\t\t\t\trequire('jquery')( root );\n\t\t\t}\n\n\t\t\treturn factory( $, root, root.document );\n\t\t};\n\t}\n\telse {\n\t\t// Browser\n\t\tfactory( jQuery, window, document );\n\t}\n}\n(function( $, window, document, undefined ) {\n\t\"use strict\";\n\n\t/**\n\t * DataTables is a plug-in for the jQuery Javascript library. It is a highly\n\t * flexible tool, based upon the foundations of progressive enhancement,\n\t * which will add advanced interaction controls to any HTML table. For a\n\t * full list of features please refer to\n\t * [DataTables.net](href=\"http://datatables.net).\n\t *\n\t * Note that the `DataTable` object is not a global variable but is aliased\n\t * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may\n\t * be  accessed.\n\t *\n\t *  @class\n\t *  @param {object} [init={}] Configuration object for DataTables. Options\n\t *    are defined by {@link DataTable.defaults}\n\t *  @requires jQuery 1.7+\n\t *\n\t *  @example\n\t *    // Basic initialisation\n\t *    $(document).ready( function {\n\t *      $('#example').dataTable();\n\t *    } );\n\t *\n\t *  @example\n\t *    // Initialisation with configuration options - in this case, disable\n\t *    // pagination and sorting.\n\t *    $(document).ready( function {\n\t *      $('#example').dataTable( {\n\t *        \"paginate\": false,\n\t *        \"sort\": false\n\t *      } );\n\t *    } );\n\t */\n\tvar DataTable = function ( options )\n\t{\n\t\t/**\n\t\t * Perform a jQuery selector action on the table's TR elements (from the tbody) and\n\t\t * return the resulting jQuery object.\n\t\t *  @param {string|node|jQuery} sSelector jQuery selector or node collection to act on\n\t\t *  @param {object} [oOpts] Optional parameters for modifying the rows to be included\n\t\t *  @param {string} [oOpts.filter=none] Select TR elements that meet the current filter\n\t\t *    criterion (\"applied\") or all TR elements (i.e. no filter).\n\t\t *  @param {string} [oOpts.order=current] Order of the TR elements in the processed array.\n\t\t *    Can be either 'current', whereby the current sorting of the table is used, or\n\t\t *    'original' whereby the original order the data was read into the table is used.\n\t\t *  @param {string} [oOpts.page=all] Limit the selection to the currently displayed page\n\t\t *    (\"current\") or not (\"all\"). If 'current' is given, then order is assumed to be\n\t\t *    'current' and filter is 'applied', regardless of what they might be given as.\n\t\t *  @returns {object} jQuery object, filtered by the given selector.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Highlight every second row\n\t\t *      oTable.$('tr:odd').css('backgroundColor', 'blue');\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Filter to rows with 'Webkit' in them, add a background colour and then\n\t\t *      // remove the filter, thus highlighting the 'Webkit' rows only.\n\t\t *      oTable.fnFilter('Webkit');\n\t\t *      oTable.$('tr', {\"search\": \"applied\"}).css('backgroundColor', 'blue');\n\t\t *      oTable.fnFilter('');\n\t\t *    } );\n\t\t */\n\t\tthis.$ = function ( sSelector, oOpts )\n\t\t{\n\t\t\treturn this.api(true).$( sSelector, oOpts );\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Almost identical to $ in operation, but in this case returns the data for the matched\n\t\t * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes\n\t\t * rather than any descendants, so the data can be obtained for the row/cell. If matching\n\t\t * rows are found, the data returned is the original data array/object that was used to\n\t\t * create the row (or a generated array if from a DOM source).\n\t\t *\n\t\t * This method is often useful in-combination with $ where both functions are given the\n\t\t * same parameters and the array indexes will match identically.\n\t\t *  @param {string|node|jQuery} sSelector jQuery selector or node collection to act on\n\t\t *  @param {object} [oOpts] Optional parameters for modifying the rows to be included\n\t\t *  @param {string} [oOpts.filter=none] Select elements that meet the current filter\n\t\t *    criterion (\"applied\") or all elements (i.e. no filter).\n\t\t *  @param {string} [oOpts.order=current] Order of the data in the processed array.\n\t\t *    Can be either 'current', whereby the current sorting of the table is used, or\n\t\t *    'original' whereby the original order the data was read into the table is used.\n\t\t *  @param {string} [oOpts.page=all] Limit the selection to the currently displayed page\n\t\t *    (\"current\") or not (\"all\"). If 'current' is given, then order is assumed to be\n\t\t *    'current' and filter is 'applied', regardless of what they might be given as.\n\t\t *  @returns {array} Data for the matched elements. If any elements, as a result of the\n\t\t *    selector, were not TR, TD or TH elements in the DataTable, they will have a null\n\t\t *    entry in the array.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Get the data from the first row in the table\n\t\t *      var data = oTable._('tr:first');\n\t\t *\n\t\t *      // Do something useful with the data\n\t\t *      alert( \"First cell is: \"+data[0] );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Filter to 'Webkit' and get all data for\n\t\t *      oTable.fnFilter('Webkit');\n\t\t *      var data = oTable._('tr', {\"search\": \"applied\"});\n\t\t *\n\t\t *      // Do something with the data\n\t\t *      alert( data.length+\" rows matched the search\" );\n\t\t *    } );\n\t\t */\n\t\tthis._ = function ( sSelector, oOpts )\n\t\t{\n\t\t\treturn this.api(true).rows( sSelector, oOpts ).data();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Create a DataTables Api instance, with the currently selected tables for\n\t\t * the Api's context.\n\t\t * @param {boolean} [traditional=false] Set the API instance's context to be\n\t\t *   only the table referred to by the `DataTable.ext.iApiIndex` option, as was\n\t\t *   used in the API presented by DataTables 1.9- (i.e. the traditional mode),\n\t\t *   or if all tables captured in the jQuery object should be used.\n\t\t * @return {DataTables.Api}\n\t\t */\n\t\tthis.api = function ( traditional )\n\t\t{\n\t\t\treturn traditional ?\n\t\t\t\tnew _Api(\n\t\t\t\t\t_fnSettingsFromNode( this[ _ext.iApiIndex ] )\n\t\t\t\t) :\n\t\t\t\tnew _Api( this );\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Add a single new row or multiple rows of data to the table. Please note\n\t\t * that this is suitable for client-side processing only - if you are using\n\t\t * server-side processing (i.e. \"bServerSide\": true), then to add data, you\n\t\t * must add it to the data source, i.e. the server-side, through an Ajax call.\n\t\t *  @param {array|object} data The data to be added to the table. This can be:\n\t\t *    <ul>\n\t\t *      <li>1D array of data - add a single row with the data provided</li>\n\t\t *      <li>2D array of arrays - add multiple rows in a single call</li>\n\t\t *      <li>object - data object when using <i>mData</i></li>\n\t\t *      <li>array of objects - multiple data objects when using <i>mData</i></li>\n\t\t *    </ul>\n\t\t *  @param {bool} [redraw=true] redraw the table or not\n\t\t *  @returns {array} An array of integers, representing the list of indexes in\n\t\t *    <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to\n\t\t *    the table.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    // Global var for counter\n\t\t *    var giCount = 2;\n\t\t *\n\t\t *    $(document).ready(function() {\n\t\t *      $('#example').dataTable();\n\t\t *    } );\n\t\t *\n\t\t *    function fnClickAddRow() {\n\t\t *      $('#example').dataTable().fnAddData( [\n\t\t *        giCount+\".1\",\n\t\t *        giCount+\".2\",\n\t\t *        giCount+\".3\",\n\t\t *        giCount+\".4\" ]\n\t\t *      );\n\t\t *\n\t\t *      giCount++;\n\t\t *    }\n\t\t */\n\t\tthis.fnAddData = function( data, redraw )\n\t\t{\n\t\t\tvar api = this.api( true );\n\t\t\n\t\t\t/* Check if we want to add multiple rows or not */\n\t\t\tvar rows = $.isArray(data) && ( $.isArray(data[0]) || $.isPlainObject(data[0]) ) ?\n\t\t\t\tapi.rows.add( data ) :\n\t\t\t\tapi.row.add( data );\n\t\t\n\t\t\tif ( redraw === undefined || redraw ) {\n\t\t\t\tapi.draw();\n\t\t\t}\n\t\t\n\t\t\treturn rows.flatten().toArray();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * This function will make DataTables recalculate the column sizes, based on the data\n\t\t * contained in the table and the sizes applied to the columns (in the DOM, CSS or\n\t\t * through the sWidth parameter). This can be useful when the width of the table's\n\t\t * parent element changes (for example a window resize).\n\t\t *  @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable( {\n\t\t *        \"sScrollY\": \"200px\",\n\t\t *        \"bPaginate\": false\n\t\t *      } );\n\t\t *\n\t\t *      $(window).bind('resize', function () {\n\t\t *        oTable.fnAdjustColumnSizing();\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\tthis.fnAdjustColumnSizing = function ( bRedraw )\n\t\t{\n\t\t\tvar api = this.api( true ).columns.adjust();\n\t\t\tvar settings = api.settings()[0];\n\t\t\tvar scroll = settings.oScroll;\n\t\t\n\t\t\tif ( bRedraw === undefined || bRedraw ) {\n\t\t\t\tapi.draw( false );\n\t\t\t}\n\t\t\telse if ( scroll.sX !== \"\" || scroll.sY !== \"\" ) {\n\t\t\t\t/* If not redrawing, but scrolling, we want to apply the new column sizes anyway */\n\t\t\t\t_fnScrollDraw( settings );\n\t\t\t}\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Quickly and simply clear a table\n\t\t *  @param {bool} [bRedraw=true] redraw the table or not\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)\n\t\t *      oTable.fnClearTable();\n\t\t *    } );\n\t\t */\n\t\tthis.fnClearTable = function( bRedraw )\n\t\t{\n\t\t\tvar api = this.api( true ).clear();\n\t\t\n\t\t\tif ( bRedraw === undefined || bRedraw ) {\n\t\t\t\tapi.draw();\n\t\t\t}\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * The exact opposite of 'opening' a row, this function will close any rows which\n\t\t * are currently 'open'.\n\t\t *  @param {node} nTr the table row to 'close'\n\t\t *  @returns {int} 0 on success, or 1 if failed (can't find the row)\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable;\n\t\t *\n\t\t *      // 'open' an information row when a row is clicked on\n\t\t *      $('#example tbody tr').click( function () {\n\t\t *        if ( oTable.fnIsOpen(this) ) {\n\t\t *          oTable.fnClose( this );\n\t\t *        } else {\n\t\t *          oTable.fnOpen( this, \"Temporary row opened\", \"info_row\" );\n\t\t *        }\n\t\t *      } );\n\t\t *\n\t\t *      oTable = $('#example').dataTable();\n\t\t *    } );\n\t\t */\n\t\tthis.fnClose = function( nTr )\n\t\t{\n\t\t\tthis.api( true ).row( nTr ).child.hide();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Remove a row for the table\n\t\t *  @param {mixed} target The index of the row from aoData to be deleted, or\n\t\t *    the TR element you want to delete\n\t\t *  @param {function|null} [callBack] Callback function\n\t\t *  @param {bool} [redraw=true] Redraw the table or not\n\t\t *  @returns {array} The row that was deleted\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Immediately remove the first row\n\t\t *      oTable.fnDeleteRow( 0 );\n\t\t *    } );\n\t\t */\n\t\tthis.fnDeleteRow = function( target, callback, redraw )\n\t\t{\n\t\t\tvar api = this.api( true );\n\t\t\tvar rows = api.rows( target );\n\t\t\tvar settings = rows.settings()[0];\n\t\t\tvar data = settings.aoData[ rows[0][0] ];\n\t\t\n\t\t\trows.remove();\n\t\t\n\t\t\tif ( callback ) {\n\t\t\t\tcallback.call( this, settings, data );\n\t\t\t}\n\t\t\n\t\t\tif ( redraw === undefined || redraw ) {\n\t\t\t\tapi.draw();\n\t\t\t}\n\t\t\n\t\t\treturn data;\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Restore the table to it's original state in the DOM by removing all of DataTables\n\t\t * enhancements, alterations to the DOM structure of the table and event listeners.\n\t\t *  @param {boolean} [remove=false] Completely remove the table from the DOM\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      // This example is fairly pointless in reality, but shows how fnDestroy can be used\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *      oTable.fnDestroy();\n\t\t *    } );\n\t\t */\n\t\tthis.fnDestroy = function ( remove )\n\t\t{\n\t\t\tthis.api( true ).destroy( remove );\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Redraw the table\n\t\t *  @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Re-draw the table - you wouldn't want to do it here, but it's an example :-)\n\t\t *      oTable.fnDraw();\n\t\t *    } );\n\t\t */\n\t\tthis.fnDraw = function( complete )\n\t\t{\n\t\t\t// Note that this isn't an exact match to the old call to _fnDraw - it takes\n\t\t\t// into account the new data, but can hold position.\n\t\t\tthis.api( true ).draw( complete );\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Filter the input based on data\n\t\t *  @param {string} sInput String to filter the table on\n\t\t *  @param {int|null} [iColumn] Column to limit filtering to\n\t\t *  @param {bool} [bRegex=false] Treat as regular expression or not\n\t\t *  @param {bool} [bSmart=true] Perform smart filtering or not\n\t\t *  @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)\n\t\t *  @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Sometime later - filter...\n\t\t *      oTable.fnFilter( 'test string' );\n\t\t *    } );\n\t\t */\n\t\tthis.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive )\n\t\t{\n\t\t\tvar api = this.api( true );\n\t\t\n\t\t\tif ( iColumn === null || iColumn === undefined ) {\n\t\t\t\tapi.search( sInput, bRegex, bSmart, bCaseInsensitive );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tapi.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive );\n\t\t\t}\n\t\t\n\t\t\tapi.draw();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Get the data for the whole table, an individual row or an individual cell based on the\n\t\t * provided parameters.\n\t\t *  @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as\n\t\t *    a TR node then the data source for the whole row will be returned. If given as a\n\t\t *    TD/TH cell node then iCol will be automatically calculated and the data for the\n\t\t *    cell returned. If given as an integer, then this is treated as the aoData internal\n\t\t *    data index for the row (see fnGetPosition) and the data for that row used.\n\t\t *  @param {int} [col] Optional column index that you want the data of.\n\t\t *  @returns {array|object|string} If mRow is undefined, then the data for all rows is\n\t\t *    returned. If mRow is defined, just data for that row, and is iCol is\n\t\t *    defined, only data for the designated cell is returned.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    // Row data\n\t\t *    $(document).ready(function() {\n\t\t *      oTable = $('#example').dataTable();\n\t\t *\n\t\t *      oTable.$('tr').click( function () {\n\t\t *        var data = oTable.fnGetData( this );\n\t\t *        // ... do something with the array / object of data for the row\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Individual cell data\n\t\t *    $(document).ready(function() {\n\t\t *      oTable = $('#example').dataTable();\n\t\t *\n\t\t *      oTable.$('td').click( function () {\n\t\t *        var sData = oTable.fnGetData( this );\n\t\t *        alert( 'The cell clicked on had the value of '+sData );\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\tthis.fnGetData = function( src, col )\n\t\t{\n\t\t\tvar api = this.api( true );\n\t\t\n\t\t\tif ( src !== undefined ) {\n\t\t\t\tvar type = src.nodeName ? src.nodeName.toLowerCase() : '';\n\t\t\n\t\t\t\treturn col !== undefined || type == 'td' || type == 'th' ?\n\t\t\t\t\tapi.cell( src, col ).data() :\n\t\t\t\t\tapi.row( src ).data() || null;\n\t\t\t}\n\t\t\n\t\t\treturn api.data().toArray();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Get an array of the TR nodes that are used in the table's body. Note that you will\n\t\t * typically want to use the '$' API method in preference to this as it is more\n\t\t * flexible.\n\t\t *  @param {int} [iRow] Optional row index for the TR element you want\n\t\t *  @returns {array|node} If iRow is undefined, returns an array of all TR elements\n\t\t *    in the table's body, or iRow is defined, just the TR element requested.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Get the nodes from the table\n\t\t *      var nNodes = oTable.fnGetNodes( );\n\t\t *    } );\n\t\t */\n\t\tthis.fnGetNodes = function( iRow )\n\t\t{\n\t\t\tvar api = this.api( true );\n\t\t\n\t\t\treturn iRow !== undefined ?\n\t\t\t\tapi.row( iRow ).node() :\n\t\t\t\tapi.rows().nodes().flatten().toArray();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Get the array indexes of a particular cell from it's DOM element\n\t\t * and column index including hidden columns\n\t\t *  @param {node} node this can either be a TR, TD or TH in the table's body\n\t\t *  @returns {int} If nNode is given as a TR, then a single index is returned, or\n\t\t *    if given as a cell, an array of [row index, column index (visible),\n\t\t *    column index (all)] is given.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      $('#example tbody td').click( function () {\n\t\t *        // Get the position of the current data from the node\n\t\t *        var aPos = oTable.fnGetPosition( this );\n\t\t *\n\t\t *        // Get the data array for this row\n\t\t *        var aData = oTable.fnGetData( aPos[0] );\n\t\t *\n\t\t *        // Update the data array and return the value\n\t\t *        aData[ aPos[1] ] = 'clicked';\n\t\t *        this.innerHTML = 'clicked';\n\t\t *      } );\n\t\t *\n\t\t *      // Init DataTables\n\t\t *      oTable = $('#example').dataTable();\n\t\t *    } );\n\t\t */\n\t\tthis.fnGetPosition = function( node )\n\t\t{\n\t\t\tvar api = this.api( true );\n\t\t\tvar nodeName = node.nodeName.toUpperCase();\n\t\t\n\t\t\tif ( nodeName == 'TR' ) {\n\t\t\t\treturn api.row( node ).index();\n\t\t\t}\n\t\t\telse if ( nodeName == 'TD' || nodeName == 'TH' ) {\n\t\t\t\tvar cell = api.cell( node ).index();\n\t\t\n\t\t\t\treturn [\n\t\t\t\t\tcell.row,\n\t\t\t\t\tcell.columnVisible,\n\t\t\t\t\tcell.column\n\t\t\t\t];\n\t\t\t}\n\t\t\treturn null;\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Check to see if a row is 'open' or not.\n\t\t *  @param {node} nTr the table row to check\n\t\t *  @returns {boolean} true if the row is currently open, false otherwise\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable;\n\t\t *\n\t\t *      // 'open' an information row when a row is clicked on\n\t\t *      $('#example tbody tr').click( function () {\n\t\t *        if ( oTable.fnIsOpen(this) ) {\n\t\t *          oTable.fnClose( this );\n\t\t *        } else {\n\t\t *          oTable.fnOpen( this, \"Temporary row opened\", \"info_row\" );\n\t\t *        }\n\t\t *      } );\n\t\t *\n\t\t *      oTable = $('#example').dataTable();\n\t\t *    } );\n\t\t */\n\t\tthis.fnIsOpen = function( nTr )\n\t\t{\n\t\t\treturn this.api( true ).row( nTr ).child.isShown();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * This function will place a new row directly after a row which is currently\n\t\t * on display on the page, with the HTML contents that is passed into the\n\t\t * function. This can be used, for example, to ask for confirmation that a\n\t\t * particular record should be deleted.\n\t\t *  @param {node} nTr The table row to 'open'\n\t\t *  @param {string|node|jQuery} mHtml The HTML to put into the row\n\t\t *  @param {string} sClass Class to give the new TD cell\n\t\t *  @returns {node} The row opened. Note that if the table row passed in as the\n\t\t *    first parameter, is not found in the table, this method will silently\n\t\t *    return.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable;\n\t\t *\n\t\t *      // 'open' an information row when a row is clicked on\n\t\t *      $('#example tbody tr').click( function () {\n\t\t *        if ( oTable.fnIsOpen(this) ) {\n\t\t *          oTable.fnClose( this );\n\t\t *        } else {\n\t\t *          oTable.fnOpen( this, \"Temporary row opened\", \"info_row\" );\n\t\t *        }\n\t\t *      } );\n\t\t *\n\t\t *      oTable = $('#example').dataTable();\n\t\t *    } );\n\t\t */\n\t\tthis.fnOpen = function( nTr, mHtml, sClass )\n\t\t{\n\t\t\treturn this.api( true )\n\t\t\t\t.row( nTr )\n\t\t\t\t.child( mHtml, sClass )\n\t\t\t\t.show()\n\t\t\t\t.child()[0];\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Change the pagination - provides the internal logic for pagination in a simple API\n\t\t * function. With this function you can have a DataTables table go to the next,\n\t\t * previous, first or last pages.\n\t\t *  @param {string|int} mAction Paging action to take: \"first\", \"previous\", \"next\" or \"last\"\n\t\t *    or page number to jump to (integer), note that page 0 is the first page.\n\t\t *  @param {bool} [bRedraw=true] Redraw the table or not\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *      oTable.fnPageChange( 'next' );\n\t\t *    } );\n\t\t */\n\t\tthis.fnPageChange = function ( mAction, bRedraw )\n\t\t{\n\t\t\tvar api = this.api( true ).page( mAction );\n\t\t\n\t\t\tif ( bRedraw === undefined || bRedraw ) {\n\t\t\t\tapi.draw(false);\n\t\t\t}\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Show a particular column\n\t\t *  @param {int} iCol The column whose display should be changed\n\t\t *  @param {bool} bShow Show (true) or hide (false) the column\n\t\t *  @param {bool} [bRedraw=true] Redraw the table or not\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Hide the second column after initialisation\n\t\t *      oTable.fnSetColumnVis( 1, false );\n\t\t *    } );\n\t\t */\n\t\tthis.fnSetColumnVis = function ( iCol, bShow, bRedraw )\n\t\t{\n\t\t\tvar api = this.api( true ).column( iCol ).visible( bShow );\n\t\t\n\t\t\tif ( bRedraw === undefined || bRedraw ) {\n\t\t\t\tapi.columns.adjust().draw();\n\t\t\t}\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Get the settings for a particular table for external manipulation\n\t\t *  @returns {object} DataTables settings object. See\n\t\t *    {@link DataTable.models.oSettings}\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *      var oSettings = oTable.fnSettings();\n\t\t *\n\t\t *      // Show an example parameter from the settings\n\t\t *      alert( oSettings._iDisplayStart );\n\t\t *    } );\n\t\t */\n\t\tthis.fnSettings = function()\n\t\t{\n\t\t\treturn _fnSettingsFromNode( this[_ext.iApiIndex] );\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Sort the table by a particular column\n\t\t *  @param {int} iCol the data index to sort on. Note that this will not match the\n\t\t *    'display index' if you have hidden data entries\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Sort immediately with columns 0 and 1\n\t\t *      oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );\n\t\t *    } );\n\t\t */\n\t\tthis.fnSort = function( aaSort )\n\t\t{\n\t\t\tthis.api( true ).order( aaSort ).draw();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Attach a sort listener to an element for a given column\n\t\t *  @param {node} nNode the element to attach the sort listener to\n\t\t *  @param {int} iColumn the column that a click on this node will sort on\n\t\t *  @param {function} [fnCallback] callback function when sort is run\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Sort on column 1, when 'sorter' is clicked on\n\t\t *      oTable.fnSortListener( document.getElementById('sorter'), 1 );\n\t\t *    } );\n\t\t */\n\t\tthis.fnSortListener = function( nNode, iColumn, fnCallback )\n\t\t{\n\t\t\tthis.api( true ).order.listener( nNode, iColumn, fnCallback );\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Update a table cell or row - this method will accept either a single value to\n\t\t * update the cell with, an array of values with one element for each column or\n\t\t * an object in the same format as the original data source. The function is\n\t\t * self-referencing in order to make the multi column updates easier.\n\t\t *  @param {object|array|string} mData Data to update the cell/row with\n\t\t *  @param {node|int} mRow TR element you want to update or the aoData index\n\t\t *  @param {int} [iColumn] The column to update, give as null or undefined to\n\t\t *    update a whole row.\n\t\t *  @param {bool} [bRedraw=true] Redraw the table or not\n\t\t *  @param {bool} [bAction=true] Perform pre-draw actions or not\n\t\t *  @returns {int} 0 on success, 1 on error\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *      oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell\n\t\t *      oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row\n\t\t *    } );\n\t\t */\n\t\tthis.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )\n\t\t{\n\t\t\tvar api = this.api( true );\n\t\t\n\t\t\tif ( iColumn === undefined || iColumn === null ) {\n\t\t\t\tapi.row( mRow ).data( mData );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tapi.cell( mRow, iColumn ).data( mData );\n\t\t\t}\n\t\t\n\t\t\tif ( bAction === undefined || bAction ) {\n\t\t\t\tapi.columns.adjust();\n\t\t\t}\n\t\t\n\t\t\tif ( bRedraw === undefined || bRedraw ) {\n\t\t\t\tapi.draw();\n\t\t\t}\n\t\t\treturn 0;\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Provide a common method for plug-ins to check the version of DataTables being used, in order\n\t\t * to ensure compatibility.\n\t\t *  @param {string} sVersion Version string to check for, in the format \"X.Y.Z\". Note that the\n\t\t *    formats \"X\" and \"X.Y\" are also acceptable.\n\t\t *  @returns {boolean} true if this version of DataTables is greater or equal to the required\n\t\t *    version, or false if this version of DataTales is not suitable\n\t\t *  @method\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *      alert( oTable.fnVersionCheck( '1.9.0' ) );\n\t\t *    } );\n\t\t */\n\t\tthis.fnVersionCheck = _ext.fnVersionCheck;\n\t\t\n\n\t\tvar _that = this;\n\t\tvar emptyInit = options === undefined;\n\t\tvar len = this.length;\n\n\t\tif ( emptyInit ) {\n\t\t\toptions = {};\n\t\t}\n\n\t\tthis.oApi = this.internal = _ext.internal;\n\n\t\t// Extend with old style plug-in API methods\n\t\tfor ( var fn in DataTable.ext.internal ) {\n\t\t\tif ( fn ) {\n\t\t\t\tthis[fn] = _fnExternApiFunc(fn);\n\t\t\t}\n\t\t}\n\n\t\tthis.each(function() {\n\t\t\t// For each initialisation we want to give it a clean initialisation\n\t\t\t// object that can be bashed around\n\t\t\tvar o = {};\n\t\t\tvar oInit = len > 1 ? // optimisation for single table case\n\t\t\t\t_fnExtend( o, options, true ) :\n\t\t\t\toptions;\n\n\t\t\t/*global oInit,_that,emptyInit*/\n\t\t\tvar i=0, iLen, j, jLen, k, kLen;\n\t\t\tvar sId = this.getAttribute( 'id' );\n\t\t\tvar bInitHandedOff = false;\n\t\t\tvar defaults = DataTable.defaults;\n\t\t\tvar $this = $(this);\n\t\t\t\n\t\t\t\n\t\t\t/* Sanity check */\n\t\t\tif ( this.nodeName.toLowerCase() != 'table' )\n\t\t\t{\n\t\t\t\t_fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 );\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\t/* Backwards compatibility for the defaults */\n\t\t\t_fnCompatOpts( defaults );\n\t\t\t_fnCompatCols( defaults.column );\n\t\t\t\n\t\t\t/* Convert the camel-case defaults to Hungarian */\n\t\t\t_fnCamelToHungarian( defaults, defaults, true );\n\t\t\t_fnCamelToHungarian( defaults.column, defaults.column, true );\n\t\t\t\n\t\t\t/* Setting up the initialisation object */\n\t\t\t_fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ) );\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t/* Check to see if we are re-initialising a table */\n\t\t\tvar allSettings = DataTable.settings;\n\t\t\tfor ( i=0, iLen=allSettings.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tvar s = allSettings[i];\n\t\t\t\n\t\t\t\t/* Base check on table node */\n\t\t\t\tif ( s.nTable == this || s.nTHead.parentNode == this || (s.nTFoot && s.nTFoot.parentNode == this) )\n\t\t\t\t{\n\t\t\t\t\tvar bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;\n\t\t\t\t\tvar bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;\n\t\t\t\n\t\t\t\t\tif ( emptyInit || bRetrieve )\n\t\t\t\t\t{\n\t\t\t\t\t\treturn s.oInstance;\n\t\t\t\t\t}\n\t\t\t\t\telse if ( bDestroy )\n\t\t\t\t\t{\n\t\t\t\t\t\ts.oInstance.fnDestroy();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t_fnLog( s, 0, 'Cannot reinitialise DataTable', 3 );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\n\t\t\t\t/* If the element we are initialising has the same ID as a table which was previously\n\t\t\t\t * initialised, but the table nodes don't match (from before) then we destroy the old\n\t\t\t\t * instance by simply deleting it. This is under the assumption that the table has been\n\t\t\t\t * destroyed by other methods. Anyone using non-id selectors will need to do this manually\n\t\t\t\t */\n\t\t\t\tif ( s.sTableId == this.id )\n\t\t\t\t{\n\t\t\t\t\tallSettings.splice( i, 1 );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t/* Ensure the table has an ID - required for accessibility */\n\t\t\tif ( sId === null || sId === \"\" )\n\t\t\t{\n\t\t\t\tsId = \"DataTables_Table_\"+(DataTable.ext._unique++);\n\t\t\t\tthis.id = sId;\n\t\t\t}\n\t\t\t\n\t\t\t/* Create the settings object for this table and set some of the default parameters */\n\t\t\tvar oSettings = $.extend( true, {}, DataTable.models.oSettings, {\n\t\t\t\t\"sDestroyWidth\": $this[0].style.width,\n\t\t\t\t\"sInstance\":     sId,\n\t\t\t\t\"sTableId\":      sId\n\t\t\t} );\n\t\t\toSettings.nTable = this;\n\t\t\toSettings.oApi   = _that.internal;\n\t\t\toSettings.oInit  = oInit;\n\t\t\t\n\t\t\tallSettings.push( oSettings );\n\t\t\t\n\t\t\t// Need to add the instance after the instance after the settings object has been added\n\t\t\t// to the settings array, so we can self reference the table instance if more than one\n\t\t\toSettings.oInstance = (_that.length===1) ? _that : $this.dataTable();\n\t\t\t\n\t\t\t// Backwards compatibility, before we apply all the defaults\n\t\t\t_fnCompatOpts( oInit );\n\t\t\t\n\t\t\tif ( oInit.oLanguage )\n\t\t\t{\n\t\t\t\t_fnLanguageCompat( oInit.oLanguage );\n\t\t\t}\n\t\t\t\n\t\t\t// If the length menu is given, but the init display length is not, use the length menu\n\t\t\tif ( oInit.aLengthMenu && ! oInit.iDisplayLength )\n\t\t\t{\n\t\t\t\toInit.iDisplayLength = $.isArray( oInit.aLengthMenu[0] ) ?\n\t\t\t\t\toInit.aLengthMenu[0][0] : oInit.aLengthMenu[0];\n\t\t\t}\n\t\t\t\n\t\t\t// Apply the defaults and init options to make a single init object will all\n\t\t\t// options defined from defaults and instance options.\n\t\t\toInit = _fnExtend( $.extend( true, {}, defaults ), oInit );\n\t\t\t\n\t\t\t\n\t\t\t// Map the initialisation options onto the settings object\n\t\t\t_fnMap( oSettings.oFeatures, oInit, [\n\t\t\t\t\"bPaginate\",\n\t\t\t\t\"bLengthChange\",\n\t\t\t\t\"bFilter\",\n\t\t\t\t\"bSort\",\n\t\t\t\t\"bSortMulti\",\n\t\t\t\t\"bInfo\",\n\t\t\t\t\"bProcessing\",\n\t\t\t\t\"bAutoWidth\",\n\t\t\t\t\"bSortClasses\",\n\t\t\t\t\"bServerSide\",\n\t\t\t\t\"bDeferRender\"\n\t\t\t] );\n\t\t\t_fnMap( oSettings, oInit, [\n\t\t\t\t\"asStripeClasses\",\n\t\t\t\t\"ajax\",\n\t\t\t\t\"fnServerData\",\n\t\t\t\t\"fnFormatNumber\",\n\t\t\t\t\"sServerMethod\",\n\t\t\t\t\"aaSorting\",\n\t\t\t\t\"aaSortingFixed\",\n\t\t\t\t\"aLengthMenu\",\n\t\t\t\t\"sPaginationType\",\n\t\t\t\t\"sAjaxSource\",\n\t\t\t\t\"sAjaxDataProp\",\n\t\t\t\t\"iStateDuration\",\n\t\t\t\t\"sDom\",\n\t\t\t\t\"bSortCellsTop\",\n\t\t\t\t\"iTabIndex\",\n\t\t\t\t\"fnStateLoadCallback\",\n\t\t\t\t\"fnStateSaveCallback\",\n\t\t\t\t\"renderer\",\n\t\t\t\t\"searchDelay\",\n\t\t\t\t\"rowId\",\n\t\t\t\t[ \"iCookieDuration\", \"iStateDuration\" ], // backwards compat\n\t\t\t\t[ \"oSearch\", \"oPreviousSearch\" ],\n\t\t\t\t[ \"aoSearchCols\", \"aoPreSearchCols\" ],\n\t\t\t\t[ \"iDisplayLength\", \"_iDisplayLength\" ],\n\t\t\t\t[ \"bJQueryUI\", \"bJUI\" ]\n\t\t\t] );\n\t\t\t_fnMap( oSettings.oScroll, oInit, [\n\t\t\t\t[ \"sScrollX\", \"sX\" ],\n\t\t\t\t[ \"sScrollXInner\", \"sXInner\" ],\n\t\t\t\t[ \"sScrollY\", \"sY\" ],\n\t\t\t\t[ \"bScrollCollapse\", \"bCollapse\" ]\n\t\t\t] );\n\t\t\t_fnMap( oSettings.oLanguage, oInit, \"fnInfoCallback\" );\n\t\t\t\n\t\t\t/* Callback functions which are array driven */\n\t\t\t_fnCallbackReg( oSettings, 'aoDrawCallback',       oInit.fnDrawCallback,      'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoServerParams',       oInit.fnServerParams,      'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoStateSaveParams',    oInit.fnStateSaveParams,   'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoStateLoadParams',    oInit.fnStateLoadParams,   'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoStateLoaded',        oInit.fnStateLoaded,       'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoRowCallback',        oInit.fnRowCallback,       'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow,        'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoHeaderCallback',     oInit.fnHeaderCallback,    'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoFooterCallback',     oInit.fnFooterCallback,    'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoInitComplete',       oInit.fnInitComplete,      'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoPreDrawCallback',    oInit.fnPreDrawCallback,   'user' );\n\t\t\t\n\t\t\toSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId );\n\t\t\t\n\t\t\t/* Browser support detection */\n\t\t\t_fnBrowserDetect( oSettings );\n\t\t\t\n\t\t\tvar oClasses = oSettings.oClasses;\n\t\t\t\n\t\t\t// @todo Remove in 1.11\n\t\t\tif ( oInit.bJQueryUI )\n\t\t\t{\n\t\t\t\t/* Use the JUI classes object for display. You could clone the oStdClasses object if\n\t\t\t\t * you want to have multiple tables with multiple independent classes\n\t\t\t\t */\n\t\t\t\t$.extend( oClasses, DataTable.ext.oJUIClasses, oInit.oClasses );\n\t\t\t\n\t\t\t\tif ( oInit.sDom === defaults.sDom && defaults.sDom === \"lfrtip\" )\n\t\t\t\t{\n\t\t\t\t\t/* Set the DOM to use a layout suitable for jQuery UI's theming */\n\t\t\t\t\toSettings.sDom = '<\"H\"lfr>t<\"F\"ip>';\n\t\t\t\t}\n\t\t\t\n\t\t\t\tif ( ! oSettings.renderer ) {\n\t\t\t\t\toSettings.renderer = 'jqueryui';\n\t\t\t\t}\n\t\t\t\telse if ( $.isPlainObject( oSettings.renderer ) && ! oSettings.renderer.header ) {\n\t\t\t\t\toSettings.renderer.header = 'jqueryui';\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t$.extend( oClasses, DataTable.ext.classes, oInit.oClasses );\n\t\t\t}\n\t\t\t$this.addClass( oClasses.sTable );\n\t\t\t\n\t\t\t\n\t\t\tif ( oSettings.iInitDisplayStart === undefined )\n\t\t\t{\n\t\t\t\t/* Display start point, taking into account the save saving */\n\t\t\t\toSettings.iInitDisplayStart = oInit.iDisplayStart;\n\t\t\t\toSettings._iDisplayStart = oInit.iDisplayStart;\n\t\t\t}\n\t\t\t\n\t\t\tif ( oInit.iDeferLoading !== null )\n\t\t\t{\n\t\t\t\toSettings.bDeferLoading = true;\n\t\t\t\tvar tmp = $.isArray( oInit.iDeferLoading );\n\t\t\t\toSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;\n\t\t\t\toSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;\n\t\t\t}\n\t\t\t\n\t\t\t/* Language definitions */\n\t\t\tvar oLanguage = oSettings.oLanguage;\n\t\t\t$.extend( true, oLanguage, oInit.oLanguage );\n\t\t\t\n\t\t\tif ( oLanguage.sUrl !== \"\" )\n\t\t\t{\n\t\t\t\t/* Get the language definitions from a file - because this Ajax call makes the language\n\t\t\t\t * get async to the remainder of this function we use bInitHandedOff to indicate that\n\t\t\t\t * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor\n\t\t\t\t */\n\t\t\t\t$.ajax( {\n\t\t\t\t\tdataType: 'json',\n\t\t\t\t\turl: oLanguage.sUrl,\n\t\t\t\t\tsuccess: function ( json ) {\n\t\t\t\t\t\t_fnLanguageCompat( json );\n\t\t\t\t\t\t_fnCamelToHungarian( defaults.oLanguage, json );\n\t\t\t\t\t\t$.extend( true, oLanguage, json );\n\t\t\t\t\t\t_fnInitialise( oSettings );\n\t\t\t\t\t},\n\t\t\t\t\terror: function () {\n\t\t\t\t\t\t// Error occurred loading language file, continue on as best we can\n\t\t\t\t\t\t_fnInitialise( oSettings );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\tbInitHandedOff = true;\n\t\t\t}\n\t\t\t\n\t\t\t/*\n\t\t\t * Stripes\n\t\t\t */\n\t\t\tif ( oInit.asStripeClasses === null )\n\t\t\t{\n\t\t\t\toSettings.asStripeClasses =[\n\t\t\t\t\toClasses.sStripeOdd,\n\t\t\t\t\toClasses.sStripeEven\n\t\t\t\t];\n\t\t\t}\n\t\t\t\n\t\t\t/* Remove row stripe classes if they are already on the table row */\n\t\t\tvar stripeClasses = oSettings.asStripeClasses;\n\t\t\tvar rowOne = $this.children('tbody').find('tr').eq(0);\n\t\t\tif ( $.inArray( true, $.map( stripeClasses, function(el, i) {\n\t\t\t\treturn rowOne.hasClass(el);\n\t\t\t} ) ) !== -1 ) {\n\t\t\t\t$('tbody tr', this).removeClass( stripeClasses.join(' ') );\n\t\t\t\toSettings.asDestroyStripes = stripeClasses.slice();\n\t\t\t}\n\t\t\t\n\t\t\t/*\n\t\t\t * Columns\n\t\t\t * See if we should load columns automatically or use defined ones\n\t\t\t */\n\t\t\tvar anThs = [];\n\t\t\tvar aoColumnsInit;\n\t\t\tvar nThead = this.getElementsByTagName('thead');\n\t\t\tif ( nThead.length !== 0 )\n\t\t\t{\n\t\t\t\t_fnDetectHeader( oSettings.aoHeader, nThead[0] );\n\t\t\t\tanThs = _fnGetUniqueThs( oSettings );\n\t\t\t}\n\t\t\t\n\t\t\t/* If not given a column array, generate one with nulls */\n\t\t\tif ( oInit.aoColumns === null )\n\t\t\t{\n\t\t\t\taoColumnsInit = [];\n\t\t\t\tfor ( i=0, iLen=anThs.length ; i<iLen ; i++ )\n\t\t\t\t{\n\t\t\t\t\taoColumnsInit.push( null );\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\taoColumnsInit = oInit.aoColumns;\n\t\t\t}\n\t\t\t\n\t\t\t/* Add the columns */\n\t\t\tfor ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\t_fnAddColumn( oSettings, anThs ? anThs[i] : null );\n\t\t\t}\n\t\t\t\n\t\t\t/* Apply the column definitions */\n\t\t\t_fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {\n\t\t\t\t_fnColumnOptions( oSettings, iCol, oDef );\n\t\t\t} );\n\t\t\t\n\t\t\t/* HTML5 attribute detection - build an mData object automatically if the\n\t\t\t * attributes are found\n\t\t\t */\n\t\t\tif ( rowOne.length ) {\n\t\t\t\tvar a = function ( cell, name ) {\n\t\t\t\t\treturn cell.getAttribute( 'data-'+name ) !== null ? name : null;\n\t\t\t\t};\n\t\t\t\n\t\t\t\t$( rowOne[0] ).children('th, td').each( function (i, cell) {\n\t\t\t\t\tvar col = oSettings.aoColumns[i];\n\t\t\t\n\t\t\t\t\tif ( col.mData === i ) {\n\t\t\t\t\t\tvar sort = a( cell, 'sort' ) || a( cell, 'order' );\n\t\t\t\t\t\tvar filter = a( cell, 'filter' ) || a( cell, 'search' );\n\t\t\t\n\t\t\t\t\t\tif ( sort !== null || filter !== null ) {\n\t\t\t\t\t\t\tcol.mData = {\n\t\t\t\t\t\t\t\t_:      i+'.display',\n\t\t\t\t\t\t\t\tsort:   sort !== null   ? i+'.@data-'+sort   : undefined,\n\t\t\t\t\t\t\t\ttype:   sort !== null   ? i+'.@data-'+sort   : undefined,\n\t\t\t\t\t\t\t\tfilter: filter !== null ? i+'.@data-'+filter : undefined\n\t\t\t\t\t\t\t};\n\t\t\t\n\t\t\t\t\t\t\t_fnColumnOptions( oSettings, i );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t\t\n\t\t\tvar features = oSettings.oFeatures;\n\t\t\t\n\t\t\t/* Must be done after everything which can be overridden by the state saving! */\n\t\t\tif ( oInit.bStateSave )\n\t\t\t{\n\t\t\t\tfeatures.bStateSave = true;\n\t\t\t\t_fnLoadState( oSettings, oInit );\n\t\t\t\t_fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );\n\t\t\t}\n\t\t\t\n\t\t\t\n\t\t\t/*\n\t\t\t * Sorting\n\t\t\t * @todo For modularisation (1.11) this needs to do into a sort start up handler\n\t\t\t */\n\t\t\t\n\t\t\t// If aaSorting is not defined, then we use the first indicator in asSorting\n\t\t\t// in case that has been altered, so the default sort reflects that option\n\t\t\tif ( oInit.aaSorting === undefined )\n\t\t\t{\n\t\t\t\tvar sorting = oSettings.aaSorting;\n\t\t\t\tfor ( i=0, iLen=sorting.length ; i<iLen ; i++ )\n\t\t\t\t{\n\t\t\t\t\tsorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t/* Do a first pass on the sorting classes (allows any size changes to be taken into\n\t\t\t * account, and also will apply sorting disabled classes if disabled\n\t\t\t */\n\t\t\t_fnSortingClasses( oSettings );\n\t\t\t\n\t\t\tif ( features.bSort )\n\t\t\t{\n\t\t\t\t_fnCallbackReg( oSettings, 'aoDrawCallback', function () {\n\t\t\t\t\tif ( oSettings.bSorted ) {\n\t\t\t\t\t\tvar aSort = _fnSortFlatten( oSettings );\n\t\t\t\t\t\tvar sortedColumns = {};\n\t\t\t\n\t\t\t\t\t\t$.each( aSort, function (i, val) {\n\t\t\t\t\t\t\tsortedColumns[ val.src ] = val.dir;\n\t\t\t\t\t\t} );\n\t\t\t\n\t\t\t\t\t\t_fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] );\n\t\t\t\t\t\t_fnSortAria( oSettings );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t\t\n\t\t\t_fnCallbackReg( oSettings, 'aoDrawCallback', function () {\n\t\t\t\tif ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {\n\t\t\t\t\t_fnSortingClasses( oSettings );\n\t\t\t\t}\n\t\t\t}, 'sc' );\n\t\t\t\n\t\t\t\n\t\t\t/*\n\t\t\t * Final init\n\t\t\t * Cache the header, body and footer as required, creating them if needed\n\t\t\t */\n\t\t\t\n\t\t\t// Work around for Webkit bug 83867 - store the caption-side before removing from doc\n\t\t\tvar captions = $this.children('caption').each( function () {\n\t\t\t\tthis._captionSide = $this.css('caption-side');\n\t\t\t} );\n\t\t\t\n\t\t\tvar thead = $this.children('thead');\n\t\t\tif ( thead.length === 0 )\n\t\t\t{\n\t\t\t\tthead = $('<thead/>').appendTo(this);\n\t\t\t}\n\t\t\toSettings.nTHead = thead[0];\n\t\t\t\n\t\t\tvar tbody = $this.children('tbody');\n\t\t\tif ( tbody.length === 0 )\n\t\t\t{\n\t\t\t\ttbody = $('<tbody/>').appendTo(this);\n\t\t\t}\n\t\t\toSettings.nTBody = tbody[0];\n\t\t\t\n\t\t\tvar tfoot = $this.children('tfoot');\n\t\t\tif ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== \"\" || oSettings.oScroll.sY !== \"\") )\n\t\t\t{\n\t\t\t\t// If we are a scrolling table, and no footer has been given, then we need to create\n\t\t\t\t// a tfoot element for the caption element to be appended to\n\t\t\t\ttfoot = $('<tfoot/>').appendTo(this);\n\t\t\t}\n\t\t\t\n\t\t\tif ( tfoot.length === 0 || tfoot.children().length === 0 ) {\n\t\t\t\t$this.addClass( oClasses.sNoFooter );\n\t\t\t}\n\t\t\telse if ( tfoot.length > 0 ) {\n\t\t\t\toSettings.nTFoot = tfoot[0];\n\t\t\t\t_fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );\n\t\t\t}\n\t\t\t\n\t\t\t/* Check if there is data passing into the constructor */\n\t\t\tif ( oInit.aaData )\n\t\t\t{\n\t\t\t\tfor ( i=0 ; i<oInit.aaData.length ; i++ )\n\t\t\t\t{\n\t\t\t\t\t_fnAddData( oSettings, oInit.aaData[ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' )\n\t\t\t{\n\t\t\t\t/* Grab the data from the page - only do this when deferred loading or no Ajax\n\t\t\t\t * source since there is no point in reading the DOM data if we are then going\n\t\t\t\t * to replace it with Ajax data\n\t\t\t\t */\n\t\t\t\t_fnAddTr( oSettings, $(oSettings.nTBody).children('tr') );\n\t\t\t}\n\t\t\t\n\t\t\t/* Copy the data index array */\n\t\t\toSettings.aiDisplay = oSettings.aiDisplayMaster.slice();\n\t\t\t\n\t\t\t/* Initialisation complete - table can be drawn */\n\t\t\toSettings.bInitialised = true;\n\t\t\t\n\t\t\t/* Check if we need to initialise the table (it might not have been handed off to the\n\t\t\t * language processor)\n\t\t\t */\n\t\t\tif ( bInitHandedOff === false )\n\t\t\t{\n\t\t\t\t_fnInitialise( oSettings );\n\t\t\t}\n\t\t} );\n\t\t_that = null;\n\t\treturn this;\n\t};\n\n\t\n\t/*\n\t * It is useful to have variables which are scoped locally so only the\n\t * DataTables functions can access them and they don't leak into global space.\n\t * At the same time these functions are often useful over multiple files in the\n\t * core and API, so we list, or at least document, all variables which are used\n\t * by DataTables as private variables here. This also ensures that there is no\n\t * clashing of variable names and that they can easily referenced for reuse.\n\t */\n\t\n\t\n\t// Defined else where\n\t//  _selector_run\n\t//  _selector_opts\n\t//  _selector_first\n\t//  _selector_row_indexes\n\t\n\tvar _ext; // DataTable.ext\n\tvar _Api; // DataTable.Api\n\tvar _api_register; // DataTable.Api.register\n\tvar _api_registerPlural; // DataTable.Api.registerPlural\n\t\n\tvar _re_dic = {};\n\tvar _re_new_lines = /[\\r\\n]/g;\n\tvar _re_html = /<.*?>/g;\n\tvar _re_date_start = /^[\\w\\+\\-]/;\n\tvar _re_date_end = /[\\w\\+\\-]$/;\n\t\n\t// Escape regular expression special characters\n\tvar _re_escape_regex = new RegExp( '(\\\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\\\', '$', '^', '-' ].join('|\\\\') + ')', 'g' );\n\t\n\t// http://en.wikipedia.org/wiki/Foreign_exchange_market\n\t// - \\u20BD - Russian ruble.\n\t// - \\u20a9 - South Korean Won\n\t// - \\u20BA - Turkish Lira\n\t// - \\u20B9 - Indian Rupee\n\t// - R - Brazil (R$) and South Africa\n\t// - fr - Swiss Franc\n\t// - kr - Swedish krona, Norwegian krone and Danish krone\n\t// - \\u2009 is thin space and \\u202F is narrow no-break space, both used in many\n\t//   standards as thousands separators.\n\tvar _re_formatted_numeric = /[',$£€¥%\\u2009\\u202F\\u20BD\\u20a9\\u20BArfk]/gi;\n\t\n\t\n\tvar _empty = function ( d ) {\n\t\treturn !d || d === true || d === '-' ? true : false;\n\t};\n\t\n\t\n\tvar _intVal = function ( s ) {\n\t\tvar integer = parseInt( s, 10 );\n\t\treturn !isNaN(integer) && isFinite(s) ? integer : null;\n\t};\n\t\n\t// Convert from a formatted number with characters other than `.` as the\n\t// decimal place, to a Javascript number\n\tvar _numToDecimal = function ( num, decimalPoint ) {\n\t\t// Cache created regular expressions for speed as this function is called often\n\t\tif ( ! _re_dic[ decimalPoint ] ) {\n\t\t\t_re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' );\n\t\t}\n\t\treturn typeof num === 'string' && decimalPoint !== '.' ?\n\t\t\tnum.replace( /\\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) :\n\t\t\tnum;\n\t};\n\t\n\t\n\tvar _isNumber = function ( d, decimalPoint, formatted ) {\n\t\tvar strType = typeof d === 'string';\n\t\n\t\t// If empty return immediately so there must be a number if it is a\n\t\t// formatted string (this stops the string \"k\", or \"kr\", etc being detected\n\t\t// as a formatted number for currency\n\t\tif ( _empty( d ) ) {\n\t\t\treturn true;\n\t\t}\n\t\n\t\tif ( decimalPoint && strType ) {\n\t\t\td = _numToDecimal( d, decimalPoint );\n\t\t}\n\t\n\t\tif ( formatted && strType ) {\n\t\t\td = d.replace( _re_formatted_numeric, '' );\n\t\t}\n\t\n\t\treturn !isNaN( parseFloat(d) ) && isFinite( d );\n\t};\n\t\n\t\n\t// A string without HTML in it can be considered to be HTML still\n\tvar _isHtml = function ( d ) {\n\t\treturn _empty( d ) || typeof d === 'string';\n\t};\n\t\n\t\n\tvar _htmlNumeric = function ( d, decimalPoint, formatted ) {\n\t\tif ( _empty( d ) ) {\n\t\t\treturn true;\n\t\t}\n\t\n\t\tvar html = _isHtml( d );\n\t\treturn ! html ?\n\t\t\tnull :\n\t\t\t_isNumber( _stripHtml( d ), decimalPoint, formatted ) ?\n\t\t\t\ttrue :\n\t\t\t\tnull;\n\t};\n\t\n\t\n\tvar _pluck = function ( a, prop, prop2 ) {\n\t\tvar out = [];\n\t\tvar i=0, ien=a.length;\n\t\n\t\t// Could have the test in the loop for slightly smaller code, but speed\n\t\t// is essential here\n\t\tif ( prop2 !== undefined ) {\n\t\t\tfor ( ; i<ien ; i++ ) {\n\t\t\t\tif ( a[i] && a[i][ prop ] ) {\n\t\t\t\t\tout.push( a[i][ prop ][ prop2 ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tfor ( ; i<ien ; i++ ) {\n\t\t\t\tif ( a[i] ) {\n\t\t\t\t\tout.push( a[i][ prop ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\treturn out;\n\t};\n\t\n\t\n\t// Basically the same as _pluck, but rather than looping over `a` we use `order`\n\t// as the indexes to pick from `a`\n\tvar _pluck_order = function ( a, order, prop, prop2 )\n\t{\n\t\tvar out = [];\n\t\tvar i=0, ien=order.length;\n\t\n\t\t// Could have the test in the loop for slightly smaller code, but speed\n\t\t// is essential here\n\t\tif ( prop2 !== undefined ) {\n\t\t\tfor ( ; i<ien ; i++ ) {\n\t\t\t\tif ( a[ order[i] ][ prop ] ) {\n\t\t\t\t\tout.push( a[ order[i] ][ prop ][ prop2 ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tfor ( ; i<ien ; i++ ) {\n\t\t\t\tout.push( a[ order[i] ][ prop ] );\n\t\t\t}\n\t\t}\n\t\n\t\treturn out;\n\t};\n\t\n\t\n\tvar _range = function ( len, start )\n\t{\n\t\tvar out = [];\n\t\tvar end;\n\t\n\t\tif ( start === undefined ) {\n\t\t\tstart = 0;\n\t\t\tend = len;\n\t\t}\n\t\telse {\n\t\t\tend = start;\n\t\t\tstart = len;\n\t\t}\n\t\n\t\tfor ( var i=start ; i<end ; i++ ) {\n\t\t\tout.push( i );\n\t\t}\n\t\n\t\treturn out;\n\t};\n\t\n\t\n\tvar _removeEmpty = function ( a )\n\t{\n\t\tvar out = [];\n\t\n\t\tfor ( var i=0, ien=a.length ; i<ien ; i++ ) {\n\t\t\tif ( a[i] ) { // careful - will remove all falsy values!\n\t\t\t\tout.push( a[i] );\n\t\t\t}\n\t\t}\n\t\n\t\treturn out;\n\t};\n\t\n\t\n\tvar _stripHtml = function ( d ) {\n\t\treturn d.replace( _re_html, '' );\n\t};\n\t\n\t\n\t/**\n\t * Find the unique elements in a source array.\n\t *\n\t * @param  {array} src Source array\n\t * @return {array} Array of unique items\n\t * @ignore\n\t */\n\tvar _unique = function ( src )\n\t{\n\t\t// A faster unique method is to use object keys to identify used values,\n\t\t// but this doesn't work with arrays or objects, which we must also\n\t\t// consider. See jsperf.com/compare-array-unique-versions/4 for more\n\t\t// information.\n\t\tvar\n\t\t\tout = [],\n\t\t\tval,\n\t\t\ti, ien=src.length,\n\t\t\tj, k=0;\n\t\n\t\tagain: for ( i=0 ; i<ien ; i++ ) {\n\t\t\tval = src[i];\n\t\n\t\t\tfor ( j=0 ; j<k ; j++ ) {\n\t\t\t\tif ( out[j] === val ) {\n\t\t\t\t\tcontinue again;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tout.push( val );\n\t\t\tk++;\n\t\t}\n\t\n\t\treturn out;\n\t};\n\t\n\t\n\t/**\n\t * DataTables utility methods\n\t * \n\t * This namespace provides helper methods that DataTables uses internally to\n\t * create a DataTable, but which are not exclusively used only for DataTables.\n\t * These methods can be used by extension authors to save the duplication of\n\t * code.\n\t *\n\t *  @namespace\n\t */\n\tDataTable.util = {\n\t\t/**\n\t\t * Throttle the calls to a function. Arguments and context are maintained\n\t\t * for the throttled function.\n\t\t *\n\t\t * @param {function} fn Function to be called\n\t\t * @param {integer} freq Call frequency in mS\n\t\t * @return {function} Wrapped function\n\t\t */\n\t\tthrottle: function ( fn, freq ) {\n\t\t\tvar\n\t\t\t\tfrequency = freq !== undefined ? freq : 200,\n\t\t\t\tlast,\n\t\t\t\ttimer;\n\t\n\t\t\treturn function () {\n\t\t\t\tvar\n\t\t\t\t\tthat = this,\n\t\t\t\t\tnow  = +new Date(),\n\t\t\t\t\targs = arguments;\n\t\n\t\t\t\tif ( last && now < last + frequency ) {\n\t\t\t\t\tclearTimeout( timer );\n\t\n\t\t\t\t\ttimer = setTimeout( function () {\n\t\t\t\t\t\tlast = undefined;\n\t\t\t\t\t\tfn.apply( that, args );\n\t\t\t\t\t}, frequency );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tlast = now;\n\t\t\t\t\tfn.apply( that, args );\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * Escape a string such that it can be used in a regular expression\n\t\t *\n\t\t *  @param {string} val string to escape\n\t\t *  @returns {string} escaped string\n\t\t */\n\t\tescapeRegex: function ( val ) {\n\t\t\treturn val.replace( _re_escape_regex, '\\\\$1' );\n\t\t}\n\t};\n\t\n\t\n\t\n\t/**\n\t * Create a mapping object that allows camel case parameters to be looked up\n\t * for their Hungarian counterparts. The mapping is stored in a private\n\t * parameter called `_hungarianMap` which can be accessed on the source object.\n\t *  @param {object} o\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnHungarianMap ( o )\n\t{\n\t\tvar\n\t\t\thungarian = 'a aa ai ao as b fn i m o s ',\n\t\t\tmatch,\n\t\t\tnewKey,\n\t\t\tmap = {};\n\t\n\t\t$.each( o, function (key, val) {\n\t\t\tmatch = key.match(/^([^A-Z]+?)([A-Z])/);\n\t\n\t\t\tif ( match && hungarian.indexOf(match[1]+' ') !== -1 )\n\t\t\t{\n\t\t\t\tnewKey = key.replace( match[0], match[2].toLowerCase() );\n\t\t\t\tmap[ newKey ] = key;\n\t\n\t\t\t\tif ( match[1] === 'o' )\n\t\t\t\t{\n\t\t\t\t\t_fnHungarianMap( o[key] );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t\n\t\to._hungarianMap = map;\n\t}\n\t\n\t\n\t/**\n\t * Convert from camel case parameters to Hungarian, based on a Hungarian map\n\t * created by _fnHungarianMap.\n\t *  @param {object} src The model object which holds all parameters that can be\n\t *    mapped.\n\t *  @param {object} user The object to convert from camel case to Hungarian.\n\t *  @param {boolean} force When set to `true`, properties which already have a\n\t *    Hungarian value in the `user` object will be overwritten. Otherwise they\n\t *    won't be.\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnCamelToHungarian ( src, user, force )\n\t{\n\t\tif ( ! src._hungarianMap ) {\n\t\t\t_fnHungarianMap( src );\n\t\t}\n\t\n\t\tvar hungarianKey;\n\t\n\t\t$.each( user, function (key, val) {\n\t\t\thungarianKey = src._hungarianMap[ key ];\n\t\n\t\t\tif ( hungarianKey !== undefined && (force || user[hungarianKey] === undefined) )\n\t\t\t{\n\t\t\t\t// For objects, we need to buzz down into the object to copy parameters\n\t\t\t\tif ( hungarianKey.charAt(0) === 'o' )\n\t\t\t\t{\n\t\t\t\t\t// Copy the camelCase options over to the hungarian\n\t\t\t\t\tif ( ! user[ hungarianKey ] ) {\n\t\t\t\t\t\tuser[ hungarianKey ] = {};\n\t\t\t\t\t}\n\t\t\t\t\t$.extend( true, user[hungarianKey], user[key] );\n\t\n\t\t\t\t\t_fnCamelToHungarian( src[hungarianKey], user[hungarianKey], force );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tuser[hungarianKey] = user[ key ];\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\t\n\t\n\t/**\n\t * Language compatibility - when certain options are given, and others aren't, we\n\t * need to duplicate the values over, in order to provide backwards compatibility\n\t * with older language files.\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnLanguageCompat( lang )\n\t{\n\t\tvar defaults = DataTable.defaults.oLanguage;\n\t\tvar zeroRecords = lang.sZeroRecords;\n\t\n\t\t/* Backwards compatibility - if there is no sEmptyTable given, then use the same as\n\t\t * sZeroRecords - assuming that is given.\n\t\t */\n\t\tif ( ! lang.sEmptyTable && zeroRecords &&\n\t\t\tdefaults.sEmptyTable === \"No data available in table\" )\n\t\t{\n\t\t\t_fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' );\n\t\t}\n\t\n\t\t/* Likewise with loading records */\n\t\tif ( ! lang.sLoadingRecords && zeroRecords &&\n\t\t\tdefaults.sLoadingRecords === \"Loading...\" )\n\t\t{\n\t\t\t_fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' );\n\t\t}\n\t\n\t\t// Old parameter name of the thousands separator mapped onto the new\n\t\tif ( lang.sInfoThousands ) {\n\t\t\tlang.sThousands = lang.sInfoThousands;\n\t\t}\n\t\n\t\tvar decimal = lang.sDecimal;\n\t\tif ( decimal ) {\n\t\t\t_addNumericSort( decimal );\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Map one parameter onto another\n\t *  @param {object} o Object to map\n\t *  @param {*} knew The new parameter name\n\t *  @param {*} old The old parameter name\n\t */\n\tvar _fnCompatMap = function ( o, knew, old ) {\n\t\tif ( o[ knew ] !== undefined ) {\n\t\t\to[ old ] = o[ knew ];\n\t\t}\n\t};\n\t\n\t\n\t/**\n\t * Provide backwards compatibility for the main DT options. Note that the new\n\t * options are mapped onto the old parameters, so this is an external interface\n\t * change only.\n\t *  @param {object} init Object to map\n\t */\n\tfunction _fnCompatOpts ( init )\n\t{\n\t\t_fnCompatMap( init, 'ordering',      'bSort' );\n\t\t_fnCompatMap( init, 'orderMulti',    'bSortMulti' );\n\t\t_fnCompatMap( init, 'orderClasses',  'bSortClasses' );\n\t\t_fnCompatMap( init, 'orderCellsTop', 'bSortCellsTop' );\n\t\t_fnCompatMap( init, 'order',         'aaSorting' );\n\t\t_fnCompatMap( init, 'orderFixed',    'aaSortingFixed' );\n\t\t_fnCompatMap( init, 'paging',        'bPaginate' );\n\t\t_fnCompatMap( init, 'pagingType',    'sPaginationType' );\n\t\t_fnCompatMap( init, 'pageLength',    'iDisplayLength' );\n\t\t_fnCompatMap( init, 'searching',     'bFilter' );\n\t\n\t\t// Boolean initialisation of x-scrolling\n\t\tif ( typeof init.sScrollX === 'boolean' ) {\n\t\t\tinit.sScrollX = init.sScrollX ? '100%' : '';\n\t\t}\n\t\tif ( typeof init.scrollX === 'boolean' ) {\n\t\t\tinit.scrollX = init.scrollX ? '100%' : '';\n\t\t}\n\t\n\t\t// Column search objects are in an array, so it needs to be converted\n\t\t// element by element\n\t\tvar searchCols = init.aoSearchCols;\n\t\n\t\tif ( searchCols ) {\n\t\t\tfor ( var i=0, ien=searchCols.length ; i<ien ; i++ ) {\n\t\t\t\tif ( searchCols[i] ) {\n\t\t\t\t\t_fnCamelToHungarian( DataTable.models.oSearch, searchCols[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Provide backwards compatibility for column options. Note that the new options\n\t * are mapped onto the old parameters, so this is an external interface change\n\t * only.\n\t *  @param {object} init Object to map\n\t */\n\tfunction _fnCompatCols ( init )\n\t{\n\t\t_fnCompatMap( init, 'orderable',     'bSortable' );\n\t\t_fnCompatMap( init, 'orderData',     'aDataSort' );\n\t\t_fnCompatMap( init, 'orderSequence', 'asSorting' );\n\t\t_fnCompatMap( init, 'orderDataType', 'sortDataType' );\n\t\n\t\t// orderData can be given as an integer\n\t\tvar dataSort = init.aDataSort;\n\t\tif ( dataSort && ! $.isArray( dataSort ) ) {\n\t\t\tinit.aDataSort = [ dataSort ];\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Browser feature detection for capabilities, quirks\n\t *  @param {object} settings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnBrowserDetect( settings )\n\t{\n\t\t// We don't need to do this every time DataTables is constructed, the values\n\t\t// calculated are specific to the browser and OS configuration which we\n\t\t// don't expect to change between initialisations\n\t\tif ( ! DataTable.__browser ) {\n\t\t\tvar browser = {};\n\t\t\tDataTable.__browser = browser;\n\t\n\t\t\t// Scrolling feature / quirks detection\n\t\t\tvar n = $('<div/>')\n\t\t\t\t.css( {\n\t\t\t\t\tposition: 'fixed',\n\t\t\t\t\ttop: 0,\n\t\t\t\t\tleft: 0,\n\t\t\t\t\theight: 1,\n\t\t\t\t\twidth: 1,\n\t\t\t\t\toverflow: 'hidden'\n\t\t\t\t} )\n\t\t\t\t.append(\n\t\t\t\t\t$('<div/>')\n\t\t\t\t\t\t.css( {\n\t\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\t\ttop: 1,\n\t\t\t\t\t\t\tleft: 1,\n\t\t\t\t\t\t\twidth: 100,\n\t\t\t\t\t\t\toverflow: 'scroll'\n\t\t\t\t\t\t} )\n\t\t\t\t\t\t.append(\n\t\t\t\t\t\t\t$('<div/>')\n\t\t\t\t\t\t\t\t.css( {\n\t\t\t\t\t\t\t\t\twidth: '100%',\n\t\t\t\t\t\t\t\t\theight: 10\n\t\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t\t.appendTo( 'body' );\n\t\n\t\t\tvar outer = n.children();\n\t\t\tvar inner = outer.children();\n\t\n\t\t\t// Numbers below, in order, are:\n\t\t\t// inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth\n\t\t\t//\n\t\t\t// IE6 XP:                           100 100 100  83\n\t\t\t// IE7 Vista:                        100 100 100  83\n\t\t\t// IE 8+ Windows:                     83  83 100  83\n\t\t\t// Evergreen Windows:                 83  83 100  83\n\t\t\t// Evergreen Mac with scrollbars:     85  85 100  85\n\t\t\t// Evergreen Mac without scrollbars: 100 100 100 100\n\t\n\t\t\t// Get scrollbar width\n\t\t\tbrowser.barWidth = outer[0].offsetWidth - outer[0].clientWidth;\n\t\n\t\t\t// IE6/7 will oversize a width 100% element inside a scrolling element, to\n\t\t\t// include the width of the scrollbar, while other browsers ensure the inner\n\t\t\t// element is contained without forcing scrolling\n\t\t\tbrowser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100;\n\t\n\t\t\t// In rtl text layout, some browsers (most, but not all) will place the\n\t\t\t// scrollbar on the left, rather than the right.\n\t\t\tbrowser.bScrollbarLeft = Math.round( inner.offset().left ) !== 1;\n\t\n\t\t\t// IE8- don't provide height and width for getBoundingClientRect\n\t\t\tbrowser.bBounding = n[0].getBoundingClientRect().width ? true : false;\n\t\n\t\t\tn.remove();\n\t\t}\n\t\n\t\t$.extend( settings.oBrowser, DataTable.__browser );\n\t\tsettings.oScroll.iBarWidth = DataTable.__browser.barWidth;\n\t}\n\t\n\t\n\t/**\n\t * Array.prototype reduce[Right] method, used for browsers which don't support\n\t * JS 1.6. Done this way to reduce code size, since we iterate either way\n\t *  @param {object} settings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnReduce ( that, fn, init, start, end, inc )\n\t{\n\t\tvar\n\t\t\ti = start,\n\t\t\tvalue,\n\t\t\tisSet = false;\n\t\n\t\tif ( init !== undefined ) {\n\t\t\tvalue = init;\n\t\t\tisSet = true;\n\t\t}\n\t\n\t\twhile ( i !== end ) {\n\t\t\tif ( ! that.hasOwnProperty(i) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\n\t\t\tvalue = isSet ?\n\t\t\t\tfn( value, that[i], i, that ) :\n\t\t\t\tthat[i];\n\t\n\t\t\tisSet = true;\n\t\t\ti += inc;\n\t\t}\n\t\n\t\treturn value;\n\t}\n\t\n\t/**\n\t * Add a column to the list used for the table with default values\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {node} nTh The th element for this column\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAddColumn( oSettings, nTh )\n\t{\n\t\t// Add column to aoColumns array\n\t\tvar oDefaults = DataTable.defaults.column;\n\t\tvar iCol = oSettings.aoColumns.length;\n\t\tvar oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, {\n\t\t\t\"nTh\": nTh ? nTh : document.createElement('th'),\n\t\t\t\"sTitle\":    oDefaults.sTitle    ? oDefaults.sTitle    : nTh ? nTh.innerHTML : '',\n\t\t\t\"aDataSort\": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],\n\t\t\t\"mData\": oDefaults.mData ? oDefaults.mData : iCol,\n\t\t\tidx: iCol\n\t\t} );\n\t\toSettings.aoColumns.push( oCol );\n\t\n\t\t// Add search object for column specific search. Note that the `searchCols[ iCol ]`\n\t\t// passed into extend can be undefined. This allows the user to give a default\n\t\t// with only some of the parameters defined, and also not give a default\n\t\tvar searchCols = oSettings.aoPreSearchCols;\n\t\tsearchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] );\n\t\n\t\t// Use the default column options function to initialise classes etc\n\t\t_fnColumnOptions( oSettings, iCol, $(nTh).data() );\n\t}\n\t\n\t\n\t/**\n\t * Apply options for a column\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {int} iCol column index to consider\n\t *  @param {object} oOptions object with sType, bVisible and bSearchable etc\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnColumnOptions( oSettings, iCol, oOptions )\n\t{\n\t\tvar oCol = oSettings.aoColumns[ iCol ];\n\t\tvar oClasses = oSettings.oClasses;\n\t\tvar th = $(oCol.nTh);\n\t\n\t\t// Try to get width information from the DOM. We can't get it from CSS\n\t\t// as we'd need to parse the CSS stylesheet. `width` option can override\n\t\tif ( ! oCol.sWidthOrig ) {\n\t\t\t// Width attribute\n\t\t\toCol.sWidthOrig = th.attr('width') || null;\n\t\n\t\t\t// Style attribute\n\t\t\tvar t = (th.attr('style') || '').match(/width:\\s*(\\d+[pxem%]+)/);\n\t\t\tif ( t ) {\n\t\t\t\toCol.sWidthOrig = t[1];\n\t\t\t}\n\t\t}\n\t\n\t\t/* User specified column options */\n\t\tif ( oOptions !== undefined && oOptions !== null )\n\t\t{\n\t\t\t// Backwards compatibility\n\t\t\t_fnCompatCols( oOptions );\n\t\n\t\t\t// Map camel case parameters to their Hungarian counterparts\n\t\t\t_fnCamelToHungarian( DataTable.defaults.column, oOptions );\n\t\n\t\t\t/* Backwards compatibility for mDataProp */\n\t\t\tif ( oOptions.mDataProp !== undefined && !oOptions.mData )\n\t\t\t{\n\t\t\t\toOptions.mData = oOptions.mDataProp;\n\t\t\t}\n\t\n\t\t\tif ( oOptions.sType )\n\t\t\t{\n\t\t\t\toCol._sManualType = oOptions.sType;\n\t\t\t}\n\t\n\t\t\t// `class` is a reserved word in Javascript, so we need to provide\n\t\t\t// the ability to use a valid name for the camel case input\n\t\t\tif ( oOptions.className && ! oOptions.sClass )\n\t\t\t{\n\t\t\t\toOptions.sClass = oOptions.className;\n\t\t\t}\n\t\n\t\t\t$.extend( oCol, oOptions );\n\t\t\t_fnMap( oCol, oOptions, \"sWidth\", \"sWidthOrig\" );\n\t\n\t\t\t/* iDataSort to be applied (backwards compatibility), but aDataSort will take\n\t\t\t * priority if defined\n\t\t\t */\n\t\t\tif ( oOptions.iDataSort !== undefined )\n\t\t\t{\n\t\t\t\toCol.aDataSort = [ oOptions.iDataSort ];\n\t\t\t}\n\t\t\t_fnMap( oCol, oOptions, \"aDataSort\" );\n\t\t}\n\t\n\t\t/* Cache the data get and set functions for speed */\n\t\tvar mDataSrc = oCol.mData;\n\t\tvar mData = _fnGetObjectDataFn( mDataSrc );\n\t\tvar mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null;\n\t\n\t\tvar attrTest = function( src ) {\n\t\t\treturn typeof src === 'string' && src.indexOf('@') !== -1;\n\t\t};\n\t\toCol._bAttrSrc = $.isPlainObject( mDataSrc ) && (\n\t\t\tattrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter)\n\t\t);\n\t\toCol._setter = null;\n\t\n\t\toCol.fnGetData = function (rowData, type, meta) {\n\t\t\tvar innerData = mData( rowData, type, undefined, meta );\n\t\n\t\t\treturn mRender && type ?\n\t\t\t\tmRender( innerData, type, rowData, meta ) :\n\t\t\t\tinnerData;\n\t\t};\n\t\toCol.fnSetData = function ( rowData, val, meta ) {\n\t\t\treturn _fnSetObjectDataFn( mDataSrc )( rowData, val, meta );\n\t\t};\n\t\n\t\t// Indicate if DataTables should read DOM data as an object or array\n\t\t// Used in _fnGetRowElements\n\t\tif ( typeof mDataSrc !== 'number' ) {\n\t\t\toSettings._rowReadObject = true;\n\t\t}\n\t\n\t\t/* Feature sorting overrides column specific when off */\n\t\tif ( !oSettings.oFeatures.bSort )\n\t\t{\n\t\t\toCol.bSortable = false;\n\t\t\tth.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called\n\t\t}\n\t\n\t\t/* Check that the class assignment is correct for sorting */\n\t\tvar bAsc = $.inArray('asc', oCol.asSorting) !== -1;\n\t\tvar bDesc = $.inArray('desc', oCol.asSorting) !== -1;\n\t\tif ( !oCol.bSortable || (!bAsc && !bDesc) )\n\t\t{\n\t\t\toCol.sSortingClass = oClasses.sSortableNone;\n\t\t\toCol.sSortingClassJUI = \"\";\n\t\t}\n\t\telse if ( bAsc && !bDesc )\n\t\t{\n\t\t\toCol.sSortingClass = oClasses.sSortableAsc;\n\t\t\toCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;\n\t\t}\n\t\telse if ( !bAsc && bDesc )\n\t\t{\n\t\t\toCol.sSortingClass = oClasses.sSortableDesc;\n\t\t\toCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;\n\t\t}\n\t\telse\n\t\t{\n\t\t\toCol.sSortingClass = oClasses.sSortable;\n\t\t\toCol.sSortingClassJUI = oClasses.sSortJUI;\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Adjust the table column widths for new data. Note: you would probably want to\n\t * do a redraw after calling this function!\n\t *  @param {object} settings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAdjustColumnSizing ( settings )\n\t{\n\t\t/* Not interested in doing column width calculation if auto-width is disabled */\n\t\tif ( settings.oFeatures.bAutoWidth !== false )\n\t\t{\n\t\t\tvar columns = settings.aoColumns;\n\t\n\t\t\t_fnCalculateColumnWidths( settings );\n\t\t\tfor ( var i=0 , iLen=columns.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tcolumns[i].nTh.style.width = columns[i].sWidth;\n\t\t\t}\n\t\t}\n\t\n\t\tvar scroll = settings.oScroll;\n\t\tif ( scroll.sY !== '' || scroll.sX !== '')\n\t\t{\n\t\t\t_fnScrollDraw( settings );\n\t\t}\n\t\n\t\t_fnCallbackFire( settings, null, 'column-sizing', [settings] );\n\t}\n\t\n\t\n\t/**\n\t * Covert the index of a visible column to the index in the data array (take account\n\t * of hidden columns)\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {int} iMatch Visible column index to lookup\n\t *  @returns {int} i the data index\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnVisibleToColumnIndex( oSettings, iMatch )\n\t{\n\t\tvar aiVis = _fnGetColumns( oSettings, 'bVisible' );\n\t\n\t\treturn typeof aiVis[iMatch] === 'number' ?\n\t\t\taiVis[iMatch] :\n\t\t\tnull;\n\t}\n\t\n\t\n\t/**\n\t * Covert the index of an index in the data array and convert it to the visible\n\t *   column index (take account of hidden columns)\n\t *  @param {int} iMatch Column index to lookup\n\t *  @param {object} oSettings dataTables settings object\n\t *  @returns {int} i the data index\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnColumnIndexToVisible( oSettings, iMatch )\n\t{\n\t\tvar aiVis = _fnGetColumns( oSettings, 'bVisible' );\n\t\tvar iPos = $.inArray( iMatch, aiVis );\n\t\n\t\treturn iPos !== -1 ? iPos : null;\n\t}\n\t\n\t\n\t/**\n\t * Get the number of visible columns\n\t *  @param {object} oSettings dataTables settings object\n\t *  @returns {int} i the number of visible columns\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnVisbleColumns( oSettings )\n\t{\n\t\tvar vis = 0;\n\t\n\t\t// No reduce in IE8, use a loop for now\n\t\t$.each( oSettings.aoColumns, function ( i, col ) {\n\t\t\tif ( col.bVisible && $(col.nTh).css('display') !== 'none' ) {\n\t\t\t\tvis++;\n\t\t\t}\n\t\t} );\n\t\n\t\treturn vis;\n\t}\n\t\n\t\n\t/**\n\t * Get an array of column indexes that match a given property\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {string} sParam Parameter in aoColumns to look for - typically\n\t *    bVisible or bSearchable\n\t *  @returns {array} Array of indexes with matched properties\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnGetColumns( oSettings, sParam )\n\t{\n\t\tvar a = [];\n\t\n\t\t$.map( oSettings.aoColumns, function(val, i) {\n\t\t\tif ( val[sParam] ) {\n\t\t\t\ta.push( i );\n\t\t\t}\n\t\t} );\n\t\n\t\treturn a;\n\t}\n\t\n\t\n\t/**\n\t * Calculate the 'type' of a column\n\t *  @param {object} settings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnColumnTypes ( settings )\n\t{\n\t\tvar columns = settings.aoColumns;\n\t\tvar data = settings.aoData;\n\t\tvar types = DataTable.ext.type.detect;\n\t\tvar i, ien, j, jen, k, ken;\n\t\tvar col, cell, detectedType, cache;\n\t\n\t\t// For each column, spin over the \n\t\tfor ( i=0, ien=columns.length ; i<ien ; i++ ) {\n\t\t\tcol = columns[i];\n\t\t\tcache = [];\n\t\n\t\t\tif ( ! col.sType && col._sManualType ) {\n\t\t\t\tcol.sType = col._sManualType;\n\t\t\t}\n\t\t\telse if ( ! col.sType ) {\n\t\t\t\tfor ( j=0, jen=types.length ; j<jen ; j++ ) {\n\t\t\t\t\tfor ( k=0, ken=data.length ; k<ken ; k++ ) {\n\t\t\t\t\t\t// Use a cache array so we only need to get the type data\n\t\t\t\t\t\t// from the formatter once (when using multiple detectors)\n\t\t\t\t\t\tif ( cache[k] === undefined ) {\n\t\t\t\t\t\t\tcache[k] = _fnGetCellData( settings, k, i, 'type' );\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\tdetectedType = types[j]( cache[k], settings );\n\t\n\t\t\t\t\t\t// If null, then this type can't apply to this column, so\n\t\t\t\t\t\t// rather than testing all cells, break out. There is an\n\t\t\t\t\t\t// exception for the last type which is `html`. We need to\n\t\t\t\t\t\t// scan all rows since it is possible to mix string and HTML\n\t\t\t\t\t\t// types\n\t\t\t\t\t\tif ( ! detectedType && j !== types.length-1 ) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t// Only a single match is needed for html type since it is\n\t\t\t\t\t\t// bottom of the pile and very similar to string\n\t\t\t\t\t\tif ( detectedType === 'html' ) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\n\t\t\t\t\t// Type is valid for all data points in the column - use this\n\t\t\t\t\t// type\n\t\t\t\t\tif ( detectedType ) {\n\t\t\t\t\t\tcol.sType = detectedType;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\n\t\t\t\t// Fall back - if no type was detected, always use string\n\t\t\t\tif ( ! col.sType ) {\n\t\t\t\t\tcol.sType = 'string';\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Take the column definitions and static columns arrays and calculate how\n\t * they relate to column indexes. The callback function will then apply the\n\t * definition found for a column to a suitable configuration object.\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {array} aoColDefs The aoColumnDefs array that is to be applied\n\t *  @param {array} aoCols The aoColumns array that defines columns individually\n\t *  @param {function} fn Callback function - takes two parameters, the calculated\n\t *    column index and the definition for that column.\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn )\n\t{\n\t\tvar i, iLen, j, jLen, k, kLen, def;\n\t\tvar columns = oSettings.aoColumns;\n\t\n\t\t// Column definitions with aTargets\n\t\tif ( aoColDefs )\n\t\t{\n\t\t\t/* Loop over the definitions array - loop in reverse so first instance has priority */\n\t\t\tfor ( i=aoColDefs.length-1 ; i>=0 ; i-- )\n\t\t\t{\n\t\t\t\tdef = aoColDefs[i];\n\t\n\t\t\t\t/* Each definition can target multiple columns, as it is an array */\n\t\t\t\tvar aTargets = def.targets !== undefined ?\n\t\t\t\t\tdef.targets :\n\t\t\t\t\tdef.aTargets;\n\t\n\t\t\t\tif ( ! $.isArray( aTargets ) )\n\t\t\t\t{\n\t\t\t\t\taTargets = [ aTargets ];\n\t\t\t\t}\n\t\n\t\t\t\tfor ( j=0, jLen=aTargets.length ; j<jLen ; j++ )\n\t\t\t\t{\n\t\t\t\t\tif ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 )\n\t\t\t\t\t{\n\t\t\t\t\t\t/* Add columns that we don't yet know about */\n\t\t\t\t\t\twhile( columns.length <= aTargets[j] )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t_fnAddColumn( oSettings );\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t/* Integer, basic index */\n\t\t\t\t\t\tfn( aTargets[j], def );\n\t\t\t\t\t}\n\t\t\t\t\telse if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )\n\t\t\t\t\t{\n\t\t\t\t\t\t/* Negative integer, right to left column counting */\n\t\t\t\t\t\tfn( columns.length+aTargets[j], def );\n\t\t\t\t\t}\n\t\t\t\t\telse if ( typeof aTargets[j] === 'string' )\n\t\t\t\t\t{\n\t\t\t\t\t\t/* Class name matching on TH element */\n\t\t\t\t\t\tfor ( k=0, kLen=columns.length ; k<kLen ; k++ )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif ( aTargets[j] == \"_all\" ||\n\t\t\t\t\t\t\t     $(columns[k].nTh).hasClass( aTargets[j] ) )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfn( k, def );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\t// Statically defined columns array\n\t\tif ( aoCols )\n\t\t{\n\t\t\tfor ( i=0, iLen=aoCols.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tfn( i, aoCols[i] );\n\t\t\t}\n\t\t}\n\t}\n\t\n\t/**\n\t * Add a data array to the table, creating DOM node etc. This is the parallel to\n\t * _fnGatherData, but for adding rows from a Javascript source, rather than a\n\t * DOM source.\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {array} aData data array to be added\n\t *  @param {node} [nTr] TR element to add to the table - optional. If not given,\n\t *    DataTables will create a row automatically\n\t *  @param {array} [anTds] Array of TD|TH elements for the row - must be given\n\t *    if nTr is.\n\t *  @returns {int} >=0 if successful (index of new aoData entry), -1 if failed\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAddData ( oSettings, aDataIn, nTr, anTds )\n\t{\n\t\t/* Create the object for storing information about this new row */\n\t\tvar iRow = oSettings.aoData.length;\n\t\tvar oData = $.extend( true, {}, DataTable.models.oRow, {\n\t\t\tsrc: nTr ? 'dom' : 'data',\n\t\t\tidx: iRow\n\t\t} );\n\t\n\t\toData._aData = aDataIn;\n\t\toSettings.aoData.push( oData );\n\t\n\t\t/* Create the cells */\n\t\tvar nTd, sThisType;\n\t\tvar columns = oSettings.aoColumns;\n\t\n\t\t// Invalidate the column types as the new data needs to be revalidated\n\t\tfor ( var i=0, iLen=columns.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tcolumns[i].sType = null;\n\t\t}\n\t\n\t\t/* Add to the display array */\n\t\toSettings.aiDisplayMaster.push( iRow );\n\t\n\t\tvar id = oSettings.rowIdFn( aDataIn );\n\t\tif ( id !== undefined ) {\n\t\t\toSettings.aIds[ id ] = oData;\n\t\t}\n\t\n\t\t/* Create the DOM information, or register it if already present */\n\t\tif ( nTr || ! oSettings.oFeatures.bDeferRender )\n\t\t{\n\t\t\t_fnCreateTr( oSettings, iRow, nTr, anTds );\n\t\t}\n\t\n\t\treturn iRow;\n\t}\n\t\n\t\n\t/**\n\t * Add one or more TR elements to the table. Generally we'd expect to\n\t * use this for reading data from a DOM sourced table, but it could be\n\t * used for an TR element. Note that if a TR is given, it is used (i.e.\n\t * it is not cloned).\n\t *  @param {object} settings dataTables settings object\n\t *  @param {array|node|jQuery} trs The TR element(s) to add to the table\n\t *  @returns {array} Array of indexes for the added rows\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAddTr( settings, trs )\n\t{\n\t\tvar row;\n\t\n\t\t// Allow an individual node to be passed in\n\t\tif ( ! (trs instanceof $) ) {\n\t\t\ttrs = $(trs);\n\t\t}\n\t\n\t\treturn trs.map( function (i, el) {\n\t\t\trow = _fnGetRowElements( settings, el );\n\t\t\treturn _fnAddData( settings, row.data, el, row.cells );\n\t\t} );\n\t}\n\t\n\t\n\t/**\n\t * Take a TR element and convert it to an index in aoData\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {node} n the TR element to find\n\t *  @returns {int} index if the node is found, null if not\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnNodeToDataIndex( oSettings, n )\n\t{\n\t\treturn (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null;\n\t}\n\t\n\t\n\t/**\n\t * Take a TD element and convert it into a column data index (not the visible index)\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {int} iRow The row number the TD/TH can be found in\n\t *  @param {node} n The TD/TH element to find\n\t *  @returns {int} index if the node is found, -1 if not\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnNodeToColumnIndex( oSettings, iRow, n )\n\t{\n\t\treturn $.inArray( n, oSettings.aoData[ iRow ].anCells );\n\t}\n\t\n\t\n\t/**\n\t * Get the data for a given cell from the internal cache, taking into account data mapping\n\t *  @param {object} settings dataTables settings object\n\t *  @param {int} rowIdx aoData row id\n\t *  @param {int} colIdx Column index\n\t *  @param {string} type data get type ('display', 'type' 'filter' 'sort')\n\t *  @returns {*} Cell data\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnGetCellData( settings, rowIdx, colIdx, type )\n\t{\n\t\tvar draw           = settings.iDraw;\n\t\tvar col            = settings.aoColumns[colIdx];\n\t\tvar rowData        = settings.aoData[rowIdx]._aData;\n\t\tvar defaultContent = col.sDefaultContent;\n\t\tvar cellData       = col.fnGetData( rowData, type, {\n\t\t\tsettings: settings,\n\t\t\trow:      rowIdx,\n\t\t\tcol:      colIdx\n\t\t} );\n\t\n\t\tif ( cellData === undefined ) {\n\t\t\tif ( settings.iDrawError != draw && defaultContent === null ) {\n\t\t\t\t_fnLog( settings, 0, \"Requested unknown parameter \"+\n\t\t\t\t\t(typeof col.mData=='function' ? '{function}' : \"'\"+col.mData+\"'\")+\n\t\t\t\t\t\" for row \"+rowIdx+\", column \"+colIdx, 4 );\n\t\t\t\tsettings.iDrawError = draw;\n\t\t\t}\n\t\t\treturn defaultContent;\n\t\t}\n\t\n\t\t// When the data source is null and a specific data type is requested (i.e.\n\t\t// not the original data), we can use default column data\n\t\tif ( (cellData === rowData || cellData === null) && defaultContent !== null && type !== undefined ) {\n\t\t\tcellData = defaultContent;\n\t\t}\n\t\telse if ( typeof cellData === 'function' ) {\n\t\t\t// If the data source is a function, then we run it and use the return,\n\t\t\t// executing in the scope of the data object (for instances)\n\t\t\treturn cellData.call( rowData );\n\t\t}\n\t\n\t\tif ( cellData === null && type == 'display' ) {\n\t\t\treturn '';\n\t\t}\n\t\treturn cellData;\n\t}\n\t\n\t\n\t/**\n\t * Set the value for a specific cell, into the internal data cache\n\t *  @param {object} settings dataTables settings object\n\t *  @param {int} rowIdx aoData row id\n\t *  @param {int} colIdx Column index\n\t *  @param {*} val Value to set\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSetCellData( settings, rowIdx, colIdx, val )\n\t{\n\t\tvar col     = settings.aoColumns[colIdx];\n\t\tvar rowData = settings.aoData[rowIdx]._aData;\n\t\n\t\tcol.fnSetData( rowData, val, {\n\t\t\tsettings: settings,\n\t\t\trow:      rowIdx,\n\t\t\tcol:      colIdx\n\t\t}  );\n\t}\n\t\n\t\n\t// Private variable that is used to match action syntax in the data property object\n\tvar __reArray = /\\[.*?\\]$/;\n\tvar __reFn = /\\(\\)$/;\n\t\n\t/**\n\t * Split string on periods, taking into account escaped periods\n\t * @param  {string} str String to split\n\t * @return {array} Split string\n\t */\n\tfunction _fnSplitObjNotation( str )\n\t{\n\t\treturn $.map( str.match(/(\\\\.|[^\\.])+/g) || [''], function ( s ) {\n\t\t\treturn s.replace(/\\\\./g, '.');\n\t\t} );\n\t}\n\t\n\t\n\t/**\n\t * Return a function that can be used to get data from a source object, taking\n\t * into account the ability to use nested objects as a source\n\t *  @param {string|int|function} mSource The data source for the object\n\t *  @returns {function} Data get function\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnGetObjectDataFn( mSource )\n\t{\n\t\tif ( $.isPlainObject( mSource ) )\n\t\t{\n\t\t\t/* Build an object of get functions, and wrap them in a single call */\n\t\t\tvar o = {};\n\t\t\t$.each( mSource, function (key, val) {\n\t\t\t\tif ( val ) {\n\t\t\t\t\to[key] = _fnGetObjectDataFn( val );\n\t\t\t\t}\n\t\t\t} );\n\t\n\t\t\treturn function (data, type, row, meta) {\n\t\t\t\tvar t = o[type] || o._;\n\t\t\t\treturn t !== undefined ?\n\t\t\t\t\tt(data, type, row, meta) :\n\t\t\t\t\tdata;\n\t\t\t};\n\t\t}\n\t\telse if ( mSource === null )\n\t\t{\n\t\t\t/* Give an empty string for rendering / sorting etc */\n\t\t\treturn function (data) { // type, row and meta also passed, but not used\n\t\t\t\treturn data;\n\t\t\t};\n\t\t}\n\t\telse if ( typeof mSource === 'function' )\n\t\t{\n\t\t\treturn function (data, type, row, meta) {\n\t\t\t\treturn mSource( data, type, row, meta );\n\t\t\t};\n\t\t}\n\t\telse if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||\n\t\t\t      mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )\n\t\t{\n\t\t\t/* If there is a . in the source string then the data source is in a\n\t\t\t * nested object so we loop over the data for each level to get the next\n\t\t\t * level down. On each loop we test for undefined, and if found immediately\n\t\t\t * return. This allows entire objects to be missing and sDefaultContent to\n\t\t\t * be used if defined, rather than throwing an error\n\t\t\t */\n\t\t\tvar fetchData = function (data, type, src) {\n\t\t\t\tvar arrayNotation, funcNotation, out, innerSrc;\n\t\n\t\t\t\tif ( src !== \"\" )\n\t\t\t\t{\n\t\t\t\t\tvar a = _fnSplitObjNotation( src );\n\t\n\t\t\t\t\tfor ( var i=0, iLen=a.length ; i<iLen ; i++ )\n\t\t\t\t\t{\n\t\t\t\t\t\t// Check if we are dealing with special notation\n\t\t\t\t\t\tarrayNotation = a[i].match(__reArray);\n\t\t\t\t\t\tfuncNotation = a[i].match(__reFn);\n\t\n\t\t\t\t\t\tif ( arrayNotation )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Array notation\n\t\t\t\t\t\t\ta[i] = a[i].replace(__reArray, '');\n\t\n\t\t\t\t\t\t\t// Condition allows simply [] to be passed in\n\t\t\t\t\t\t\tif ( a[i] !== \"\" ) {\n\t\t\t\t\t\t\t\tdata = data[ a[i] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tout = [];\n\t\n\t\t\t\t\t\t\t// Get the remainder of the nested object to get\n\t\t\t\t\t\t\ta.splice( 0, i+1 );\n\t\t\t\t\t\t\tinnerSrc = a.join('.');\n\t\n\t\t\t\t\t\t\t// Traverse each entry in the array getting the properties requested\n\t\t\t\t\t\t\tif ( $.isArray( data ) ) {\n\t\t\t\t\t\t\t\tfor ( var j=0, jLen=data.length ; j<jLen ; j++ ) {\n\t\t\t\t\t\t\t\t\tout.push( fetchData( data[j], type, innerSrc ) );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t\t// If a string is given in between the array notation indicators, that\n\t\t\t\t\t\t\t// is used to join the strings together, otherwise an array is returned\n\t\t\t\t\t\t\tvar join = arrayNotation[0].substring(1, arrayNotation[0].length-1);\n\t\t\t\t\t\t\tdata = (join===\"\") ? out : out.join(join);\n\t\n\t\t\t\t\t\t\t// The inner call to fetchData has already traversed through the remainder\n\t\t\t\t\t\t\t// of the source requested, so we exit from the loop\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if ( funcNotation )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Function call\n\t\t\t\t\t\t\ta[i] = a[i].replace(__reFn, '');\n\t\t\t\t\t\t\tdata = data[ a[i] ]();\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\tif ( data === null || data[ a[i] ] === undefined )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdata = data[ a[i] ];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\n\t\t\t\treturn data;\n\t\t\t};\n\t\n\t\t\treturn function (data, type) { // row and meta also passed, but not used\n\t\t\t\treturn fetchData( data, type, mSource );\n\t\t\t};\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* Array or flat object mapping */\n\t\t\treturn function (data, type) { // row and meta also passed, but not used\n\t\t\t\treturn data[mSource];\n\t\t\t};\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Return a function that can be used to set data from a source object, taking\n\t * into account the ability to use nested objects as a source\n\t *  @param {string|int|function} mSource The data source for the object\n\t *  @returns {function} Data set function\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSetObjectDataFn( mSource )\n\t{\n\t\tif ( $.isPlainObject( mSource ) )\n\t\t{\n\t\t\t/* Unlike get, only the underscore (global) option is used for for\n\t\t\t * setting data since we don't know the type here. This is why an object\n\t\t\t * option is not documented for `mData` (which is read/write), but it is\n\t\t\t * for `mRender` which is read only.\n\t\t\t */\n\t\t\treturn _fnSetObjectDataFn( mSource._ );\n\t\t}\n\t\telse if ( mSource === null )\n\t\t{\n\t\t\t/* Nothing to do when the data source is null */\n\t\t\treturn function () {};\n\t\t}\n\t\telse if ( typeof mSource === 'function' )\n\t\t{\n\t\t\treturn function (data, val, meta) {\n\t\t\t\tmSource( data, 'set', val, meta );\n\t\t\t};\n\t\t}\n\t\telse if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||\n\t\t\t      mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )\n\t\t{\n\t\t\t/* Like the get, we need to get data from a nested object */\n\t\t\tvar setData = function (data, val, src) {\n\t\t\t\tvar a = _fnSplitObjNotation( src ), b;\n\t\t\t\tvar aLast = a[a.length-1];\n\t\t\t\tvar arrayNotation, funcNotation, o, innerSrc;\n\t\n\t\t\t\tfor ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )\n\t\t\t\t{\n\t\t\t\t\t// Check if we are dealing with an array notation request\n\t\t\t\t\tarrayNotation = a[i].match(__reArray);\n\t\t\t\t\tfuncNotation = a[i].match(__reFn);\n\t\n\t\t\t\t\tif ( arrayNotation )\n\t\t\t\t\t{\n\t\t\t\t\t\ta[i] = a[i].replace(__reArray, '');\n\t\t\t\t\t\tdata[ a[i] ] = [];\n\t\n\t\t\t\t\t\t// Get the remainder of the nested object to set so we can recurse\n\t\t\t\t\t\tb = a.slice();\n\t\t\t\t\t\tb.splice( 0, i+1 );\n\t\t\t\t\t\tinnerSrc = b.join('.');\n\t\n\t\t\t\t\t\t// Traverse each entry in the array setting the properties requested\n\t\t\t\t\t\tif ( $.isArray( val ) )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfor ( var j=0, jLen=val.length ; j<jLen ; j++ )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\to = {};\n\t\t\t\t\t\t\t\tsetData( o, val[j], innerSrc );\n\t\t\t\t\t\t\t\tdata[ a[i] ].push( o );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// We've been asked to save data to an array, but it\n\t\t\t\t\t\t\t// isn't array data to be saved. Best that can be done\n\t\t\t\t\t\t\t// is to just save the value.\n\t\t\t\t\t\t\tdata[ a[i] ] = val;\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t// The inner call to setData has already traversed through the remainder\n\t\t\t\t\t\t// of the source and has set the data, thus we can exit here\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\telse if ( funcNotation )\n\t\t\t\t\t{\n\t\t\t\t\t\t// Function call\n\t\t\t\t\t\ta[i] = a[i].replace(__reFn, '');\n\t\t\t\t\t\tdata = data[ a[i] ]( val );\n\t\t\t\t\t}\n\t\n\t\t\t\t\t// If the nested object doesn't currently exist - since we are\n\t\t\t\t\t// trying to set the value - create it\n\t\t\t\t\tif ( data[ a[i] ] === null || data[ a[i] ] === undefined )\n\t\t\t\t\t{\n\t\t\t\t\t\tdata[ a[i] ] = {};\n\t\t\t\t\t}\n\t\t\t\t\tdata = data[ a[i] ];\n\t\t\t\t}\n\t\n\t\t\t\t// Last item in the input - i.e, the actual set\n\t\t\t\tif ( aLast.match(__reFn ) )\n\t\t\t\t{\n\t\t\t\t\t// Function call\n\t\t\t\t\tdata = data[ aLast.replace(__reFn, '') ]( val );\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// If array notation is used, we just want to strip it and use the property name\n\t\t\t\t\t// and assign the value. If it isn't used, then we get the result we want anyway\n\t\t\t\t\tdata[ aLast.replace(__reArray, '') ] = val;\n\t\t\t\t}\n\t\t\t};\n\t\n\t\t\treturn function (data, val) { // meta is also passed in, but not used\n\t\t\t\treturn setData( data, val, mSource );\n\t\t\t};\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* Array or flat object mapping */\n\t\t\treturn function (data, val) { // meta is also passed in, but not used\n\t\t\t\tdata[mSource] = val;\n\t\t\t};\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Return an array with the full table data\n\t *  @param {object} oSettings dataTables settings object\n\t *  @returns array {array} aData Master data array\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnGetDataMaster ( settings )\n\t{\n\t\treturn _pluck( settings.aoData, '_aData' );\n\t}\n\t\n\t\n\t/**\n\t * Nuke the table\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnClearTable( settings )\n\t{\n\t\tsettings.aoData.length = 0;\n\t\tsettings.aiDisplayMaster.length = 0;\n\t\tsettings.aiDisplay.length = 0;\n\t\tsettings.aIds = {};\n\t}\n\t\n\t\n\t /**\n\t * Take an array of integers (index array) and remove a target integer (value - not\n\t * the key!)\n\t *  @param {array} a Index array to target\n\t *  @param {int} iTarget value to find\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnDeleteIndex( a, iTarget, splice )\n\t{\n\t\tvar iTargetIndex = -1;\n\t\n\t\tfor ( var i=0, iLen=a.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tif ( a[i] == iTarget )\n\t\t\t{\n\t\t\t\tiTargetIndex = i;\n\t\t\t}\n\t\t\telse if ( a[i] > iTarget )\n\t\t\t{\n\t\t\t\ta[i]--;\n\t\t\t}\n\t\t}\n\t\n\t\tif ( iTargetIndex != -1 && splice === undefined )\n\t\t{\n\t\t\ta.splice( iTargetIndex, 1 );\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Mark cached data as invalid such that a re-read of the data will occur when\n\t * the cached data is next requested. Also update from the data source object.\n\t *\n\t * @param {object} settings DataTables settings object\n\t * @param {int}    rowIdx   Row index to invalidate\n\t * @param {string} [src]    Source to invalidate from: undefined, 'auto', 'dom'\n\t *     or 'data'\n\t * @param {int}    [colIdx] Column index to invalidate. If undefined the whole\n\t *     row will be invalidated\n\t * @memberof DataTable#oApi\n\t *\n\t * @todo For the modularisation of v1.11 this will need to become a callback, so\n\t *   the sort and filter methods can subscribe to it. That will required\n\t *   initialisation options for sorting, which is why it is not already baked in\n\t */\n\tfunction _fnInvalidate( settings, rowIdx, src, colIdx )\n\t{\n\t\tvar row = settings.aoData[ rowIdx ];\n\t\tvar i, ien;\n\t\tvar cellWrite = function ( cell, col ) {\n\t\t\t// This is very frustrating, but in IE if you just write directly\n\t\t\t// to innerHTML, and elements that are overwritten are GC'ed,\n\t\t\t// even if there is a reference to them elsewhere\n\t\t\twhile ( cell.childNodes.length ) {\n\t\t\t\tcell.removeChild( cell.firstChild );\n\t\t\t}\n\t\n\t\t\tcell.innerHTML = _fnGetCellData( settings, rowIdx, col, 'display' );\n\t\t};\n\t\n\t\t// Are we reading last data from DOM or the data object?\n\t\tif ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) {\n\t\t\t// Read the data from the DOM\n\t\t\trow._aData = _fnGetRowElements(\n\t\t\t\t\tsettings, row, colIdx, colIdx === undefined ? undefined : row._aData\n\t\t\t\t)\n\t\t\t\t.data;\n\t\t}\n\t\telse {\n\t\t\t// Reading from data object, update the DOM\n\t\t\tvar cells = row.anCells;\n\t\n\t\t\tif ( cells ) {\n\t\t\t\tif ( colIdx !== undefined ) {\n\t\t\t\t\tcellWrite( cells[colIdx], colIdx );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tfor ( i=0, ien=cells.length ; i<ien ; i++ ) {\n\t\t\t\t\t\tcellWrite( cells[i], i );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\t// For both row and cell invalidation, the cached data for sorting and\n\t\t// filtering is nulled out\n\t\trow._aSortData = null;\n\t\trow._aFilterData = null;\n\t\n\t\t// Invalidate the type for a specific column (if given) or all columns since\n\t\t// the data might have changed\n\t\tvar cols = settings.aoColumns;\n\t\tif ( colIdx !== undefined ) {\n\t\t\tcols[ colIdx ].sType = null;\n\t\t}\n\t\telse {\n\t\t\tfor ( i=0, ien=cols.length ; i<ien ; i++ ) {\n\t\t\t\tcols[i].sType = null;\n\t\t\t}\n\t\n\t\t\t// Update DataTables special `DT_*` attributes for the row\n\t\t\t_fnRowAttributes( settings, row );\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Build a data source object from an HTML row, reading the contents of the\n\t * cells that are in the row.\n\t *\n\t * @param {object} settings DataTables settings object\n\t * @param {node|object} TR element from which to read data or existing row\n\t *   object from which to re-read the data from the cells\n\t * @param {int} [colIdx] Optional column index\n\t * @param {array|object} [d] Data source object. If `colIdx` is given then this\n\t *   parameter should also be given and will be used to write the data into.\n\t *   Only the column in question will be written\n\t * @returns {object} Object with two parameters: `data` the data read, in\n\t *   document order, and `cells` and array of nodes (they can be useful to the\n\t *   caller, so rather than needing a second traversal to get them, just return\n\t *   them from here).\n\t * @memberof DataTable#oApi\n\t */\n\tfunction _fnGetRowElements( settings, row, colIdx, d )\n\t{\n\t\tvar\n\t\t\ttds = [],\n\t\t\ttd = row.firstChild,\n\t\t\tname, col, o, i=0, contents,\n\t\t\tcolumns = settings.aoColumns,\n\t\t\tobjectRead = settings._rowReadObject;\n\t\n\t\t// Allow the data object to be passed in, or construct\n\t\td = d !== undefined ?\n\t\t\td :\n\t\t\tobjectRead ?\n\t\t\t\t{} :\n\t\t\t\t[];\n\t\n\t\tvar attr = function ( str, td  ) {\n\t\t\tif ( typeof str === 'string' ) {\n\t\t\t\tvar idx = str.indexOf('@');\n\t\n\t\t\t\tif ( idx !== -1 ) {\n\t\t\t\t\tvar attr = str.substring( idx+1 );\n\t\t\t\t\tvar setter = _fnSetObjectDataFn( str );\n\t\t\t\t\tsetter( d, td.getAttribute( attr ) );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\n\t\t// Read data from a cell and store into the data object\n\t\tvar cellProcess = function ( cell ) {\n\t\t\tif ( colIdx === undefined || colIdx === i ) {\n\t\t\t\tcol = columns[i];\n\t\t\t\tcontents = $.trim(cell.innerHTML);\n\t\n\t\t\t\tif ( col && col._bAttrSrc ) {\n\t\t\t\t\tvar setter = _fnSetObjectDataFn( col.mData._ );\n\t\t\t\t\tsetter( d, contents );\n\t\n\t\t\t\t\tattr( col.mData.sort, cell );\n\t\t\t\t\tattr( col.mData.type, cell );\n\t\t\t\t\tattr( col.mData.filter, cell );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// Depending on the `data` option for the columns the data can\n\t\t\t\t\t// be read to either an object or an array.\n\t\t\t\t\tif ( objectRead ) {\n\t\t\t\t\t\tif ( ! col._setter ) {\n\t\t\t\t\t\t\t// Cache the setter function\n\t\t\t\t\t\t\tcol._setter = _fnSetObjectDataFn( col.mData );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcol._setter( d, contents );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\td[i] = contents;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\ti++;\n\t\t};\n\t\n\t\tif ( td ) {\n\t\t\t// `tr` element was passed in\n\t\t\twhile ( td ) {\n\t\t\t\tname = td.nodeName.toUpperCase();\n\t\n\t\t\t\tif ( name == \"TD\" || name == \"TH\" ) {\n\t\t\t\t\tcellProcess( td );\n\t\t\t\t\ttds.push( td );\n\t\t\t\t}\n\t\n\t\t\t\ttd = td.nextSibling;\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\t// Existing row object passed in\n\t\t\ttds = row.anCells;\n\t\n\t\t\tfor ( var j=0, jen=tds.length ; j<jen ; j++ ) {\n\t\t\t\tcellProcess( tds[j] );\n\t\t\t}\n\t\t}\n\t\n\t\t// Read the ID from the DOM if present\n\t\tvar rowNode = row.firstChild ? row : row.nTr;\n\t\n\t\tif ( rowNode ) {\n\t\t\tvar id = rowNode.getAttribute( 'id' );\n\t\n\t\t\tif ( id ) {\n\t\t\t\t_fnSetObjectDataFn( settings.rowId )( d, id );\n\t\t\t}\n\t\t}\n\t\n\t\treturn {\n\t\t\tdata: d,\n\t\t\tcells: tds\n\t\t};\n\t}\n\t/**\n\t * Create a new TR element (and it's TD children) for a row\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {int} iRow Row to consider\n\t *  @param {node} [nTrIn] TR element to add to the table - optional. If not given,\n\t *    DataTables will create a row automatically\n\t *  @param {array} [anTds] Array of TD|TH elements for the row - must be given\n\t *    if nTr is.\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnCreateTr ( oSettings, iRow, nTrIn, anTds )\n\t{\n\t\tvar\n\t\t\trow = oSettings.aoData[iRow],\n\t\t\trowData = row._aData,\n\t\t\tcells = [],\n\t\t\tnTr, nTd, oCol,\n\t\t\ti, iLen;\n\t\n\t\tif ( row.nTr === null )\n\t\t{\n\t\t\tnTr = nTrIn || document.createElement('tr');\n\t\n\t\t\trow.nTr = nTr;\n\t\t\trow.anCells = cells;\n\t\n\t\t\t/* Use a private property on the node to allow reserve mapping from the node\n\t\t\t * to the aoData array for fast look up\n\t\t\t */\n\t\t\tnTr._DT_RowIndex = iRow;\n\t\n\t\t\t/* Special parameters can be given by the data source to be used on the row */\n\t\t\t_fnRowAttributes( oSettings, row );\n\t\n\t\t\t/* Process each column */\n\t\t\tfor ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\toCol = oSettings.aoColumns[i];\n\t\n\t\t\t\tnTd = nTrIn ? anTds[i] : document.createElement( oCol.sCellType );\n\t\t\t\tnTd._DT_CellIndex = {\n\t\t\t\t\trow: iRow,\n\t\t\t\t\tcolumn: i\n\t\t\t\t};\n\t\t\t\t\n\t\t\t\tcells.push( nTd );\n\t\n\t\t\t\t// Need to create the HTML if new, or if a rendering function is defined\n\t\t\t\tif ( (!nTrIn || oCol.mRender || oCol.mData !== i) &&\n\t\t\t\t\t (!$.isPlainObject(oCol.mData) || oCol.mData._ !== i+'.display')\n\t\t\t\t) {\n\t\t\t\t\tnTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' );\n\t\t\t\t}\n\t\n\t\t\t\t/* Add user defined class */\n\t\t\t\tif ( oCol.sClass )\n\t\t\t\t{\n\t\t\t\t\tnTd.className += ' '+oCol.sClass;\n\t\t\t\t}\n\t\n\t\t\t\t// Visibility - add or remove as required\n\t\t\t\tif ( oCol.bVisible && ! nTrIn )\n\t\t\t\t{\n\t\t\t\t\tnTr.appendChild( nTd );\n\t\t\t\t}\n\t\t\t\telse if ( ! oCol.bVisible && nTrIn )\n\t\t\t\t{\n\t\t\t\t\tnTd.parentNode.removeChild( nTd );\n\t\t\t\t}\n\t\n\t\t\t\tif ( oCol.fnCreatedCell )\n\t\t\t\t{\n\t\t\t\t\toCol.fnCreatedCell.call( oSettings.oInstance,\n\t\t\t\t\t\tnTd, _fnGetCellData( oSettings, iRow, i ), rowData, iRow, i\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t_fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow] );\n\t\t}\n\t\n\t\t// Remove once webkit bug 131819 and Chromium bug 365619 have been resolved\n\t\t// and deployed\n\t\trow.nTr.setAttribute( 'role', 'row' );\n\t}\n\t\n\t\n\t/**\n\t * Add attributes to a row based on the special `DT_*` parameters in a data\n\t * source object.\n\t *  @param {object} settings DataTables settings object\n\t *  @param {object} DataTables row object for the row to be modified\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnRowAttributes( settings, row )\n\t{\n\t\tvar tr = row.nTr;\n\t\tvar data = row._aData;\n\t\n\t\tif ( tr ) {\n\t\t\tvar id = settings.rowIdFn( data );\n\t\n\t\t\tif ( id ) {\n\t\t\t\ttr.id = id;\n\t\t\t}\n\t\n\t\t\tif ( data.DT_RowClass ) {\n\t\t\t\t// Remove any classes added by DT_RowClass before\n\t\t\t\tvar a = data.DT_RowClass.split(' ');\n\t\t\t\trow.__rowc = row.__rowc ?\n\t\t\t\t\t_unique( row.__rowc.concat( a ) ) :\n\t\t\t\t\ta;\n\t\n\t\t\t\t$(tr)\n\t\t\t\t\t.removeClass( row.__rowc.join(' ') )\n\t\t\t\t\t.addClass( data.DT_RowClass );\n\t\t\t}\n\t\n\t\t\tif ( data.DT_RowAttr ) {\n\t\t\t\t$(tr).attr( data.DT_RowAttr );\n\t\t\t}\n\t\n\t\t\tif ( data.DT_RowData ) {\n\t\t\t\t$(tr).data( data.DT_RowData );\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Create the HTML header for the table\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnBuildHead( oSettings )\n\t{\n\t\tvar i, ien, cell, row, column;\n\t\tvar thead = oSettings.nTHead;\n\t\tvar tfoot = oSettings.nTFoot;\n\t\tvar createHeader = $('th, td', thead).length === 0;\n\t\tvar classes = oSettings.oClasses;\n\t\tvar columns = oSettings.aoColumns;\n\t\n\t\tif ( createHeader ) {\n\t\t\trow = $('<tr/>').appendTo( thead );\n\t\t}\n\t\n\t\tfor ( i=0, ien=columns.length ; i<ien ; i++ ) {\n\t\t\tcolumn = columns[i];\n\t\t\tcell = $( column.nTh ).addClass( column.sClass );\n\t\n\t\t\tif ( createHeader ) {\n\t\t\t\tcell.appendTo( row );\n\t\t\t}\n\t\n\t\t\t// 1.11 move into sorting\n\t\t\tif ( oSettings.oFeatures.bSort ) {\n\t\t\t\tcell.addClass( column.sSortingClass );\n\t\n\t\t\t\tif ( column.bSortable !== false ) {\n\t\t\t\t\tcell\n\t\t\t\t\t\t.attr( 'tabindex', oSettings.iTabIndex )\n\t\t\t\t\t\t.attr( 'aria-controls', oSettings.sTableId );\n\t\n\t\t\t\t\t_fnSortAttachListener( oSettings, column.nTh, i );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tif ( column.sTitle != cell[0].innerHTML ) {\n\t\t\t\tcell.html( column.sTitle );\n\t\t\t}\n\t\n\t\t\t_fnRenderer( oSettings, 'header' )(\n\t\t\t\toSettings, cell, column, classes\n\t\t\t);\n\t\t}\n\t\n\t\tif ( createHeader ) {\n\t\t\t_fnDetectHeader( oSettings.aoHeader, thead );\n\t\t}\n\t\t\n\t\t/* ARIA role for the rows */\n\t \t$(thead).find('>tr').attr('role', 'row');\n\t\n\t\t/* Deal with the footer - add classes if required */\n\t\t$(thead).find('>tr>th, >tr>td').addClass( classes.sHeaderTH );\n\t\t$(tfoot).find('>tr>th, >tr>td').addClass( classes.sFooterTH );\n\t\n\t\t// Cache the footer cells. Note that we only take the cells from the first\n\t\t// row in the footer. If there is more than one row the user wants to\n\t\t// interact with, they need to use the table().foot() method. Note also this\n\t\t// allows cells to be used for multiple columns using colspan\n\t\tif ( tfoot !== null ) {\n\t\t\tvar cells = oSettings.aoFooter[0];\n\t\n\t\t\tfor ( i=0, ien=cells.length ; i<ien ; i++ ) {\n\t\t\t\tcolumn = columns[i];\n\t\t\t\tcolumn.nTf = cells[i].cell;\n\t\n\t\t\t\tif ( column.sClass ) {\n\t\t\t\t\t$(column.nTf).addClass( column.sClass );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Draw the header (or footer) element based on the column visibility states. The\n\t * methodology here is to use the layout array from _fnDetectHeader, modified for\n\t * the instantaneous column visibility, to construct the new layout. The grid is\n\t * traversed over cell at a time in a rows x columns grid fashion, although each\n\t * cell insert can cover multiple elements in the grid - which is tracks using the\n\t * aApplied array. Cell inserts in the grid will only occur where there isn't\n\t * already a cell in that position.\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param array {objects} aoSource Layout array from _fnDetectHeader\n\t *  @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnDrawHead( oSettings, aoSource, bIncludeHidden )\n\t{\n\t\tvar i, iLen, j, jLen, k, kLen, n, nLocalTr;\n\t\tvar aoLocal = [];\n\t\tvar aApplied = [];\n\t\tvar iColumns = oSettings.aoColumns.length;\n\t\tvar iRowspan, iColspan;\n\t\n\t\tif ( ! aoSource )\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\n\t\tif (  bIncludeHidden === undefined )\n\t\t{\n\t\t\tbIncludeHidden = false;\n\t\t}\n\t\n\t\t/* Make a copy of the master layout array, but without the visible columns in it */\n\t\tfor ( i=0, iLen=aoSource.length ; i<iLen ; i++ )\n\t\t{\n\t\t\taoLocal[i] = aoSource[i].slice();\n\t\t\taoLocal[i].nTr = aoSource[i].nTr;\n\t\n\t\t\t/* Remove any columns which are currently hidden */\n\t\t\tfor ( j=iColumns-1 ; j>=0 ; j-- )\n\t\t\t{\n\t\t\t\tif ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden )\n\t\t\t\t{\n\t\t\t\t\taoLocal[i].splice( j, 1 );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t/* Prep the applied array - it needs an element for each row */\n\t\t\taApplied.push( [] );\n\t\t}\n\t\n\t\tfor ( i=0, iLen=aoLocal.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tnLocalTr = aoLocal[i].nTr;\n\t\n\t\t\t/* All cells are going to be replaced, so empty out the row */\n\t\t\tif ( nLocalTr )\n\t\t\t{\n\t\t\t\twhile( (n = nLocalTr.firstChild) )\n\t\t\t\t{\n\t\t\t\t\tnLocalTr.removeChild( n );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tfor ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ )\n\t\t\t{\n\t\t\t\tiRowspan = 1;\n\t\t\t\tiColspan = 1;\n\t\n\t\t\t\t/* Check to see if there is already a cell (row/colspan) covering our target\n\t\t\t\t * insert point. If there is, then there is nothing to do.\n\t\t\t\t */\n\t\t\t\tif ( aApplied[i][j] === undefined )\n\t\t\t\t{\n\t\t\t\t\tnLocalTr.appendChild( aoLocal[i][j].cell );\n\t\t\t\t\taApplied[i][j] = 1;\n\t\n\t\t\t\t\t/* Expand the cell to cover as many rows as needed */\n\t\t\t\t\twhile ( aoLocal[i+iRowspan] !== undefined &&\n\t\t\t\t\t        aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell )\n\t\t\t\t\t{\n\t\t\t\t\t\taApplied[i+iRowspan][j] = 1;\n\t\t\t\t\t\tiRowspan++;\n\t\t\t\t\t}\n\t\n\t\t\t\t\t/* Expand the cell to cover as many columns as needed */\n\t\t\t\t\twhile ( aoLocal[i][j+iColspan] !== undefined &&\n\t\t\t\t\t        aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell )\n\t\t\t\t\t{\n\t\t\t\t\t\t/* Must update the applied array over the rows for the columns */\n\t\t\t\t\t\tfor ( k=0 ; k<iRowspan ; k++ )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\taApplied[i+k][j+iColspan] = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tiColspan++;\n\t\t\t\t\t}\n\t\n\t\t\t\t\t/* Do the actual expansion in the DOM */\n\t\t\t\t\t$(aoLocal[i][j].cell)\n\t\t\t\t\t\t.attr('rowspan', iRowspan)\n\t\t\t\t\t\t.attr('colspan', iColspan);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Insert the required TR nodes into the table for display\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnDraw( oSettings )\n\t{\n\t\t/* Provide a pre-callback function which can be used to cancel the draw is false is returned */\n\t\tvar aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] );\n\t\tif ( $.inArray( false, aPreDraw ) !== -1 )\n\t\t{\n\t\t\t_fnProcessingDisplay( oSettings, false );\n\t\t\treturn;\n\t\t}\n\t\n\t\tvar i, iLen, n;\n\t\tvar anRows = [];\n\t\tvar iRowCount = 0;\n\t\tvar asStripeClasses = oSettings.asStripeClasses;\n\t\tvar iStripes = asStripeClasses.length;\n\t\tvar iOpenRows = oSettings.aoOpenRows.length;\n\t\tvar oLang = oSettings.oLanguage;\n\t\tvar iInitDisplayStart = oSettings.iInitDisplayStart;\n\t\tvar bServerSide = _fnDataSource( oSettings ) == 'ssp';\n\t\tvar aiDisplay = oSettings.aiDisplay;\n\t\n\t\toSettings.bDrawing = true;\n\t\n\t\t/* Check and see if we have an initial draw position from state saving */\n\t\tif ( iInitDisplayStart !== undefined && iInitDisplayStart !== -1 )\n\t\t{\n\t\t\toSettings._iDisplayStart = bServerSide ?\n\t\t\t\tiInitDisplayStart :\n\t\t\t\tiInitDisplayStart >= oSettings.fnRecordsDisplay() ?\n\t\t\t\t\t0 :\n\t\t\t\t\tiInitDisplayStart;\n\t\n\t\t\toSettings.iInitDisplayStart = -1;\n\t\t}\n\t\n\t\tvar iDisplayStart = oSettings._iDisplayStart;\n\t\tvar iDisplayEnd = oSettings.fnDisplayEnd();\n\t\n\t\t/* Server-side processing draw intercept */\n\t\tif ( oSettings.bDeferLoading )\n\t\t{\n\t\t\toSettings.bDeferLoading = false;\n\t\t\toSettings.iDraw++;\n\t\t\t_fnProcessingDisplay( oSettings, false );\n\t\t}\n\t\telse if ( !bServerSide )\n\t\t{\n\t\t\toSettings.iDraw++;\n\t\t}\n\t\telse if ( !oSettings.bDestroying && !_fnAjaxUpdate( oSettings ) )\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\n\t\tif ( aiDisplay.length !== 0 )\n\t\t{\n\t\t\tvar iStart = bServerSide ? 0 : iDisplayStart;\n\t\t\tvar iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd;\n\t\n\t\t\tfor ( var j=iStart ; j<iEnd ; j++ )\n\t\t\t{\n\t\t\t\tvar iDataIndex = aiDisplay[j];\n\t\t\t\tvar aoData = oSettings.aoData[ iDataIndex ];\n\t\t\t\tif ( aoData.nTr === null )\n\t\t\t\t{\n\t\t\t\t\t_fnCreateTr( oSettings, iDataIndex );\n\t\t\t\t}\n\t\n\t\t\t\tvar nRow = aoData.nTr;\n\t\n\t\t\t\t/* Remove the old striping classes and then add the new one */\n\t\t\t\tif ( iStripes !== 0 )\n\t\t\t\t{\n\t\t\t\t\tvar sStripe = asStripeClasses[ iRowCount % iStripes ];\n\t\t\t\t\tif ( aoData._sRowStripe != sStripe )\n\t\t\t\t\t{\n\t\t\t\t\t\t$(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe );\n\t\t\t\t\t\taoData._sRowStripe = sStripe;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\n\t\t\t\t// Row callback functions - might want to manipulate the row\n\t\t\t\t// iRowCount and j are not currently documented. Are they at all\n\t\t\t\t// useful?\n\t\t\t\t_fnCallbackFire( oSettings, 'aoRowCallback', null,\n\t\t\t\t\t[nRow, aoData._aData, iRowCount, j] );\n\t\n\t\t\t\tanRows.push( nRow );\n\t\t\t\tiRowCount++;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* Table is empty - create a row with an empty message in it */\n\t\t\tvar sZero = oLang.sZeroRecords;\n\t\t\tif ( oSettings.iDraw == 1 &&  _fnDataSource( oSettings ) == 'ajax' )\n\t\t\t{\n\t\t\t\tsZero = oLang.sLoadingRecords;\n\t\t\t}\n\t\t\telse if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 )\n\t\t\t{\n\t\t\t\tsZero = oLang.sEmptyTable;\n\t\t\t}\n\t\n\t\t\tanRows[ 0 ] = $( '<tr/>', { 'class': iStripes ? asStripeClasses[0] : '' } )\n\t\t\t\t.append( $('<td />', {\n\t\t\t\t\t'valign':  'top',\n\t\t\t\t\t'colSpan': _fnVisbleColumns( oSettings ),\n\t\t\t\t\t'class':   oSettings.oClasses.sRowEmpty\n\t\t\t\t} ).html( sZero ) )[0];\n\t\t}\n\t\n\t\t/* Header and footer callbacks */\n\t\t_fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0],\n\t\t\t_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );\n\t\n\t\t_fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],\n\t\t\t_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );\n\t\n\t\tvar body = $(oSettings.nTBody);\n\t\n\t\tbody.children().detach();\n\t\tbody.append( $(anRows) );\n\t\n\t\t/* Call all required callback functions for the end of a draw */\n\t\t_fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );\n\t\n\t\t/* Draw is complete, sorting and filtering must be as well */\n\t\toSettings.bSorted = false;\n\t\toSettings.bFiltered = false;\n\t\toSettings.bDrawing = false;\n\t}\n\t\n\t\n\t/**\n\t * Redraw the table - taking account of the various features which are enabled\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {boolean} [holdPosition] Keep the current paging position. By default\n\t *    the paging is reset to the first page\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnReDraw( settings, holdPosition )\n\t{\n\t\tvar\n\t\t\tfeatures = settings.oFeatures,\n\t\t\tsort     = features.bSort,\n\t\t\tfilter   = features.bFilter;\n\t\n\t\tif ( sort ) {\n\t\t\t_fnSort( settings );\n\t\t}\n\t\n\t\tif ( filter ) {\n\t\t\t_fnFilterComplete( settings, settings.oPreviousSearch );\n\t\t}\n\t\telse {\n\t\t\t// No filtering, so we want to just use the display master\n\t\t\tsettings.aiDisplay = settings.aiDisplayMaster.slice();\n\t\t}\n\t\n\t\tif ( holdPosition !== true ) {\n\t\t\tsettings._iDisplayStart = 0;\n\t\t}\n\t\n\t\t// Let any modules know about the draw hold position state (used by\n\t\t// scrolling internally)\n\t\tsettings._drawHold = holdPosition;\n\t\n\t\t_fnDraw( settings );\n\t\n\t\tsettings._drawHold = false;\n\t}\n\t\n\t\n\t/**\n\t * Add the options to the page HTML for the table\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAddOptionsHtml ( oSettings )\n\t{\n\t\tvar classes = oSettings.oClasses;\n\t\tvar table = $(oSettings.nTable);\n\t\tvar holding = $('<div/>').insertBefore( table ); // Holding element for speed\n\t\tvar features = oSettings.oFeatures;\n\t\n\t\t// All DataTables are wrapped in a div\n\t\tvar insert = $('<div/>', {\n\t\t\tid:      oSettings.sTableId+'_wrapper',\n\t\t\t'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter)\n\t\t} );\n\t\n\t\toSettings.nHolding = holding[0];\n\t\toSettings.nTableWrapper = insert[0];\n\t\toSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;\n\t\n\t\t/* Loop over the user set positioning and place the elements as needed */\n\t\tvar aDom = oSettings.sDom.split('');\n\t\tvar featureNode, cOption, nNewNode, cNext, sAttr, j;\n\t\tfor ( var i=0 ; i<aDom.length ; i++ )\n\t\t{\n\t\t\tfeatureNode = null;\n\t\t\tcOption = aDom[i];\n\t\n\t\t\tif ( cOption == '<' )\n\t\t\t{\n\t\t\t\t/* New container div */\n\t\t\t\tnNewNode = $('<div/>')[0];\n\t\n\t\t\t\t/* Check to see if we should append an id and/or a class name to the container */\n\t\t\t\tcNext = aDom[i+1];\n\t\t\t\tif ( cNext == \"'\" || cNext == '\"' )\n\t\t\t\t{\n\t\t\t\t\tsAttr = \"\";\n\t\t\t\t\tj = 2;\n\t\t\t\t\twhile ( aDom[i+j] != cNext )\n\t\t\t\t\t{\n\t\t\t\t\t\tsAttr += aDom[i+j];\n\t\t\t\t\t\tj++;\n\t\t\t\t\t}\n\t\n\t\t\t\t\t/* Replace jQuery UI constants @todo depreciated */\n\t\t\t\t\tif ( sAttr == \"H\" )\n\t\t\t\t\t{\n\t\t\t\t\t\tsAttr = classes.sJUIHeader;\n\t\t\t\t\t}\n\t\t\t\t\telse if ( sAttr == \"F\" )\n\t\t\t\t\t{\n\t\t\t\t\t\tsAttr = classes.sJUIFooter;\n\t\t\t\t\t}\n\t\n\t\t\t\t\t/* The attribute can be in the format of \"#id.class\", \"#id\" or \"class\" This logic\n\t\t\t\t\t * breaks the string into parts and applies them as needed\n\t\t\t\t\t */\n\t\t\t\t\tif ( sAttr.indexOf('.') != -1 )\n\t\t\t\t\t{\n\t\t\t\t\t\tvar aSplit = sAttr.split('.');\n\t\t\t\t\t\tnNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);\n\t\t\t\t\t\tnNewNode.className = aSplit[1];\n\t\t\t\t\t}\n\t\t\t\t\telse if ( sAttr.charAt(0) == \"#\" )\n\t\t\t\t\t{\n\t\t\t\t\t\tnNewNode.id = sAttr.substr(1, sAttr.length-1);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tnNewNode.className = sAttr;\n\t\t\t\t\t}\n\t\n\t\t\t\t\ti += j; /* Move along the position array */\n\t\t\t\t}\n\t\n\t\t\t\tinsert.append( nNewNode );\n\t\t\t\tinsert = $(nNewNode);\n\t\t\t}\n\t\t\telse if ( cOption == '>' )\n\t\t\t{\n\t\t\t\t/* End container div */\n\t\t\t\tinsert = insert.parent();\n\t\t\t}\n\t\t\t// @todo Move options into their own plugins?\n\t\t\telse if ( cOption == 'l' && features.bPaginate && features.bLengthChange )\n\t\t\t{\n\t\t\t\t/* Length */\n\t\t\t\tfeatureNode = _fnFeatureHtmlLength( oSettings );\n\t\t\t}\n\t\t\telse if ( cOption == 'f' && features.bFilter )\n\t\t\t{\n\t\t\t\t/* Filter */\n\t\t\t\tfeatureNode = _fnFeatureHtmlFilter( oSettings );\n\t\t\t}\n\t\t\telse if ( cOption == 'r' && features.bProcessing )\n\t\t\t{\n\t\t\t\t/* pRocessing */\n\t\t\t\tfeatureNode = _fnFeatureHtmlProcessing( oSettings );\n\t\t\t}\n\t\t\telse if ( cOption == 't' )\n\t\t\t{\n\t\t\t\t/* Table */\n\t\t\t\tfeatureNode = _fnFeatureHtmlTable( oSettings );\n\t\t\t}\n\t\t\telse if ( cOption ==  'i' && features.bInfo )\n\t\t\t{\n\t\t\t\t/* Info */\n\t\t\t\tfeatureNode = _fnFeatureHtmlInfo( oSettings );\n\t\t\t}\n\t\t\telse if ( cOption == 'p' && features.bPaginate )\n\t\t\t{\n\t\t\t\t/* Pagination */\n\t\t\t\tfeatureNode = _fnFeatureHtmlPaginate( oSettings );\n\t\t\t}\n\t\t\telse if ( DataTable.ext.feature.length !== 0 )\n\t\t\t{\n\t\t\t\t/* Plug-in features */\n\t\t\t\tvar aoFeatures = DataTable.ext.feature;\n\t\t\t\tfor ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ )\n\t\t\t\t{\n\t\t\t\t\tif ( cOption == aoFeatures[k].cFeature )\n\t\t\t\t\t{\n\t\t\t\t\t\tfeatureNode = aoFeatures[k].fnInit( oSettings );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t/* Add to the 2D features array */\n\t\t\tif ( featureNode )\n\t\t\t{\n\t\t\t\tvar aanFeatures = oSettings.aanFeatures;\n\t\n\t\t\t\tif ( ! aanFeatures[cOption] )\n\t\t\t\t{\n\t\t\t\t\taanFeatures[cOption] = [];\n\t\t\t\t}\n\t\n\t\t\t\taanFeatures[cOption].push( featureNode );\n\t\t\t\tinsert.append( featureNode );\n\t\t\t}\n\t\t}\n\t\n\t\t/* Built our DOM structure - replace the holding div with what we want */\n\t\tholding.replaceWith( insert );\n\t\toSettings.nHolding = null;\n\t}\n\t\n\t\n\t/**\n\t * Use the DOM source to create up an array of header cells. The idea here is to\n\t * create a layout grid (array) of rows x columns, which contains a reference\n\t * to the cell that that point in the grid (regardless of col/rowspan), such that\n\t * any column / row could be removed and the new grid constructed\n\t *  @param array {object} aLayout Array to store the calculated layout in\n\t *  @param {node} nThead The header/footer element for the table\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnDetectHeader ( aLayout, nThead )\n\t{\n\t\tvar nTrs = $(nThead).children('tr');\n\t\tvar nTr, nCell;\n\t\tvar i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;\n\t\tvar bUnique;\n\t\tvar fnShiftCol = function ( a, i, j ) {\n\t\t\tvar k = a[i];\n\t                while ( k[j] ) {\n\t\t\t\tj++;\n\t\t\t}\n\t\t\treturn j;\n\t\t};\n\t\n\t\taLayout.splice( 0, aLayout.length );\n\t\n\t\t/* We know how many rows there are in the layout - so prep it */\n\t\tfor ( i=0, iLen=nTrs.length ; i<iLen ; i++ )\n\t\t{\n\t\t\taLayout.push( [] );\n\t\t}\n\t\n\t\t/* Calculate a layout array */\n\t\tfor ( i=0, iLen=nTrs.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tnTr = nTrs[i];\n\t\t\tiColumn = 0;\n\t\n\t\t\t/* For every cell in the row... */\n\t\t\tnCell = nTr.firstChild;\n\t\t\twhile ( nCell ) {\n\t\t\t\tif ( nCell.nodeName.toUpperCase() == \"TD\" ||\n\t\t\t\t     nCell.nodeName.toUpperCase() == \"TH\" )\n\t\t\t\t{\n\t\t\t\t\t/* Get the col and rowspan attributes from the DOM and sanitise them */\n\t\t\t\t\tiColspan = nCell.getAttribute('colspan') * 1;\n\t\t\t\t\tiRowspan = nCell.getAttribute('rowspan') * 1;\n\t\t\t\t\tiColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan;\n\t\t\t\t\tiRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan;\n\t\n\t\t\t\t\t/* There might be colspan cells already in this row, so shift our target\n\t\t\t\t\t * accordingly\n\t\t\t\t\t */\n\t\t\t\t\tiColShifted = fnShiftCol( aLayout, i, iColumn );\n\t\n\t\t\t\t\t/* Cache calculation for unique columns */\n\t\t\t\t\tbUnique = iColspan === 1 ? true : false;\n\t\n\t\t\t\t\t/* If there is col / rowspan, copy the information into the layout grid */\n\t\t\t\t\tfor ( l=0 ; l<iColspan ; l++ )\n\t\t\t\t\t{\n\t\t\t\t\t\tfor ( k=0 ; k<iRowspan ; k++ )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\taLayout[i+k][iColShifted+l] = {\n\t\t\t\t\t\t\t\t\"cell\": nCell,\n\t\t\t\t\t\t\t\t\"unique\": bUnique\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\taLayout[i+k].nTr = nTr;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tnCell = nCell.nextSibling;\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Get an array of unique th elements, one for each column\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {node} nHeader automatically detect the layout from this node - optional\n\t *  @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional\n\t *  @returns array {node} aReturn list of unique th's\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnGetUniqueThs ( oSettings, nHeader, aLayout )\n\t{\n\t\tvar aReturn = [];\n\t\tif ( !aLayout )\n\t\t{\n\t\t\taLayout = oSettings.aoHeader;\n\t\t\tif ( nHeader )\n\t\t\t{\n\t\t\t\taLayout = [];\n\t\t\t\t_fnDetectHeader( aLayout, nHeader );\n\t\t\t}\n\t\t}\n\t\n\t\tfor ( var i=0, iLen=aLayout.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tfor ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ )\n\t\t\t{\n\t\t\t\tif ( aLayout[i][j].unique &&\n\t\t\t\t\t (!aReturn[j] || !oSettings.bSortCellsTop) )\n\t\t\t\t{\n\t\t\t\t\taReturn[j] = aLayout[i][j].cell;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\treturn aReturn;\n\t}\n\t\n\t/**\n\t * Create an Ajax call based on the table's settings, taking into account that\n\t * parameters can have multiple forms, and backwards compatibility.\n\t *\n\t * @param {object} oSettings dataTables settings object\n\t * @param {array} data Data to send to the server, required by\n\t *     DataTables - may be augmented by developer callbacks\n\t * @param {function} fn Callback function to run when data is obtained\n\t */\n\tfunction _fnBuildAjax( oSettings, data, fn )\n\t{\n\t\t// Compatibility with 1.9-, allow fnServerData and event to manipulate\n\t\t_fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] );\n\t\n\t\t// Convert to object based for 1.10+ if using the old array scheme which can\n\t\t// come from server-side processing or serverParams\n\t\tif ( data && $.isArray(data) ) {\n\t\t\tvar tmp = {};\n\t\t\tvar rbracket = /(.*?)\\[\\]$/;\n\t\n\t\t\t$.each( data, function (key, val) {\n\t\t\t\tvar match = val.name.match(rbracket);\n\t\n\t\t\t\tif ( match ) {\n\t\t\t\t\t// Support for arrays\n\t\t\t\t\tvar name = match[0];\n\t\n\t\t\t\t\tif ( ! tmp[ name ] ) {\n\t\t\t\t\t\ttmp[ name ] = [];\n\t\t\t\t\t}\n\t\t\t\t\ttmp[ name ].push( val.value );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\ttmp[val.name] = val.value;\n\t\t\t\t}\n\t\t\t} );\n\t\t\tdata = tmp;\n\t\t}\n\t\n\t\tvar ajaxData;\n\t\tvar ajax = oSettings.ajax;\n\t\tvar instance = oSettings.oInstance;\n\t\tvar callback = function ( json ) {\n\t\t\t_fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR] );\n\t\t\tfn( json );\n\t\t};\n\t\n\t\tif ( $.isPlainObject( ajax ) && ajax.data )\n\t\t{\n\t\t\tajaxData = ajax.data;\n\t\n\t\t\tvar newData = $.isFunction( ajaxData ) ?\n\t\t\t\tajaxData( data, oSettings ) :  // fn can manipulate data or return\n\t\t\t\tajaxData;                      // an object object or array to merge\n\t\n\t\t\t// If the function returned something, use that alone\n\t\t\tdata = $.isFunction( ajaxData ) && newData ?\n\t\t\t\tnewData :\n\t\t\t\t$.extend( true, data, newData );\n\t\n\t\t\t// Remove the data property as we've resolved it already and don't want\n\t\t\t// jQuery to do it again (it is restored at the end of the function)\n\t\t\tdelete ajax.data;\n\t\t}\n\t\n\t\tvar baseAjax = {\n\t\t\t\"data\": data,\n\t\t\t\"success\": function (json) {\n\t\t\t\tvar error = json.error || json.sError;\n\t\t\t\tif ( error ) {\n\t\t\t\t\t_fnLog( oSettings, 0, error );\n\t\t\t\t}\n\t\n\t\t\t\toSettings.json = json;\n\t\t\t\tcallback( json );\n\t\t\t},\n\t\t\t\"dataType\": \"json\",\n\t\t\t\"cache\": false,\n\t\t\t\"type\": oSettings.sServerMethod,\n\t\t\t\"error\": function (xhr, error, thrown) {\n\t\t\t\tvar ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR] );\n\t\n\t\t\t\tif ( $.inArray( true, ret ) === -1 ) {\n\t\t\t\t\tif ( error == \"parsererror\" ) {\n\t\t\t\t\t\t_fnLog( oSettings, 0, 'Invalid JSON response', 1 );\n\t\t\t\t\t}\n\t\t\t\t\telse if ( xhr.readyState === 4 ) {\n\t\t\t\t\t\t_fnLog( oSettings, 0, 'Ajax error', 7 );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\n\t\t\t\t_fnProcessingDisplay( oSettings, false );\n\t\t\t}\n\t\t};\n\t\n\t\t// Store the data submitted for the API\n\t\toSettings.oAjaxData = data;\n\t\n\t\t// Allow plug-ins and external processes to modify the data\n\t\t_fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] );\n\t\n\t\tif ( oSettings.fnServerData )\n\t\t{\n\t\t\t// DataTables 1.9- compatibility\n\t\t\toSettings.fnServerData.call( instance,\n\t\t\t\toSettings.sAjaxSource,\n\t\t\t\t$.map( data, function (val, key) { // Need to convert back to 1.9 trad format\n\t\t\t\t\treturn { name: key, value: val };\n\t\t\t\t} ),\n\t\t\t\tcallback,\n\t\t\t\toSettings\n\t\t\t);\n\t\t}\n\t\telse if ( oSettings.sAjaxSource || typeof ajax === 'string' )\n\t\t{\n\t\t\t// DataTables 1.9- compatibility\n\t\t\toSettings.jqXHR = $.ajax( $.extend( baseAjax, {\n\t\t\t\turl: ajax || oSettings.sAjaxSource\n\t\t\t} ) );\n\t\t}\n\t\telse if ( $.isFunction( ajax ) )\n\t\t{\n\t\t\t// Is a function - let the caller define what needs to be done\n\t\t\toSettings.jqXHR = ajax.call( instance, data, callback, oSettings );\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Object to extend the base settings\n\t\t\toSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) );\n\t\n\t\t\t// Restore for next time around\n\t\t\tajax.data = ajaxData;\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Update the table using an Ajax call\n\t *  @param {object} settings dataTables settings object\n\t *  @returns {boolean} Block the table drawing or not\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAjaxUpdate( settings )\n\t{\n\t\tif ( settings.bAjaxDataGet ) {\n\t\t\tsettings.iDraw++;\n\t\t\t_fnProcessingDisplay( settings, true );\n\t\n\t\t\t_fnBuildAjax(\n\t\t\t\tsettings,\n\t\t\t\t_fnAjaxParameters( settings ),\n\t\t\t\tfunction(json) {\n\t\t\t\t\t_fnAjaxUpdateDraw( settings, json );\n\t\t\t\t}\n\t\t\t);\n\t\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\t\n\t\n\t/**\n\t * Build up the parameters in an object needed for a server-side processing\n\t * request. Note that this is basically done twice, is different ways - a modern\n\t * method which is used by default in DataTables 1.10 which uses objects and\n\t * arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if\n\t * the sAjaxSource option is used in the initialisation, or the legacyAjax\n\t * option is set.\n\t *  @param {object} oSettings dataTables settings object\n\t *  @returns {bool} block the table drawing or not\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAjaxParameters( settings )\n\t{\n\t\tvar\n\t\t\tcolumns = settings.aoColumns,\n\t\t\tcolumnCount = columns.length,\n\t\t\tfeatures = settings.oFeatures,\n\t\t\tpreSearch = settings.oPreviousSearch,\n\t\t\tpreColSearch = settings.aoPreSearchCols,\n\t\t\ti, data = [], dataProp, column, columnSearch,\n\t\t\tsort = _fnSortFlatten( settings ),\n\t\t\tdisplayStart = settings._iDisplayStart,\n\t\t\tdisplayLength = features.bPaginate !== false ?\n\t\t\t\tsettings._iDisplayLength :\n\t\t\t\t-1;\n\t\n\t\tvar param = function ( name, value ) {\n\t\t\tdata.push( { 'name': name, 'value': value } );\n\t\t};\n\t\n\t\t// DataTables 1.9- compatible method\n\t\tparam( 'sEcho',          settings.iDraw );\n\t\tparam( 'iColumns',       columnCount );\n\t\tparam( 'sColumns',       _pluck( columns, 'sName' ).join(',') );\n\t\tparam( 'iDisplayStart',  displayStart );\n\t\tparam( 'iDisplayLength', displayLength );\n\t\n\t\t// DataTables 1.10+ method\n\t\tvar d = {\n\t\t\tdraw:    settings.iDraw,\n\t\t\tcolumns: [],\n\t\t\torder:   [],\n\t\t\tstart:   displayStart,\n\t\t\tlength:  displayLength,\n\t\t\tsearch:  {\n\t\t\t\tvalue: preSearch.sSearch,\n\t\t\t\tregex: preSearch.bRegex\n\t\t\t}\n\t\t};\n\t\n\t\tfor ( i=0 ; i<columnCount ; i++ ) {\n\t\t\tcolumn = columns[i];\n\t\t\tcolumnSearch = preColSearch[i];\n\t\t\tdataProp = typeof column.mData==\"function\" ? 'function' : column.mData ;\n\t\n\t\t\td.columns.push( {\n\t\t\t\tdata:       dataProp,\n\t\t\t\tname:       column.sName,\n\t\t\t\tsearchable: column.bSearchable,\n\t\t\t\torderable:  column.bSortable,\n\t\t\t\tsearch:     {\n\t\t\t\t\tvalue: columnSearch.sSearch,\n\t\t\t\t\tregex: columnSearch.bRegex\n\t\t\t\t}\n\t\t\t} );\n\t\n\t\t\tparam( \"mDataProp_\"+i, dataProp );\n\t\n\t\t\tif ( features.bFilter ) {\n\t\t\t\tparam( 'sSearch_'+i,     columnSearch.sSearch );\n\t\t\t\tparam( 'bRegex_'+i,      columnSearch.bRegex );\n\t\t\t\tparam( 'bSearchable_'+i, column.bSearchable );\n\t\t\t}\n\t\n\t\t\tif ( features.bSort ) {\n\t\t\t\tparam( 'bSortable_'+i, column.bSortable );\n\t\t\t}\n\t\t}\n\t\n\t\tif ( features.bFilter ) {\n\t\t\tparam( 'sSearch', preSearch.sSearch );\n\t\t\tparam( 'bRegex', preSearch.bRegex );\n\t\t}\n\t\n\t\tif ( features.bSort ) {\n\t\t\t$.each( sort, function ( i, val ) {\n\t\t\t\td.order.push( { column: val.col, dir: val.dir } );\n\t\n\t\t\t\tparam( 'iSortCol_'+i, val.col );\n\t\t\t\tparam( 'sSortDir_'+i, val.dir );\n\t\t\t} );\n\t\n\t\t\tparam( 'iSortingCols', sort.length );\n\t\t}\n\t\n\t\t// If the legacy.ajax parameter is null, then we automatically decide which\n\t\t// form to use, based on sAjaxSource\n\t\tvar legacy = DataTable.ext.legacy.ajax;\n\t\tif ( legacy === null ) {\n\t\t\treturn settings.sAjaxSource ? data : d;\n\t\t}\n\t\n\t\t// Otherwise, if legacy has been specified then we use that to decide on the\n\t\t// form\n\t\treturn legacy ? data : d;\n\t}\n\t\n\t\n\t/**\n\t * Data the data from the server (nuking the old) and redraw the table\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {object} json json data return from the server.\n\t *  @param {string} json.sEcho Tracking flag for DataTables to match requests\n\t *  @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering\n\t *  @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering\n\t *  @param {array} json.aaData The data to display on this page\n\t *  @param {string} [json.sColumns] Column ordering (sName, comma separated)\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAjaxUpdateDraw ( settings, json )\n\t{\n\t\t// v1.10 uses camelCase variables, while 1.9 uses Hungarian notation.\n\t\t// Support both\n\t\tvar compat = function ( old, modern ) {\n\t\t\treturn json[old] !== undefined ? json[old] : json[modern];\n\t\t};\n\t\n\t\tvar data = _fnAjaxDataSrc( settings, json );\n\t\tvar draw            = compat( 'sEcho',                'draw' );\n\t\tvar recordsTotal    = compat( 'iTotalRecords',        'recordsTotal' );\n\t\tvar recordsFiltered = compat( 'iTotalDisplayRecords', 'recordsFiltered' );\n\t\n\t\tif ( draw ) {\n\t\t\t// Protect against out of sequence returns\n\t\t\tif ( draw*1 < settings.iDraw ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettings.iDraw = draw * 1;\n\t\t}\n\t\n\t\t_fnClearTable( settings );\n\t\tsettings._iRecordsTotal   = parseInt(recordsTotal, 10);\n\t\tsettings._iRecordsDisplay = parseInt(recordsFiltered, 10);\n\t\n\t\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\n\t\t\t_fnAddData( settings, data[i] );\n\t\t}\n\t\tsettings.aiDisplay = settings.aiDisplayMaster.slice();\n\t\n\t\tsettings.bAjaxDataGet = false;\n\t\t_fnDraw( settings );\n\t\n\t\tif ( ! settings._bInitComplete ) {\n\t\t\t_fnInitComplete( settings, json );\n\t\t}\n\t\n\t\tsettings.bAjaxDataGet = true;\n\t\t_fnProcessingDisplay( settings, false );\n\t}\n\t\n\t\n\t/**\n\t * Get the data from the JSON data source to use for drawing a table. Using\n\t * `_fnGetObjectDataFn` allows the data to be sourced from a property of the\n\t * source object, or from a processing function.\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param  {object} json Data source object / array from the server\n\t *  @return {array} Array of data to use\n\t */\n\tfunction _fnAjaxDataSrc ( oSettings, json )\n\t{\n\t\tvar dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ?\n\t\t\toSettings.ajax.dataSrc :\n\t\t\toSettings.sAjaxDataProp; // Compatibility with 1.9-.\n\t\n\t\t// Compatibility with 1.9-. In order to read from aaData, check if the\n\t\t// default has been changed, if not, check for aaData\n\t\tif ( dataSrc === 'data' ) {\n\t\t\treturn json.aaData || json[dataSrc];\n\t\t}\n\t\n\t\treturn dataSrc !== \"\" ?\n\t\t\t_fnGetObjectDataFn( dataSrc )( json ) :\n\t\t\tjson;\n\t}\n\t\n\t/**\n\t * Generate the node required for filtering text\n\t *  @returns {node} Filter control element\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFeatureHtmlFilter ( settings )\n\t{\n\t\tvar classes = settings.oClasses;\n\t\tvar tableId = settings.sTableId;\n\t\tvar language = settings.oLanguage;\n\t\tvar previousSearch = settings.oPreviousSearch;\n\t\tvar features = settings.aanFeatures;\n\t\tvar input = '<input type=\"search\" class=\"'+classes.sFilterInput+'\"/>';\n\t\n\t\tvar str = language.sSearch;\n\t\tstr = str.match(/_INPUT_/) ?\n\t\t\tstr.replace('_INPUT_', input) :\n\t\t\tstr+input;\n\t\n\t\tvar filter = $('<div/>', {\n\t\t\t\t'id': ! features.f ? tableId+'_filter' : null,\n\t\t\t\t'class': classes.sFilter\n\t\t\t} )\n\t\t\t.append( $('<label/>' ).append( str ) );\n\t\n\t\tvar searchFn = function() {\n\t\t\t/* Update all other filter input elements for the new display */\n\t\t\tvar n = features.f;\n\t\t\tvar val = !this.value ? \"\" : this.value; // mental IE8 fix :-(\n\t\n\t\t\t/* Now do the filter */\n\t\t\tif ( val != previousSearch.sSearch ) {\n\t\t\t\t_fnFilterComplete( settings, {\n\t\t\t\t\t\"sSearch\": val,\n\t\t\t\t\t\"bRegex\": previousSearch.bRegex,\n\t\t\t\t\t\"bSmart\": previousSearch.bSmart ,\n\t\t\t\t\t\"bCaseInsensitive\": previousSearch.bCaseInsensitive\n\t\t\t\t} );\n\t\n\t\t\t\t// Need to redraw, without resorting\n\t\t\t\tsettings._iDisplayStart = 0;\n\t\t\t\t_fnDraw( settings );\n\t\t\t}\n\t\t};\n\t\n\t\tvar searchDelay = settings.searchDelay !== null ?\n\t\t\tsettings.searchDelay :\n\t\t\t_fnDataSource( settings ) === 'ssp' ?\n\t\t\t\t400 :\n\t\t\t\t0;\n\t\n\t\tvar jqFilter = $('input', filter)\n\t\t\t.val( previousSearch.sSearch )\n\t\t\t.attr( 'placeholder', language.sSearchPlaceholder )\n\t\t\t.bind(\n\t\t\t\t'keyup.DT search.DT input.DT paste.DT cut.DT',\n\t\t\t\tsearchDelay ?\n\t\t\t\t\t_fnThrottle( searchFn, searchDelay ) :\n\t\t\t\t\tsearchFn\n\t\t\t)\n\t\t\t.bind( 'keypress.DT', function(e) {\n\t\t\t\t/* Prevent form submission */\n\t\t\t\tif ( e.keyCode == 13 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.attr('aria-controls', tableId);\n\t\n\t\t// Update the input elements whenever the table is filtered\n\t\t$(settings.nTable).on( 'search.dt.DT', function ( ev, s ) {\n\t\t\tif ( settings === s ) {\n\t\t\t\t// IE9 throws an 'unknown error' if document.activeElement is used\n\t\t\t\t// inside an iframe or frame...\n\t\t\t\ttry {\n\t\t\t\t\tif ( jqFilter[0] !== document.activeElement ) {\n\t\t\t\t\t\tjqFilter.val( previousSearch.sSearch );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch ( e ) {}\n\t\t\t}\n\t\t} );\n\t\n\t\treturn filter[0];\n\t}\n\t\n\t\n\t/**\n\t * Filter the table using both the global filter and column based filtering\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {object} oSearch search information\n\t *  @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFilterComplete ( oSettings, oInput, iForce )\n\t{\n\t\tvar oPrevSearch = oSettings.oPreviousSearch;\n\t\tvar aoPrevSearch = oSettings.aoPreSearchCols;\n\t\tvar fnSaveFilter = function ( oFilter ) {\n\t\t\t/* Save the filtering values */\n\t\t\toPrevSearch.sSearch = oFilter.sSearch;\n\t\t\toPrevSearch.bRegex = oFilter.bRegex;\n\t\t\toPrevSearch.bSmart = oFilter.bSmart;\n\t\t\toPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;\n\t\t};\n\t\tvar fnRegex = function ( o ) {\n\t\t\t// Backwards compatibility with the bEscapeRegex option\n\t\t\treturn o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;\n\t\t};\n\t\n\t\t// Resolve any column types that are unknown due to addition or invalidation\n\t\t// @todo As per sort - can this be moved into an event handler?\n\t\t_fnColumnTypes( oSettings );\n\t\n\t\t/* In server-side processing all filtering is done by the server, so no point hanging around here */\n\t\tif ( _fnDataSource( oSettings ) != 'ssp' )\n\t\t{\n\t\t\t/* Global filter */\n\t\t\t_fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive );\n\t\t\tfnSaveFilter( oInput );\n\t\n\t\t\t/* Now do the individual column filter */\n\t\t\tfor ( var i=0 ; i<aoPrevSearch.length ; i++ )\n\t\t\t{\n\t\t\t\t_fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]),\n\t\t\t\t\taoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive );\n\t\t\t}\n\t\n\t\t\t/* Custom filtering */\n\t\t\t_fnFilterCustom( oSettings );\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfnSaveFilter( oInput );\n\t\t}\n\t\n\t\t/* Tell the draw function we have been filtering */\n\t\toSettings.bFiltered = true;\n\t\t_fnCallbackFire( oSettings, null, 'search', [oSettings] );\n\t}\n\t\n\t\n\t/**\n\t * Apply custom filtering functions\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFilterCustom( settings )\n\t{\n\t\tvar filters = DataTable.ext.search;\n\t\tvar displayRows = settings.aiDisplay;\n\t\tvar row, rowIdx;\n\t\n\t\tfor ( var i=0, ien=filters.length ; i<ien ; i++ ) {\n\t\t\tvar rows = [];\n\t\n\t\t\t// Loop over each row and see if it should be included\n\t\t\tfor ( var j=0, jen=displayRows.length ; j<jen ; j++ ) {\n\t\t\t\trowIdx = displayRows[ j ];\n\t\t\t\trow = settings.aoData[ rowIdx ];\n\t\n\t\t\t\tif ( filters[i]( settings, row._aFilterData, rowIdx, row._aData, j ) ) {\n\t\t\t\t\trows.push( rowIdx );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t// So the array reference doesn't break set the results into the\n\t\t\t// existing array\n\t\t\tdisplayRows.length = 0;\n\t\t\t$.merge( displayRows, rows );\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Filter the table on a per-column basis\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {string} sInput string to filter on\n\t *  @param {int} iColumn column to filter\n\t *  @param {bool} bRegex treat search string as a regular expression or not\n\t *  @param {bool} bSmart use smart filtering or not\n\t *  @param {bool} bCaseInsensitive Do case insenstive matching or not\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFilterColumn ( settings, searchStr, colIdx, regex, smart, caseInsensitive )\n\t{\n\t\tif ( searchStr === '' ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\tvar data;\n\t\tvar display = settings.aiDisplay;\n\t\tvar rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive );\n\t\n\t\tfor ( var i=display.length-1 ; i>=0 ; i-- ) {\n\t\t\tdata = settings.aoData[ display[i] ]._aFilterData[ colIdx ];\n\t\n\t\t\tif ( ! rpSearch.test( data ) ) {\n\t\t\t\tdisplay.splice( i, 1 );\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Filter the data table based on user input and draw the table\n\t *  @param {object} settings dataTables settings object\n\t *  @param {string} input string to filter on\n\t *  @param {int} force optional - force a research of the master array (1) or not (undefined or 0)\n\t *  @param {bool} regex treat as a regular expression or not\n\t *  @param {bool} smart perform smart filtering or not\n\t *  @param {bool} caseInsensitive Do case insenstive matching or not\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFilter( settings, input, force, regex, smart, caseInsensitive )\n\t{\n\t\tvar rpSearch = _fnFilterCreateSearch( input, regex, smart, caseInsensitive );\n\t\tvar prevSearch = settings.oPreviousSearch.sSearch;\n\t\tvar displayMaster = settings.aiDisplayMaster;\n\t\tvar display, invalidated, i;\n\t\n\t\t// Need to take account of custom filtering functions - always filter\n\t\tif ( DataTable.ext.search.length !== 0 ) {\n\t\t\tforce = true;\n\t\t}\n\t\n\t\t// Check if any of the rows were invalidated\n\t\tinvalidated = _fnFilterData( settings );\n\t\n\t\t// If the input is blank - we just want the full data set\n\t\tif ( input.length <= 0 ) {\n\t\t\tsettings.aiDisplay = displayMaster.slice();\n\t\t}\n\t\telse {\n\t\t\t// New search - start from the master array\n\t\t\tif ( invalidated ||\n\t\t\t\t force ||\n\t\t\t\t prevSearch.length > input.length ||\n\t\t\t\t input.indexOf(prevSearch) !== 0 ||\n\t\t\t\t settings.bSorted // On resort, the display master needs to be\n\t\t\t\t                  // re-filtered since indexes will have changed\n\t\t\t) {\n\t\t\t\tsettings.aiDisplay = displayMaster.slice();\n\t\t\t}\n\t\n\t\t\t// Search the display array\n\t\t\tdisplay = settings.aiDisplay;\n\t\n\t\t\tfor ( i=display.length-1 ; i>=0 ; i-- ) {\n\t\t\t\tif ( ! rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) {\n\t\t\t\t\tdisplay.splice( i, 1 );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Build a regular expression object suitable for searching a table\n\t *  @param {string} sSearch string to search for\n\t *  @param {bool} bRegex treat as a regular expression or not\n\t *  @param {bool} bSmart perform smart filtering or not\n\t *  @param {bool} bCaseInsensitive Do case insensitive matching or not\n\t *  @returns {RegExp} constructed object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFilterCreateSearch( search, regex, smart, caseInsensitive )\n\t{\n\t\tsearch = regex ?\n\t\t\tsearch :\n\t\t\t_fnEscapeRegex( search );\n\t\t\n\t\tif ( smart ) {\n\t\t\t/* For smart filtering we want to allow the search to work regardless of\n\t\t\t * word order. We also want double quoted text to be preserved, so word\n\t\t\t * order is important - a la google. So this is what we want to\n\t\t\t * generate:\n\t\t\t * \n\t\t\t * ^(?=.*?\\bone\\b)(?=.*?\\btwo three\\b)(?=.*?\\bfour\\b).*$\n\t\t\t */\n\t\t\tvar a = $.map( search.match( /\"[^\"]+\"|[^ ]+/g ) || [''], function ( word ) {\n\t\t\t\tif ( word.charAt(0) === '\"' ) {\n\t\t\t\t\tvar m = word.match( /^\"(.*)\"$/ );\n\t\t\t\t\tword = m ? m[1] : word;\n\t\t\t\t}\n\t\n\t\t\t\treturn word.replace('\"', '');\n\t\t\t} );\n\t\n\t\t\tsearch = '^(?=.*?'+a.join( ')(?=.*?' )+').*$';\n\t\t}\n\t\n\t\treturn new RegExp( search, caseInsensitive ? 'i' : '' );\n\t}\n\t\n\t\n\t/**\n\t * Escape a string such that it can be used in a regular expression\n\t *  @param {string} sVal string to escape\n\t *  @returns {string} escaped string\n\t *  @memberof DataTable#oApi\n\t */\n\tvar _fnEscapeRegex = DataTable.util.escapeRegex;\n\t\n\tvar __filter_div = $('<div>')[0];\n\tvar __filter_div_textContent = __filter_div.textContent !== undefined;\n\t\n\t// Update the filtering data for each row if needed (by invalidation or first run)\n\tfunction _fnFilterData ( settings )\n\t{\n\t\tvar columns = settings.aoColumns;\n\t\tvar column;\n\t\tvar i, j, ien, jen, filterData, cellData, row;\n\t\tvar fomatters = DataTable.ext.type.search;\n\t\tvar wasInvalidated = false;\n\t\n\t\tfor ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\n\t\t\trow = settings.aoData[i];\n\t\n\t\t\tif ( ! row._aFilterData ) {\n\t\t\t\tfilterData = [];\n\t\n\t\t\t\tfor ( j=0, jen=columns.length ; j<jen ; j++ ) {\n\t\t\t\t\tcolumn = columns[j];\n\t\n\t\t\t\t\tif ( column.bSearchable ) {\n\t\t\t\t\t\tcellData = _fnGetCellData( settings, i, j, 'filter' );\n\t\n\t\t\t\t\t\tif ( fomatters[ column.sType ] ) {\n\t\t\t\t\t\t\tcellData = fomatters[ column.sType ]( cellData );\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t// Search in DataTables 1.10 is string based. In 1.11 this\n\t\t\t\t\t\t// should be altered to also allow strict type checking.\n\t\t\t\t\t\tif ( cellData === null ) {\n\t\t\t\t\t\t\tcellData = '';\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\tif ( typeof cellData !== 'string' && cellData.toString ) {\n\t\t\t\t\t\t\tcellData = cellData.toString();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tcellData = '';\n\t\t\t\t\t}\n\t\n\t\t\t\t\t// If it looks like there is an HTML entity in the string,\n\t\t\t\t\t// attempt to decode it so sorting works as expected. Note that\n\t\t\t\t\t// we could use a single line of jQuery to do this, but the DOM\n\t\t\t\t\t// method used here is much faster http://jsperf.com/html-decode\n\t\t\t\t\tif ( cellData.indexOf && cellData.indexOf('&') !== -1 ) {\n\t\t\t\t\t\t__filter_div.innerHTML = cellData;\n\t\t\t\t\t\tcellData = __filter_div_textContent ?\n\t\t\t\t\t\t\t__filter_div.textContent :\n\t\t\t\t\t\t\t__filter_div.innerText;\n\t\t\t\t\t}\n\t\n\t\t\t\t\tif ( cellData.replace ) {\n\t\t\t\t\t\tcellData = cellData.replace(/[\\r\\n]/g, '');\n\t\t\t\t\t}\n\t\n\t\t\t\t\tfilterData.push( cellData );\n\t\t\t\t}\n\t\n\t\t\t\trow._aFilterData = filterData;\n\t\t\t\trow._sFilterRow = filterData.join('  ');\n\t\t\t\twasInvalidated = true;\n\t\t\t}\n\t\t}\n\t\n\t\treturn wasInvalidated;\n\t}\n\t\n\t\n\t/**\n\t * Convert from the internal Hungarian notation to camelCase for external\n\t * interaction\n\t *  @param {object} obj Object to convert\n\t *  @returns {object} Inverted object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSearchToCamel ( obj )\n\t{\n\t\treturn {\n\t\t\tsearch:          obj.sSearch,\n\t\t\tsmart:           obj.bSmart,\n\t\t\tregex:           obj.bRegex,\n\t\t\tcaseInsensitive: obj.bCaseInsensitive\n\t\t};\n\t}\n\t\n\t\n\t\n\t/**\n\t * Convert from camelCase notation to the internal Hungarian. We could use the\n\t * Hungarian convert function here, but this is cleaner\n\t *  @param {object} obj Object to convert\n\t *  @returns {object} Inverted object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSearchToHung ( obj )\n\t{\n\t\treturn {\n\t\t\tsSearch:          obj.search,\n\t\t\tbSmart:           obj.smart,\n\t\t\tbRegex:           obj.regex,\n\t\t\tbCaseInsensitive: obj.caseInsensitive\n\t\t};\n\t}\n\t\n\t/**\n\t * Generate the node required for the info display\n\t *  @param {object} oSettings dataTables settings object\n\t *  @returns {node} Information element\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFeatureHtmlInfo ( settings )\n\t{\n\t\tvar\n\t\t\ttid = settings.sTableId,\n\t\t\tnodes = settings.aanFeatures.i,\n\t\t\tn = $('<div/>', {\n\t\t\t\t'class': settings.oClasses.sInfo,\n\t\t\t\t'id': ! nodes ? tid+'_info' : null\n\t\t\t} );\n\t\n\t\tif ( ! nodes ) {\n\t\t\t// Update display on each draw\n\t\t\tsettings.aoDrawCallback.push( {\n\t\t\t\t\"fn\": _fnUpdateInfo,\n\t\t\t\t\"sName\": \"information\"\n\t\t\t} );\n\t\n\t\t\tn\n\t\t\t\t.attr( 'role', 'status' )\n\t\t\t\t.attr( 'aria-live', 'polite' );\n\t\n\t\t\t// Table is described by our info div\n\t\t\t$(settings.nTable).attr( 'aria-describedby', tid+'_info' );\n\t\t}\n\t\n\t\treturn n[0];\n\t}\n\t\n\t\n\t/**\n\t * Update the information elements in the display\n\t *  @param {object} settings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnUpdateInfo ( settings )\n\t{\n\t\t/* Show information about the table */\n\t\tvar nodes = settings.aanFeatures.i;\n\t\tif ( nodes.length === 0 ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\tvar\n\t\t\tlang  = settings.oLanguage,\n\t\t\tstart = settings._iDisplayStart+1,\n\t\t\tend   = settings.fnDisplayEnd(),\n\t\t\tmax   = settings.fnRecordsTotal(),\n\t\t\ttotal = settings.fnRecordsDisplay(),\n\t\t\tout   = total ?\n\t\t\t\tlang.sInfo :\n\t\t\t\tlang.sInfoEmpty;\n\t\n\t\tif ( total !== max ) {\n\t\t\t/* Record set after filtering */\n\t\t\tout += ' ' + lang.sInfoFiltered;\n\t\t}\n\t\n\t\t// Convert the macros\n\t\tout += lang.sInfoPostFix;\n\t\tout = _fnInfoMacros( settings, out );\n\t\n\t\tvar callback = lang.fnInfoCallback;\n\t\tif ( callback !== null ) {\n\t\t\tout = callback.call( settings.oInstance,\n\t\t\t\tsettings, start, end, max, total, out\n\t\t\t);\n\t\t}\n\t\n\t\t$(nodes).html( out );\n\t}\n\t\n\t\n\tfunction _fnInfoMacros ( settings, str )\n\t{\n\t\t// When infinite scrolling, we are always starting at 1. _iDisplayStart is used only\n\t\t// internally\n\t\tvar\n\t\t\tformatter  = settings.fnFormatNumber,\n\t\t\tstart      = settings._iDisplayStart+1,\n\t\t\tlen        = settings._iDisplayLength,\n\t\t\tvis        = settings.fnRecordsDisplay(),\n\t\t\tall        = len === -1;\n\t\n\t\treturn str.\n\t\t\treplace(/_START_/g, formatter.call( settings, start ) ).\n\t\t\treplace(/_END_/g,   formatter.call( settings, settings.fnDisplayEnd() ) ).\n\t\t\treplace(/_MAX_/g,   formatter.call( settings, settings.fnRecordsTotal() ) ).\n\t\t\treplace(/_TOTAL_/g, formatter.call( settings, vis ) ).\n\t\t\treplace(/_PAGE_/g,  formatter.call( settings, all ? 1 : Math.ceil( start / len ) ) ).\n\t\t\treplace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) );\n\t}\n\t\n\t\n\t\n\t/**\n\t * Draw the table for the first time, adding all required features\n\t *  @param {object} settings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnInitialise ( settings )\n\t{\n\t\tvar i, iLen, iAjaxStart=settings.iInitDisplayStart;\n\t\tvar columns = settings.aoColumns, column;\n\t\tvar features = settings.oFeatures;\n\t\tvar deferLoading = settings.bDeferLoading; // value modified by the draw\n\t\n\t\t/* Ensure that the table data is fully initialised */\n\t\tif ( ! settings.bInitialised ) {\n\t\t\tsetTimeout( function(){ _fnInitialise( settings ); }, 200 );\n\t\t\treturn;\n\t\t}\n\t\n\t\t/* Show the display HTML options */\n\t\t_fnAddOptionsHtml( settings );\n\t\n\t\t/* Build and draw the header / footer for the table */\n\t\t_fnBuildHead( settings );\n\t\t_fnDrawHead( settings, settings.aoHeader );\n\t\t_fnDrawHead( settings, settings.aoFooter );\n\t\n\t\t/* Okay to show that something is going on now */\n\t\t_fnProcessingDisplay( settings, true );\n\t\n\t\t/* Calculate sizes for columns */\n\t\tif ( features.bAutoWidth ) {\n\t\t\t_fnCalculateColumnWidths( settings );\n\t\t}\n\t\n\t\tfor ( i=0, iLen=columns.length ; i<iLen ; i++ ) {\n\t\t\tcolumn = columns[i];\n\t\n\t\t\tif ( column.sWidth ) {\n\t\t\t\tcolumn.nTh.style.width = _fnStringToCss( column.sWidth );\n\t\t\t}\n\t\t}\n\t\n\t\t_fnCallbackFire( settings, null, 'preInit', [settings] );\n\t\n\t\t// If there is default sorting required - let's do it. The sort function\n\t\t// will do the drawing for us. Otherwise we draw the table regardless of the\n\t\t// Ajax source - this allows the table to look initialised for Ajax sourcing\n\t\t// data (show 'loading' message possibly)\n\t\t_fnReDraw( settings );\n\t\n\t\t// Server-side processing init complete is done by _fnAjaxUpdateDraw\n\t\tvar dataSrc = _fnDataSource( settings );\n\t\tif ( dataSrc != 'ssp' || deferLoading ) {\n\t\t\t// if there is an ajax source load the data\n\t\t\tif ( dataSrc == 'ajax' ) {\n\t\t\t\t_fnBuildAjax( settings, [], function(json) {\n\t\t\t\t\tvar aData = _fnAjaxDataSrc( settings, json );\n\t\n\t\t\t\t\t// Got the data - add it to the table\n\t\t\t\t\tfor ( i=0 ; i<aData.length ; i++ ) {\n\t\t\t\t\t\t_fnAddData( settings, aData[i] );\n\t\t\t\t\t}\n\t\n\t\t\t\t\t// Reset the init display for cookie saving. We've already done\n\t\t\t\t\t// a filter, and therefore cleared it before. So we need to make\n\t\t\t\t\t// it appear 'fresh'\n\t\t\t\t\tsettings.iInitDisplayStart = iAjaxStart;\n\t\n\t\t\t\t\t_fnReDraw( settings );\n\t\n\t\t\t\t\t_fnProcessingDisplay( settings, false );\n\t\t\t\t\t_fnInitComplete( settings, json );\n\t\t\t\t}, settings );\n\t\t\t}\n\t\t\telse {\n\t\t\t\t_fnProcessingDisplay( settings, false );\n\t\t\t\t_fnInitComplete( settings );\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Draw the table for the first time, adding all required features\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {object} [json] JSON from the server that completed the table, if using Ajax source\n\t *    with client-side processing (optional)\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnInitComplete ( settings, json )\n\t{\n\t\tsettings._bInitComplete = true;\n\t\n\t\t// When data was added after the initialisation (data or Ajax) we need to\n\t\t// calculate the column sizing\n\t\tif ( json || settings.oInit.aaData ) {\n\t\t\t_fnAdjustColumnSizing( settings );\n\t\t}\n\t\n\t\t_fnCallbackFire( settings, null, 'plugin-init', [settings, json] );\n\t\t_fnCallbackFire( settings, 'aoInitComplete', 'init', [settings, json] );\n\t}\n\t\n\t\n\tfunction _fnLengthChange ( settings, val )\n\t{\n\t\tvar len = parseInt( val, 10 );\n\t\tsettings._iDisplayLength = len;\n\t\n\t\t_fnLengthOverflow( settings );\n\t\n\t\t// Fire length change event\n\t\t_fnCallbackFire( settings, null, 'length', [settings, len] );\n\t}\n\t\n\t\n\t/**\n\t * Generate the node required for user display length changing\n\t *  @param {object} settings dataTables settings object\n\t *  @returns {node} Display length feature node\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFeatureHtmlLength ( settings )\n\t{\n\t\tvar\n\t\t\tclasses  = settings.oClasses,\n\t\t\ttableId  = settings.sTableId,\n\t\t\tmenu     = settings.aLengthMenu,\n\t\t\td2       = $.isArray( menu[0] ),\n\t\t\tlengths  = d2 ? menu[0] : menu,\n\t\t\tlanguage = d2 ? menu[1] : menu;\n\t\n\t\tvar select = $('<select/>', {\n\t\t\t'name':          tableId+'_length',\n\t\t\t'aria-controls': tableId,\n\t\t\t'class':         classes.sLengthSelect\n\t\t} );\n\t\n\t\tfor ( var i=0, ien=lengths.length ; i<ien ; i++ ) {\n\t\t\tselect[0][ i ] = new Option( language[i], lengths[i] );\n\t\t}\n\t\n\t\tvar div = $('<div><label/></div>').addClass( classes.sLength );\n\t\tif ( ! settings.aanFeatures.l ) {\n\t\t\tdiv[0].id = tableId+'_length';\n\t\t}\n\t\n\t\tdiv.children().append(\n\t\t\tsettings.oLanguage.sLengthMenu.replace( '_MENU_', select[0].outerHTML )\n\t\t);\n\t\n\t\t// Can't use `select` variable as user might provide their own and the\n\t\t// reference is broken by the use of outerHTML\n\t\t$('select', div)\n\t\t\t.val( settings._iDisplayLength )\n\t\t\t.bind( 'change.DT', function(e) {\n\t\t\t\t_fnLengthChange( settings, $(this).val() );\n\t\t\t\t_fnDraw( settings );\n\t\t\t} );\n\t\n\t\t// Update node value whenever anything changes the table's length\n\t\t$(settings.nTable).bind( 'length.dt.DT', function (e, s, len) {\n\t\t\tif ( settings === s ) {\n\t\t\t\t$('select', div).val( len );\n\t\t\t}\n\t\t} );\n\t\n\t\treturn div[0];\n\t}\n\t\n\t\n\t\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Note that most of the paging logic is done in\n\t * DataTable.ext.pager\n\t */\n\t\n\t/**\n\t * Generate the node required for default pagination\n\t *  @param {object} oSettings dataTables settings object\n\t *  @returns {node} Pagination feature node\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFeatureHtmlPaginate ( settings )\n\t{\n\t\tvar\n\t\t\ttype   = settings.sPaginationType,\n\t\t\tplugin = DataTable.ext.pager[ type ],\n\t\t\tmodern = typeof plugin === 'function',\n\t\t\tredraw = function( settings ) {\n\t\t\t\t_fnDraw( settings );\n\t\t\t},\n\t\t\tnode = $('<div/>').addClass( settings.oClasses.sPaging + type )[0],\n\t\t\tfeatures = settings.aanFeatures;\n\t\n\t\tif ( ! modern ) {\n\t\t\tplugin.fnInit( settings, node, redraw );\n\t\t}\n\t\n\t\t/* Add a draw callback for the pagination on first instance, to update the paging display */\n\t\tif ( ! features.p )\n\t\t{\n\t\t\tnode.id = settings.sTableId+'_paginate';\n\t\n\t\t\tsettings.aoDrawCallback.push( {\n\t\t\t\t\"fn\": function( settings ) {\n\t\t\t\t\tif ( modern ) {\n\t\t\t\t\t\tvar\n\t\t\t\t\t\t\tstart      = settings._iDisplayStart,\n\t\t\t\t\t\t\tlen        = settings._iDisplayLength,\n\t\t\t\t\t\t\tvisRecords = settings.fnRecordsDisplay(),\n\t\t\t\t\t\t\tall        = len === -1,\n\t\t\t\t\t\t\tpage = all ? 0 : Math.ceil( start / len ),\n\t\t\t\t\t\t\tpages = all ? 1 : Math.ceil( visRecords / len ),\n\t\t\t\t\t\t\tbuttons = plugin(page, pages),\n\t\t\t\t\t\t\ti, ien;\n\t\n\t\t\t\t\t\tfor ( i=0, ien=features.p.length ; i<ien ; i++ ) {\n\t\t\t\t\t\t\t_fnRenderer( settings, 'pageButton' )(\n\t\t\t\t\t\t\t\tsettings, features.p[i], i, buttons, page, pages\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tplugin.fnUpdate( settings, redraw );\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\"sName\": \"pagination\"\n\t\t\t} );\n\t\t}\n\t\n\t\treturn node;\n\t}\n\t\n\t\n\t/**\n\t * Alter the display settings to change the page\n\t *  @param {object} settings DataTables settings object\n\t *  @param {string|int} action Paging action to take: \"first\", \"previous\",\n\t *    \"next\" or \"last\" or page number to jump to (integer)\n\t *  @param [bool] redraw Automatically draw the update or not\n\t *  @returns {bool} true page has changed, false - no change\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnPageChange ( settings, action, redraw )\n\t{\n\t\tvar\n\t\t\tstart     = settings._iDisplayStart,\n\t\t\tlen       = settings._iDisplayLength,\n\t\t\trecords   = settings.fnRecordsDisplay();\n\t\n\t\tif ( records === 0 || len === -1 )\n\t\t{\n\t\t\tstart = 0;\n\t\t}\n\t\telse if ( typeof action === \"number\" )\n\t\t{\n\t\t\tstart = action * len;\n\t\n\t\t\tif ( start > records )\n\t\t\t{\n\t\t\t\tstart = 0;\n\t\t\t}\n\t\t}\n\t\telse if ( action == \"first\" )\n\t\t{\n\t\t\tstart = 0;\n\t\t}\n\t\telse if ( action == \"previous\" )\n\t\t{\n\t\t\tstart = len >= 0 ?\n\t\t\t\tstart - len :\n\t\t\t\t0;\n\t\n\t\t\tif ( start < 0 )\n\t\t\t{\n\t\t\t  start = 0;\n\t\t\t}\n\t\t}\n\t\telse if ( action == \"next\" )\n\t\t{\n\t\t\tif ( start + len < records )\n\t\t\t{\n\t\t\t\tstart += len;\n\t\t\t}\n\t\t}\n\t\telse if ( action == \"last\" )\n\t\t{\n\t\t\tstart = Math.floor( (records-1) / len) * len;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t_fnLog( settings, 0, \"Unknown paging action: \"+action, 5 );\n\t\t}\n\t\n\t\tvar changed = settings._iDisplayStart !== start;\n\t\tsettings._iDisplayStart = start;\n\t\n\t\tif ( changed ) {\n\t\t\t_fnCallbackFire( settings, null, 'page', [settings] );\n\t\n\t\t\tif ( redraw ) {\n\t\t\t\t_fnDraw( settings );\n\t\t\t}\n\t\t}\n\t\n\t\treturn changed;\n\t}\n\t\n\t\n\t\n\t/**\n\t * Generate the node required for the processing node\n\t *  @param {object} settings dataTables settings object\n\t *  @returns {node} Processing element\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFeatureHtmlProcessing ( settings )\n\t{\n\t\treturn $('<div/>', {\n\t\t\t\t'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null,\n\t\t\t\t'class': settings.oClasses.sProcessing\n\t\t\t} )\n\t\t\t.html( settings.oLanguage.sProcessing )\n\t\t\t.insertBefore( settings.nTable )[0];\n\t}\n\t\n\t\n\t/**\n\t * Display or hide the processing indicator\n\t *  @param {object} settings dataTables settings object\n\t *  @param {bool} show Show the processing indicator (true) or not (false)\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnProcessingDisplay ( settings, show )\n\t{\n\t\tif ( settings.oFeatures.bProcessing ) {\n\t\t\t$(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' );\n\t\t}\n\t\n\t\t_fnCallbackFire( settings, null, 'processing', [settings, show] );\n\t}\n\t\n\t/**\n\t * Add any control elements for the table - specifically scrolling\n\t *  @param {object} settings dataTables settings object\n\t *  @returns {node} Node to add to the DOM\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFeatureHtmlTable ( settings )\n\t{\n\t\tvar table = $(settings.nTable);\n\t\n\t\t// Add the ARIA grid role to the table\n\t\ttable.attr( 'role', 'grid' );\n\t\n\t\t// Scrolling from here on in\n\t\tvar scroll = settings.oScroll;\n\t\n\t\tif ( scroll.sX === '' && scroll.sY === '' ) {\n\t\t\treturn settings.nTable;\n\t\t}\n\t\n\t\tvar scrollX = scroll.sX;\n\t\tvar scrollY = scroll.sY;\n\t\tvar classes = settings.oClasses;\n\t\tvar caption = table.children('caption');\n\t\tvar captionSide = caption.length ? caption[0]._captionSide : null;\n\t\tvar headerClone = $( table[0].cloneNode(false) );\n\t\tvar footerClone = $( table[0].cloneNode(false) );\n\t\tvar footer = table.children('tfoot');\n\t\tvar _div = '<div/>';\n\t\tvar size = function ( s ) {\n\t\t\treturn !s ? null : _fnStringToCss( s );\n\t\t};\n\t\n\t\tif ( ! footer.length ) {\n\t\t\tfooter = null;\n\t\t}\n\t\n\t\t/*\n\t\t * The HTML structure that we want to generate in this function is:\n\t\t *  div - scroller\n\t\t *    div - scroll head\n\t\t *      div - scroll head inner\n\t\t *        table - scroll head table\n\t\t *          thead - thead\n\t\t *    div - scroll body\n\t\t *      table - table (master table)\n\t\t *        thead - thead clone for sizing\n\t\t *        tbody - tbody\n\t\t *    div - scroll foot\n\t\t *      div - scroll foot inner\n\t\t *        table - scroll foot table\n\t\t *          tfoot - tfoot\n\t\t */\n\t\tvar scroller = $( _div, { 'class': classes.sScrollWrapper } )\n\t\t\t.append(\n\t\t\t\t$(_div, { 'class': classes.sScrollHead } )\n\t\t\t\t\t.css( {\n\t\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\t\tposition: 'relative',\n\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\twidth: scrollX ? size(scrollX) : '100%'\n\t\t\t\t\t} )\n\t\t\t\t\t.append(\n\t\t\t\t\t\t$(_div, { 'class': classes.sScrollHeadInner } )\n\t\t\t\t\t\t\t.css( {\n\t\t\t\t\t\t\t\t'box-sizing': 'content-box',\n\t\t\t\t\t\t\t\twidth: scroll.sXInner || '100%'\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.append(\n\t\t\t\t\t\t\t\theaderClone\n\t\t\t\t\t\t\t\t\t.removeAttr('id')\n\t\t\t\t\t\t\t\t\t.css( 'margin-left', 0 )\n\t\t\t\t\t\t\t\t\t.append( captionSide === 'top' ? caption : null )\n\t\t\t\t\t\t\t\t\t.append(\n\t\t\t\t\t\t\t\t\t\ttable.children('thead')\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t)\n\t\t\t.append(\n\t\t\t\t$(_div, { 'class': classes.sScrollBody } )\n\t\t\t\t\t.css( {\n\t\t\t\t\t\tposition: 'relative',\n\t\t\t\t\t\toverflow: 'auto',\n\t\t\t\t\t\twidth: size( scrollX )\n\t\t\t\t\t} )\n\t\t\t\t\t.append( table )\n\t\t\t);\n\t\n\t\tif ( footer ) {\n\t\t\tscroller.append(\n\t\t\t\t$(_div, { 'class': classes.sScrollFoot } )\n\t\t\t\t\t.css( {\n\t\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\twidth: scrollX ? size(scrollX) : '100%'\n\t\t\t\t\t} )\n\t\t\t\t\t.append(\n\t\t\t\t\t\t$(_div, { 'class': classes.sScrollFootInner } )\n\t\t\t\t\t\t\t.append(\n\t\t\t\t\t\t\t\tfooterClone\n\t\t\t\t\t\t\t\t\t.removeAttr('id')\n\t\t\t\t\t\t\t\t\t.css( 'margin-left', 0 )\n\t\t\t\t\t\t\t\t\t.append( captionSide === 'bottom' ? caption : null )\n\t\t\t\t\t\t\t\t\t.append(\n\t\t\t\t\t\t\t\t\t\ttable.children('tfoot')\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t);\n\t\t}\n\t\n\t\tvar children = scroller.children();\n\t\tvar scrollHead = children[0];\n\t\tvar scrollBody = children[1];\n\t\tvar scrollFoot = footer ? children[2] : null;\n\t\n\t\t// When the body is scrolled, then we also want to scroll the headers\n\t\tif ( scrollX ) {\n\t\t\t$(scrollBody).on( 'scroll.DT', function (e) {\n\t\t\t\tvar scrollLeft = this.scrollLeft;\n\t\n\t\t\t\tscrollHead.scrollLeft = scrollLeft;\n\t\n\t\t\t\tif ( footer ) {\n\t\t\t\t\tscrollFoot.scrollLeft = scrollLeft;\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t\n\t\t$(scrollBody).css(\n\t\t\tscrollY && scroll.bCollapse ? 'max-height' : 'height', \n\t\t\tscrollY\n\t\t);\n\t\n\t\tsettings.nScrollHead = scrollHead;\n\t\tsettings.nScrollBody = scrollBody;\n\t\tsettings.nScrollFoot = scrollFoot;\n\t\n\t\t// On redraw - align columns\n\t\tsettings.aoDrawCallback.push( {\n\t\t\t\"fn\": _fnScrollDraw,\n\t\t\t\"sName\": \"scrolling\"\n\t\t} );\n\t\n\t\treturn scroller[0];\n\t}\n\t\n\t\n\t\n\t/**\n\t * Update the header, footer and body tables for resizing - i.e. column\n\t * alignment.\n\t *\n\t * Welcome to the most horrible function DataTables. The process that this\n\t * function follows is basically:\n\t *   1. Re-create the table inside the scrolling div\n\t *   2. Take live measurements from the DOM\n\t *   3. Apply the measurements to align the columns\n\t *   4. Clean up\n\t *\n\t *  @param {object} settings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnScrollDraw ( settings )\n\t{\n\t\t// Given that this is such a monster function, a lot of variables are use\n\t\t// to try and keep the minimised size as small as possible\n\t\tvar\n\t\t\tscroll         = settings.oScroll,\n\t\t\tscrollX        = scroll.sX,\n\t\t\tscrollXInner   = scroll.sXInner,\n\t\t\tscrollY        = scroll.sY,\n\t\t\tbarWidth       = scroll.iBarWidth,\n\t\t\tdivHeader      = $(settings.nScrollHead),\n\t\t\tdivHeaderStyle = divHeader[0].style,\n\t\t\tdivHeaderInner = divHeader.children('div'),\n\t\t\tdivHeaderInnerStyle = divHeaderInner[0].style,\n\t\t\tdivHeaderTable = divHeaderInner.children('table'),\n\t\t\tdivBodyEl      = settings.nScrollBody,\n\t\t\tdivBody        = $(divBodyEl),\n\t\t\tdivBodyStyle   = divBodyEl.style,\n\t\t\tdivFooter      = $(settings.nScrollFoot),\n\t\t\tdivFooterInner = divFooter.children('div'),\n\t\t\tdivFooterTable = divFooterInner.children('table'),\n\t\t\theader         = $(settings.nTHead),\n\t\t\ttable          = $(settings.nTable),\n\t\t\ttableEl        = table[0],\n\t\t\ttableStyle     = tableEl.style,\n\t\t\tfooter         = settings.nTFoot ? $(settings.nTFoot) : null,\n\t\t\tbrowser        = settings.oBrowser,\n\t\t\tie67           = browser.bScrollOversize,\n\t\t\tdtHeaderCells  = _pluck( settings.aoColumns, 'nTh' ),\n\t\t\theaderTrgEls, footerTrgEls,\n\t\t\theaderSrcEls, footerSrcEls,\n\t\t\theaderCopy, footerCopy,\n\t\t\theaderWidths=[], footerWidths=[],\n\t\t\theaderContent=[], footerContent=[],\n\t\t\tidx, correction, sanityWidth,\n\t\t\tzeroOut = function(nSizer) {\n\t\t\t\tvar style = nSizer.style;\n\t\t\t\tstyle.paddingTop = \"0\";\n\t\t\t\tstyle.paddingBottom = \"0\";\n\t\t\t\tstyle.borderTopWidth = \"0\";\n\t\t\t\tstyle.borderBottomWidth = \"0\";\n\t\t\t\tstyle.height = 0;\n\t\t\t};\n\t\n\t\t// If the scrollbar visibility has changed from the last draw, we need to\n\t\t// adjust the column sizes as the table width will have changed to account\n\t\t// for the scrollbar\n\t\tvar scrollBarVis = divBodyEl.scrollHeight > divBodyEl.clientHeight;\n\t\t\n\t\tif ( settings.scrollBarVis !== scrollBarVis && settings.scrollBarVis !== undefined ) {\n\t\t\tsettings.scrollBarVis = scrollBarVis;\n\t\t\t_fnAdjustColumnSizing( settings );\n\t\t\treturn; // adjust column sizing will call this function again\n\t\t}\n\t\telse {\n\t\t\tsettings.scrollBarVis = scrollBarVis;\n\t\t}\n\t\n\t\t/*\n\t\t * 1. Re-create the table inside the scrolling div\n\t\t */\n\t\n\t\t// Remove the old minimised thead and tfoot elements in the inner table\n\t\ttable.children('thead, tfoot').remove();\n\t\n\t\tif ( footer ) {\n\t\t\tfooterCopy = footer.clone().prependTo( table );\n\t\t\tfooterTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized\n\t\t\tfooterSrcEls = footerCopy.find('tr');\n\t\t}\n\t\n\t\t// Clone the current header and footer elements and then place it into the inner table\n\t\theaderCopy = header.clone().prependTo( table );\n\t\theaderTrgEls = header.find('tr'); // original header is in its own table\n\t\theaderSrcEls = headerCopy.find('tr');\n\t\theaderCopy.find('th, td').removeAttr('tabindex');\n\t\n\t\n\t\t/*\n\t\t * 2. Take live measurements from the DOM - do not alter the DOM itself!\n\t\t */\n\t\n\t\t// Remove old sizing and apply the calculated column widths\n\t\t// Get the unique column headers in the newly created (cloned) header. We want to apply the\n\t\t// calculated sizes to this header\n\t\tif ( ! scrollX )\n\t\t{\n\t\t\tdivBodyStyle.width = '100%';\n\t\t\tdivHeader[0].style.width = '100%';\n\t\t}\n\t\n\t\t$.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) {\n\t\t\tidx = _fnVisibleToColumnIndex( settings, i );\n\t\t\tel.style.width = settings.aoColumns[idx].sWidth;\n\t\t} );\n\t\n\t\tif ( footer ) {\n\t\t\t_fnApplyToChildren( function(n) {\n\t\t\t\tn.style.width = \"\";\n\t\t\t}, footerSrcEls );\n\t\t}\n\t\n\t\t// Size the table as a whole\n\t\tsanityWidth = table.outerWidth();\n\t\tif ( scrollX === \"\" ) {\n\t\t\t// No x scrolling\n\t\t\ttableStyle.width = \"100%\";\n\t\n\t\t\t// IE7 will make the width of the table when 100% include the scrollbar\n\t\t\t// - which is shouldn't. When there is a scrollbar we need to take this\n\t\t\t// into account.\n\t\t\tif ( ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||\n\t\t\t\tdivBody.css('overflow-y') == \"scroll\")\n\t\t\t) {\n\t\t\t\ttableStyle.width = _fnStringToCss( table.outerWidth() - barWidth);\n\t\t\t}\n\t\n\t\t\t// Recalculate the sanity width\n\t\t\tsanityWidth = table.outerWidth();\n\t\t}\n\t\telse if ( scrollXInner !== \"\" ) {\n\t\t\t// legacy x scroll inner has been given - use it\n\t\t\ttableStyle.width = _fnStringToCss(scrollXInner);\n\t\n\t\t\t// Recalculate the sanity width\n\t\t\tsanityWidth = table.outerWidth();\n\t\t}\n\t\n\t\t// Hidden header should have zero height, so remove padding and borders. Then\n\t\t// set the width based on the real headers\n\t\n\t\t// Apply all styles in one pass\n\t\t_fnApplyToChildren( zeroOut, headerSrcEls );\n\t\n\t\t// Read all widths in next pass\n\t\t_fnApplyToChildren( function(nSizer) {\n\t\t\theaderContent.push( nSizer.innerHTML );\n\t\t\theaderWidths.push( _fnStringToCss( $(nSizer).css('width') ) );\n\t\t}, headerSrcEls );\n\t\n\t\t// Apply all widths in final pass\n\t\t_fnApplyToChildren( function(nToSize, i) {\n\t\t\t// Only apply widths to the DataTables detected header cells - this\n\t\t\t// prevents complex headers from having contradictory sizes applied\n\t\t\tif ( $.inArray( nToSize, dtHeaderCells ) !== -1 ) {\n\t\t\t\tnToSize.style.width = headerWidths[i];\n\t\t\t}\n\t\t}, headerTrgEls );\n\t\n\t\t$(headerSrcEls).height(0);\n\t\n\t\t/* Same again with the footer if we have one */\n\t\tif ( footer )\n\t\t{\n\t\t\t_fnApplyToChildren( zeroOut, footerSrcEls );\n\t\n\t\t\t_fnApplyToChildren( function(nSizer) {\n\t\t\t\tfooterContent.push( nSizer.innerHTML );\n\t\t\t\tfooterWidths.push( _fnStringToCss( $(nSizer).css('width') ) );\n\t\t\t}, footerSrcEls );\n\t\n\t\t\t_fnApplyToChildren( function(nToSize, i) {\n\t\t\t\tnToSize.style.width = footerWidths[i];\n\t\t\t}, footerTrgEls );\n\t\n\t\t\t$(footerSrcEls).height(0);\n\t\t}\n\t\n\t\n\t\t/*\n\t\t * 3. Apply the measurements\n\t\t */\n\t\n\t\t// \"Hide\" the header and footer that we used for the sizing. We need to keep\n\t\t// the content of the cell so that the width applied to the header and body\n\t\t// both match, but we want to hide it completely. We want to also fix their\n\t\t// width to what they currently are\n\t\t_fnApplyToChildren( function(nSizer, i) {\n\t\t\tnSizer.innerHTML = '<div class=\"dataTables_sizing\" style=\"height:0;overflow:hidden;\">'+headerContent[i]+'</div>';\n\t\t\tnSizer.style.width = headerWidths[i];\n\t\t}, headerSrcEls );\n\t\n\t\tif ( footer )\n\t\t{\n\t\t\t_fnApplyToChildren( function(nSizer, i) {\n\t\t\t\tnSizer.innerHTML = '<div class=\"dataTables_sizing\" style=\"height:0;overflow:hidden;\">'+footerContent[i]+'</div>';\n\t\t\t\tnSizer.style.width = footerWidths[i];\n\t\t\t}, footerSrcEls );\n\t\t}\n\t\n\t\t// Sanity check that the table is of a sensible width. If not then we are going to get\n\t\t// misalignment - try to prevent this by not allowing the table to shrink below its min width\n\t\tif ( table.outerWidth() < sanityWidth )\n\t\t{\n\t\t\t// The min width depends upon if we have a vertical scrollbar visible or not */\n\t\t\tcorrection = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||\n\t\t\t\tdivBody.css('overflow-y') == \"scroll\")) ?\n\t\t\t\t\tsanityWidth+barWidth :\n\t\t\t\t\tsanityWidth;\n\t\n\t\t\t// IE6/7 are a law unto themselves...\n\t\t\tif ( ie67 && (divBodyEl.scrollHeight >\n\t\t\t\tdivBodyEl.offsetHeight || divBody.css('overflow-y') == \"scroll\")\n\t\t\t) {\n\t\t\t\ttableStyle.width = _fnStringToCss( correction-barWidth );\n\t\t\t}\n\t\n\t\t\t// And give the user a warning that we've stopped the table getting too small\n\t\t\tif ( scrollX === \"\" || scrollXInner !== \"\" ) {\n\t\t\t\t_fnLog( settings, 1, 'Possible column misalignment', 6 );\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tcorrection = '100%';\n\t\t}\n\t\n\t\t// Apply to the container elements\n\t\tdivBodyStyle.width = _fnStringToCss( correction );\n\t\tdivHeaderStyle.width = _fnStringToCss( correction );\n\t\n\t\tif ( footer ) {\n\t\t\tsettings.nScrollFoot.style.width = _fnStringToCss( correction );\n\t\t}\n\t\n\t\n\t\t/*\n\t\t * 4. Clean up\n\t\t */\n\t\tif ( ! scrollY ) {\n\t\t\t/* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting\n\t\t\t * the scrollbar height from the visible display, rather than adding it on. We need to\n\t\t\t * set the height in order to sort this. Don't want to do it in any other browsers.\n\t\t\t */\n\t\t\tif ( ie67 ) {\n\t\t\t\tdivBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+barWidth );\n\t\t\t}\n\t\t}\n\t\n\t\t/* Finally set the width's of the header and footer tables */\n\t\tvar iOuterWidth = table.outerWidth();\n\t\tdivHeaderTable[0].style.width = _fnStringToCss( iOuterWidth );\n\t\tdivHeaderInnerStyle.width = _fnStringToCss( iOuterWidth );\n\t\n\t\t// Figure out if there are scrollbar present - if so then we need a the header and footer to\n\t\t// provide a bit more space to allow \"overflow\" scrolling (i.e. past the scrollbar)\n\t\tvar bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == \"scroll\";\n\t\tvar padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' );\n\t\tdivHeaderInnerStyle[ padding ] = bScrolling ? barWidth+\"px\" : \"0px\";\n\t\n\t\tif ( footer ) {\n\t\t\tdivFooterTable[0].style.width = _fnStringToCss( iOuterWidth );\n\t\t\tdivFooterInner[0].style.width = _fnStringToCss( iOuterWidth );\n\t\t\tdivFooterInner[0].style[padding] = bScrolling ? barWidth+\"px\" : \"0px\";\n\t\t}\n\t\n\t\t// Correct DOM ordering for colgroup - comes before the thead\n\t\ttable.children('colgroup').insertBefore( table.children('thead') );\n\t\n\t\t/* Adjust the position of the header in case we loose the y-scrollbar */\n\t\tdivBody.scroll();\n\t\n\t\t// If sorting or filtering has occurred, jump the scrolling back to the top\n\t\t// only if we aren't holding the position\n\t\tif ( (settings.bSorted || settings.bFiltered) && ! settings._drawHold ) {\n\t\t\tdivBodyEl.scrollTop = 0;\n\t\t}\n\t}\n\t\n\t\n\t\n\t/**\n\t * Apply a given function to the display child nodes of an element array (typically\n\t * TD children of TR rows\n\t *  @param {function} fn Method to apply to the objects\n\t *  @param array {nodes} an1 List of elements to look through for display children\n\t *  @param array {nodes} an2 Another list (identical structure to the first) - optional\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnApplyToChildren( fn, an1, an2 )\n\t{\n\t\tvar index=0, i=0, iLen=an1.length;\n\t\tvar nNode1, nNode2;\n\t\n\t\twhile ( i < iLen ) {\n\t\t\tnNode1 = an1[i].firstChild;\n\t\t\tnNode2 = an2 ? an2[i].firstChild : null;\n\t\n\t\t\twhile ( nNode1 ) {\n\t\t\t\tif ( nNode1.nodeType === 1 ) {\n\t\t\t\t\tif ( an2 ) {\n\t\t\t\t\t\tfn( nNode1, nNode2, index );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tfn( nNode1, index );\n\t\t\t\t\t}\n\t\n\t\t\t\t\tindex++;\n\t\t\t\t}\n\t\n\t\t\t\tnNode1 = nNode1.nextSibling;\n\t\t\t\tnNode2 = an2 ? nNode2.nextSibling : null;\n\t\t\t}\n\t\n\t\t\ti++;\n\t\t}\n\t}\n\t\n\t\n\t\n\tvar __re_html_remove = /<.*?>/g;\n\t\n\t\n\t/**\n\t * Calculate the width of columns for the table\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnCalculateColumnWidths ( oSettings )\n\t{\n\t\tvar\n\t\t\ttable = oSettings.nTable,\n\t\t\tcolumns = oSettings.aoColumns,\n\t\t\tscroll = oSettings.oScroll,\n\t\t\tscrollY = scroll.sY,\n\t\t\tscrollX = scroll.sX,\n\t\t\tscrollXInner = scroll.sXInner,\n\t\t\tcolumnCount = columns.length,\n\t\t\tvisibleColumns = _fnGetColumns( oSettings, 'bVisible' ),\n\t\t\theaderCells = $('th', oSettings.nTHead),\n\t\t\ttableWidthAttr = table.getAttribute('width'), // from DOM element\n\t\t\ttableContainer = table.parentNode,\n\t\t\tuserInputs = false,\n\t\t\ti, column, columnIdx, width, outerWidth,\n\t\t\tbrowser = oSettings.oBrowser,\n\t\t\tie67 = browser.bScrollOversize;\n\t\n\t\tvar styleWidth = table.style.width;\n\t\tif ( styleWidth && styleWidth.indexOf('%') !== -1 ) {\n\t\t\ttableWidthAttr = styleWidth;\n\t\t}\n\t\n\t\t/* Convert any user input sizes into pixel sizes */\n\t\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\n\t\t\tcolumn = columns[ visibleColumns[i] ];\n\t\n\t\t\tif ( column.sWidth !== null ) {\n\t\t\t\tcolumn.sWidth = _fnConvertToWidth( column.sWidthOrig, tableContainer );\n\t\n\t\t\t\tuserInputs = true;\n\t\t\t}\n\t\t}\n\t\n\t\t/* If the number of columns in the DOM equals the number that we have to\n\t\t * process in DataTables, then we can use the offsets that are created by\n\t\t * the web- browser. No custom sizes can be set in order for this to happen,\n\t\t * nor scrolling used\n\t\t */\n\t\tif ( ie67 || ! userInputs && ! scrollX && ! scrollY &&\n\t\t     columnCount == _fnVisbleColumns( oSettings ) &&\n\t\t     columnCount == headerCells.length\n\t\t) {\n\t\t\tfor ( i=0 ; i<columnCount ; i++ ) {\n\t\t\t\tvar colIdx = _fnVisibleToColumnIndex( oSettings, i );\n\t\n\t\t\t\tif ( colIdx !== null ) {\n\t\t\t\t\tcolumns[ colIdx ].sWidth = _fnStringToCss( headerCells.eq(i).width() );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Otherwise construct a single row, worst case, table with the widest\n\t\t\t// node in the data, assign any user defined widths, then insert it into\n\t\t\t// the DOM and allow the browser to do all the hard work of calculating\n\t\t\t// table widths\n\t\t\tvar tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table\n\t\t\t\t.css( 'visibility', 'hidden' )\n\t\t\t\t.removeAttr( 'id' );\n\t\n\t\t\t// Clean up the table body\n\t\t\ttmpTable.find('tbody tr').remove();\n\t\t\tvar tr = $('<tr/>').appendTo( tmpTable.find('tbody') );\n\t\n\t\t\t// Clone the table header and footer - we can't use the header / footer\n\t\t\t// from the cloned table, since if scrolling is active, the table's\n\t\t\t// real header and footer are contained in different table tags\n\t\t\ttmpTable.find('thead, tfoot').remove();\n\t\t\ttmpTable\n\t\t\t\t.append( $(oSettings.nTHead).clone() )\n\t\t\t\t.append( $(oSettings.nTFoot).clone() );\n\t\n\t\t\t// Remove any assigned widths from the footer (from scrolling)\n\t\t\ttmpTable.find('tfoot th, tfoot td').css('width', '');\n\t\n\t\t\t// Apply custom sizing to the cloned header\n\t\t\theaderCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] );\n\t\n\t\t\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\n\t\t\t\tcolumn = columns[ visibleColumns[i] ];\n\t\n\t\t\t\theaderCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ?\n\t\t\t\t\t_fnStringToCss( column.sWidthOrig ) :\n\t\t\t\t\t'';\n\t\n\t\t\t\t// For scrollX we need to force the column width otherwise the\n\t\t\t\t// browser will collapse it. If this width is smaller than the\n\t\t\t\t// width the column requires, then it will have no effect\n\t\t\t\tif ( column.sWidthOrig && scrollX ) {\n\t\t\t\t\t$( headerCells[i] ).append( $('<div/>').css( {\n\t\t\t\t\t\twidth: column.sWidthOrig,\n\t\t\t\t\t\tmargin: 0,\n\t\t\t\t\t\tpadding: 0,\n\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\theight: 1\n\t\t\t\t\t} ) );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t// Find the widest cell for each column and put it into the table\n\t\t\tif ( oSettings.aoData.length ) {\n\t\t\t\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\n\t\t\t\t\tcolumnIdx = visibleColumns[i];\n\t\t\t\t\tcolumn = columns[ columnIdx ];\n\t\n\t\t\t\t\t$( _fnGetWidestNode( oSettings, columnIdx ) )\n\t\t\t\t\t\t.clone( false )\n\t\t\t\t\t\t.append( column.sContentPadding )\n\t\t\t\t\t\t.appendTo( tr );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t// Tidy the temporary table - remove name attributes so there aren't\n\t\t\t// duplicated in the dom (radio elements for example)\n\t\t\t$('[name]', tmpTable).removeAttr('name');\n\t\n\t\t\t// Table has been built, attach to the document so we can work with it.\n\t\t\t// A holding element is used, positioned at the top of the container\n\t\t\t// with minimal height, so it has no effect on if the container scrolls\n\t\t\t// or not. Otherwise it might trigger scrolling when it actually isn't\n\t\t\t// needed\n\t\t\tvar holder = $('<div/>').css( scrollX || scrollY ?\n\t\t\t\t\t{\n\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\theight: 1,\n\t\t\t\t\t\tright: 0,\n\t\t\t\t\t\toverflow: 'hidden'\n\t\t\t\t\t} :\n\t\t\t\t\t{}\n\t\t\t\t)\n\t\t\t\t.append( tmpTable )\n\t\t\t\t.appendTo( tableContainer );\n\t\n\t\t\t// When scrolling (X or Y) we want to set the width of the table as \n\t\t\t// appropriate. However, when not scrolling leave the table width as it\n\t\t\t// is. This results in slightly different, but I think correct behaviour\n\t\t\tif ( scrollX && scrollXInner ) {\n\t\t\t\ttmpTable.width( scrollXInner );\n\t\t\t}\n\t\t\telse if ( scrollX ) {\n\t\t\t\ttmpTable.css( 'width', 'auto' );\n\t\t\t\ttmpTable.removeAttr('width');\n\t\n\t\t\t\t// If there is no width attribute or style, then allow the table to\n\t\t\t\t// collapse\n\t\t\t\tif ( tmpTable.width() < tableContainer.clientWidth && tableWidthAttr ) {\n\t\t\t\t\ttmpTable.width( tableContainer.clientWidth );\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( scrollY ) {\n\t\t\t\ttmpTable.width( tableContainer.clientWidth );\n\t\t\t}\n\t\t\telse if ( tableWidthAttr ) {\n\t\t\t\ttmpTable.width( tableWidthAttr );\n\t\t\t}\n\t\n\t\t\t// Get the width of each column in the constructed table - we need to\n\t\t\t// know the inner width (so it can be assigned to the other table's\n\t\t\t// cells) and the outer width so we can calculate the full width of the\n\t\t\t// table. This is safe since DataTables requires a unique cell for each\n\t\t\t// column, but if ever a header can span multiple columns, this will\n\t\t\t// need to be modified.\n\t\t\tvar total = 0;\n\t\t\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\n\t\t\t\tvar cell = $(headerCells[i]);\n\t\t\t\tvar border = cell.outerWidth() - cell.width();\n\t\n\t\t\t\t// Use getBounding... where possible (not IE8-) because it can give\n\t\t\t\t// sub-pixel accuracy, which we then want to round up!\n\t\t\t\tvar bounding = browser.bBounding ?\n\t\t\t\t\tMath.ceil( headerCells[i].getBoundingClientRect().width ) :\n\t\t\t\t\tcell.outerWidth();\n\t\n\t\t\t\t// Total is tracked to remove any sub-pixel errors as the outerWidth\n\t\t\t\t// of the table might not equal the total given here (IE!).\n\t\t\t\ttotal += bounding;\n\t\n\t\t\t\t// Width for each column to use\n\t\t\t\tcolumns[ visibleColumns[i] ].sWidth = _fnStringToCss( bounding - border );\n\t\t\t}\n\t\n\t\t\ttable.style.width = _fnStringToCss( total );\n\t\n\t\t\t// Finished with the table - ditch it\n\t\t\tholder.remove();\n\t\t}\n\t\n\t\t// If there is a width attr, we want to attach an event listener which\n\t\t// allows the table sizing to automatically adjust when the window is\n\t\t// resized. Use the width attr rather than CSS, since we can't know if the\n\t\t// CSS is a relative value or absolute - DOM read is always px.\n\t\tif ( tableWidthAttr ) {\n\t\t\ttable.style.width = _fnStringToCss( tableWidthAttr );\n\t\t}\n\t\n\t\tif ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) {\n\t\t\tvar bindResize = function () {\n\t\t\t\t$(window).bind('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {\n\t\t\t\t\t_fnAdjustColumnSizing( oSettings );\n\t\t\t\t} ) );\n\t\t\t};\n\t\n\t\t\t// IE6/7 will crash if we bind a resize event handler on page load.\n\t\t\t// To be removed in 1.11 which drops IE6/7 support\n\t\t\tif ( ie67 ) {\n\t\t\t\tsetTimeout( bindResize, 1000 );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tbindResize();\n\t\t\t}\n\t\n\t\t\toSettings._reszEvt = true;\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Throttle the calls to a function. Arguments and context are maintained for\n\t * the throttled function\n\t *  @param {function} fn Function to be called\n\t *  @param {int} [freq=200] call frequency in mS\n\t *  @returns {function} wrapped function\n\t *  @memberof DataTable#oApi\n\t */\n\tvar _fnThrottle = DataTable.util.throttle;\n\t\n\t\n\t/**\n\t * Convert a CSS unit width to pixels (e.g. 2em)\n\t *  @param {string} width width to be converted\n\t *  @param {node} parent parent to get the with for (required for relative widths) - optional\n\t *  @returns {int} width in pixels\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnConvertToWidth ( width, parent )\n\t{\n\t\tif ( ! width ) {\n\t\t\treturn 0;\n\t\t}\n\t\n\t\tvar n = $('<div/>')\n\t\t\t.css( 'width', _fnStringToCss( width ) )\n\t\t\t.appendTo( parent || document.body );\n\t\n\t\tvar val = n[0].offsetWidth;\n\t\tn.remove();\n\t\n\t\treturn val;\n\t}\n\t\n\t\n\t/**\n\t * Get the widest node\n\t *  @param {object} settings dataTables settings object\n\t *  @param {int} colIdx column of interest\n\t *  @returns {node} widest table node\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnGetWidestNode( settings, colIdx )\n\t{\n\t\tvar idx = _fnGetMaxLenString( settings, colIdx );\n\t\tif ( idx < 0 ) {\n\t\t\treturn null;\n\t\t}\n\t\n\t\tvar data = settings.aoData[ idx ];\n\t\treturn ! data.nTr ? // Might not have been created when deferred rendering\n\t\t\t$('<td/>').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] :\n\t\t\tdata.anCells[ colIdx ];\n\t}\n\t\n\t\n\t/**\n\t * Get the maximum strlen for each data column\n\t *  @param {object} settings dataTables settings object\n\t *  @param {int} colIdx column of interest\n\t *  @returns {string} max string length for each column\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnGetMaxLenString( settings, colIdx )\n\t{\n\t\tvar s, max=-1, maxIdx = -1;\n\t\n\t\tfor ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\n\t\t\ts = _fnGetCellData( settings, i, colIdx, 'display' )+'';\n\t\t\ts = s.replace( __re_html_remove, '' );\n\t\t\ts = s.replace( /&nbsp;/g, ' ' );\n\t\n\t\t\tif ( s.length > max ) {\n\t\t\t\tmax = s.length;\n\t\t\t\tmaxIdx = i;\n\t\t\t}\n\t\t}\n\t\n\t\treturn maxIdx;\n\t}\n\t\n\t\n\t/**\n\t * Append a CSS unit (only if required) to a string\n\t *  @param {string} value to css-ify\n\t *  @returns {string} value with css unit\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnStringToCss( s )\n\t{\n\t\tif ( s === null ) {\n\t\t\treturn '0px';\n\t\t}\n\t\n\t\tif ( typeof s == 'number' ) {\n\t\t\treturn s < 0 ?\n\t\t\t\t'0px' :\n\t\t\t\ts+'px';\n\t\t}\n\t\n\t\t// Check it has a unit character already\n\t\treturn s.match(/\\d$/) ?\n\t\t\ts+'px' :\n\t\t\ts;\n\t}\n\t\n\t\n\t\n\tfunction _fnSortFlatten ( settings )\n\t{\n\t\tvar\n\t\t\ti, iLen, k, kLen,\n\t\t\taSort = [],\n\t\t\taiOrig = [],\n\t\t\taoColumns = settings.aoColumns,\n\t\t\taDataSort, iCol, sType, srcCol,\n\t\t\tfixed = settings.aaSortingFixed,\n\t\t\tfixedObj = $.isPlainObject( fixed ),\n\t\t\tnestedSort = [],\n\t\t\tadd = function ( a ) {\n\t\t\t\tif ( a.length && ! $.isArray( a[0] ) ) {\n\t\t\t\t\t// 1D array\n\t\t\t\t\tnestedSort.push( a );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// 2D array\n\t\t\t\t\t$.merge( nestedSort, a );\n\t\t\t\t}\n\t\t\t};\n\t\n\t\t// Build the sort array, with pre-fix and post-fix options if they have been\n\t\t// specified\n\t\tif ( $.isArray( fixed ) ) {\n\t\t\tadd( fixed );\n\t\t}\n\t\n\t\tif ( fixedObj && fixed.pre ) {\n\t\t\tadd( fixed.pre );\n\t\t}\n\t\n\t\tadd( settings.aaSorting );\n\t\n\t\tif (fixedObj && fixed.post ) {\n\t\t\tadd( fixed.post );\n\t\t}\n\t\n\t\tfor ( i=0 ; i<nestedSort.length ; i++ )\n\t\t{\n\t\t\tsrcCol = nestedSort[i][0];\n\t\t\taDataSort = aoColumns[ srcCol ].aDataSort;\n\t\n\t\t\tfor ( k=0, kLen=aDataSort.length ; k<kLen ; k++ )\n\t\t\t{\n\t\t\t\tiCol = aDataSort[k];\n\t\t\t\tsType = aoColumns[ iCol ].sType || 'string';\n\t\n\t\t\t\tif ( nestedSort[i]._idx === undefined ) {\n\t\t\t\t\tnestedSort[i]._idx = $.inArray( nestedSort[i][1], aoColumns[iCol].asSorting );\n\t\t\t\t}\n\t\n\t\t\t\taSort.push( {\n\t\t\t\t\tsrc:       srcCol,\n\t\t\t\t\tcol:       iCol,\n\t\t\t\t\tdir:       nestedSort[i][1],\n\t\t\t\t\tindex:     nestedSort[i]._idx,\n\t\t\t\t\ttype:      sType,\n\t\t\t\t\tformatter: DataTable.ext.type.order[ sType+\"-pre\" ]\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t\n\t\treturn aSort;\n\t}\n\t\n\t/**\n\t * Change the order of the table\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t *  @todo This really needs split up!\n\t */\n\tfunction _fnSort ( oSettings )\n\t{\n\t\tvar\n\t\t\ti, ien, iLen, j, jLen, k, kLen,\n\t\t\tsDataType, nTh,\n\t\t\taiOrig = [],\n\t\t\toExtSort = DataTable.ext.type.order,\n\t\t\taoData = oSettings.aoData,\n\t\t\taoColumns = oSettings.aoColumns,\n\t\t\taDataSort, data, iCol, sType, oSort,\n\t\t\tformatters = 0,\n\t\t\tsortCol,\n\t\t\tdisplayMaster = oSettings.aiDisplayMaster,\n\t\t\taSort;\n\t\n\t\t// Resolve any column types that are unknown due to addition or invalidation\n\t\t// @todo Can this be moved into a 'data-ready' handler which is called when\n\t\t//   data is going to be used in the table?\n\t\t_fnColumnTypes( oSettings );\n\t\n\t\taSort = _fnSortFlatten( oSettings );\n\t\n\t\tfor ( i=0, ien=aSort.length ; i<ien ; i++ ) {\n\t\t\tsortCol = aSort[i];\n\t\n\t\t\t// Track if we can use the fast sort algorithm\n\t\t\tif ( sortCol.formatter ) {\n\t\t\t\tformatters++;\n\t\t\t}\n\t\n\t\t\t// Load the data needed for the sort, for each cell\n\t\t\t_fnSortData( oSettings, sortCol.col );\n\t\t}\n\t\n\t\t/* No sorting required if server-side or no sorting array */\n\t\tif ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 )\n\t\t{\n\t\t\t// Create a value - key array of the current row positions such that we can use their\n\t\t\t// current position during the sort, if values match, in order to perform stable sorting\n\t\t\tfor ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) {\n\t\t\t\taiOrig[ displayMaster[i] ] = i;\n\t\t\t}\n\t\n\t\t\t/* Do the sort - here we want multi-column sorting based on a given data source (column)\n\t\t\t * and sorting function (from oSort) in a certain direction. It's reasonably complex to\n\t\t\t * follow on it's own, but this is what we want (example two column sorting):\n\t\t\t *  fnLocalSorting = function(a,b){\n\t\t\t *    var iTest;\n\t\t\t *    iTest = oSort['string-asc']('data11', 'data12');\n\t\t\t *      if (iTest !== 0)\n\t\t\t *        return iTest;\n\t\t\t *    iTest = oSort['numeric-desc']('data21', 'data22');\n\t\t\t *    if (iTest !== 0)\n\t\t\t *      return iTest;\n\t\t\t *    return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );\n\t\t\t *  }\n\t\t\t * Basically we have a test for each sorting column, if the data in that column is equal,\n\t\t\t * test the next column. If all columns match, then we use a numeric sort on the row\n\t\t\t * positions in the original data array to provide a stable sort.\n\t\t\t *\n\t\t\t * Note - I know it seems excessive to have two sorting methods, but the first is around\n\t\t\t * 15% faster, so the second is only maintained for backwards compatibility with sorting\n\t\t\t * methods which do not have a pre-sort formatting function.\n\t\t\t */\n\t\t\tif ( formatters === aSort.length ) {\n\t\t\t\t// All sort types have formatting functions\n\t\t\t\tdisplayMaster.sort( function ( a, b ) {\n\t\t\t\t\tvar\n\t\t\t\t\t\tx, y, k, test, sort,\n\t\t\t\t\t\tlen=aSort.length,\n\t\t\t\t\t\tdataA = aoData[a]._aSortData,\n\t\t\t\t\t\tdataB = aoData[b]._aSortData;\n\t\n\t\t\t\t\tfor ( k=0 ; k<len ; k++ ) {\n\t\t\t\t\t\tsort = aSort[k];\n\t\n\t\t\t\t\t\tx = dataA[ sort.col ];\n\t\t\t\t\t\ty = dataB[ sort.col ];\n\t\n\t\t\t\t\t\ttest = x<y ? -1 : x>y ? 1 : 0;\n\t\t\t\t\t\tif ( test !== 0 ) {\n\t\t\t\t\t\t\treturn sort.dir === 'asc' ? test : -test;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\n\t\t\t\t\tx = aiOrig[a];\n\t\t\t\t\ty = aiOrig[b];\n\t\t\t\t\treturn x<y ? -1 : x>y ? 1 : 0;\n\t\t\t\t} );\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Depreciated - remove in 1.11 (providing a plug-in option)\n\t\t\t\t// Not all sort types have formatting methods, so we have to call their sorting\n\t\t\t\t// methods.\n\t\t\t\tdisplayMaster.sort( function ( a, b ) {\n\t\t\t\t\tvar\n\t\t\t\t\t\tx, y, k, l, test, sort, fn,\n\t\t\t\t\t\tlen=aSort.length,\n\t\t\t\t\t\tdataA = aoData[a]._aSortData,\n\t\t\t\t\t\tdataB = aoData[b]._aSortData;\n\t\n\t\t\t\t\tfor ( k=0 ; k<len ; k++ ) {\n\t\t\t\t\t\tsort = aSort[k];\n\t\n\t\t\t\t\t\tx = dataA[ sort.col ];\n\t\t\t\t\t\ty = dataB[ sort.col ];\n\t\n\t\t\t\t\t\tfn = oExtSort[ sort.type+\"-\"+sort.dir ] || oExtSort[ \"string-\"+sort.dir ];\n\t\t\t\t\t\ttest = fn( x, y );\n\t\t\t\t\t\tif ( test !== 0 ) {\n\t\t\t\t\t\t\treturn test;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\n\t\t\t\t\tx = aiOrig[a];\n\t\t\t\t\ty = aiOrig[b];\n\t\t\t\t\treturn x<y ? -1 : x>y ? 1 : 0;\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t\n\t\t/* Tell the draw function that we have sorted the data */\n\t\toSettings.bSorted = true;\n\t}\n\t\n\t\n\tfunction _fnSortAria ( settings )\n\t{\n\t\tvar label;\n\t\tvar nextSort;\n\t\tvar columns = settings.aoColumns;\n\t\tvar aSort = _fnSortFlatten( settings );\n\t\tvar oAria = settings.oLanguage.oAria;\n\t\n\t\t// ARIA attributes - need to loop all columns, to update all (removing old\n\t\t// attributes as needed)\n\t\tfor ( var i=0, iLen=columns.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tvar col = columns[i];\n\t\t\tvar asSorting = col.asSorting;\n\t\t\tvar sTitle = col.sTitle.replace( /<.*?>/g, \"\" );\n\t\t\tvar th = col.nTh;\n\t\n\t\t\t// IE7 is throwing an error when setting these properties with jQuery's\n\t\t\t// attr() and removeAttr() methods...\n\t\t\tth.removeAttribute('aria-sort');\n\t\n\t\t\t/* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */\n\t\t\tif ( col.bSortable ) {\n\t\t\t\tif ( aSort.length > 0 && aSort[0].col == i ) {\n\t\t\t\t\tth.setAttribute('aria-sort', aSort[0].dir==\"asc\" ? \"ascending\" : \"descending\" );\n\t\t\t\t\tnextSort = asSorting[ aSort[0].index+1 ] || asSorting[0];\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tnextSort = asSorting[0];\n\t\t\t\t}\n\t\n\t\t\t\tlabel = sTitle + ( nextSort === \"asc\" ?\n\t\t\t\t\toAria.sSortAscending :\n\t\t\t\t\toAria.sSortDescending\n\t\t\t\t);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tlabel = sTitle;\n\t\t\t}\n\t\n\t\t\tth.setAttribute('aria-label', label);\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Function to run on user sort request\n\t *  @param {object} settings dataTables settings object\n\t *  @param {node} attachTo node to attach the handler to\n\t *  @param {int} colIdx column sorting index\n\t *  @param {boolean} [append=false] Append the requested sort to the existing\n\t *    sort if true (i.e. multi-column sort)\n\t *  @param {function} [callback] callback function\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSortListener ( settings, colIdx, append, callback )\n\t{\n\t\tvar col = settings.aoColumns[ colIdx ];\n\t\tvar sorting = settings.aaSorting;\n\t\tvar asSorting = col.asSorting;\n\t\tvar nextSortIdx;\n\t\tvar next = function ( a, overflow ) {\n\t\t\tvar idx = a._idx;\n\t\t\tif ( idx === undefined ) {\n\t\t\t\tidx = $.inArray( a[1], asSorting );\n\t\t\t}\n\t\n\t\t\treturn idx+1 < asSorting.length ?\n\t\t\t\tidx+1 :\n\t\t\t\toverflow ?\n\t\t\t\t\tnull :\n\t\t\t\t\t0;\n\t\t};\n\t\n\t\t// Convert to 2D array if needed\n\t\tif ( typeof sorting[0] === 'number' ) {\n\t\t\tsorting = settings.aaSorting = [ sorting ];\n\t\t}\n\t\n\t\t// If appending the sort then we are multi-column sorting\n\t\tif ( append && settings.oFeatures.bSortMulti ) {\n\t\t\t// Are we already doing some kind of sort on this column?\n\t\t\tvar sortIdx = $.inArray( colIdx, _pluck(sorting, '0') );\n\t\n\t\t\tif ( sortIdx !== -1 ) {\n\t\t\t\t// Yes, modify the sort\n\t\t\t\tnextSortIdx = next( sorting[sortIdx], true );\n\t\n\t\t\t\tif ( nextSortIdx === null && sorting.length === 1 ) {\n\t\t\t\t\tnextSortIdx = 0; // can't remove sorting completely\n\t\t\t\t}\n\t\n\t\t\t\tif ( nextSortIdx === null ) {\n\t\t\t\t\tsorting.splice( sortIdx, 1 );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tsorting[sortIdx][1] = asSorting[ nextSortIdx ];\n\t\t\t\t\tsorting[sortIdx]._idx = nextSortIdx;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// No sort on this column yet\n\t\t\t\tsorting.push( [ colIdx, asSorting[0], 0 ] );\n\t\t\t\tsorting[sorting.length-1]._idx = 0;\n\t\t\t}\n\t\t}\n\t\telse if ( sorting.length && sorting[0][0] == colIdx ) {\n\t\t\t// Single column - already sorting on this column, modify the sort\n\t\t\tnextSortIdx = next( sorting[0] );\n\t\n\t\t\tsorting.length = 1;\n\t\t\tsorting[0][1] = asSorting[ nextSortIdx ];\n\t\t\tsorting[0]._idx = nextSortIdx;\n\t\t}\n\t\telse {\n\t\t\t// Single column - sort only on this column\n\t\t\tsorting.length = 0;\n\t\t\tsorting.push( [ colIdx, asSorting[0] ] );\n\t\t\tsorting[0]._idx = 0;\n\t\t}\n\t\n\t\t// Run the sort by calling a full redraw\n\t\t_fnReDraw( settings );\n\t\n\t\t// callback used for async user interaction\n\t\tif ( typeof callback == 'function' ) {\n\t\t\tcallback( settings );\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Attach a sort handler (click) to a node\n\t *  @param {object} settings dataTables settings object\n\t *  @param {node} attachTo node to attach the handler to\n\t *  @param {int} colIdx column sorting index\n\t *  @param {function} [callback] callback function\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSortAttachListener ( settings, attachTo, colIdx, callback )\n\t{\n\t\tvar col = settings.aoColumns[ colIdx ];\n\t\n\t\t_fnBindAction( attachTo, {}, function (e) {\n\t\t\t/* If the column is not sortable - don't to anything */\n\t\t\tif ( col.bSortable === false ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\t// If processing is enabled use a timeout to allow the processing\n\t\t\t// display to be shown - otherwise to it synchronously\n\t\t\tif ( settings.oFeatures.bProcessing ) {\n\t\t\t\t_fnProcessingDisplay( settings, true );\n\t\n\t\t\t\tsetTimeout( function() {\n\t\t\t\t\t_fnSortListener( settings, colIdx, e.shiftKey, callback );\n\t\n\t\t\t\t\t// In server-side processing, the draw callback will remove the\n\t\t\t\t\t// processing display\n\t\t\t\t\tif ( _fnDataSource( settings ) !== 'ssp' ) {\n\t\t\t\t\t\t_fnProcessingDisplay( settings, false );\n\t\t\t\t\t}\n\t\t\t\t}, 0 );\n\t\t\t}\n\t\t\telse {\n\t\t\t\t_fnSortListener( settings, colIdx, e.shiftKey, callback );\n\t\t\t}\n\t\t} );\n\t}\n\t\n\t\n\t/**\n\t * Set the sorting classes on table's body, Note: it is safe to call this function\n\t * when bSort and bSortClasses are false\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSortingClasses( settings )\n\t{\n\t\tvar oldSort = settings.aLastSort;\n\t\tvar sortClass = settings.oClasses.sSortColumn;\n\t\tvar sort = _fnSortFlatten( settings );\n\t\tvar features = settings.oFeatures;\n\t\tvar i, ien, colIdx;\n\t\n\t\tif ( features.bSort && features.bSortClasses ) {\n\t\t\t// Remove old sorting classes\n\t\t\tfor ( i=0, ien=oldSort.length ; i<ien ; i++ ) {\n\t\t\t\tcolIdx = oldSort[i].src;\n\t\n\t\t\t\t// Remove column sorting\n\t\t\t\t$( _pluck( settings.aoData, 'anCells', colIdx ) )\n\t\t\t\t\t.removeClass( sortClass + (i<2 ? i+1 : 3) );\n\t\t\t}\n\t\n\t\t\t// Add new column sorting\n\t\t\tfor ( i=0, ien=sort.length ; i<ien ; i++ ) {\n\t\t\t\tcolIdx = sort[i].src;\n\t\n\t\t\t\t$( _pluck( settings.aoData, 'anCells', colIdx ) )\n\t\t\t\t\t.addClass( sortClass + (i<2 ? i+1 : 3) );\n\t\t\t}\n\t\t}\n\t\n\t\tsettings.aLastSort = sort;\n\t}\n\t\n\t\n\t// Get the data to sort a column, be it from cache, fresh (populating the\n\t// cache), or from a sort formatter\n\tfunction _fnSortData( settings, idx )\n\t{\n\t\t// Custom sorting function - provided by the sort data type\n\t\tvar column = settings.aoColumns[ idx ];\n\t\tvar customSort = DataTable.ext.order[ column.sSortDataType ];\n\t\tvar customData;\n\t\n\t\tif ( customSort ) {\n\t\t\tcustomData = customSort.call( settings.oInstance, settings, idx,\n\t\t\t\t_fnColumnIndexToVisible( settings, idx )\n\t\t\t);\n\t\t}\n\t\n\t\t// Use / populate cache\n\t\tvar row, cellData;\n\t\tvar formatter = DataTable.ext.type.order[ column.sType+\"-pre\" ];\n\t\n\t\tfor ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\n\t\t\trow = settings.aoData[i];\n\t\n\t\t\tif ( ! row._aSortData ) {\n\t\t\t\trow._aSortData = [];\n\t\t\t}\n\t\n\t\t\tif ( ! row._aSortData[idx] || customSort ) {\n\t\t\t\tcellData = customSort ?\n\t\t\t\t\tcustomData[i] : // If there was a custom sort function, use data from there\n\t\t\t\t\t_fnGetCellData( settings, i, idx, 'sort' );\n\t\n\t\t\t\trow._aSortData[ idx ] = formatter ?\n\t\t\t\t\tformatter( cellData ) :\n\t\t\t\t\tcellData;\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t\n\t/**\n\t * Save the state of a table\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSaveState ( settings )\n\t{\n\t\tif ( !settings.oFeatures.bStateSave || settings.bDestroying )\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\n\t\t/* Store the interesting variables */\n\t\tvar state = {\n\t\t\ttime:    +new Date(),\n\t\t\tstart:   settings._iDisplayStart,\n\t\t\tlength:  settings._iDisplayLength,\n\t\t\torder:   $.extend( true, [], settings.aaSorting ),\n\t\t\tsearch:  _fnSearchToCamel( settings.oPreviousSearch ),\n\t\t\tcolumns: $.map( settings.aoColumns, function ( col, i ) {\n\t\t\t\treturn {\n\t\t\t\t\tvisible: col.bVisible,\n\t\t\t\t\tsearch: _fnSearchToCamel( settings.aoPreSearchCols[i] )\n\t\t\t\t};\n\t\t\t} )\n\t\t};\n\t\n\t\t_fnCallbackFire( settings, \"aoStateSaveParams\", 'stateSaveParams', [settings, state] );\n\t\n\t\tsettings.oSavedState = state;\n\t\tsettings.fnStateSaveCallback.call( settings.oInstance, settings, state );\n\t}\n\t\n\t\n\t/**\n\t * Attempt to load a saved table state\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {object} oInit DataTables init object so we can override settings\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnLoadState ( settings, oInit )\n\t{\n\t\tvar i, ien;\n\t\tvar columns = settings.aoColumns;\n\t\n\t\tif ( ! settings.oFeatures.bStateSave ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\tvar state = settings.fnStateLoadCallback.call( settings.oInstance, settings );\n\t\tif ( ! state || ! state.time ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\t/* Allow custom and plug-in manipulation functions to alter the saved data set and\n\t\t * cancelling of loading by returning false\n\t\t */\n\t\tvar abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, state] );\n\t\tif ( $.inArray( false, abStateLoad ) !== -1 ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\t/* Reject old data */\n\t\tvar duration = settings.iStateDuration;\n\t\tif ( duration > 0 && state.time < +new Date() - (duration*1000) ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\t// Number of columns have changed - all bets are off, no restore of settings\n\t\tif ( columns.length !== state.columns.length ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\t// Store the saved state so it might be accessed at any time\n\t\tsettings.oLoadedState = $.extend( true, {}, state );\n\t\n\t\t// Restore key features - todo - for 1.11 this needs to be done by\n\t\t// subscribed events\n\t\tif ( state.start !== undefined ) {\n\t\t\tsettings._iDisplayStart    = state.start;\n\t\t\tsettings.iInitDisplayStart = state.start;\n\t\t}\n\t\tif ( state.length !== undefined ) {\n\t\t\tsettings._iDisplayLength   = state.length;\n\t\t}\n\t\n\t\t// Order\n\t\tif ( state.order !== undefined ) {\n\t\t\tsettings.aaSorting = [];\n\t\t\t$.each( state.order, function ( i, col ) {\n\t\t\t\tsettings.aaSorting.push( col[0] >= columns.length ?\n\t\t\t\t\t[ 0, col[1] ] :\n\t\t\t\t\tcol\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\t\n\t\t// Search\n\t\tif ( state.search !== undefined ) {\n\t\t\t$.extend( settings.oPreviousSearch, _fnSearchToHung( state.search ) );\n\t\t}\n\t\n\t\t// Columns\n\t\tfor ( i=0, ien=state.columns.length ; i<ien ; i++ ) {\n\t\t\tvar col = state.columns[i];\n\t\n\t\t\t// Visibility\n\t\t\tif ( col.visible !== undefined ) {\n\t\t\t\tcolumns[i].bVisible = col.visible;\n\t\t\t}\n\t\n\t\t\t// Search\n\t\t\tif ( col.search !== undefined ) {\n\t\t\t\t$.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) );\n\t\t\t}\n\t\t}\n\t\n\t\t_fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, state] );\n\t}\n\t\n\t\n\t/**\n\t * Return the settings object for a particular table\n\t *  @param {node} table table we are using as a dataTable\n\t *  @returns {object} Settings object - or null if not found\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSettingsFromNode ( table )\n\t{\n\t\tvar settings = DataTable.settings;\n\t\tvar idx = $.inArray( table, _pluck( settings, 'nTable' ) );\n\t\n\t\treturn idx !== -1 ?\n\t\t\tsettings[ idx ] :\n\t\t\tnull;\n\t}\n\t\n\t\n\t/**\n\t * Log an error message\n\t *  @param {object} settings dataTables settings object\n\t *  @param {int} level log error messages, or display them to the user\n\t *  @param {string} msg error message\n\t *  @param {int} tn Technical note id to get more information about the error.\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnLog( settings, level, msg, tn )\n\t{\n\t\tmsg = 'DataTables warning: '+\n\t\t\t(settings ? 'table id='+settings.sTableId+' - ' : '')+msg;\n\t\n\t\tif ( tn ) {\n\t\t\tmsg += '. For more information about this error, please see '+\n\t\t\t'http://datatables.net/tn/'+tn;\n\t\t}\n\t\n\t\tif ( ! level  ) {\n\t\t\t// Backwards compatibility pre 1.10\n\t\t\tvar ext = DataTable.ext;\n\t\t\tvar type = ext.sErrMode || ext.errMode;\n\t\n\t\t\tif ( settings ) {\n\t\t\t\t_fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] );\n\t\t\t}\n\t\n\t\t\tif ( type == 'alert' ) {\n\t\t\t\talert( msg );\n\t\t\t}\n\t\t\telse if ( type == 'throw' ) {\n\t\t\t\tthrow new Error(msg);\n\t\t\t}\n\t\t\telse if ( typeof type == 'function' ) {\n\t\t\t\ttype( settings, tn, msg );\n\t\t\t}\n\t\t}\n\t\telse if ( window.console && console.log ) {\n\t\t\tconsole.log( msg );\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * See if a property is defined on one object, if so assign it to the other object\n\t *  @param {object} ret target object\n\t *  @param {object} src source object\n\t *  @param {string} name property\n\t *  @param {string} [mappedName] name to map too - optional, name used if not given\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnMap( ret, src, name, mappedName )\n\t{\n\t\tif ( $.isArray( name ) ) {\n\t\t\t$.each( name, function (i, val) {\n\t\t\t\tif ( $.isArray( val ) ) {\n\t\t\t\t\t_fnMap( ret, src, val[0], val[1] );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t_fnMap( ret, src, val );\n\t\t\t\t}\n\t\t\t} );\n\t\n\t\t\treturn;\n\t\t}\n\t\n\t\tif ( mappedName === undefined ) {\n\t\t\tmappedName = name;\n\t\t}\n\t\n\t\tif ( src[name] !== undefined ) {\n\t\t\tret[mappedName] = src[name];\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Extend objects - very similar to jQuery.extend, but deep copy objects, and\n\t * shallow copy arrays. The reason we need to do this, is that we don't want to\n\t * deep copy array init values (such as aaSorting) since the dev wouldn't be\n\t * able to override them, but we do want to deep copy arrays.\n\t *  @param {object} out Object to extend\n\t *  @param {object} extender Object from which the properties will be applied to\n\t *      out\n\t *  @param {boolean} breakRefs If true, then arrays will be sliced to take an\n\t *      independent copy with the exception of the `data` or `aaData` parameters\n\t *      if they are present. This is so you can pass in a collection to\n\t *      DataTables and have that used as your data source without breaking the\n\t *      references\n\t *  @returns {object} out Reference, just for convenience - out === the return.\n\t *  @memberof DataTable#oApi\n\t *  @todo This doesn't take account of arrays inside the deep copied objects.\n\t */\n\tfunction _fnExtend( out, extender, breakRefs )\n\t{\n\t\tvar val;\n\t\n\t\tfor ( var prop in extender ) {\n\t\t\tif ( extender.hasOwnProperty(prop) ) {\n\t\t\t\tval = extender[prop];\n\t\n\t\t\t\tif ( $.isPlainObject( val ) ) {\n\t\t\t\t\tif ( ! $.isPlainObject( out[prop] ) ) {\n\t\t\t\t\t\tout[prop] = {};\n\t\t\t\t\t}\n\t\t\t\t\t$.extend( true, out[prop], val );\n\t\t\t\t}\n\t\t\t\telse if ( breakRefs && prop !== 'data' && prop !== 'aaData' && $.isArray(val) ) {\n\t\t\t\t\tout[prop] = val.slice();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tout[prop] = val;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\treturn out;\n\t}\n\t\n\t\n\t/**\n\t * Bind an event handers to allow a click or return key to activate the callback.\n\t * This is good for accessibility since a return on the keyboard will have the\n\t * same effect as a click, if the element has focus.\n\t *  @param {element} n Element to bind the action to\n\t *  @param {object} oData Data object to pass to the triggered function\n\t *  @param {function} fn Callback function for when the event is triggered\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnBindAction( n, oData, fn )\n\t{\n\t\t$(n)\n\t\t\t.bind( 'click.DT', oData, function (e) {\n\t\t\t\t\tn.blur(); // Remove focus outline for mouse users\n\t\t\t\t\tfn(e);\n\t\t\t\t} )\n\t\t\t.bind( 'keypress.DT', oData, function (e){\n\t\t\t\t\tif ( e.which === 13 ) {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tfn(e);\n\t\t\t\t\t}\n\t\t\t\t} )\n\t\t\t.bind( 'selectstart.DT', function () {\n\t\t\t\t\t/* Take the brutal approach to cancelling text selection */\n\t\t\t\t\treturn false;\n\t\t\t\t} );\n\t}\n\t\n\t\n\t/**\n\t * Register a callback function. Easily allows a callback function to be added to\n\t * an array store of callback functions that can then all be called together.\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {string} sStore Name of the array storage for the callbacks in oSettings\n\t *  @param {function} fn Function to be called back\n\t *  @param {string} sName Identifying name for the callback (i.e. a label)\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnCallbackReg( oSettings, sStore, fn, sName )\n\t{\n\t\tif ( fn )\n\t\t{\n\t\t\toSettings[sStore].push( {\n\t\t\t\t\"fn\": fn,\n\t\t\t\t\"sName\": sName\n\t\t\t} );\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Fire callback functions and trigger events. Note that the loop over the\n\t * callback array store is done backwards! Further note that you do not want to\n\t * fire off triggers in time sensitive applications (for example cell creation)\n\t * as its slow.\n\t *  @param {object} settings dataTables settings object\n\t *  @param {string} callbackArr Name of the array storage for the callbacks in\n\t *      oSettings\n\t *  @param {string} eventName Name of the jQuery custom event to trigger. If\n\t *      null no trigger is fired\n\t *  @param {array} args Array of arguments to pass to the callback function /\n\t *      trigger\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnCallbackFire( settings, callbackArr, eventName, args )\n\t{\n\t\tvar ret = [];\n\t\n\t\tif ( callbackArr ) {\n\t\t\tret = $.map( settings[callbackArr].slice().reverse(), function (val, i) {\n\t\t\t\treturn val.fn.apply( settings.oInstance, args );\n\t\t\t} );\n\t\t}\n\t\n\t\tif ( eventName !== null ) {\n\t\t\tvar e = $.Event( eventName+'.dt' );\n\t\n\t\t\t$(settings.nTable).trigger( e, args );\n\t\n\t\t\tret.push( e.result );\n\t\t}\n\t\n\t\treturn ret;\n\t}\n\t\n\t\n\tfunction _fnLengthOverflow ( settings )\n\t{\n\t\tvar\n\t\t\tstart = settings._iDisplayStart,\n\t\t\tend = settings.fnDisplayEnd(),\n\t\t\tlen = settings._iDisplayLength;\n\t\n\t\t/* If we have space to show extra rows (backing up from the end point - then do so */\n\t\tif ( start >= end )\n\t\t{\n\t\t\tstart = end - len;\n\t\t}\n\t\n\t\t// Keep the start record on the current page\n\t\tstart -= (start % len);\n\t\n\t\tif ( len === -1 || start < 0 )\n\t\t{\n\t\t\tstart = 0;\n\t\t}\n\t\n\t\tsettings._iDisplayStart = start;\n\t}\n\t\n\t\n\tfunction _fnRenderer( settings, type )\n\t{\n\t\tvar renderer = settings.renderer;\n\t\tvar host = DataTable.ext.renderer[type];\n\t\n\t\tif ( $.isPlainObject( renderer ) && renderer[type] ) {\n\t\t\t// Specific renderer for this type. If available use it, otherwise use\n\t\t\t// the default.\n\t\t\treturn host[renderer[type]] || host._;\n\t\t}\n\t\telse if ( typeof renderer === 'string' ) {\n\t\t\t// Common renderer - if there is one available for this type use it,\n\t\t\t// otherwise use the default\n\t\t\treturn host[renderer] || host._;\n\t\t}\n\t\n\t\t// Use the default\n\t\treturn host._;\n\t}\n\t\n\t\n\t/**\n\t * Detect the data source being used for the table. Used to simplify the code\n\t * a little (ajax) and to make it compress a little smaller.\n\t *\n\t *  @param {object} settings dataTables settings object\n\t *  @returns {string} Data source\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnDataSource ( settings )\n\t{\n\t\tif ( settings.oFeatures.bServerSide ) {\n\t\t\treturn 'ssp';\n\t\t}\n\t\telse if ( settings.ajax || settings.sAjaxSource ) {\n\t\t\treturn 'ajax';\n\t\t}\n\t\treturn 'dom';\n\t}\n\t\n\n\t\n\t\n\t/**\n\t * Computed structure of the DataTables API, defined by the options passed to\n\t * `DataTable.Api.register()` when building the API.\n\t *\n\t * The structure is built in order to speed creation and extension of the Api\n\t * objects since the extensions are effectively pre-parsed.\n\t *\n\t * The array is an array of objects with the following structure, where this\n\t * base array represents the Api prototype base:\n\t *\n\t *     [\n\t *       {\n\t *         name:      'data'                -- string   - Property name\n\t *         val:       function () {},       -- function - Api method (or undefined if just an object\n\t *         methodExt: [ ... ],              -- array    - Array of Api object definitions to extend the method result\n\t *         propExt:   [ ... ]               -- array    - Array of Api object definitions to extend the property\n\t *       },\n\t *       {\n\t *         name:     'row'\n\t *         val:       {},\n\t *         methodExt: [ ... ],\n\t *         propExt:   [\n\t *           {\n\t *             name:      'data'\n\t *             val:       function () {},\n\t *             methodExt: [ ... ],\n\t *             propExt:   [ ... ]\n\t *           },\n\t *           ...\n\t *         ]\n\t *       }\n\t *     ]\n\t *\n\t * @type {Array}\n\t * @ignore\n\t */\n\tvar __apiStruct = [];\n\t\n\t\n\t/**\n\t * `Array.prototype` reference.\n\t *\n\t * @type object\n\t * @ignore\n\t */\n\tvar __arrayProto = Array.prototype;\n\t\n\t\n\t/**\n\t * Abstraction for `context` parameter of the `Api` constructor to allow it to\n\t * take several different forms for ease of use.\n\t *\n\t * Each of the input parameter types will be converted to a DataTables settings\n\t * object where possible.\n\t *\n\t * @param  {string|node|jQuery|object} mixed DataTable identifier. Can be one\n\t *   of:\n\t *\n\t *   * `string` - jQuery selector. Any DataTables' matching the given selector\n\t *     with be found and used.\n\t *   * `node` - `TABLE` node which has already been formed into a DataTable.\n\t *   * `jQuery` - A jQuery object of `TABLE` nodes.\n\t *   * `object` - DataTables settings object\n\t *   * `DataTables.Api` - API instance\n\t * @return {array|null} Matching DataTables settings objects. `null` or\n\t *   `undefined` is returned if no matching DataTable is found.\n\t * @ignore\n\t */\n\tvar _toSettings = function ( mixed )\n\t{\n\t\tvar idx, jq;\n\t\tvar settings = DataTable.settings;\n\t\tvar tables = $.map( settings, function (el, i) {\n\t\t\treturn el.nTable;\n\t\t} );\n\t\n\t\tif ( ! mixed ) {\n\t\t\treturn [];\n\t\t}\n\t\telse if ( mixed.nTable && mixed.oApi ) {\n\t\t\t// DataTables settings object\n\t\t\treturn [ mixed ];\n\t\t}\n\t\telse if ( mixed.nodeName && mixed.nodeName.toLowerCase() === 'table' ) {\n\t\t\t// Table node\n\t\t\tidx = $.inArray( mixed, tables );\n\t\t\treturn idx !== -1 ? [ settings[idx] ] : null;\n\t\t}\n\t\telse if ( mixed && typeof mixed.settings === 'function' ) {\n\t\t\treturn mixed.settings().toArray();\n\t\t}\n\t\telse if ( typeof mixed === 'string' ) {\n\t\t\t// jQuery selector\n\t\t\tjq = $(mixed);\n\t\t}\n\t\telse if ( mixed instanceof $ ) {\n\t\t\t// jQuery object (also DataTables instance)\n\t\t\tjq = mixed;\n\t\t}\n\t\n\t\tif ( jq ) {\n\t\t\treturn jq.map( function(i) {\n\t\t\t\tidx = $.inArray( this, tables );\n\t\t\t\treturn idx !== -1 ? settings[idx] : null;\n\t\t\t} ).toArray();\n\t\t}\n\t};\n\t\n\t\n\t/**\n\t * DataTables API class - used to control and interface with  one or more\n\t * DataTables enhanced tables.\n\t *\n\t * The API class is heavily based on jQuery, presenting a chainable interface\n\t * that you can use to interact with tables. Each instance of the API class has\n\t * a \"context\" - i.e. the tables that it will operate on. This could be a single\n\t * table, all tables on a page or a sub-set thereof.\n\t *\n\t * Additionally the API is designed to allow you to easily work with the data in\n\t * the tables, retrieving and manipulating it as required. This is done by\n\t * presenting the API class as an array like interface. The contents of the\n\t * array depend upon the actions requested by each method (for example\n\t * `rows().nodes()` will return an array of nodes, while `rows().data()` will\n\t * return an array of objects or arrays depending upon your table's\n\t * configuration). The API object has a number of array like methods (`push`,\n\t * `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`,\n\t * `unique` etc) to assist your working with the data held in a table.\n\t *\n\t * Most methods (those which return an Api instance) are chainable, which means\n\t * the return from a method call also has all of the methods available that the\n\t * top level object had. For example, these two calls are equivalent:\n\t *\n\t *     // Not chained\n\t *     api.row.add( {...} );\n\t *     api.draw();\n\t *\n\t *     // Chained\n\t *     api.row.add( {...} ).draw();\n\t *\n\t * @class DataTable.Api\n\t * @param {array|object|string|jQuery} context DataTable identifier. This is\n\t *   used to define which DataTables enhanced tables this API will operate on.\n\t *   Can be one of:\n\t *\n\t *   * `string` - jQuery selector. Any DataTables' matching the given selector\n\t *     with be found and used.\n\t *   * `node` - `TABLE` node which has already been formed into a DataTable.\n\t *   * `jQuery` - A jQuery object of `TABLE` nodes.\n\t *   * `object` - DataTables settings object\n\t * @param {array} [data] Data to initialise the Api instance with.\n\t *\n\t * @example\n\t *   // Direct initialisation during DataTables construction\n\t *   var api = $('#example').DataTable();\n\t *\n\t * @example\n\t *   // Initialisation using a DataTables jQuery object\n\t *   var api = $('#example').dataTable().api();\n\t *\n\t * @example\n\t *   // Initialisation as a constructor\n\t *   var api = new $.fn.DataTable.Api( 'table.dataTable' );\n\t */\n\t_Api = function ( context, data )\n\t{\n\t\tif ( ! (this instanceof _Api) ) {\n\t\t\treturn new _Api( context, data );\n\t\t}\n\t\n\t\tvar settings = [];\n\t\tvar ctxSettings = function ( o ) {\n\t\t\tvar a = _toSettings( o );\n\t\t\tif ( a ) {\n\t\t\t\tsettings = settings.concat( a );\n\t\t\t}\n\t\t};\n\t\n\t\tif ( $.isArray( context ) ) {\n\t\t\tfor ( var i=0, ien=context.length ; i<ien ; i++ ) {\n\t\t\t\tctxSettings( context[i] );\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tctxSettings( context );\n\t\t}\n\t\n\t\t// Remove duplicates\n\t\tthis.context = _unique( settings );\n\t\n\t\t// Initial data\n\t\tif ( data ) {\n\t\t\t$.merge( this, data );\n\t\t}\n\t\n\t\t// selector\n\t\tthis.selector = {\n\t\t\trows: null,\n\t\t\tcols: null,\n\t\t\topts: null\n\t\t};\n\t\n\t\t_Api.extend( this, this, __apiStruct );\n\t};\n\t\n\tDataTable.Api = _Api;\n\t\n\t// Don't destroy the existing prototype, just extend it. Required for jQuery 2's\n\t// isPlainObject.\n\t$.extend( _Api.prototype, {\n\t\tany: function ()\n\t\t{\n\t\t\treturn this.count() !== 0;\n\t\t},\n\t\n\t\n\t\tconcat:  __arrayProto.concat,\n\t\n\t\n\t\tcontext: [], // array of table settings objects\n\t\n\t\n\t\tcount: function ()\n\t\t{\n\t\t\treturn this.flatten().length;\n\t\t},\n\t\n\t\n\t\teach: function ( fn )\n\t\t{\n\t\t\tfor ( var i=0, ien=this.length ; i<ien; i++ ) {\n\t\t\t\tfn.call( this, this[i], i, this );\n\t\t\t}\n\t\n\t\t\treturn this;\n\t\t},\n\t\n\t\n\t\teq: function ( idx )\n\t\t{\n\t\t\tvar ctx = this.context;\n\t\n\t\t\treturn ctx.length > idx ?\n\t\t\t\tnew _Api( ctx[idx], this[idx] ) :\n\t\t\t\tnull;\n\t\t},\n\t\n\t\n\t\tfilter: function ( fn )\n\t\t{\n\t\t\tvar a = [];\n\t\n\t\t\tif ( __arrayProto.filter ) {\n\t\t\t\ta = __arrayProto.filter.call( this, fn, this );\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Compatibility for browsers without EMCA-252-5 (JS 1.6)\n\t\t\t\tfor ( var i=0, ien=this.length ; i<ien ; i++ ) {\n\t\t\t\t\tif ( fn.call( this, this[i], i, this ) ) {\n\t\t\t\t\t\ta.push( this[i] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\treturn new _Api( this.context, a );\n\t\t},\n\t\n\t\n\t\tflatten: function ()\n\t\t{\n\t\t\tvar a = [];\n\t\t\treturn new _Api( this.context, a.concat.apply( a, this.toArray() ) );\n\t\t},\n\t\n\t\n\t\tjoin:    __arrayProto.join,\n\t\n\t\n\t\tindexOf: __arrayProto.indexOf || function (obj, start)\n\t\t{\n\t\t\tfor ( var i=(start || 0), ien=this.length ; i<ien ; i++ ) {\n\t\t\t\tif ( this[i] === obj ) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn -1;\n\t\t},\n\t\n\t\titerator: function ( flatten, type, fn, alwaysNew ) {\n\t\t\tvar\n\t\t\t\ta = [], ret,\n\t\t\t\ti, ien, j, jen,\n\t\t\t\tcontext = this.context,\n\t\t\t\trows, items, item,\n\t\t\t\tselector = this.selector;\n\t\n\t\t\t// Argument shifting\n\t\t\tif ( typeof flatten === 'string' ) {\n\t\t\t\talwaysNew = fn;\n\t\t\t\tfn = type;\n\t\t\t\ttype = flatten;\n\t\t\t\tflatten = false;\n\t\t\t}\n\t\n\t\t\tfor ( i=0, ien=context.length ; i<ien ; i++ ) {\n\t\t\t\tvar apiInst = new _Api( context[i] );\n\t\n\t\t\t\tif ( type === 'table' ) {\n\t\t\t\t\tret = fn.call( apiInst, context[i], i );\n\t\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\ta.push( ret );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if ( type === 'columns' || type === 'rows' ) {\n\t\t\t\t\t// this has same length as context - one entry for each table\n\t\t\t\t\tret = fn.call( apiInst, context[i], this[i], i );\n\t\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\ta.push( ret );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if ( type === 'column' || type === 'column-rows' || type === 'row' || type === 'cell' ) {\n\t\t\t\t\t// columns and rows share the same structure.\n\t\t\t\t\t// 'this' is an array of column indexes for each context\n\t\t\t\t\titems = this[i];\n\t\n\t\t\t\t\tif ( type === 'column-rows' ) {\n\t\t\t\t\t\trows = _selector_row_indexes( context[i], selector.opts );\n\t\t\t\t\t}\n\t\n\t\t\t\t\tfor ( j=0, jen=items.length ; j<jen ; j++ ) {\n\t\t\t\t\t\titem = items[j];\n\t\n\t\t\t\t\t\tif ( type === 'cell' ) {\n\t\t\t\t\t\t\tret = fn.call( apiInst, context[i], item.row, item.column, i, j );\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tret = fn.call( apiInst, context[i], item, i, j, rows );\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\t\ta.push( ret );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tif ( a.length || alwaysNew ) {\n\t\t\t\tvar api = new _Api( context, flatten ? a.concat.apply( [], a ) : a );\n\t\t\t\tvar apiSelector = api.selector;\n\t\t\t\tapiSelector.rows = selector.rows;\n\t\t\t\tapiSelector.cols = selector.cols;\n\t\t\t\tapiSelector.opts = selector.opts;\n\t\t\t\treturn api;\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\t\n\t\n\t\tlastIndexOf: __arrayProto.lastIndexOf || function (obj, start)\n\t\t{\n\t\t\t// Bit cheeky...\n\t\t\treturn this.indexOf.apply( this.toArray.reverse(), arguments );\n\t\t},\n\t\n\t\n\t\tlength:  0,\n\t\n\t\n\t\tmap: function ( fn )\n\t\t{\n\t\t\tvar a = [];\n\t\n\t\t\tif ( __arrayProto.map ) {\n\t\t\t\ta = __arrayProto.map.call( this, fn, this );\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Compatibility for browsers without EMCA-252-5 (JS 1.6)\n\t\t\t\tfor ( var i=0, ien=this.length ; i<ien ; i++ ) {\n\t\t\t\t\ta.push( fn.call( this, this[i], i ) );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\treturn new _Api( this.context, a );\n\t\t},\n\t\n\t\n\t\tpluck: function ( prop )\n\t\t{\n\t\t\treturn this.map( function ( el ) {\n\t\t\t\treturn el[ prop ];\n\t\t\t} );\n\t\t},\n\t\n\t\tpop:     __arrayProto.pop,\n\t\n\t\n\t\tpush:    __arrayProto.push,\n\t\n\t\n\t\t// Does not return an API instance\n\t\treduce: __arrayProto.reduce || function ( fn, init )\n\t\t{\n\t\t\treturn _fnReduce( this, fn, init, 0, this.length, 1 );\n\t\t},\n\t\n\t\n\t\treduceRight: __arrayProto.reduceRight || function ( fn, init )\n\t\t{\n\t\t\treturn _fnReduce( this, fn, init, this.length-1, -1, -1 );\n\t\t},\n\t\n\t\n\t\treverse: __arrayProto.reverse,\n\t\n\t\n\t\t// Object with rows, columns and opts\n\t\tselector: null,\n\t\n\t\n\t\tshift:   __arrayProto.shift,\n\t\n\t\n\t\tsort:    __arrayProto.sort, // ? name - order?\n\t\n\t\n\t\tsplice:  __arrayProto.splice,\n\t\n\t\n\t\ttoArray: function ()\n\t\t{\n\t\t\treturn __arrayProto.slice.call( this );\n\t\t},\n\t\n\t\n\t\tto$: function ()\n\t\t{\n\t\t\treturn $( this );\n\t\t},\n\t\n\t\n\t\ttoJQuery: function ()\n\t\t{\n\t\t\treturn $( this );\n\t\t},\n\t\n\t\n\t\tunique: function ()\n\t\t{\n\t\t\treturn new _Api( this.context, _unique(this) );\n\t\t},\n\t\n\t\n\t\tunshift: __arrayProto.unshift\n\t} );\n\t\n\t\n\t_Api.extend = function ( scope, obj, ext )\n\t{\n\t\t// Only extend API instances and static properties of the API\n\t\tif ( ! ext.length || ! obj || ( ! (obj instanceof _Api) && ! obj.__dt_wrapper ) ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\tvar\n\t\t\ti, ien,\n\t\t\tj, jen,\n\t\t\tstruct, inner,\n\t\t\tmethodScoping = function ( scope, fn, struc ) {\n\t\t\t\treturn function () {\n\t\t\t\t\tvar ret = fn.apply( scope, arguments );\n\t\n\t\t\t\t\t// Method extension\n\t\t\t\t\t_Api.extend( ret, ret, struc.methodExt );\n\t\t\t\t\treturn ret;\n\t\t\t\t};\n\t\t\t};\n\t\n\t\tfor ( i=0, ien=ext.length ; i<ien ; i++ ) {\n\t\t\tstruct = ext[i];\n\t\n\t\t\t// Value\n\t\t\tobj[ struct.name ] = typeof struct.val === 'function' ?\n\t\t\t\tmethodScoping( scope, struct.val, struct ) :\n\t\t\t\t$.isPlainObject( struct.val ) ?\n\t\t\t\t\t{} :\n\t\t\t\t\tstruct.val;\n\t\n\t\t\tobj[ struct.name ].__dt_wrapper = true;\n\t\n\t\t\t// Property extension\n\t\t\t_Api.extend( scope, obj[ struct.name ], struct.propExt );\n\t\t}\n\t};\n\t\n\t\n\t// @todo - Is there need for an augment function?\n\t// _Api.augment = function ( inst, name )\n\t// {\n\t// \t// Find src object in the structure from the name\n\t// \tvar parts = name.split('.');\n\t\n\t// \t_Api.extend( inst, obj );\n\t// };\n\t\n\t\n\t//     [\n\t//       {\n\t//         name:      'data'                -- string   - Property name\n\t//         val:       function () {},       -- function - Api method (or undefined if just an object\n\t//         methodExt: [ ... ],              -- array    - Array of Api object definitions to extend the method result\n\t//         propExt:   [ ... ]               -- array    - Array of Api object definitions to extend the property\n\t//       },\n\t//       {\n\t//         name:     'row'\n\t//         val:       {},\n\t//         methodExt: [ ... ],\n\t//         propExt:   [\n\t//           {\n\t//             name:      'data'\n\t//             val:       function () {},\n\t//             methodExt: [ ... ],\n\t//             propExt:   [ ... ]\n\t//           },\n\t//           ...\n\t//         ]\n\t//       }\n\t//     ]\n\t\n\t_Api.register = _api_register = function ( name, val )\n\t{\n\t\tif ( $.isArray( name ) ) {\n\t\t\tfor ( var j=0, jen=name.length ; j<jen ; j++ ) {\n\t\t\t\t_Api.register( name[j], val );\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\n\t\tvar\n\t\t\ti, ien,\n\t\t\their = name.split('.'),\n\t\t\tstruct = __apiStruct,\n\t\t\tkey, method;\n\t\n\t\tvar find = function ( src, name ) {\n\t\t\tfor ( var i=0, ien=src.length ; i<ien ; i++ ) {\n\t\t\t\tif ( src[i].name === name ) {\n\t\t\t\t\treturn src[i];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t};\n\t\n\t\tfor ( i=0, ien=heir.length ; i<ien ; i++ ) {\n\t\t\tmethod = heir[i].indexOf('()') !== -1;\n\t\t\tkey = method ?\n\t\t\t\their[i].replace('()', '') :\n\t\t\t\their[i];\n\t\n\t\t\tvar src = find( struct, key );\n\t\t\tif ( ! src ) {\n\t\t\t\tsrc = {\n\t\t\t\t\tname:      key,\n\t\t\t\t\tval:       {},\n\t\t\t\t\tmethodExt: [],\n\t\t\t\t\tpropExt:   []\n\t\t\t\t};\n\t\t\t\tstruct.push( src );\n\t\t\t}\n\t\n\t\t\tif ( i === ien-1 ) {\n\t\t\t\tsrc.val = val;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tstruct = method ?\n\t\t\t\t\tsrc.methodExt :\n\t\t\t\t\tsrc.propExt;\n\t\t\t}\n\t\t}\n\t};\n\t\n\t\n\t_Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) {\n\t\t_Api.register( pluralName, val );\n\t\n\t\t_Api.register( singularName, function () {\n\t\t\tvar ret = val.apply( this, arguments );\n\t\n\t\t\tif ( ret === this ) {\n\t\t\t\t// Returned item is the API instance that was passed in, return it\n\t\t\t\treturn this;\n\t\t\t}\n\t\t\telse if ( ret instanceof _Api ) {\n\t\t\t\t// New API instance returned, want the value from the first item\n\t\t\t\t// in the returned array for the singular result.\n\t\t\t\treturn ret.length ?\n\t\t\t\t\t$.isArray( ret[0] ) ?\n\t\t\t\t\t\tnew _Api( ret.context, ret[0] ) : // Array results are 'enhanced'\n\t\t\t\t\t\tret[0] :\n\t\t\t\t\tundefined;\n\t\t\t}\n\t\n\t\t\t// Non-API return - just fire it back\n\t\t\treturn ret;\n\t\t} );\n\t};\n\t\n\t\n\t/**\n\t * Selector for HTML tables. Apply the given selector to the give array of\n\t * DataTables settings objects.\n\t *\n\t * @param {string|integer} [selector] jQuery selector string or integer\n\t * @param  {array} Array of DataTables settings objects to be filtered\n\t * @return {array}\n\t * @ignore\n\t */\n\tvar __table_selector = function ( selector, a )\n\t{\n\t\t// Integer is used to pick out a table by index\n\t\tif ( typeof selector === 'number' ) {\n\t\t\treturn [ a[ selector ] ];\n\t\t}\n\t\n\t\t// Perform a jQuery selector on the table nodes\n\t\tvar nodes = $.map( a, function (el, i) {\n\t\t\treturn el.nTable;\n\t\t} );\n\t\n\t\treturn $(nodes)\n\t\t\t.filter( selector )\n\t\t\t.map( function (i) {\n\t\t\t\t// Need to translate back from the table node to the settings\n\t\t\t\tvar idx = $.inArray( this, nodes );\n\t\t\t\treturn a[ idx ];\n\t\t\t} )\n\t\t\t.toArray();\n\t};\n\t\n\t\n\t\n\t/**\n\t * Context selector for the API's context (i.e. the tables the API instance\n\t * refers to.\n\t *\n\t * @name    DataTable.Api#tables\n\t * @param {string|integer} [selector] Selector to pick which tables the iterator\n\t *   should operate on. If not given, all tables in the current context are\n\t *   used. This can be given as a jQuery selector (for example `':gt(0)'`) to\n\t *   select multiple tables or as an integer to select a single table.\n\t * @returns {DataTable.Api} Returns a new API instance if a selector is given.\n\t */\n\t_api_register( 'tables()', function ( selector ) {\n\t\t// A new instance is created if there was a selector specified\n\t\treturn selector ?\n\t\t\tnew _Api( __table_selector( selector, this.context ) ) :\n\t\t\tthis;\n\t} );\n\t\n\t\n\t_api_register( 'table()', function ( selector ) {\n\t\tvar tables = this.tables( selector );\n\t\tvar ctx = tables.context;\n\t\n\t\t// Truncate to the first matched table\n\t\treturn ctx.length ?\n\t\t\tnew _Api( ctx[0] ) :\n\t\t\ttables;\n\t} );\n\t\n\t\n\t_api_registerPlural( 'tables().nodes()', 'table().node()' , function () {\n\t\treturn this.iterator( 'table', function ( ctx ) {\n\t\t\treturn ctx.nTable;\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'tables().body()', 'table().body()' , function () {\n\t\treturn this.iterator( 'table', function ( ctx ) {\n\t\t\treturn ctx.nTBody;\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'tables().header()', 'table().header()' , function () {\n\t\treturn this.iterator( 'table', function ( ctx ) {\n\t\t\treturn ctx.nTHead;\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'tables().footer()', 'table().footer()' , function () {\n\t\treturn this.iterator( 'table', function ( ctx ) {\n\t\t\treturn ctx.nTFoot;\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'tables().containers()', 'table().container()' , function () {\n\t\treturn this.iterator( 'table', function ( ctx ) {\n\t\t\treturn ctx.nTableWrapper;\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t\n\t/**\n\t * Redraw the tables in the current context.\n\t */\n\t_api_register( 'draw()', function ( paging ) {\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\tif ( paging === 'page' ) {\n\t\t\t\t_fnDraw( settings );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif ( typeof paging === 'string' ) {\n\t\t\t\t\tpaging = paging === 'full-hold' ?\n\t\t\t\t\t\tfalse :\n\t\t\t\t\t\ttrue;\n\t\t\t\t}\n\t\n\t\t\t\t_fnReDraw( settings, paging===false );\n\t\t\t}\n\t\t} );\n\t} );\n\t\n\t\n\t\n\t/**\n\t * Get the current page index.\n\t *\n\t * @return {integer} Current page index (zero based)\n\t *//**\n\t * Set the current page.\n\t *\n\t * Note that if you attempt to show a page which does not exist, DataTables will\n\t * not throw an error, but rather reset the paging.\n\t *\n\t * @param {integer|string} action The paging action to take. This can be one of:\n\t *  * `integer` - The page index to jump to\n\t *  * `string` - An action to take:\n\t *    * `first` - Jump to first page.\n\t *    * `next` - Jump to the next page\n\t *    * `previous` - Jump to previous page\n\t *    * `last` - Jump to the last page.\n\t * @returns {DataTables.Api} this\n\t */\n\t_api_register( 'page()', function ( action ) {\n\t\tif ( action === undefined ) {\n\t\t\treturn this.page.info().page; // not an expensive call\n\t\t}\n\t\n\t\t// else, have an action to take on all tables\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t_fnPageChange( settings, action );\n\t\t} );\n\t} );\n\t\n\t\n\t/**\n\t * Paging information for the first table in the current context.\n\t *\n\t * If you require paging information for another table, use the `table()` method\n\t * with a suitable selector.\n\t *\n\t * @return {object} Object with the following properties set:\n\t *  * `page` - Current page index (zero based - i.e. the first page is `0`)\n\t *  * `pages` - Total number of pages\n\t *  * `start` - Display index for the first record shown on the current page\n\t *  * `end` - Display index for the last record shown on the current page\n\t *  * `length` - Display length (number of records). Note that generally `start\n\t *    + length = end`, but this is not always true, for example if there are\n\t *    only 2 records to show on the final page, with a length of 10.\n\t *  * `recordsTotal` - Full data set length\n\t *  * `recordsDisplay` - Data set length once the current filtering criterion\n\t *    are applied.\n\t */\n\t_api_register( 'page.info()', function ( action ) {\n\t\tif ( this.context.length === 0 ) {\n\t\t\treturn undefined;\n\t\t}\n\t\n\t\tvar\n\t\t\tsettings   = this.context[0],\n\t\t\tstart      = settings._iDisplayStart,\n\t\t\tlen        = settings.oFeatures.bPaginate ? settings._iDisplayLength : -1,\n\t\t\tvisRecords = settings.fnRecordsDisplay(),\n\t\t\tall        = len === -1;\n\t\n\t\treturn {\n\t\t\t\"page\":           all ? 0 : Math.floor( start / len ),\n\t\t\t\"pages\":          all ? 1 : Math.ceil( visRecords / len ),\n\t\t\t\"start\":          start,\n\t\t\t\"end\":            settings.fnDisplayEnd(),\n\t\t\t\"length\":         len,\n\t\t\t\"recordsTotal\":   settings.fnRecordsTotal(),\n\t\t\t\"recordsDisplay\": visRecords,\n\t\t\t\"serverSide\":     _fnDataSource( settings ) === 'ssp'\n\t\t};\n\t} );\n\t\n\t\n\t/**\n\t * Get the current page length.\n\t *\n\t * @return {integer} Current page length. Note `-1` indicates that all records\n\t *   are to be shown.\n\t *//**\n\t * Set the current page length.\n\t *\n\t * @param {integer} Page length to set. Use `-1` to show all records.\n\t * @returns {DataTables.Api} this\n\t */\n\t_api_register( 'page.len()', function ( len ) {\n\t\t// Note that we can't call this function 'length()' because `length`\n\t\t// is a Javascript property of functions which defines how many arguments\n\t\t// the function expects.\n\t\tif ( len === undefined ) {\n\t\t\treturn this.context.length !== 0 ?\n\t\t\t\tthis.context[0]._iDisplayLength :\n\t\t\t\tundefined;\n\t\t}\n\t\n\t\t// else, set the page length\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t_fnLengthChange( settings, len );\n\t\t} );\n\t} );\n\t\n\t\n\t\n\tvar __reload = function ( settings, holdPosition, callback ) {\n\t\t// Use the draw event to trigger a callback\n\t\tif ( callback ) {\n\t\t\tvar api = new _Api( settings );\n\t\n\t\t\tapi.one( 'draw', function () {\n\t\t\t\tcallback( api.ajax.json() );\n\t\t\t} );\n\t\t}\n\t\n\t\tif ( _fnDataSource( settings ) == 'ssp' ) {\n\t\t\t_fnReDraw( settings, holdPosition );\n\t\t}\n\t\telse {\n\t\t\t_fnProcessingDisplay( settings, true );\n\t\n\t\t\t// Cancel an existing request\n\t\t\tvar xhr = settings.jqXHR;\n\t\t\tif ( xhr && xhr.readyState !== 4 ) {\n\t\t\t\txhr.abort();\n\t\t\t}\n\t\n\t\t\t// Trigger xhr\n\t\t\t_fnBuildAjax( settings, [], function( json ) {\n\t\t\t\t_fnClearTable( settings );\n\t\n\t\t\t\tvar data = _fnAjaxDataSrc( settings, json );\n\t\t\t\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\n\t\t\t\t\t_fnAddData( settings, data[i] );\n\t\t\t\t}\n\t\n\t\t\t\t_fnReDraw( settings, holdPosition );\n\t\t\t\t_fnProcessingDisplay( settings, false );\n\t\t\t} );\n\t\t}\n\t};\n\t\n\t\n\t/**\n\t * Get the JSON response from the last Ajax request that DataTables made to the\n\t * server. Note that this returns the JSON from the first table in the current\n\t * context.\n\t *\n\t * @return {object} JSON received from the server.\n\t */\n\t_api_register( 'ajax.json()', function () {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( ctx.length > 0 ) {\n\t\t\treturn ctx[0].json;\n\t\t}\n\t\n\t\t// else return undefined;\n\t} );\n\t\n\t\n\t/**\n\t * Get the data submitted in the last Ajax request\n\t */\n\t_api_register( 'ajax.params()', function () {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( ctx.length > 0 ) {\n\t\t\treturn ctx[0].oAjaxData;\n\t\t}\n\t\n\t\t// else return undefined;\n\t} );\n\t\n\t\n\t/**\n\t * Reload tables from the Ajax data source. Note that this function will\n\t * automatically re-draw the table when the remote data has been loaded.\n\t *\n\t * @param {boolean} [reset=true] Reset (default) or hold the current paging\n\t *   position. A full re-sort and re-filter is performed when this method is\n\t *   called, which is why the pagination reset is the default action.\n\t * @returns {DataTables.Api} this\n\t */\n\t_api_register( 'ajax.reload()', function ( callback, resetPaging ) {\n\t\treturn this.iterator( 'table', function (settings) {\n\t\t\t__reload( settings, resetPaging===false, callback );\n\t\t} );\n\t} );\n\t\n\t\n\t/**\n\t * Get the current Ajax URL. Note that this returns the URL from the first\n\t * table in the current context.\n\t *\n\t * @return {string} Current Ajax source URL\n\t *//**\n\t * Set the Ajax URL. Note that this will set the URL for all tables in the\n\t * current context.\n\t *\n\t * @param {string} url URL to set.\n\t * @returns {DataTables.Api} this\n\t */\n\t_api_register( 'ajax.url()', function ( url ) {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( url === undefined ) {\n\t\t\t// get\n\t\t\tif ( ctx.length === 0 ) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tctx = ctx[0];\n\t\n\t\t\treturn ctx.ajax ?\n\t\t\t\t$.isPlainObject( ctx.ajax ) ?\n\t\t\t\t\tctx.ajax.url :\n\t\t\t\t\tctx.ajax :\n\t\t\t\tctx.sAjaxSource;\n\t\t}\n\t\n\t\t// set\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\tif ( $.isPlainObject( settings.ajax ) ) {\n\t\t\t\tsettings.ajax.url = url;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tsettings.ajax = url;\n\t\t\t}\n\t\t\t// No need to consider sAjaxSource here since DataTables gives priority\n\t\t\t// to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any\n\t\t\t// value of `sAjaxSource` redundant.\n\t\t} );\n\t} );\n\t\n\t\n\t/**\n\t * Load data from the newly set Ajax URL. Note that this method is only\n\t * available when `ajax.url()` is used to set a URL. Additionally, this method\n\t * has the same effect as calling `ajax.reload()` but is provided for\n\t * convenience when setting a new URL. Like `ajax.reload()` it will\n\t * automatically redraw the table once the remote data has been loaded.\n\t *\n\t * @returns {DataTables.Api} this\n\t */\n\t_api_register( 'ajax.url().load()', function ( callback, resetPaging ) {\n\t\t// Same as a reload, but makes sense to present it for easy access after a\n\t\t// url change\n\t\treturn this.iterator( 'table', function ( ctx ) {\n\t\t\t__reload( ctx, resetPaging===false, callback );\n\t\t} );\n\t} );\n\t\n\t\n\t\n\t\n\tvar _selector_run = function ( type, selector, selectFn, settings, opts )\n\t{\n\t\tvar\n\t\t\tout = [], res,\n\t\t\ta, i, ien, j, jen,\n\t\t\tselectorType = typeof selector;\n\t\n\t\t// Can't just check for isArray here, as an API or jQuery instance might be\n\t\t// given with their array like look\n\t\tif ( ! selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined ) {\n\t\t\tselector = [ selector ];\n\t\t}\n\t\n\t\tfor ( i=0, ien=selector.length ; i<ien ; i++ ) {\n\t\t\ta = selector[i] && selector[i].split ?\n\t\t\t\tselector[i].split(',') :\n\t\t\t\t[ selector[i] ];\n\t\n\t\t\tfor ( j=0, jen=a.length ; j<jen ; j++ ) {\n\t\t\t\tres = selectFn( typeof a[j] === 'string' ? $.trim(a[j]) : a[j] );\n\t\n\t\t\t\tif ( res && res.length ) {\n\t\t\t\t\tout = out.concat( res );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\t// selector extensions\n\t\tvar ext = _ext.selector[ type ];\n\t\tif ( ext.length ) {\n\t\t\tfor ( i=0, ien=ext.length ; i<ien ; i++ ) {\n\t\t\t\tout = ext[i]( settings, opts, out );\n\t\t\t}\n\t\t}\n\t\n\t\treturn _unique( out );\n\t};\n\t\n\t\n\tvar _selector_opts = function ( opts )\n\t{\n\t\tif ( ! opts ) {\n\t\t\topts = {};\n\t\t}\n\t\n\t\t// Backwards compatibility for 1.9- which used the terminology filter rather\n\t\t// than search\n\t\tif ( opts.filter && opts.search === undefined ) {\n\t\t\topts.search = opts.filter;\n\t\t}\n\t\n\t\treturn $.extend( {\n\t\t\tsearch: 'none',\n\t\t\torder: 'current',\n\t\t\tpage: 'all'\n\t\t}, opts );\n\t};\n\t\n\t\n\tvar _selector_first = function ( inst )\n\t{\n\t\t// Reduce the API instance to the first item found\n\t\tfor ( var i=0, ien=inst.length ; i<ien ; i++ ) {\n\t\t\tif ( inst[i].length > 0 ) {\n\t\t\t\t// Assign the first element to the first item in the instance\n\t\t\t\t// and truncate the instance and context\n\t\t\t\tinst[0] = inst[i];\n\t\t\t\tinst[0].length = 1;\n\t\t\t\tinst.length = 1;\n\t\t\t\tinst.context = [ inst.context[i] ];\n\t\n\t\t\t\treturn inst;\n\t\t\t}\n\t\t}\n\t\n\t\t// Not found - return an empty instance\n\t\tinst.length = 0;\n\t\treturn inst;\n\t};\n\t\n\t\n\tvar _selector_row_indexes = function ( settings, opts )\n\t{\n\t\tvar\n\t\t\ti, ien, tmp, a=[],\n\t\t\tdisplayFiltered = settings.aiDisplay,\n\t\t\tdisplayMaster = settings.aiDisplayMaster;\n\t\n\t\tvar\n\t\t\tsearch = opts.search,  // none, applied, removed\n\t\t\torder  = opts.order,   // applied, current, index (original - compatibility with 1.9)\n\t\t\tpage   = opts.page;    // all, current\n\t\n\t\tif ( _fnDataSource( settings ) == 'ssp' ) {\n\t\t\t// In server-side processing mode, most options are irrelevant since\n\t\t\t// rows not shown don't exist and the index order is the applied order\n\t\t\t// Removed is a special case - for consistency just return an empty\n\t\t\t// array\n\t\t\treturn search === 'removed' ?\n\t\t\t\t[] :\n\t\t\t\t_range( 0, displayMaster.length );\n\t\t}\n\t\telse if ( page == 'current' ) {\n\t\t\t// Current page implies that order=current and fitler=applied, since it is\n\t\t\t// fairly senseless otherwise, regardless of what order and search actually\n\t\t\t// are\n\t\t\tfor ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) {\n\t\t\t\ta.push( displayFiltered[i] );\n\t\t\t}\n\t\t}\n\t\telse if ( order == 'current' || order == 'applied' ) {\n\t\t\ta = search == 'none' ?\n\t\t\t\tdisplayMaster.slice() :                      // no search\n\t\t\t\tsearch == 'applied' ?\n\t\t\t\t\tdisplayFiltered.slice() :                // applied search\n\t\t\t\t\t$.map( displayMaster, function (el, i) { // removed search\n\t\t\t\t\t\treturn $.inArray( el, displayFiltered ) === -1 ? el : null;\n\t\t\t\t\t} );\n\t\t}\n\t\telse if ( order == 'index' || order == 'original' ) {\n\t\t\tfor ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\n\t\t\t\tif ( search == 'none' ) {\n\t\t\t\t\ta.push( i );\n\t\t\t\t}\n\t\t\t\telse { // applied | removed\n\t\t\t\t\ttmp = $.inArray( i, displayFiltered );\n\t\n\t\t\t\t\tif ((tmp === -1 && search == 'removed') ||\n\t\t\t\t\t\t(tmp >= 0   && search == 'applied') )\n\t\t\t\t\t{\n\t\t\t\t\t\ta.push( i );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\treturn a;\n\t};\n\t\n\t\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Rows\n\t *\n\t * {}          - no selector - use all available rows\n\t * {integer}   - row aoData index\n\t * {node}      - TR node\n\t * {string}    - jQuery selector to apply to the TR elements\n\t * {array}     - jQuery array of nodes, or simply an array of TR nodes\n\t *\n\t */\n\t\n\t\n\tvar __row_selector = function ( settings, selector, opts )\n\t{\n\t\tvar run = function ( sel ) {\n\t\t\tvar selInt = _intVal( sel );\n\t\t\tvar i, ien;\n\t\n\t\t\t// Short cut - selector is a number and no options provided (default is\n\t\t\t// all records, so no need to check if the index is in there, since it\n\t\t\t// must be - dev error if the index doesn't exist).\n\t\t\tif ( selInt !== null && ! opts ) {\n\t\t\t\treturn [ selInt ];\n\t\t\t}\n\t\n\t\t\tvar rows = _selector_row_indexes( settings, opts );\n\t\n\t\t\tif ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) {\n\t\t\t\t// Selector - integer\n\t\t\t\treturn [ selInt ];\n\t\t\t}\n\t\t\telse if ( ! sel ) {\n\t\t\t\t// Selector - none\n\t\t\t\treturn rows;\n\t\t\t}\n\t\n\t\t\t// Selector - function\n\t\t\tif ( typeof sel === 'function' ) {\n\t\t\t\treturn $.map( rows, function (idx) {\n\t\t\t\t\tvar row = settings.aoData[ idx ];\n\t\t\t\t\treturn sel( idx, row._aData, row.nTr ) ? idx : null;\n\t\t\t\t} );\n\t\t\t}\n\t\n\t\t\t// Get nodes in the order from the `rows` array with null values removed\n\t\t\tvar nodes = _removeEmpty(\n\t\t\t\t_pluck_order( settings.aoData, rows, 'nTr' )\n\t\t\t);\n\t\n\t\t\t// Selector - node\n\t\t\tif ( sel.nodeName ) {\n\t\t\t\tif ( sel._DT_RowIndex !== undefined ) {\n\t\t\t\t\treturn [ sel._DT_RowIndex ]; // Property added by DT for fast lookup\n\t\t\t\t}\n\t\t\t\telse if ( sel._DT_CellIndex ) {\n\t\t\t\t\treturn [ sel._DT_CellIndex.row ];\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tvar host = $(sel).closest('*[data-dt-row]');\n\t\t\t\t\treturn host.length ?\n\t\t\t\t\t\t[ host.data('dt-row') ] :\n\t\t\t\t\t\t[];\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t// ID selector. Want to always be able to select rows by id, regardless\n\t\t\t// of if the tr element has been created or not, so can't rely upon\n\t\t\t// jQuery here - hence a custom implementation. This does not match\n\t\t\t// Sizzle's fast selector or HTML4 - in HTML5 the ID can be anything,\n\t\t\t// but to select it using a CSS selector engine (like Sizzle or\n\t\t\t// querySelect) it would need to need to be escaped for some characters.\n\t\t\t// DataTables simplifies this for row selectors since you can select\n\t\t\t// only a row. A # indicates an id any anything that follows is the id -\n\t\t\t// unescaped.\n\t\t\tif ( typeof sel === 'string' && sel.charAt(0) === '#' ) {\n\t\t\t\t// get row index from id\n\t\t\t\tvar rowObj = settings.aIds[ sel.replace( /^#/, '' ) ];\n\t\t\t\tif ( rowObj !== undefined ) {\n\t\t\t\t\treturn [ rowObj.idx ];\n\t\t\t\t}\n\t\n\t\t\t\t// need to fall through to jQuery in case there is DOM id that\n\t\t\t\t// matches\n\t\t\t}\n\t\n\t\t\t// Selector - jQuery selector string, array of nodes or jQuery object/\n\t\t\t// As jQuery's .filter() allows jQuery objects to be passed in filter,\n\t\t\t// it also allows arrays, so this will cope with all three options\n\t\t\treturn $(nodes)\n\t\t\t\t.filter( sel )\n\t\t\t\t.map( function () {\n\t\t\t\t\treturn this._DT_RowIndex;\n\t\t\t\t} )\n\t\t\t\t.toArray();\n\t\t};\n\t\n\t\treturn _selector_run( 'row', selector, run, settings, opts );\n\t};\n\t\n\t\n\t_api_register( 'rows()', function ( selector, opts ) {\n\t\t// argument shifting\n\t\tif ( selector === undefined ) {\n\t\t\tselector = '';\n\t\t}\n\t\telse if ( $.isPlainObject( selector ) ) {\n\t\t\topts = selector;\n\t\t\tselector = '';\n\t\t}\n\t\n\t\topts = _selector_opts( opts );\n\t\n\t\tvar inst = this.iterator( 'table', function ( settings ) {\n\t\t\treturn __row_selector( settings, selector, opts );\n\t\t}, 1 );\n\t\n\t\t// Want argument shifting here and in __row_selector?\n\t\tinst.selector.rows = selector;\n\t\tinst.selector.opts = opts;\n\t\n\t\treturn inst;\n\t} );\n\t\n\t_api_register( 'rows().nodes()', function () {\n\t\treturn this.iterator( 'row', function ( settings, row ) {\n\t\t\treturn settings.aoData[ row ].nTr || undefined;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_register( 'rows().data()', function () {\n\t\treturn this.iterator( true, 'rows', function ( settings, rows ) {\n\t\t\treturn _pluck_order( settings.aoData, rows, '_aData' );\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) {\n\t\treturn this.iterator( 'row', function ( settings, row ) {\n\t\t\tvar r = settings.aoData[ row ];\n\t\t\treturn type === 'search' ? r._aFilterData : r._aSortData;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) {\n\t\treturn this.iterator( 'row', function ( settings, row ) {\n\t\t\t_fnInvalidate( settings, row, src );\n\t\t} );\n\t} );\n\t\n\t_api_registerPlural( 'rows().indexes()', 'row().index()', function () {\n\t\treturn this.iterator( 'row', function ( settings, row ) {\n\t\t\treturn row;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'rows().ids()', 'row().id()', function ( hash ) {\n\t\tvar a = [];\n\t\tvar context = this.context;\n\t\n\t\t// `iterator` will drop undefined values, but in this case we want them\n\t\tfor ( var i=0, ien=context.length ; i<ien ; i++ ) {\n\t\t\tfor ( var j=0, jen=this[i].length ; j<jen ; j++ ) {\n\t\t\t\tvar id = context[i].rowIdFn( context[i].aoData[ this[i][j] ]._aData );\n\t\t\t\ta.push( (hash === true ? '#' : '' )+ id );\n\t\t\t}\n\t\t}\n\t\n\t\treturn new _Api( context, a );\n\t} );\n\t\n\t_api_registerPlural( 'rows().remove()', 'row().remove()', function () {\n\t\tvar that = this;\n\t\n\t\tthis.iterator( 'row', function ( settings, row, thatIdx ) {\n\t\t\tvar data = settings.aoData;\n\t\t\tvar rowData = data[ row ];\n\t\t\tvar i, ien, j, jen;\n\t\t\tvar loopRow, loopCells;\n\t\n\t\t\tdata.splice( row, 1 );\n\t\n\t\t\t// Update the cached indexes\n\t\t\tfor ( i=0, ien=data.length ; i<ien ; i++ ) {\n\t\t\t\tloopRow = data[i];\n\t\t\t\tloopCells = loopRow.anCells;\n\t\n\t\t\t\t// Rows\n\t\t\t\tif ( loopRow.nTr !== null ) {\n\t\t\t\t\tloopRow.nTr._DT_RowIndex = i;\n\t\t\t\t}\n\t\n\t\t\t\t// Cells\n\t\t\t\tif ( loopCells !== null ) {\n\t\t\t\t\tfor ( j=0, jen=loopCells.length ; j<jen ; j++ ) {\n\t\t\t\t\t\tloopCells[j]._DT_CellIndex.row = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t// Delete from the display arrays\n\t\t\t_fnDeleteIndex( settings.aiDisplayMaster, row );\n\t\t\t_fnDeleteIndex( settings.aiDisplay, row );\n\t\t\t_fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes\n\t\n\t\t\t// Check for an 'overflow' they case for displaying the table\n\t\t\t_fnLengthOverflow( settings );\n\t\n\t\t\t// Remove the row's ID reference if there is one\n\t\t\tvar id = settings.rowIdFn( rowData._aData );\n\t\t\tif ( id !== undefined ) {\n\t\t\t\tdelete settings.aIds[ id ];\n\t\t\t}\n\t\t} );\n\t\n\t\tthis.iterator( 'table', function ( settings ) {\n\t\t\tfor ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\n\t\t\t\tsettings.aoData[i].idx = i;\n\t\t\t}\n\t\t} );\n\t\n\t\treturn this;\n\t} );\n\t\n\t\n\t_api_register( 'rows.add()', function ( rows ) {\n\t\tvar newRows = this.iterator( 'table', function ( settings ) {\n\t\t\t\tvar row, i, ien;\n\t\t\t\tvar out = [];\n\t\n\t\t\t\tfor ( i=0, ien=rows.length ; i<ien ; i++ ) {\n\t\t\t\t\trow = rows[i];\n\t\n\t\t\t\t\tif ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {\n\t\t\t\t\t\tout.push( _fnAddTr( settings, row )[0] );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tout.push( _fnAddData( settings, row ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\n\t\t\t\treturn out;\n\t\t\t}, 1 );\n\t\n\t\t// Return an Api.rows() extended instance, so rows().nodes() etc can be used\n\t\tvar modRows = this.rows( -1 );\n\t\tmodRows.pop();\n\t\t$.merge( modRows, newRows );\n\t\n\t\treturn modRows;\n\t} );\n\t\n\t\n\t\n\t\n\t\n\t/**\n\t *\n\t */\n\t_api_register( 'row()', function ( selector, opts ) {\n\t\treturn _selector_first( this.rows( selector, opts ) );\n\t} );\n\t\n\t\n\t_api_register( 'row().data()', function ( data ) {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( data === undefined ) {\n\t\t\t// Get\n\t\t\treturn ctx.length && this.length ?\n\t\t\t\tctx[0].aoData[ this[0] ]._aData :\n\t\t\t\tundefined;\n\t\t}\n\t\n\t\t// Set\n\t\tctx[0].aoData[ this[0] ]._aData = data;\n\t\n\t\t// Automatically invalidate\n\t\t_fnInvalidate( ctx[0], this[0], 'data' );\n\t\n\t\treturn this;\n\t} );\n\t\n\t\n\t_api_register( 'row().node()', function () {\n\t\tvar ctx = this.context;\n\t\n\t\treturn ctx.length && this.length ?\n\t\t\tctx[0].aoData[ this[0] ].nTr || null :\n\t\t\tnull;\n\t} );\n\t\n\t\n\t_api_register( 'row.add()', function ( row ) {\n\t\t// Allow a jQuery object to be passed in - only a single row is added from\n\t\t// it though - the first element in the set\n\t\tif ( row instanceof $ && row.length ) {\n\t\t\trow = row[0];\n\t\t}\n\t\n\t\tvar rows = this.iterator( 'table', function ( settings ) {\n\t\t\tif ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {\n\t\t\t\treturn _fnAddTr( settings, row )[0];\n\t\t\t}\n\t\t\treturn _fnAddData( settings, row );\n\t\t} );\n\t\n\t\t// Return an Api.rows() extended instance, with the newly added row selected\n\t\treturn this.row( rows[0] );\n\t} );\n\t\n\t\n\t\n\tvar __details_add = function ( ctx, row, data, klass )\n\t{\n\t\t// Convert to array of TR elements\n\t\tvar rows = [];\n\t\tvar addRow = function ( r, k ) {\n\t\t\t// Recursion to allow for arrays of jQuery objects\n\t\t\tif ( $.isArray( r ) || r instanceof $ ) {\n\t\t\t\tfor ( var i=0, ien=r.length ; i<ien ; i++ ) {\n\t\t\t\t\taddRow( r[i], k );\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\t// If we get a TR element, then just add it directly - up to the dev\n\t\t\t// to add the correct number of columns etc\n\t\t\tif ( r.nodeName && r.nodeName.toLowerCase() === 'tr' ) {\n\t\t\t\trows.push( r );\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Otherwise create a row with a wrapper\n\t\t\t\tvar created = $('<tr><td/></tr>').addClass( k );\n\t\t\t\t$('td', created)\n\t\t\t\t\t.addClass( k )\n\t\t\t\t\t.html( r )\n\t\t\t\t\t[0].colSpan = _fnVisbleColumns( ctx );\n\t\n\t\t\t\trows.push( created[0] );\n\t\t\t}\n\t\t};\n\t\n\t\taddRow( data, klass );\n\t\n\t\tif ( row._details ) {\n\t\t\trow._details.remove();\n\t\t}\n\t\n\t\trow._details = $(rows);\n\t\n\t\t// If the children were already shown, that state should be retained\n\t\tif ( row._detailsShow ) {\n\t\t\trow._details.insertAfter( row.nTr );\n\t\t}\n\t};\n\t\n\t\n\tvar __details_remove = function ( api, idx )\n\t{\n\t\tvar ctx = api.context;\n\t\n\t\tif ( ctx.length ) {\n\t\t\tvar row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ];\n\t\n\t\t\tif ( row && row._details ) {\n\t\t\t\trow._details.remove();\n\t\n\t\t\t\trow._detailsShow = undefined;\n\t\t\t\trow._details = undefined;\n\t\t\t}\n\t\t}\n\t};\n\t\n\t\n\tvar __details_display = function ( api, show ) {\n\t\tvar ctx = api.context;\n\t\n\t\tif ( ctx.length && api.length ) {\n\t\t\tvar row = ctx[0].aoData[ api[0] ];\n\t\n\t\t\tif ( row._details ) {\n\t\t\t\trow._detailsShow = show;\n\t\n\t\t\t\tif ( show ) {\n\t\t\t\t\trow._details.insertAfter( row.nTr );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\trow._details.detach();\n\t\t\t\t}\n\t\n\t\t\t\t__details_events( ctx[0] );\n\t\t\t}\n\t\t}\n\t};\n\t\n\t\n\tvar __details_events = function ( settings )\n\t{\n\t\tvar api = new _Api( settings );\n\t\tvar namespace = '.dt.DT_details';\n\t\tvar drawEvent = 'draw'+namespace;\n\t\tvar colvisEvent = 'column-visibility'+namespace;\n\t\tvar destroyEvent = 'destroy'+namespace;\n\t\tvar data = settings.aoData;\n\t\n\t\tapi.off( drawEvent +' '+ colvisEvent +' '+ destroyEvent );\n\t\n\t\tif ( _pluck( data, '_details' ).length > 0 ) {\n\t\t\t// On each draw, insert the required elements into the document\n\t\t\tapi.on( drawEvent, function ( e, ctx ) {\n\t\t\t\tif ( settings !== ctx ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\n\t\t\t\tapi.rows( {page:'current'} ).eq(0).each( function (idx) {\n\t\t\t\t\t// Internal data grab\n\t\t\t\t\tvar row = data[ idx ];\n\t\n\t\t\t\t\tif ( row._detailsShow ) {\n\t\t\t\t\t\trow._details.insertAfter( row.nTr );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t} );\n\t\n\t\t\t// Column visibility change - update the colspan\n\t\t\tapi.on( colvisEvent, function ( e, ctx, idx, vis ) {\n\t\t\t\tif ( settings !== ctx ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\n\t\t\t\t// Update the colspan for the details rows (note, only if it already has\n\t\t\t\t// a colspan)\n\t\t\t\tvar row, visible = _fnVisbleColumns( ctx );\n\t\n\t\t\t\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\n\t\t\t\t\trow = data[i];\n\t\n\t\t\t\t\tif ( row._details ) {\n\t\t\t\t\t\trow._details.children('td[colspan]').attr('colspan', visible );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\n\t\t\t// Table destroyed - nuke any child rows\n\t\t\tapi.on( destroyEvent, function ( e, ctx ) {\n\t\t\t\tif ( settings !== ctx ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\n\t\t\t\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\n\t\t\t\t\tif ( data[i]._details ) {\n\t\t\t\t\t\t__details_remove( api, i );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t};\n\t\n\t// Strings for the method names to help minification\n\tvar _emp = '';\n\tvar _child_obj = _emp+'row().child';\n\tvar _child_mth = _child_obj+'()';\n\t\n\t// data can be:\n\t//  tr\n\t//  string\n\t//  jQuery or array of any of the above\n\t_api_register( _child_mth, function ( data, klass ) {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( data === undefined ) {\n\t\t\t// get\n\t\t\treturn ctx.length && this.length ?\n\t\t\t\tctx[0].aoData[ this[0] ]._details :\n\t\t\t\tundefined;\n\t\t}\n\t\telse if ( data === true ) {\n\t\t\t// show\n\t\t\tthis.child.show();\n\t\t}\n\t\telse if ( data === false ) {\n\t\t\t// remove\n\t\t\t__details_remove( this );\n\t\t}\n\t\telse if ( ctx.length && this.length ) {\n\t\t\t// set\n\t\t\t__details_add( ctx[0], ctx[0].aoData[ this[0] ], data, klass );\n\t\t}\n\t\n\t\treturn this;\n\t} );\n\t\n\t\n\t_api_register( [\n\t\t_child_obj+'.show()',\n\t\t_child_mth+'.show()' // only when `child()` was called with parameters (without\n\t], function ( show ) {   // it returns an object and this method is not executed)\n\t\t__details_display( this, true );\n\t\treturn this;\n\t} );\n\t\n\t\n\t_api_register( [\n\t\t_child_obj+'.hide()',\n\t\t_child_mth+'.hide()' // only when `child()` was called with parameters (without\n\t], function () {         // it returns an object and this method is not executed)\n\t\t__details_display( this, false );\n\t\treturn this;\n\t} );\n\t\n\t\n\t_api_register( [\n\t\t_child_obj+'.remove()',\n\t\t_child_mth+'.remove()' // only when `child()` was called with parameters (without\n\t], function () {           // it returns an object and this method is not executed)\n\t\t__details_remove( this );\n\t\treturn this;\n\t} );\n\t\n\t\n\t_api_register( _child_obj+'.isShown()', function () {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( ctx.length && this.length ) {\n\t\t\t// _detailsShown as false or undefined will fall through to return false\n\t\t\treturn ctx[0].aoData[ this[0] ]._detailsShow || false;\n\t\t}\n\t\treturn false;\n\t} );\n\t\n\t\n\t\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Columns\n\t *\n\t * {integer}           - column index (>=0 count from left, <0 count from right)\n\t * \"{integer}:visIdx\"  - visible column index (i.e. translate to column index)  (>=0 count from left, <0 count from right)\n\t * \"{integer}:visible\" - alias for {integer}:visIdx  (>=0 count from left, <0 count from right)\n\t * \"{string}:name\"     - column name\n\t * \"{string}\"          - jQuery selector on column header nodes\n\t *\n\t */\n\t\n\t// can be an array of these items, comma separated list, or an array of comma\n\t// separated lists\n\t\n\tvar __re_column_selector = /^(.+):(name|visIdx|visible)$/;\n\t\n\t\n\t// r1 and r2 are redundant - but it means that the parameters match for the\n\t// iterator callback in columns().data()\n\tvar __columnData = function ( settings, column, r1, r2, rows ) {\n\t\tvar a = [];\n\t\tfor ( var row=0, ien=rows.length ; row<ien ; row++ ) {\n\t\t\ta.push( _fnGetCellData( settings, rows[row], column ) );\n\t\t}\n\t\treturn a;\n\t};\n\t\n\t\n\tvar __column_selector = function ( settings, selector, opts )\n\t{\n\t\tvar\n\t\t\tcolumns = settings.aoColumns,\n\t\t\tnames = _pluck( columns, 'sName' ),\n\t\t\tnodes = _pluck( columns, 'nTh' );\n\t\n\t\tvar run = function ( s ) {\n\t\t\tvar selInt = _intVal( s );\n\t\n\t\t\t// Selector - all\n\t\t\tif ( s === '' ) {\n\t\t\t\treturn _range( columns.length );\n\t\t\t}\n\t\n\t\t\t// Selector - index\n\t\t\tif ( selInt !== null ) {\n\t\t\t\treturn [ selInt >= 0 ?\n\t\t\t\t\tselInt : // Count from left\n\t\t\t\t\tcolumns.length + selInt // Count from right (+ because its a negative value)\n\t\t\t\t];\n\t\t\t}\n\t\n\t\t\t// Selector = function\n\t\t\tif ( typeof s === 'function' ) {\n\t\t\t\tvar rows = _selector_row_indexes( settings, opts );\n\t\n\t\t\t\treturn $.map( columns, function (col, idx) {\n\t\t\t\t\treturn s(\n\t\t\t\t\t\t\tidx,\n\t\t\t\t\t\t\t__columnData( settings, idx, 0, 0, rows ),\n\t\t\t\t\t\t\tnodes[ idx ]\n\t\t\t\t\t\t) ? idx : null;\n\t\t\t\t} );\n\t\t\t}\n\t\n\t\t\t// jQuery or string selector\n\t\t\tvar match = typeof s === 'string' ?\n\t\t\t\ts.match( __re_column_selector ) :\n\t\t\t\t'';\n\t\n\t\t\tif ( match ) {\n\t\t\t\tswitch( match[2] ) {\n\t\t\t\t\tcase 'visIdx':\n\t\t\t\t\tcase 'visible':\n\t\t\t\t\t\tvar idx = parseInt( match[1], 10 );\n\t\t\t\t\t\t// Visible index given, convert to column index\n\t\t\t\t\t\tif ( idx < 0 ) {\n\t\t\t\t\t\t\t// Counting from the right\n\t\t\t\t\t\t\tvar visColumns = $.map( columns, function (col,i) {\n\t\t\t\t\t\t\t\treturn col.bVisible ? i : null;\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\treturn [ visColumns[ visColumns.length + idx ] ];\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Counting from the left\n\t\t\t\t\t\treturn [ _fnVisibleToColumnIndex( settings, idx ) ];\n\t\n\t\t\t\t\tcase 'name':\n\t\t\t\t\t\t// match by name. `names` is column index complete and in order\n\t\t\t\t\t\treturn $.map( names, function (name, i) {\n\t\t\t\t\t\t\treturn name === match[1] ? i : null;\n\t\t\t\t\t\t} );\n\t\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t// Cell in the table body\n\t\t\tif ( s.nodeName && s._DT_CellIndex ) {\n\t\t\t\treturn [ s._DT_CellIndex.column ];\n\t\t\t}\n\t\n\t\t\t// jQuery selector on the TH elements for the columns\n\t\t\tvar jqResult = $( nodes )\n\t\t\t\t.filter( s )\n\t\t\t\t.map( function () {\n\t\t\t\t\treturn $.inArray( this, nodes ); // `nodes` is column index complete and in order\n\t\t\t\t} )\n\t\t\t\t.toArray();\n\t\n\t\t\tif ( jqResult.length || ! s.nodeName ) {\n\t\t\t\treturn jqResult;\n\t\t\t}\n\t\n\t\t\t// Otherwise a node which might have a `dt-column` data attribute, or be\n\t\t\t// a child or such an element\n\t\t\tvar host = $(s).closest('*[data-dt-column]');\n\t\t\treturn host.length ?\n\t\t\t\t[ host.data('dt-column') ] :\n\t\t\t\t[];\n\t\t};\n\t\n\t\treturn _selector_run( 'column', selector, run, settings, opts );\n\t};\n\t\n\t\n\tvar __setColumnVis = function ( settings, column, vis ) {\n\t\tvar\n\t\t\tcols = settings.aoColumns,\n\t\t\tcol  = cols[ column ],\n\t\t\tdata = settings.aoData,\n\t\t\trow, cells, i, ien, tr;\n\t\n\t\t// Get\n\t\tif ( vis === undefined ) {\n\t\t\treturn col.bVisible;\n\t\t}\n\t\n\t\t// Set\n\t\t// No change\n\t\tif ( col.bVisible === vis ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\tif ( vis ) {\n\t\t\t// Insert column\n\t\t\t// Need to decide if we should use appendChild or insertBefore\n\t\t\tvar insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 );\n\t\n\t\t\tfor ( i=0, ien=data.length ; i<ien ; i++ ) {\n\t\t\t\ttr = data[i].nTr;\n\t\t\t\tcells = data[i].anCells;\n\t\n\t\t\t\tif ( tr ) {\n\t\t\t\t\t// insertBefore can act like appendChild if 2nd arg is null\n\t\t\t\t\ttr.insertBefore( cells[ column ], cells[ insertBefore ] || null );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\t// Remove column\n\t\t\t$( _pluck( settings.aoData, 'anCells', column ) ).detach();\n\t\t}\n\t\n\t\t// Common actions\n\t\tcol.bVisible = vis;\n\t\t_fnDrawHead( settings, settings.aoHeader );\n\t\t_fnDrawHead( settings, settings.aoFooter );\n\t\n\t\t_fnSaveState( settings );\n\t};\n\t\n\t\n\t_api_register( 'columns()', function ( selector, opts ) {\n\t\t// argument shifting\n\t\tif ( selector === undefined ) {\n\t\t\tselector = '';\n\t\t}\n\t\telse if ( $.isPlainObject( selector ) ) {\n\t\t\topts = selector;\n\t\t\tselector = '';\n\t\t}\n\t\n\t\topts = _selector_opts( opts );\n\t\n\t\tvar inst = this.iterator( 'table', function ( settings ) {\n\t\t\treturn __column_selector( settings, selector, opts );\n\t\t}, 1 );\n\t\n\t\t// Want argument shifting here and in _row_selector?\n\t\tinst.selector.cols = selector;\n\t\tinst.selector.opts = opts;\n\t\n\t\treturn inst;\n\t} );\n\t\n\t_api_registerPlural( 'columns().header()', 'column().header()', function ( selector, opts ) {\n\t\treturn this.iterator( 'column', function ( settings, column ) {\n\t\t\treturn settings.aoColumns[column].nTh;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'columns().footer()', 'column().footer()', function ( selector, opts ) {\n\t\treturn this.iterator( 'column', function ( settings, column ) {\n\t\t\treturn settings.aoColumns[column].nTf;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'columns().data()', 'column().data()', function () {\n\t\treturn this.iterator( 'column-rows', __columnData, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'columns().dataSrc()', 'column().dataSrc()', function () {\n\t\treturn this.iterator( 'column', function ( settings, column ) {\n\t\t\treturn settings.aoColumns[column].mData;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'columns().cache()', 'column().cache()', function ( type ) {\n\t\treturn this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {\n\t\t\treturn _pluck_order( settings.aoData, rows,\n\t\t\t\ttype === 'search' ? '_aFilterData' : '_aSortData', column\n\t\t\t);\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'columns().nodes()', 'column().nodes()', function () {\n\t\treturn this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {\n\t\t\treturn _pluck_order( settings.aoData, rows, 'anCells', column ) ;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis, calc ) {\n\t\tvar ret = this.iterator( 'column', function ( settings, column ) {\n\t\t\tif ( vis === undefined ) {\n\t\t\t\treturn settings.aoColumns[ column ].bVisible;\n\t\t\t} // else\n\t\t\t__setColumnVis( settings, column, vis );\n\t\t} );\n\t\n\t\t// Group the column visibility changes\n\t\tif ( vis !== undefined ) {\n\t\t\t// Second loop once the first is done for events\n\t\t\tthis.iterator( 'column', function ( settings, column ) {\n\t\t\t\t_fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis, calc] );\n\t\t\t} );\n\t\n\t\t\tif ( calc === undefined || calc ) {\n\t\t\t\tthis.columns.adjust();\n\t\t\t}\n\t\t}\n\t\n\t\treturn ret;\n\t} );\n\t\n\t_api_registerPlural( 'columns().indexes()', 'column().index()', function ( type ) {\n\t\treturn this.iterator( 'column', function ( settings, column ) {\n\t\t\treturn type === 'visible' ?\n\t\t\t\t_fnColumnIndexToVisible( settings, column ) :\n\t\t\t\tcolumn;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_register( 'columns.adjust()', function () {\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t_fnAdjustColumnSizing( settings );\n\t\t}, 1 );\n\t} );\n\t\n\t_api_register( 'column.index()', function ( type, idx ) {\n\t\tif ( this.context.length !== 0 ) {\n\t\t\tvar ctx = this.context[0];\n\t\n\t\t\tif ( type === 'fromVisible' || type === 'toData' ) {\n\t\t\t\treturn _fnVisibleToColumnIndex( ctx, idx );\n\t\t\t}\n\t\t\telse if ( type === 'fromData' || type === 'toVisible' ) {\n\t\t\t\treturn _fnColumnIndexToVisible( ctx, idx );\n\t\t\t}\n\t\t}\n\t} );\n\t\n\t_api_register( 'column()', function ( selector, opts ) {\n\t\treturn _selector_first( this.columns( selector, opts ) );\n\t} );\n\t\n\t\n\t\n\tvar __cell_selector = function ( settings, selector, opts )\n\t{\n\t\tvar data = settings.aoData;\n\t\tvar rows = _selector_row_indexes( settings, opts );\n\t\tvar cells = _removeEmpty( _pluck_order( data, rows, 'anCells' ) );\n\t\tvar allCells = $( [].concat.apply([], cells) );\n\t\tvar row;\n\t\tvar columns = settings.aoColumns.length;\n\t\tvar a, i, ien, j, o, host;\n\t\n\t\tvar run = function ( s ) {\n\t\t\tvar fnSelector = typeof s === 'function';\n\t\n\t\t\tif ( s === null || s === undefined || fnSelector ) {\n\t\t\t\t// All cells and function selectors\n\t\t\t\ta = [];\n\t\n\t\t\t\tfor ( i=0, ien=rows.length ; i<ien ; i++ ) {\n\t\t\t\t\trow = rows[i];\n\t\n\t\t\t\t\tfor ( j=0 ; j<columns ; j++ ) {\n\t\t\t\t\t\to = {\n\t\t\t\t\t\t\trow: row,\n\t\t\t\t\t\t\tcolumn: j\n\t\t\t\t\t\t};\n\t\n\t\t\t\t\t\tif ( fnSelector ) {\n\t\t\t\t\t\t\t// Selector - function\n\t\t\t\t\t\t\thost = data[ row ];\n\t\n\t\t\t\t\t\t\tif ( s( o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null ) ) {\n\t\t\t\t\t\t\t\ta.push( o );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t// Selector - all\n\t\t\t\t\t\t\ta.push( o );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\n\t\t\t\treturn a;\n\t\t\t}\n\t\t\t\n\t\t\t// Selector - index\n\t\t\tif ( $.isPlainObject( s ) ) {\n\t\t\t\treturn [s];\n\t\t\t}\n\t\n\t\t\t// Selector - jQuery filtered cells\n\t\t\tvar jqResult = allCells\n\t\t\t\t.filter( s )\n\t\t\t\t.map( function (i, el) {\n\t\t\t\t\treturn { // use a new object, in case someone changes the values\n\t\t\t\t\t\trow:    el._DT_CellIndex.row,\n\t\t\t\t\t\tcolumn: el._DT_CellIndex.column\n\t \t\t\t\t};\n\t\t\t\t} )\n\t\t\t\t.toArray();\n\t\n\t\t\tif ( jqResult.length || ! s.nodeName ) {\n\t\t\t\treturn jqResult;\n\t\t\t}\n\t\n\t\t\t// Otherwise the selector is a node, and there is one last option - the\n\t\t\t// element might be a child of an element which has dt-row and dt-column\n\t\t\t// data attributes\n\t\t\thost = $(s).closest('*[data-dt-row]');\n\t\t\treturn host.length ?\n\t\t\t\t[ {\n\t\t\t\t\trow: host.data('dt-row'),\n\t\t\t\t\tcolumn: host.data('dt-column')\n\t\t\t\t} ] :\n\t\t\t\t[];\n\t\t};\n\t\n\t\treturn _selector_run( 'cell', selector, run, settings, opts );\n\t};\n\t\n\t\n\t\n\t\n\t_api_register( 'cells()', function ( rowSelector, columnSelector, opts ) {\n\t\t// Argument shifting\n\t\tif ( $.isPlainObject( rowSelector ) ) {\n\t\t\t// Indexes\n\t\t\tif ( rowSelector.row === undefined ) {\n\t\t\t\t// Selector options in first parameter\n\t\t\t\topts = rowSelector;\n\t\t\t\trowSelector = null;\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Cell index objects in first parameter\n\t\t\t\topts = columnSelector;\n\t\t\t\tcolumnSelector = null;\n\t\t\t}\n\t\t}\n\t\tif ( $.isPlainObject( columnSelector ) ) {\n\t\t\topts = columnSelector;\n\t\t\tcolumnSelector = null;\n\t\t}\n\t\n\t\t// Cell selector\n\t\tif ( columnSelector === null || columnSelector === undefined ) {\n\t\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t\treturn __cell_selector( settings, rowSelector, _selector_opts( opts ) );\n\t\t\t} );\n\t\t}\n\t\n\t\t// Row + column selector\n\t\tvar columns = this.columns( columnSelector, opts );\n\t\tvar rows = this.rows( rowSelector, opts );\n\t\tvar a, i, ien, j, jen;\n\t\n\t\tvar cells = this.iterator( 'table', function ( settings, idx ) {\n\t\t\ta = [];\n\t\n\t\t\tfor ( i=0, ien=rows[idx].length ; i<ien ; i++ ) {\n\t\t\t\tfor ( j=0, jen=columns[idx].length ; j<jen ; j++ ) {\n\t\t\t\t\ta.push( {\n\t\t\t\t\t\trow:    rows[idx][i],\n\t\t\t\t\t\tcolumn: columns[idx][j]\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\treturn a;\n\t\t}, 1 );\n\t\n\t\t$.extend( cells.selector, {\n\t\t\tcols: columnSelector,\n\t\t\trows: rowSelector,\n\t\t\topts: opts\n\t\t} );\n\t\n\t\treturn cells;\n\t} );\n\t\n\t\n\t_api_registerPlural( 'cells().nodes()', 'cell().node()', function () {\n\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n\t\t\tvar data = settings.aoData[ row ];\n\t\n\t\t\treturn data && data.anCells ?\n\t\t\t\tdata.anCells[ column ] :\n\t\t\t\tundefined;\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_register( 'cells().data()', function () {\n\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n\t\t\treturn _fnGetCellData( settings, row, column );\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'cells().cache()', 'cell().cache()', function ( type ) {\n\t\ttype = type === 'search' ? '_aFilterData' : '_aSortData';\n\t\n\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n\t\t\treturn settings.aoData[ row ][ type ][ column ];\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'cells().render()', 'cell().render()', function ( type ) {\n\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n\t\t\treturn _fnGetCellData( settings, row, column, type );\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'cells().indexes()', 'cell().index()', function () {\n\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n\t\t\treturn {\n\t\t\t\trow: row,\n\t\t\t\tcolumn: column,\n\t\t\t\tcolumnVisible: _fnColumnIndexToVisible( settings, column )\n\t\t\t};\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'cells().invalidate()', 'cell().invalidate()', function ( src ) {\n\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n\t\t\t_fnInvalidate( settings, row, src, column );\n\t\t} );\n\t} );\n\t\n\t\n\t\n\t_api_register( 'cell()', function ( rowSelector, columnSelector, opts ) {\n\t\treturn _selector_first( this.cells( rowSelector, columnSelector, opts ) );\n\t} );\n\t\n\t\n\t_api_register( 'cell().data()', function ( data ) {\n\t\tvar ctx = this.context;\n\t\tvar cell = this[0];\n\t\n\t\tif ( data === undefined ) {\n\t\t\t// Get\n\t\t\treturn ctx.length && cell.length ?\n\t\t\t\t_fnGetCellData( ctx[0], cell[0].row, cell[0].column ) :\n\t\t\t\tundefined;\n\t\t}\n\t\n\t\t// Set\n\t\t_fnSetCellData( ctx[0], cell[0].row, cell[0].column, data );\n\t\t_fnInvalidate( ctx[0], cell[0].row, 'data', cell[0].column );\n\t\n\t\treturn this;\n\t} );\n\t\n\t\n\t\n\t/**\n\t * Get current ordering (sorting) that has been applied to the table.\n\t *\n\t * @returns {array} 2D array containing the sorting information for the first\n\t *   table in the current context. Each element in the parent array represents\n\t *   a column being sorted upon (i.e. multi-sorting with two columns would have\n\t *   2 inner arrays). The inner arrays may have 2 or 3 elements. The first is\n\t *   the column index that the sorting condition applies to, the second is the\n\t *   direction of the sort (`desc` or `asc`) and, optionally, the third is the\n\t *   index of the sorting order from the `column.sorting` initialisation array.\n\t *//**\n\t * Set the ordering for the table.\n\t *\n\t * @param {integer} order Column index to sort upon.\n\t * @param {string} direction Direction of the sort to be applied (`asc` or `desc`)\n\t * @returns {DataTables.Api} this\n\t *//**\n\t * Set the ordering for the table.\n\t *\n\t * @param {array} order 1D array of sorting information to be applied.\n\t * @param {array} [...] Optional additional sorting conditions\n\t * @returns {DataTables.Api} this\n\t *//**\n\t * Set the ordering for the table.\n\t *\n\t * @param {array} order 2D array of sorting information to be applied.\n\t * @returns {DataTables.Api} this\n\t */\n\t_api_register( 'order()', function ( order, dir ) {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( order === undefined ) {\n\t\t\t// get\n\t\t\treturn ctx.length !== 0 ?\n\t\t\t\tctx[0].aaSorting :\n\t\t\t\tundefined;\n\t\t}\n\t\n\t\t// set\n\t\tif ( typeof order === 'number' ) {\n\t\t\t// Simple column / direction passed in\n\t\t\torder = [ [ order, dir ] ];\n\t\t}\n\t\telse if ( order.length && ! $.isArray( order[0] ) ) {\n\t\t\t// Arguments passed in (list of 1D arrays)\n\t\t\torder = Array.prototype.slice.call( arguments );\n\t\t}\n\t\t// otherwise a 2D array was passed in\n\t\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\tsettings.aaSorting = order.slice();\n\t\t} );\n\t} );\n\t\n\t\n\t/**\n\t * Attach a sort listener to an element for a given column\n\t *\n\t * @param {node|jQuery|string} node Identifier for the element(s) to attach the\n\t *   listener to. This can take the form of a single DOM node, a jQuery\n\t *   collection of nodes or a jQuery selector which will identify the node(s).\n\t * @param {integer} column the column that a click on this node will sort on\n\t * @param {function} [callback] callback function when sort is run\n\t * @returns {DataTables.Api} this\n\t */\n\t_api_register( 'order.listener()', function ( node, column, callback ) {\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t_fnSortAttachListener( settings, node, column, callback );\n\t\t} );\n\t} );\n\t\n\t\n\t_api_register( 'order.fixed()', function ( set ) {\n\t\tif ( ! set ) {\n\t\t\tvar ctx = this.context;\n\t\t\tvar fixed = ctx.length ?\n\t\t\t\tctx[0].aaSortingFixed :\n\t\t\t\tundefined;\n\t\n\t\t\treturn $.isArray( fixed ) ?\n\t\t\t\t{ pre: fixed } :\n\t\t\t\tfixed;\n\t\t}\n\t\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\tsettings.aaSortingFixed = $.extend( true, {}, set );\n\t\t} );\n\t} );\n\t\n\t\n\t// Order by the selected column(s)\n\t_api_register( [\n\t\t'columns().order()',\n\t\t'column().order()'\n\t], function ( dir ) {\n\t\tvar that = this;\n\t\n\t\treturn this.iterator( 'table', function ( settings, i ) {\n\t\t\tvar sort = [];\n\t\n\t\t\t$.each( that[i], function (j, col) {\n\t\t\t\tsort.push( [ col, dir ] );\n\t\t\t} );\n\t\n\t\t\tsettings.aaSorting = sort;\n\t\t} );\n\t} );\n\t\n\t\n\t\n\t_api_register( 'search()', function ( input, regex, smart, caseInsen ) {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( input === undefined ) {\n\t\t\t// get\n\t\t\treturn ctx.length !== 0 ?\n\t\t\t\tctx[0].oPreviousSearch.sSearch :\n\t\t\t\tundefined;\n\t\t}\n\t\n\t\t// set\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\tif ( ! settings.oFeatures.bFilter ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\t_fnFilterComplete( settings, $.extend( {}, settings.oPreviousSearch, {\n\t\t\t\t\"sSearch\": input+\"\",\n\t\t\t\t\"bRegex\":  regex === null ? false : regex,\n\t\t\t\t\"bSmart\":  smart === null ? true  : smart,\n\t\t\t\t\"bCaseInsensitive\": caseInsen === null ? true : caseInsen\n\t\t\t} ), 1 );\n\t\t} );\n\t} );\n\t\n\t\n\t_api_registerPlural(\n\t\t'columns().search()',\n\t\t'column().search()',\n\t\tfunction ( input, regex, smart, caseInsen ) {\n\t\t\treturn this.iterator( 'column', function ( settings, column ) {\n\t\t\t\tvar preSearch = settings.aoPreSearchCols;\n\t\n\t\t\t\tif ( input === undefined ) {\n\t\t\t\t\t// get\n\t\t\t\t\treturn preSearch[ column ].sSearch;\n\t\t\t\t}\n\t\n\t\t\t\t// set\n\t\t\t\tif ( ! settings.oFeatures.bFilter ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\n\t\t\t\t$.extend( preSearch[ column ], {\n\t\t\t\t\t\"sSearch\": input+\"\",\n\t\t\t\t\t\"bRegex\":  regex === null ? false : regex,\n\t\t\t\t\t\"bSmart\":  smart === null ? true  : smart,\n\t\t\t\t\t\"bCaseInsensitive\": caseInsen === null ? true : caseInsen\n\t\t\t\t} );\n\t\n\t\t\t\t_fnFilterComplete( settings, settings.oPreviousSearch, 1 );\n\t\t\t} );\n\t\t}\n\t);\n\t\n\t/*\n\t * State API methods\n\t */\n\t\n\t_api_register( 'state()', function () {\n\t\treturn this.context.length ?\n\t\t\tthis.context[0].oSavedState :\n\t\t\tnull;\n\t} );\n\t\n\t\n\t_api_register( 'state.clear()', function () {\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t// Save an empty object\n\t\t\tsettings.fnStateSaveCallback.call( settings.oInstance, settings, {} );\n\t\t} );\n\t} );\n\t\n\t\n\t_api_register( 'state.loaded()', function () {\n\t\treturn this.context.length ?\n\t\t\tthis.context[0].oLoadedState :\n\t\t\tnull;\n\t} );\n\t\n\t\n\t_api_register( 'state.save()', function () {\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t_fnSaveState( settings );\n\t\t} );\n\t} );\n\t\n\t\n\t\n\t/**\n\t * Provide a common method for plug-ins to check the version of DataTables being\n\t * used, in order to ensure compatibility.\n\t *\n\t *  @param {string} version Version string to check for, in the format \"X.Y.Z\".\n\t *    Note that the formats \"X\" and \"X.Y\" are also acceptable.\n\t *  @returns {boolean} true if this version of DataTables is greater or equal to\n\t *    the required version, or false if this version of DataTales is not\n\t *    suitable\n\t *  @static\n\t *  @dtopt API-Static\n\t *\n\t *  @example\n\t *    alert( $.fn.dataTable.versionCheck( '1.9.0' ) );\n\t */\n\tDataTable.versionCheck = DataTable.fnVersionCheck = function( version )\n\t{\n\t\tvar aThis = DataTable.version.split('.');\n\t\tvar aThat = version.split('.');\n\t\tvar iThis, iThat;\n\t\n\t\tfor ( var i=0, iLen=aThat.length ; i<iLen ; i++ ) {\n\t\t\tiThis = parseInt( aThis[i], 10 ) || 0;\n\t\t\tiThat = parseInt( aThat[i], 10 ) || 0;\n\t\n\t\t\t// Parts are the same, keep comparing\n\t\t\tif (iThis === iThat) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\n\t\t\t// Parts are different, return immediately\n\t\t\treturn iThis > iThat;\n\t\t}\n\t\n\t\treturn true;\n\t};\n\t\n\t\n\t/**\n\t * Check if a `<table>` node is a DataTable table already or not.\n\t *\n\t *  @param {node|jquery|string} table Table node, jQuery object or jQuery\n\t *      selector for the table to test. Note that if more than more than one\n\t *      table is passed on, only the first will be checked\n\t *  @returns {boolean} true the table given is a DataTable, or false otherwise\n\t *  @static\n\t *  @dtopt API-Static\n\t *\n\t *  @example\n\t *    if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {\n\t *      $('#example').dataTable();\n\t *    }\n\t */\n\tDataTable.isDataTable = DataTable.fnIsDataTable = function ( table )\n\t{\n\t\tvar t = $(table).get(0);\n\t\tvar is = false;\n\t\n\t\t$.each( DataTable.settings, function (i, o) {\n\t\t\tvar head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null;\n\t\t\tvar foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null;\n\t\n\t\t\tif ( o.nTable === t || head === t || foot === t ) {\n\t\t\t\tis = true;\n\t\t\t}\n\t\t} );\n\t\n\t\treturn is;\n\t};\n\t\n\t\n\t/**\n\t * Get all DataTable tables that have been initialised - optionally you can\n\t * select to get only currently visible tables.\n\t *\n\t *  @param {boolean} [visible=false] Flag to indicate if you want all (default)\n\t *    or visible tables only.\n\t *  @returns {array} Array of `table` nodes (not DataTable instances) which are\n\t *    DataTables\n\t *  @static\n\t *  @dtopt API-Static\n\t *\n\t *  @example\n\t *    $.each( $.fn.dataTable.tables(true), function () {\n\t *      $(table).DataTable().columns.adjust();\n\t *    } );\n\t */\n\tDataTable.tables = DataTable.fnTables = function ( visible )\n\t{\n\t\tvar api = false;\n\t\n\t\tif ( $.isPlainObject( visible ) ) {\n\t\t\tapi = visible.api;\n\t\t\tvisible = visible.visible;\n\t\t}\n\t\n\t\tvar a = $.map( DataTable.settings, function (o) {\n\t\t\tif ( !visible || (visible && $(o.nTable).is(':visible')) ) {\n\t\t\t\treturn o.nTable;\n\t\t\t}\n\t\t} );\n\t\n\t\treturn api ?\n\t\t\tnew _Api( a ) :\n\t\t\ta;\n\t};\n\t\n\t\n\t/**\n\t * Convert from camel case parameters to Hungarian notation. This is made public\n\t * for the extensions to provide the same ability as DataTables core to accept\n\t * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase\n\t * parameters.\n\t *\n\t *  @param {object} src The model object which holds all parameters that can be\n\t *    mapped.\n\t *  @param {object} user The object to convert from camel case to Hungarian.\n\t *  @param {boolean} force When set to `true`, properties which already have a\n\t *    Hungarian value in the `user` object will be overwritten. Otherwise they\n\t *    won't be.\n\t */\n\tDataTable.camelToHungarian = _fnCamelToHungarian;\n\t\n\t\n\t\n\t/**\n\t *\n\t */\n\t_api_register( '$()', function ( selector, opts ) {\n\t\tvar\n\t\t\trows   = this.rows( opts ).nodes(), // Get all rows\n\t\t\tjqRows = $(rows);\n\t\n\t\treturn $( [].concat(\n\t\t\tjqRows.filter( selector ).toArray(),\n\t\t\tjqRows.find( selector ).toArray()\n\t\t) );\n\t} );\n\t\n\t\n\t// jQuery functions to operate on the tables\n\t$.each( [ 'on', 'one', 'off' ], function (i, key) {\n\t\t_api_register( key+'()', function ( /* event, handler */ ) {\n\t\t\tvar args = Array.prototype.slice.call(arguments);\n\t\n\t\t\t// Add the `dt` namespace automatically if it isn't already present\n\t\t\tif ( ! args[0].match(/\\.dt\\b/) ) {\n\t\t\t\targs[0] += '.dt';\n\t\t\t}\n\t\n\t\t\tvar inst = $( this.tables().nodes() );\n\t\t\tinst[key].apply( inst, args );\n\t\t\treturn this;\n\t\t} );\n\t} );\n\t\n\t\n\t_api_register( 'clear()', function () {\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t_fnClearTable( settings );\n\t\t} );\n\t} );\n\t\n\t\n\t_api_register( 'settings()', function () {\n\t\treturn new _Api( this.context, this.context );\n\t} );\n\t\n\t\n\t_api_register( 'init()', function () {\n\t\tvar ctx = this.context;\n\t\treturn ctx.length ? ctx[0].oInit : null;\n\t} );\n\t\n\t\n\t_api_register( 'data()', function () {\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\treturn _pluck( settings.aoData, '_aData' );\n\t\t} ).flatten();\n\t} );\n\t\n\t\n\t_api_register( 'destroy()', function ( remove ) {\n\t\tremove = remove || false;\n\t\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\tvar orig      = settings.nTableWrapper.parentNode;\n\t\t\tvar classes   = settings.oClasses;\n\t\t\tvar table     = settings.nTable;\n\t\t\tvar tbody     = settings.nTBody;\n\t\t\tvar thead     = settings.nTHead;\n\t\t\tvar tfoot     = settings.nTFoot;\n\t\t\tvar jqTable   = $(table);\n\t\t\tvar jqTbody   = $(tbody);\n\t\t\tvar jqWrapper = $(settings.nTableWrapper);\n\t\t\tvar rows      = $.map( settings.aoData, function (r) { return r.nTr; } );\n\t\t\tvar i, ien;\n\t\n\t\t\t// Flag to note that the table is currently being destroyed - no action\n\t\t\t// should be taken\n\t\t\tsettings.bDestroying = true;\n\t\n\t\t\t// Fire off the destroy callbacks for plug-ins etc\n\t\t\t_fnCallbackFire( settings, \"aoDestroyCallback\", \"destroy\", [settings] );\n\t\n\t\t\t// If not being removed from the document, make all columns visible\n\t\t\tif ( ! remove ) {\n\t\t\t\tnew _Api( settings ).columns().visible( true );\n\t\t\t}\n\t\n\t\t\t// Blitz all `DT` namespaced events (these are internal events, the\n\t\t\t// lowercase, `dt` events are user subscribed and they are responsible\n\t\t\t// for removing them\n\t\t\tjqWrapper.unbind('.DT').find(':not(tbody *)').unbind('.DT');\n\t\t\t$(window).unbind('.DT-'+settings.sInstance);\n\t\n\t\t\t// When scrolling we had to break the table up - restore it\n\t\t\tif ( table != thead.parentNode ) {\n\t\t\t\tjqTable.children('thead').detach();\n\t\t\t\tjqTable.append( thead );\n\t\t\t}\n\t\n\t\t\tif ( tfoot && table != tfoot.parentNode ) {\n\t\t\t\tjqTable.children('tfoot').detach();\n\t\t\t\tjqTable.append( tfoot );\n\t\t\t}\n\t\n\t\t\tsettings.aaSorting = [];\n\t\t\tsettings.aaSortingFixed = [];\n\t\t\t_fnSortingClasses( settings );\n\t\n\t\t\t$( rows ).removeClass( settings.asStripeClasses.join(' ') );\n\t\n\t\t\t$('th, td', thead).removeClass( classes.sSortable+' '+\n\t\t\t\tclasses.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone\n\t\t\t);\n\t\n\t\t\tif ( settings.bJUI ) {\n\t\t\t\t$('th span.'+classes.sSortIcon+ ', td span.'+classes.sSortIcon, thead).detach();\n\t\t\t\t$('th, td', thead).each( function () {\n\t\t\t\t\tvar wrapper = $('div.'+classes.sSortJUIWrapper, this);\n\t\t\t\t\t$(this).append( wrapper.contents() );\n\t\t\t\t\twrapper.detach();\n\t\t\t\t} );\n\t\t\t}\n\t\n\t\t\t// Add the TR elements back into the table in their original order\n\t\t\tjqTbody.children().detach();\n\t\t\tjqTbody.append( rows );\n\t\n\t\t\t// Remove the DataTables generated nodes, events and classes\n\t\t\tvar removedMethod = remove ? 'remove' : 'detach';\n\t\t\tjqTable[ removedMethod ]();\n\t\t\tjqWrapper[ removedMethod ]();\n\t\n\t\t\t// If we need to reattach the table to the document\n\t\t\tif ( ! remove && orig ) {\n\t\t\t\t// insertBefore acts like appendChild if !arg[1]\n\t\t\t\torig.insertBefore( table, settings.nTableReinsertBefore );\n\t\n\t\t\t\t// Restore the width of the original table - was read from the style property,\n\t\t\t\t// so we can restore directly to that\n\t\t\t\tjqTable\n\t\t\t\t\t.css( 'width', settings.sDestroyWidth )\n\t\t\t\t\t.removeClass( classes.sTable );\n\t\n\t\t\t\t// If the were originally stripe classes - then we add them back here.\n\t\t\t\t// Note this is not fool proof (for example if not all rows had stripe\n\t\t\t\t// classes - but it's a good effort without getting carried away\n\t\t\t\tien = settings.asDestroyStripes.length;\n\t\n\t\t\t\tif ( ien ) {\n\t\t\t\t\tjqTbody.children().each( function (i) {\n\t\t\t\t\t\t$(this).addClass( settings.asDestroyStripes[i % ien] );\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t/* Remove the settings object from the settings array */\n\t\t\tvar idx = $.inArray( settings, DataTable.settings );\n\t\t\tif ( idx !== -1 ) {\n\t\t\t\tDataTable.settings.splice( idx, 1 );\n\t\t\t}\n\t\t} );\n\t} );\n\t\n\t\n\t// Add the `every()` method for rows, columns and cells in a compact form\n\t$.each( [ 'column', 'row', 'cell' ], function ( i, type ) {\n\t\t_api_register( type+'s().every()', function ( fn ) {\n\t\t\tvar opts = this.selector.opts;\n\t\t\tvar api = this;\n\t\n\t\t\treturn this.iterator( type, function ( settings, arg1, arg2, arg3, arg4 ) {\n\t\t\t\t// Rows and columns:\n\t\t\t\t//  arg1 - index\n\t\t\t\t//  arg2 - table counter\n\t\t\t\t//  arg3 - loop counter\n\t\t\t\t//  arg4 - undefined\n\t\t\t\t// Cells:\n\t\t\t\t//  arg1 - row index\n\t\t\t\t//  arg2 - column index\n\t\t\t\t//  arg3 - table counter\n\t\t\t\t//  arg4 - loop counter\n\t\t\t\tfn.call(\n\t\t\t\t\tapi[ type ](\n\t\t\t\t\t\targ1,\n\t\t\t\t\t\ttype==='cell' ? arg2 : opts,\n\t\t\t\t\t\ttype==='cell' ? opts : undefined\n\t\t\t\t\t),\n\t\t\t\t\targ1, arg2, arg3, arg4\n\t\t\t\t);\n\t\t\t} );\n\t\t} );\n\t} );\n\t\n\t\n\t// i18n method for extensions to be able to use the language object from the\n\t// DataTable\n\t_api_register( 'i18n()', function ( token, def, plural ) {\n\t\tvar ctx = this.context[0];\n\t\tvar resolved = _fnGetObjectDataFn( token )( ctx.oLanguage );\n\t\n\t\tif ( resolved === undefined ) {\n\t\t\tresolved = def;\n\t\t}\n\t\n\t\tif ( plural !== undefined && $.isPlainObject( resolved ) ) {\n\t\t\tresolved = resolved[ plural ] !== undefined ?\n\t\t\t\tresolved[ plural ] :\n\t\t\t\tresolved._;\n\t\t}\n\t\n\t\treturn resolved.replace( '%d', plural ); // nb: plural might be undefined,\n\t} );\n\n\t/**\n\t * Version string for plug-ins to check compatibility. Allowed format is\n\t * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used\n\t * only for non-release builds. See http://semver.org/ for more information.\n\t *  @member\n\t *  @type string\n\t *  @default Version number\n\t */\n\tDataTable.version = \"1.10.12\";\n\n\t/**\n\t * Private data store, containing all of the settings objects that are\n\t * created for the tables on a given page.\n\t *\n\t * Note that the `DataTable.settings` object is aliased to\n\t * `jQuery.fn.dataTableExt` through which it may be accessed and\n\t * manipulated, or `jQuery.fn.dataTable.settings`.\n\t *  @member\n\t *  @type array\n\t *  @default []\n\t *  @private\n\t */\n\tDataTable.settings = [];\n\n\t/**\n\t * Object models container, for the various models that DataTables has\n\t * available to it. These models define the objects that are used to hold\n\t * the active state and configuration of the table.\n\t *  @namespace\n\t */\n\tDataTable.models = {};\n\t\n\t\n\t\n\t/**\n\t * Template object for the way in which DataTables holds information about\n\t * search information for the global filter and individual column filters.\n\t *  @namespace\n\t */\n\tDataTable.models.oSearch = {\n\t\t/**\n\t\t * Flag to indicate if the filtering should be case insensitive or not\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t */\n\t\t\"bCaseInsensitive\": true,\n\t\n\t\t/**\n\t\t * Applied search term\n\t\t *  @type string\n\t\t *  @default <i>Empty string</i>\n\t\t */\n\t\t\"sSearch\": \"\",\n\t\n\t\t/**\n\t\t * Flag to indicate if the search term should be interpreted as a\n\t\t * regular expression (true) or not (false) and therefore and special\n\t\t * regex characters escaped.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t */\n\t\t\"bRegex\": false,\n\t\n\t\t/**\n\t\t * Flag to indicate if DataTables is to use its smart filtering or not.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t */\n\t\t\"bSmart\": true\n\t};\n\t\n\t\n\t\n\t\n\t/**\n\t * Template object for the way in which DataTables holds information about\n\t * each individual row. This is the object format used for the settings\n\t * aoData array.\n\t *  @namespace\n\t */\n\tDataTable.models.oRow = {\n\t\t/**\n\t\t * TR element for the row\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTr\": null,\n\t\n\t\t/**\n\t\t * Array of TD elements for each row. This is null until the row has been\n\t\t * created.\n\t\t *  @type array nodes\n\t\t *  @default []\n\t\t */\n\t\t\"anCells\": null,\n\t\n\t\t/**\n\t\t * Data object from the original data source for the row. This is either\n\t\t * an array if using the traditional form of DataTables, or an object if\n\t\t * using mData options. The exact type will depend on the passed in\n\t\t * data from the data source, or will be an array if using DOM a data\n\t\t * source.\n\t\t *  @type array|object\n\t\t *  @default []\n\t\t */\n\t\t\"_aData\": [],\n\t\n\t\t/**\n\t\t * Sorting data cache - this array is ostensibly the same length as the\n\t\t * number of columns (although each index is generated only as it is\n\t\t * needed), and holds the data that is used for sorting each column in the\n\t\t * row. We do this cache generation at the start of the sort in order that\n\t\t * the formatting of the sort data need be done only once for each cell\n\t\t * per sort. This array should not be read from or written to by anything\n\t\t * other than the master sorting methods.\n\t\t *  @type array\n\t\t *  @default null\n\t\t *  @private\n\t\t */\n\t\t\"_aSortData\": null,\n\t\n\t\t/**\n\t\t * Per cell filtering data cache. As per the sort data cache, used to\n\t\t * increase the performance of the filtering in DataTables\n\t\t *  @type array\n\t\t *  @default null\n\t\t *  @private\n\t\t */\n\t\t\"_aFilterData\": null,\n\t\n\t\t/**\n\t\t * Filtering data cache. This is the same as the cell filtering cache, but\n\t\t * in this case a string rather than an array. This is easily computed with\n\t\t * a join on `_aFilterData`, but is provided as a cache so the join isn't\n\t\t * needed on every search (memory traded for performance)\n\t\t *  @type array\n\t\t *  @default null\n\t\t *  @private\n\t\t */\n\t\t\"_sFilterRow\": null,\n\t\n\t\t/**\n\t\t * Cache of the class name that DataTables has applied to the row, so we\n\t\t * can quickly look at this variable rather than needing to do a DOM check\n\t\t * on className for the nTr property.\n\t\t *  @type string\n\t\t *  @default <i>Empty string</i>\n\t\t *  @private\n\t\t */\n\t\t\"_sRowStripe\": \"\",\n\t\n\t\t/**\n\t\t * Denote if the original data source was from the DOM, or the data source\n\t\t * object. This is used for invalidating data, so DataTables can\n\t\t * automatically read data from the original source, unless uninstructed\n\t\t * otherwise.\n\t\t *  @type string\n\t\t *  @default null\n\t\t *  @private\n\t\t */\n\t\t\"src\": null,\n\t\n\t\t/**\n\t\t * Index in the aoData array. This saves an indexOf lookup when we have the\n\t\t * object, but want to know the index\n\t\t *  @type integer\n\t\t *  @default -1\n\t\t *  @private\n\t\t */\n\t\t\"idx\": -1\n\t};\n\t\n\t\n\t/**\n\t * Template object for the column information object in DataTables. This object\n\t * is held in the settings aoColumns array and contains all the information that\n\t * DataTables needs about each individual column.\n\t *\n\t * Note that this object is related to {@link DataTable.defaults.column}\n\t * but this one is the internal data store for DataTables's cache of columns.\n\t * It should NOT be manipulated outside of DataTables. Any configuration should\n\t * be done through the initialisation options.\n\t *  @namespace\n\t */\n\tDataTable.models.oColumn = {\n\t\t/**\n\t\t * Column index. This could be worked out on-the-fly with $.inArray, but it\n\t\t * is faster to just hold it as a variable\n\t\t *  @type integer\n\t\t *  @default null\n\t\t */\n\t\t\"idx\": null,\n\t\n\t\t/**\n\t\t * A list of the columns that sorting should occur on when this column\n\t\t * is sorted. That this property is an array allows multi-column sorting\n\t\t * to be defined for a column (for example first name / last name columns\n\t\t * would benefit from this). The values are integers pointing to the\n\t\t * columns to be sorted on (typically it will be a single integer pointing\n\t\t * at itself, but that doesn't need to be the case).\n\t\t *  @type array\n\t\t */\n\t\t\"aDataSort\": null,\n\t\n\t\t/**\n\t\t * Define the sorting directions that are applied to the column, in sequence\n\t\t * as the column is repeatedly sorted upon - i.e. the first value is used\n\t\t * as the sorting direction when the column if first sorted (clicked on).\n\t\t * Sort it again (click again) and it will move on to the next index.\n\t\t * Repeat until loop.\n\t\t *  @type array\n\t\t */\n\t\t\"asSorting\": null,\n\t\n\t\t/**\n\t\t * Flag to indicate if the column is searchable, and thus should be included\n\t\t * in the filtering or not.\n\t\t *  @type boolean\n\t\t */\n\t\t\"bSearchable\": null,\n\t\n\t\t/**\n\t\t * Flag to indicate if the column is sortable or not.\n\t\t *  @type boolean\n\t\t */\n\t\t\"bSortable\": null,\n\t\n\t\t/**\n\t\t * Flag to indicate if the column is currently visible in the table or not\n\t\t *  @type boolean\n\t\t */\n\t\t\"bVisible\": null,\n\t\n\t\t/**\n\t\t * Store for manual type assignment using the `column.type` option. This\n\t\t * is held in store so we can manipulate the column's `sType` property.\n\t\t *  @type string\n\t\t *  @default null\n\t\t *  @private\n\t\t */\n\t\t\"_sManualType\": null,\n\t\n\t\t/**\n\t\t * Flag to indicate if HTML5 data attributes should be used as the data\n\t\t * source for filtering or sorting. True is either are.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *  @private\n\t\t */\n\t\t\"_bAttrSrc\": false,\n\t\n\t\t/**\n\t\t * Developer definable function that is called whenever a cell is created (Ajax source,\n\t\t * etc) or processed for input (DOM source). This can be used as a compliment to mRender\n\t\t * allowing you to modify the DOM element (add background colour for example) when the\n\t\t * element is available.\n\t\t *  @type function\n\t\t *  @param {element} nTd The TD node that has been created\n\t\t *  @param {*} sData The Data for the cell\n\t\t *  @param {array|object} oData The data for the whole row\n\t\t *  @param {int} iRow The row index for the aoData data store\n\t\t *  @default null\n\t\t */\n\t\t\"fnCreatedCell\": null,\n\t\n\t\t/**\n\t\t * Function to get data from a cell in a column. You should <b>never</b>\n\t\t * access data directly through _aData internally in DataTables - always use\n\t\t * the method attached to this property. It allows mData to function as\n\t\t * required. This function is automatically assigned by the column\n\t\t * initialisation method\n\t\t *  @type function\n\t\t *  @param {array|object} oData The data array/object for the array\n\t\t *    (i.e. aoData[]._aData)\n\t\t *  @param {string} sSpecific The specific data type you want to get -\n\t\t *    'display', 'type' 'filter' 'sort'\n\t\t *  @returns {*} The data for the cell from the given row's data\n\t\t *  @default null\n\t\t */\n\t\t\"fnGetData\": null,\n\t\n\t\t/**\n\t\t * Function to set data for a cell in the column. You should <b>never</b>\n\t\t * set the data directly to _aData internally in DataTables - always use\n\t\t * this method. It allows mData to function as required. This function\n\t\t * is automatically assigned by the column initialisation method\n\t\t *  @type function\n\t\t *  @param {array|object} oData The data array/object for the array\n\t\t *    (i.e. aoData[]._aData)\n\t\t *  @param {*} sValue Value to set\n\t\t *  @default null\n\t\t */\n\t\t\"fnSetData\": null,\n\t\n\t\t/**\n\t\t * Property to read the value for the cells in the column from the data\n\t\t * source array / object. If null, then the default content is used, if a\n\t\t * function is given then the return from the function is used.\n\t\t *  @type function|int|string|null\n\t\t *  @default null\n\t\t */\n\t\t\"mData\": null,\n\t\n\t\t/**\n\t\t * Partner property to mData which is used (only when defined) to get\n\t\t * the data - i.e. it is basically the same as mData, but without the\n\t\t * 'set' option, and also the data fed to it is the result from mData.\n\t\t * This is the rendering method to match the data method of mData.\n\t\t *  @type function|int|string|null\n\t\t *  @default null\n\t\t */\n\t\t\"mRender\": null,\n\t\n\t\t/**\n\t\t * Unique header TH/TD element for this column - this is what the sorting\n\t\t * listener is attached to (if sorting is enabled.)\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTh\": null,\n\t\n\t\t/**\n\t\t * Unique footer TH/TD element for this column (if there is one). Not used\n\t\t * in DataTables as such, but can be used for plug-ins to reference the\n\t\t * footer for each column.\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTf\": null,\n\t\n\t\t/**\n\t\t * The class to apply to all TD elements in the table's TBODY for the column\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sClass\": null,\n\t\n\t\t/**\n\t\t * When DataTables calculates the column widths to assign to each column,\n\t\t * it finds the longest string in each column and then constructs a\n\t\t * temporary table and reads the widths from that. The problem with this\n\t\t * is that \"mmm\" is much wider then \"iiii\", but the latter is a longer\n\t\t * string - thus the calculation can go wrong (doing it properly and putting\n\t\t * it into an DOM object and measuring that is horribly(!) slow). Thus as\n\t\t * a \"work around\" we provide this option. It will append its value to the\n\t\t * text that is found to be the longest string for the column - i.e. padding.\n\t\t *  @type string\n\t\t */\n\t\t\"sContentPadding\": null,\n\t\n\t\t/**\n\t\t * Allows a default value to be given for a column's data, and will be used\n\t\t * whenever a null data source is encountered (this can be because mData\n\t\t * is set to null, or because the data source itself is null).\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sDefaultContent\": null,\n\t\n\t\t/**\n\t\t * Name for the column, allowing reference to the column by name as well as\n\t\t * by index (needs a lookup to work by name).\n\t\t *  @type string\n\t\t */\n\t\t\"sName\": null,\n\t\n\t\t/**\n\t\t * Custom sorting data type - defines which of the available plug-ins in\n\t\t * afnSortData the custom sorting will use - if any is defined.\n\t\t *  @type string\n\t\t *  @default std\n\t\t */\n\t\t\"sSortDataType\": 'std',\n\t\n\t\t/**\n\t\t * Class to be applied to the header element when sorting on this column\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sSortingClass\": null,\n\t\n\t\t/**\n\t\t * Class to be applied to the header element when sorting on this column -\n\t\t * when jQuery UI theming is used.\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sSortingClassJUI\": null,\n\t\n\t\t/**\n\t\t * Title of the column - what is seen in the TH element (nTh).\n\t\t *  @type string\n\t\t */\n\t\t\"sTitle\": null,\n\t\n\t\t/**\n\t\t * Column sorting and filtering type\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sType\": null,\n\t\n\t\t/**\n\t\t * Width of the column\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sWidth\": null,\n\t\n\t\t/**\n\t\t * Width of the column when it was first \"encountered\"\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sWidthOrig\": null\n\t};\n\t\n\t\n\t/*\n\t * Developer note: The properties of the object below are given in Hungarian\n\t * notation, that was used as the interface for DataTables prior to v1.10, however\n\t * from v1.10 onwards the primary interface is camel case. In order to avoid\n\t * breaking backwards compatibility utterly with this change, the Hungarian\n\t * version is still, internally the primary interface, but is is not documented\n\t * - hence the @name tags in each doc comment. This allows a Javascript function\n\t * to create a map from Hungarian notation to camel case (going the other direction\n\t * would require each property to be listed, which would at around 3K to the size\n\t * of DataTables, while this method is about a 0.5K hit.\n\t *\n\t * Ultimately this does pave the way for Hungarian notation to be dropped\n\t * completely, but that is a massive amount of work and will break current\n\t * installs (therefore is on-hold until v2).\n\t */\n\t\n\t/**\n\t * Initialisation options that can be given to DataTables at initialisation\n\t * time.\n\t *  @namespace\n\t */\n\tDataTable.defaults = {\n\t\t/**\n\t\t * An array of data to use for the table, passed in at initialisation which\n\t\t * will be used in preference to any data which is already in the DOM. This is\n\t\t * particularly useful for constructing tables purely in Javascript, for\n\t\t * example with a custom Ajax call.\n\t\t *  @type array\n\t\t *  @default null\n\t\t *\n\t\t *  @dtopt Option\n\t\t *  @name DataTable.defaults.data\n\t\t *\n\t\t *  @example\n\t\t *    // Using a 2D array data source\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"data\": [\n\t\t *          ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],\n\t\t *          ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],\n\t\t *        ],\n\t\t *        \"columns\": [\n\t\t *          { \"title\": \"Engine\" },\n\t\t *          { \"title\": \"Browser\" },\n\t\t *          { \"title\": \"Platform\" },\n\t\t *          { \"title\": \"Version\" },\n\t\t *          { \"title\": \"Grade\" }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using an array of objects as a data source (`data`)\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"data\": [\n\t\t *          {\n\t\t *            \"engine\":   \"Trident\",\n\t\t *            \"browser\":  \"Internet Explorer 4.0\",\n\t\t *            \"platform\": \"Win 95+\",\n\t\t *            \"version\":  4,\n\t\t *            \"grade\":    \"X\"\n\t\t *          },\n\t\t *          {\n\t\t *            \"engine\":   \"Trident\",\n\t\t *            \"browser\":  \"Internet Explorer 5.0\",\n\t\t *            \"platform\": \"Win 95+\",\n\t\t *            \"version\":  5,\n\t\t *            \"grade\":    \"C\"\n\t\t *          }\n\t\t *        ],\n\t\t *        \"columns\": [\n\t\t *          { \"title\": \"Engine\",   \"data\": \"engine\" },\n\t\t *          { \"title\": \"Browser\",  \"data\": \"browser\" },\n\t\t *          { \"title\": \"Platform\", \"data\": \"platform\" },\n\t\t *          { \"title\": \"Version\",  \"data\": \"version\" },\n\t\t *          { \"title\": \"Grade\",    \"data\": \"grade\" }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"aaData\": null,\n\t\n\t\n\t\t/**\n\t\t * If ordering is enabled, then DataTables will perform a first pass sort on\n\t\t * initialisation. You can define which column(s) the sort is performed\n\t\t * upon, and the sorting direction, with this variable. The `sorting` array\n\t\t * should contain an array for each column to be sorted initially containing\n\t\t * the column's index and a direction string ('asc' or 'desc').\n\t\t *  @type array\n\t\t *  @default [[0,'asc']]\n\t\t *\n\t\t *  @dtopt Option\n\t\t *  @name DataTable.defaults.order\n\t\t *\n\t\t *  @example\n\t\t *    // Sort by 3rd column first, and then 4th column\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"order\": [[2,'asc'], [3,'desc']]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *    // No initial sorting\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"order\": []\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"aaSorting\": [[0,'asc']],\n\t\n\t\n\t\t/**\n\t\t * This parameter is basically identical to the `sorting` parameter, but\n\t\t * cannot be overridden by user interaction with the table. What this means\n\t\t * is that you could have a column (visible or hidden) which the sorting\n\t\t * will always be forced on first - any sorting after that (from the user)\n\t\t * will then be performed as required. This can be useful for grouping rows\n\t\t * together.\n\t\t *  @type array\n\t\t *  @default null\n\t\t *\n\t\t *  @dtopt Option\n\t\t *  @name DataTable.defaults.orderFixed\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"orderFixed\": [[0,'asc']]\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"aaSortingFixed\": [],\n\t\n\t\n\t\t/**\n\t\t * DataTables can be instructed to load data to display in the table from a\n\t\t * Ajax source. This option defines how that Ajax call is made and where to.\n\t\t *\n\t\t * The `ajax` property has three different modes of operation, depending on\n\t\t * how it is defined. These are:\n\t\t *\n\t\t * * `string` - Set the URL from where the data should be loaded from.\n\t\t * * `object` - Define properties for `jQuery.ajax`.\n\t\t * * `function` - Custom data get function\n\t\t *\n\t\t * `string`\n\t\t * --------\n\t\t *\n\t\t * As a string, the `ajax` property simply defines the URL from which\n\t\t * DataTables will load data.\n\t\t *\n\t\t * `object`\n\t\t * --------\n\t\t *\n\t\t * As an object, the parameters in the object are passed to\n\t\t * [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control\n\t\t * of the Ajax request. DataTables has a number of default parameters which\n\t\t * you can override using this option. Please refer to the jQuery\n\t\t * documentation for a full description of the options available, although\n\t\t * the following parameters provide additional options in DataTables or\n\t\t * require special consideration:\n\t\t *\n\t\t * * `data` - As with jQuery, `data` can be provided as an object, but it\n\t\t *   can also be used as a function to manipulate the data DataTables sends\n\t\t *   to the server. The function takes a single parameter, an object of\n\t\t *   parameters with the values that DataTables has readied for sending. An\n\t\t *   object may be returned which will be merged into the DataTables\n\t\t *   defaults, or you can add the items to the object that was passed in and\n\t\t *   not return anything from the function. This supersedes `fnServerParams`\n\t\t *   from DataTables 1.9-.\n\t\t *\n\t\t * * `dataSrc` - By default DataTables will look for the property `data` (or\n\t\t *   `aaData` for compatibility with DataTables 1.9-) when obtaining data\n\t\t *   from an Ajax source or for server-side processing - this parameter\n\t\t *   allows that property to be changed. You can use Javascript dotted\n\t\t *   object notation to get a data source for multiple levels of nesting, or\n\t\t *   it my be used as a function. As a function it takes a single parameter,\n\t\t *   the JSON returned from the server, which can be manipulated as\n\t\t *   required, with the returned value being that used by DataTables as the\n\t\t *   data source for the table. This supersedes `sAjaxDataProp` from\n\t\t *   DataTables 1.9-.\n\t\t *\n\t\t * * `success` - Should not be overridden it is used internally in\n\t\t *   DataTables. To manipulate / transform the data returned by the server\n\t\t *   use `ajax.dataSrc`, or use `ajax` as a function (see below).\n\t\t *\n\t\t * `function`\n\t\t * ----------\n\t\t *\n\t\t * As a function, making the Ajax call is left up to yourself allowing\n\t\t * complete control of the Ajax request. Indeed, if desired, a method other\n\t\t * than Ajax could be used to obtain the required data, such as Web storage\n\t\t * or an AIR database.\n\t\t *\n\t\t * The function is given four parameters and no return is required. The\n\t\t * parameters are:\n\t\t *\n\t\t * 1. _object_ - Data to send to the server\n\t\t * 2. _function_ - Callback function that must be executed when the required\n\t\t *    data has been obtained. That data should be passed into the callback\n\t\t *    as the only parameter\n\t\t * 3. _object_ - DataTables settings object for the table\n\t\t *\n\t\t * Note that this supersedes `fnServerData` from DataTables 1.9-.\n\t\t *\n\t\t *  @type string|object|function\n\t\t *  @default null\n\t\t *\n\t\t *  @dtopt Option\n\t\t *  @name DataTable.defaults.ajax\n\t\t *  @since 1.10.0\n\t\t *\n\t\t * @example\n\t\t *   // Get JSON data from a file via Ajax.\n\t\t *   // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default).\n\t\t *   $('#example').dataTable( {\n\t\t *     \"ajax\": \"data.json\"\n\t\t *   } );\n\t\t *\n\t\t * @example\n\t\t *   // Get JSON data from a file via Ajax, using `dataSrc` to change\n\t\t *   // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`)\n\t\t *   $('#example').dataTable( {\n\t\t *     \"ajax\": {\n\t\t *       \"url\": \"data.json\",\n\t\t *       \"dataSrc\": \"tableData\"\n\t\t *     }\n\t\t *   } );\n\t\t *\n\t\t * @example\n\t\t *   // Get JSON data from a file via Ajax, using `dataSrc` to read data\n\t\t *   // from a plain array rather than an array in an object\n\t\t *   $('#example').dataTable( {\n\t\t *     \"ajax\": {\n\t\t *       \"url\": \"data.json\",\n\t\t *       \"dataSrc\": \"\"\n\t\t *     }\n\t\t *   } );\n\t\t *\n\t\t * @example\n\t\t *   // Manipulate the data returned from the server - add a link to data\n\t\t *   // (note this can, should, be done using `render` for the column - this\n\t\t *   // is just a simple example of how the data can be manipulated).\n\t\t *   $('#example').dataTable( {\n\t\t *     \"ajax\": {\n\t\t *       \"url\": \"data.json\",\n\t\t *       \"dataSrc\": function ( json ) {\n\t\t *         for ( var i=0, ien=json.length ; i<ien ; i++ ) {\n\t\t *           json[i][0] = '<a href=\"/message/'+json[i][0]+'>View message</a>';\n\t\t *         }\n\t\t *         return json;\n\t\t *       }\n\t\t *     }\n\t\t *   } );\n\t\t *\n\t\t * @example\n\t\t *   // Add data to the request\n\t\t *   $('#example').dataTable( {\n\t\t *     \"ajax\": {\n\t\t *       \"url\": \"data.json\",\n\t\t *       \"data\": function ( d ) {\n\t\t *         return {\n\t\t *           \"extra_search\": $('#extra').val()\n\t\t *         };\n\t\t *       }\n\t\t *     }\n\t\t *   } );\n\t\t *\n\t\t * @example\n\t\t *   // Send request as POST\n\t\t *   $('#example').dataTable( {\n\t\t *     \"ajax\": {\n\t\t *       \"url\": \"data.json\",\n\t\t *       \"type\": \"POST\"\n\t\t *     }\n\t\t *   } );\n\t\t *\n\t\t * @example\n\t\t *   // Get the data from localStorage (could interface with a form for\n\t\t *   // adding, editing and removing rows).\n\t\t *   $('#example').dataTable( {\n\t\t *     \"ajax\": function (data, callback, settings) {\n\t\t *       callback(\n\t\t *         JSON.parse( localStorage.getItem('dataTablesData') )\n\t\t *       );\n\t\t *     }\n\t\t *   } );\n\t\t */\n\t\t\"ajax\": null,\n\t\n\t\n\t\t/**\n\t\t * This parameter allows you to readily specify the entries in the length drop\n\t\t * down menu that DataTables shows when pagination is enabled. It can be\n\t\t * either a 1D array of options which will be used for both the displayed\n\t\t * option and the value, or a 2D array which will use the array in the first\n\t\t * position as the value, and the array in the second position as the\n\t\t * displayed options (useful for language strings such as 'All').\n\t\t *\n\t\t * Note that the `pageLength` property will be automatically set to the\n\t\t * first value given in this array, unless `pageLength` is also provided.\n\t\t *  @type array\n\t\t *  @default [ 10, 25, 50, 100 ]\n\t\t *\n\t\t *  @dtopt Option\n\t\t *  @name DataTable.defaults.lengthMenu\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"lengthMenu\": [[10, 25, 50, -1], [10, 25, 50, \"All\"]]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"aLengthMenu\": [ 10, 25, 50, 100 ],\n\t\n\t\n\t\t/**\n\t\t * The `columns` option in the initialisation parameter allows you to define\n\t\t * details about the way individual columns behave. For a full list of\n\t\t * column options that can be set, please see\n\t\t * {@link DataTable.defaults.column}. Note that if you use `columns` to\n\t\t * define your columns, you must have an entry in the array for every single\n\t\t * column that you have in your table (these can be null if you don't which\n\t\t * to specify any options).\n\t\t *  @member\n\t\t *\n\t\t *  @name DataTable.defaults.column\n\t\t */\n\t\t\"aoColumns\": null,\n\t\n\t\t/**\n\t\t * Very similar to `columns`, `columnDefs` allows you to target a specific\n\t\t * column, multiple columns, or all columns, using the `targets` property of\n\t\t * each object in the array. This allows great flexibility when creating\n\t\t * tables, as the `columnDefs` arrays can be of any length, targeting the\n\t\t * columns you specifically want. `columnDefs` may use any of the column\n\t\t * options available: {@link DataTable.defaults.column}, but it _must_\n\t\t * have `targets` defined in each object in the array. Values in the `targets`\n\t\t * array may be:\n\t\t *   <ul>\n\t\t *     <li>a string - class name will be matched on the TH for the column</li>\n\t\t *     <li>0 or a positive integer - column index counting from the left</li>\n\t\t *     <li>a negative integer - column index counting from the right</li>\n\t\t *     <li>the string \"_all\" - all columns (i.e. assign a default)</li>\n\t\t *   </ul>\n\t\t *  @member\n\t\t *\n\t\t *  @name DataTable.defaults.columnDefs\n\t\t */\n\t\t\"aoColumnDefs\": null,\n\t\n\t\n\t\t/**\n\t\t * Basically the same as `search`, this parameter defines the individual column\n\t\t * filtering state at initialisation time. The array must be of the same size\n\t\t * as the number of columns, and each element be an object with the parameters\n\t\t * `search` and `escapeRegex` (the latter is optional). 'null' is also\n\t\t * accepted and the default will be used.\n\t\t *  @type array\n\t\t *  @default []\n\t\t *\n\t\t *  @dtopt Option\n\t\t *  @name DataTable.defaults.searchCols\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"searchCols\": [\n\t\t *          null,\n\t\t *          { \"search\": \"My filter\" },\n\t\t *          null,\n\t\t *          { \"search\": \"^[0-9]\", \"escapeRegex\": false }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"aoSearchCols\": [],\n\t\n\t\n\t\t/**\n\t\t * An array of CSS classes that should be applied to displayed rows. This\n\t\t * array may be of any length, and DataTables will apply each class\n\t\t * sequentially, looping when required.\n\t\t *  @type array\n\t\t *  @default null <i>Will take the values determined by the `oClasses.stripe*`\n\t\t *    options</i>\n\t\t *\n\t\t *  @dtopt Option\n\t\t *  @name DataTable.defaults.stripeClasses\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stripeClasses\": [ 'strip1', 'strip2', 'strip3' ]\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"asStripeClasses\": null,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable automatic column width calculation. This can be disabled\n\t\t * as an optimisation (it takes some time to calculate the widths) if the\n\t\t * tables widths are passed in using `columns`.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.autoWidth\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"autoWidth\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bAutoWidth\": true,\n\t\n\t\n\t\t/**\n\t\t * Deferred rendering can provide DataTables with a huge speed boost when you\n\t\t * are using an Ajax or JS data source for the table. This option, when set to\n\t\t * true, will cause DataTables to defer the creation of the table elements for\n\t\t * each row until they are needed for a draw - saving a significant amount of\n\t\t * time.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.deferRender\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"ajax\": \"sources/arrays.txt\",\n\t\t *        \"deferRender\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bDeferRender\": false,\n\t\n\t\n\t\t/**\n\t\t * Replace a DataTable which matches the given selector and replace it with\n\t\t * one which has the properties of the new initialisation object passed. If no\n\t\t * table matches the selector, then the new DataTable will be constructed as\n\t\t * per normal.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.destroy\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"srollY\": \"200px\",\n\t\t *        \"paginate\": false\n\t\t *      } );\n\t\t *\n\t\t *      // Some time later....\n\t\t *      $('#example').dataTable( {\n\t\t *        \"filter\": false,\n\t\t *        \"destroy\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bDestroy\": false,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable filtering of data. Filtering in DataTables is \"smart\" in\n\t\t * that it allows the end user to input multiple words (space separated) and\n\t\t * will match a row containing those words, even if not in the order that was\n\t\t * specified (this allow matching across multiple columns). Note that if you\n\t\t * wish to use filtering in DataTables this must remain 'true' - to remove the\n\t\t * default filtering input box and retain filtering abilities, please use\n\t\t * {@link DataTable.defaults.dom}.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.searching\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"searching\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bFilter\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable the table information display. This shows information\n\t\t * about the data that is currently visible on the page, including information\n\t\t * about filtered data if that action is being performed.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.info\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"info\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bInfo\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable jQuery UI ThemeRoller support (required as ThemeRoller requires some\n\t\t * slightly different and additional mark-up from what DataTables has\n\t\t * traditionally used).\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.jQueryUI\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"jQueryUI\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bJQueryUI\": false,\n\t\n\t\n\t\t/**\n\t\t * Allows the end user to select the size of a formatted page from a select\n\t\t * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`).\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.lengthChange\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"lengthChange\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bLengthChange\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable pagination.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.paging\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"paging\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bPaginate\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable the display of a 'processing' indicator when the table is\n\t\t * being processed (e.g. a sort). This is particularly useful for tables with\n\t\t * large amounts of data where it can take a noticeable amount of time to sort\n\t\t * the entries.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.processing\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"processing\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bProcessing\": false,\n\t\n\t\n\t\t/**\n\t\t * Retrieve the DataTables object for the given selector. Note that if the\n\t\t * table has already been initialised, this parameter will cause DataTables\n\t\t * to simply return the object that has already been set up - it will not take\n\t\t * account of any changes you might have made to the initialisation object\n\t\t * passed to DataTables (setting this parameter to true is an acknowledgement\n\t\t * that you understand this). `destroy` can be used to reinitialise a table if\n\t\t * you need.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.retrieve\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      initTable();\n\t\t *      tableActions();\n\t\t *    } );\n\t\t *\n\t\t *    function initTable ()\n\t\t *    {\n\t\t *      return $('#example').dataTable( {\n\t\t *        \"scrollY\": \"200px\",\n\t\t *        \"paginate\": false,\n\t\t *        \"retrieve\": true\n\t\t *      } );\n\t\t *    }\n\t\t *\n\t\t *    function tableActions ()\n\t\t *    {\n\t\t *      var table = initTable();\n\t\t *      // perform API operations with oTable\n\t\t *    }\n\t\t */\n\t\t\"bRetrieve\": false,\n\t\n\t\n\t\t/**\n\t\t * When vertical (y) scrolling is enabled, DataTables will force the height of\n\t\t * the table's viewport to the given height at all times (useful for layout).\n\t\t * However, this can look odd when filtering data down to a small data set,\n\t\t * and the footer is left \"floating\" further down. This parameter (when\n\t\t * enabled) will cause DataTables to collapse the table's viewport down when\n\t\t * the result set will fit within the given Y height.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.scrollCollapse\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"scrollY\": \"200\",\n\t\t *        \"scrollCollapse\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bScrollCollapse\": false,\n\t\n\t\n\t\t/**\n\t\t * Configure DataTables to use server-side processing. Note that the\n\t\t * `ajax` parameter must also be given in order to give DataTables a\n\t\t * source to obtain the required data for each draw.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @dtopt Server-side\n\t\t *  @name DataTable.defaults.serverSide\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"serverSide\": true,\n\t\t *        \"ajax\": \"xhr.php\"\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bServerSide\": false,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable sorting of columns. Sorting of individual columns can be\n\t\t * disabled by the `sortable` option for each column.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.ordering\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"ordering\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bSort\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable or display DataTables' ability to sort multiple columns at the\n\t\t * same time (activated by shift-click by the user).\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.orderMulti\n\t\t *\n\t\t *  @example\n\t\t *    // Disable multiple column sorting ability\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"orderMulti\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bSortMulti\": true,\n\t\n\t\n\t\t/**\n\t\t * Allows control over whether DataTables should use the top (true) unique\n\t\t * cell that is found for a single column, or the bottom (false - default).\n\t\t * This is useful when using complex headers.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.orderCellsTop\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"orderCellsTop\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bSortCellsTop\": false,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable the addition of the classes `sorting\\_1`, `sorting\\_2` and\n\t\t * `sorting\\_3` to the columns which are currently being sorted on. This is\n\t\t * presented as a feature switch as it can increase processing time (while\n\t\t * classes are removed and added) so for large data sets you might want to\n\t\t * turn this off.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.orderClasses\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"orderClasses\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bSortClasses\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable state saving. When enabled HTML5 `localStorage` will be\n\t\t * used to save table display information such as pagination information,\n\t\t * display length, filtering and sorting. As such when the end user reloads\n\t\t * the page the display display will match what thy had previously set up.\n\t\t *\n\t\t * Due to the use of `localStorage` the default state saving is not supported\n\t\t * in IE6 or 7. If state saving is required in those browsers, use\n\t\t * `stateSaveCallback` to provide a storage solution such as cookies.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.stateSave\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateSave\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bStateSave\": false,\n\t\n\t\n\t\t/**\n\t\t * This function is called when a TR element is created (and all TD child\n\t\t * elements have been inserted), or registered if using a DOM source, allowing\n\t\t * manipulation of the TR element (adding classes etc).\n\t\t *  @type function\n\t\t *  @param {node} row \"TR\" element for the current row\n\t\t *  @param {array} data Raw data array for this row\n\t\t *  @param {int} dataIndex The index of this row in the internal aoData array\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.createdRow\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"createdRow\": function( row, data, dataIndex ) {\n\t\t *          // Bold the grade for all 'A' grade browsers\n\t\t *          if ( data[4] == \"A\" )\n\t\t *          {\n\t\t *            $('td:eq(4)', row).html( '<b>A</b>' );\n\t\t *          }\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnCreatedRow\": null,\n\t\n\t\n\t\t/**\n\t\t * This function is called on every 'draw' event, and allows you to\n\t\t * dynamically modify any aspect you want about the created DOM.\n\t\t *  @type function\n\t\t *  @param {object} settings DataTables settings object\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.drawCallback\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"drawCallback\": function( settings ) {\n\t\t *          alert( 'DataTables has redrawn the table' );\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnDrawCallback\": null,\n\t\n\t\n\t\t/**\n\t\t * Identical to fnHeaderCallback() but for the table footer this function\n\t\t * allows you to modify the table footer on every 'draw' event.\n\t\t *  @type function\n\t\t *  @param {node} foot \"TR\" element for the footer\n\t\t *  @param {array} data Full table data (as derived from the original HTML)\n\t\t *  @param {int} start Index for the current display starting point in the\n\t\t *    display array\n\t\t *  @param {int} end Index for the current display ending point in the\n\t\t *    display array\n\t\t *  @param {array int} display Index array to translate the visual position\n\t\t *    to the full data array\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.footerCallback\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"footerCallback\": function( tfoot, data, start, end, display ) {\n\t\t *          tfoot.getElementsByTagName('th')[0].innerHTML = \"Starting index is \"+start;\n\t\t *        }\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"fnFooterCallback\": null,\n\t\n\t\n\t\t/**\n\t\t * When rendering large numbers in the information element for the table\n\t\t * (i.e. \"Showing 1 to 10 of 57 entries\") DataTables will render large numbers\n\t\t * to have a comma separator for the 'thousands' units (e.g. 1 million is\n\t\t * rendered as \"1,000,000\") to help readability for the end user. This\n\t\t * function will override the default method DataTables uses.\n\t\t *  @type function\n\t\t *  @member\n\t\t *  @param {int} toFormat number to be formatted\n\t\t *  @returns {string} formatted string for DataTables to show the number\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.formatNumber\n\t\t *\n\t\t *  @example\n\t\t *    // Format a number using a single quote for the separator (note that\n\t\t *    // this can also be done with the language.thousands option)\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"formatNumber\": function ( toFormat ) {\n\t\t *          return toFormat.toString().replace(\n\t\t *            /\\B(?=(\\d{3})+(?!\\d))/g, \"'\"\n\t\t *          );\n\t\t *        };\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnFormatNumber\": function ( toFormat ) {\n\t\t\treturn toFormat.toString().replace(\n\t\t\t\t/\\B(?=(\\d{3})+(?!\\d))/g,\n\t\t\t\tthis.oLanguage.sThousands\n\t\t\t);\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * This function is called on every 'draw' event, and allows you to\n\t\t * dynamically modify the header row. This can be used to calculate and\n\t\t * display useful information about the table.\n\t\t *  @type function\n\t\t *  @param {node} head \"TR\" element for the header\n\t\t *  @param {array} data Full table data (as derived from the original HTML)\n\t\t *  @param {int} start Index for the current display starting point in the\n\t\t *    display array\n\t\t *  @param {int} end Index for the current display ending point in the\n\t\t *    display array\n\t\t *  @param {array int} display Index array to translate the visual position\n\t\t *    to the full data array\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.headerCallback\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"fheaderCallback\": function( head, data, start, end, display ) {\n\t\t *          head.getElementsByTagName('th')[0].innerHTML = \"Displaying \"+(end-start)+\" records\";\n\t\t *        }\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"fnHeaderCallback\": null,\n\t\n\t\n\t\t/**\n\t\t * The information element can be used to convey information about the current\n\t\t * state of the table. Although the internationalisation options presented by\n\t\t * DataTables are quite capable of dealing with most customisations, there may\n\t\t * be times where you wish to customise the string further. This callback\n\t\t * allows you to do exactly that.\n\t\t *  @type function\n\t\t *  @param {object} oSettings DataTables settings object\n\t\t *  @param {int} start Starting position in data for the draw\n\t\t *  @param {int} end End position in data for the draw\n\t\t *  @param {int} max Total number of rows in the table (regardless of\n\t\t *    filtering)\n\t\t *  @param {int} total Total number of rows in the data set, after filtering\n\t\t *  @param {string} pre The string that DataTables has formatted using it's\n\t\t *    own rules\n\t\t *  @returns {string} The string to be displayed in the information element.\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.infoCallback\n\t\t *\n\t\t *  @example\n\t\t *    $('#example').dataTable( {\n\t\t *      \"infoCallback\": function( settings, start, end, max, total, pre ) {\n\t\t *        return start +\" to \"+ end;\n\t\t *      }\n\t\t *    } );\n\t\t */\n\t\t\"fnInfoCallback\": null,\n\t\n\t\n\t\t/**\n\t\t * Called when the table has been initialised. Normally DataTables will\n\t\t * initialise sequentially and there will be no need for this function,\n\t\t * however, this does not hold true when using external language information\n\t\t * since that is obtained using an async XHR call.\n\t\t *  @type function\n\t\t *  @param {object} settings DataTables settings object\n\t\t *  @param {object} json The JSON object request from the server - only\n\t\t *    present if client-side Ajax sourced data is used\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.initComplete\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"initComplete\": function(settings, json) {\n\t\t *          alert( 'DataTables has finished its initialisation.' );\n\t\t *        }\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"fnInitComplete\": null,\n\t\n\t\n\t\t/**\n\t\t * Called at the very start of each table draw and can be used to cancel the\n\t\t * draw by returning false, any other return (including undefined) results in\n\t\t * the full draw occurring).\n\t\t *  @type function\n\t\t *  @param {object} settings DataTables settings object\n\t\t *  @returns {boolean} False will cancel the draw, anything else (including no\n\t\t *    return) will allow it to complete.\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.preDrawCallback\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"preDrawCallback\": function( settings ) {\n\t\t *          if ( $('#test').val() == 1 ) {\n\t\t *            return false;\n\t\t *          }\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnPreDrawCallback\": null,\n\t\n\t\n\t\t/**\n\t\t * This function allows you to 'post process' each row after it have been\n\t\t * generated for each table draw, but before it is rendered on screen. This\n\t\t * function might be used for setting the row class name etc.\n\t\t *  @type function\n\t\t *  @param {node} row \"TR\" element for the current row\n\t\t *  @param {array} data Raw data array for this row\n\t\t *  @param {int} displayIndex The display index for the current table draw\n\t\t *  @param {int} displayIndexFull The index of the data in the full list of\n\t\t *    rows (after filtering)\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.rowCallback\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"rowCallback\": function( row, data, displayIndex, displayIndexFull ) {\n\t\t *          // Bold the grade for all 'A' grade browsers\n\t\t *          if ( data[4] == \"A\" ) {\n\t\t *            $('td:eq(4)', row).html( '<b>A</b>' );\n\t\t *          }\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnRowCallback\": null,\n\t\n\t\n\t\t/**\n\t\t * __Deprecated__ The functionality provided by this parameter has now been\n\t\t * superseded by that provided through `ajax`, which should be used instead.\n\t\t *\n\t\t * This parameter allows you to override the default function which obtains\n\t\t * the data from the server so something more suitable for your application.\n\t\t * For example you could use POST data, or pull information from a Gears or\n\t\t * AIR database.\n\t\t *  @type function\n\t\t *  @member\n\t\t *  @param {string} source HTTP source to obtain the data from (`ajax`)\n\t\t *  @param {array} data A key/value pair object containing the data to send\n\t\t *    to the server\n\t\t *  @param {function} callback to be called on completion of the data get\n\t\t *    process that will draw the data on the page.\n\t\t *  @param {object} settings DataTables settings object\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @dtopt Server-side\n\t\t *  @name DataTable.defaults.serverData\n\t\t *\n\t\t *  @deprecated 1.10. Please use `ajax` for this functionality now.\n\t\t */\n\t\t\"fnServerData\": null,\n\t\n\t\n\t\t/**\n\t\t * __Deprecated__ The functionality provided by this parameter has now been\n\t\t * superseded by that provided through `ajax`, which should be used instead.\n\t\t *\n\t\t *  It is often useful to send extra data to the server when making an Ajax\n\t\t * request - for example custom filtering information, and this callback\n\t\t * function makes it trivial to send extra information to the server. The\n\t\t * passed in parameter is the data set that has been constructed by\n\t\t * DataTables, and you can add to this or modify it as you require.\n\t\t *  @type function\n\t\t *  @param {array} data Data array (array of objects which are name/value\n\t\t *    pairs) that has been constructed by DataTables and will be sent to the\n\t\t *    server. In the case of Ajax sourced data with server-side processing\n\t\t *    this will be an empty array, for server-side processing there will be a\n\t\t *    significant number of parameters!\n\t\t *  @returns {undefined} Ensure that you modify the data array passed in,\n\t\t *    as this is passed by reference.\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @dtopt Server-side\n\t\t *  @name DataTable.defaults.serverParams\n\t\t *\n\t\t *  @deprecated 1.10. Please use `ajax` for this functionality now.\n\t\t */\n\t\t\"fnServerParams\": null,\n\t\n\t\n\t\t/**\n\t\t * Load the table state. With this function you can define from where, and how, the\n\t\t * state of a table is loaded. By default DataTables will load from `localStorage`\n\t\t * but you might wish to use a server-side database or cookies.\n\t\t *  @type function\n\t\t *  @member\n\t\t *  @param {object} settings DataTables settings object\n\t\t *  @return {object} The DataTables state object to be loaded\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.stateLoadCallback\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateSave\": true,\n\t\t *        \"stateLoadCallback\": function (settings) {\n\t\t *          var o;\n\t\t *\n\t\t *          // Send an Ajax request to the server to get the data. Note that\n\t\t *          // this is a synchronous request.\n\t\t *          $.ajax( {\n\t\t *            \"url\": \"/state_load\",\n\t\t *            \"async\": false,\n\t\t *            \"dataType\": \"json\",\n\t\t *            \"success\": function (json) {\n\t\t *              o = json;\n\t\t *            }\n\t\t *          } );\n\t\t *\n\t\t *          return o;\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnStateLoadCallback\": function ( settings ) {\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(\n\t\t\t\t\t(settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem(\n\t\t\t\t\t\t'DataTables_'+settings.sInstance+'_'+location.pathname\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} catch (e) {}\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * Callback which allows modification of the saved state prior to loading that state.\n\t\t * This callback is called when the table is loading state from the stored data, but\n\t\t * prior to the settings object being modified by the saved state. Note that for\n\t\t * plug-in authors, you should use the `stateLoadParams` event to load parameters for\n\t\t * a plug-in.\n\t\t *  @type function\n\t\t *  @param {object} settings DataTables settings object\n\t\t *  @param {object} data The state object that is to be loaded\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.stateLoadParams\n\t\t *\n\t\t *  @example\n\t\t *    // Remove a saved filter, so filtering is never loaded\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateSave\": true,\n\t\t *        \"stateLoadParams\": function (settings, data) {\n\t\t *          data.oSearch.sSearch = \"\";\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Disallow state loading by returning false\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateSave\": true,\n\t\t *        \"stateLoadParams\": function (settings, data) {\n\t\t *          return false;\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnStateLoadParams\": null,\n\t\n\t\n\t\t/**\n\t\t * Callback that is called when the state has been loaded from the state saving method\n\t\t * and the DataTables settings object has been modified as a result of the loaded state.\n\t\t *  @type function\n\t\t *  @param {object} settings DataTables settings object\n\t\t *  @param {object} data The state object that was loaded\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.stateLoaded\n\t\t *\n\t\t *  @example\n\t\t *    // Show an alert with the filtering value that was saved\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateSave\": true,\n\t\t *        \"stateLoaded\": function (settings, data) {\n\t\t *          alert( 'Saved filter was: '+data.oSearch.sSearch );\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnStateLoaded\": null,\n\t\n\t\n\t\t/**\n\t\t * Save the table state. This function allows you to define where and how the state\n\t\t * information for the table is stored By default DataTables will use `localStorage`\n\t\t * but you might wish to use a server-side database or cookies.\n\t\t *  @type function\n\t\t *  @member\n\t\t *  @param {object} settings DataTables settings object\n\t\t *  @param {object} data The state object to be saved\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.stateSaveCallback\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateSave\": true,\n\t\t *        \"stateSaveCallback\": function (settings, data) {\n\t\t *          // Send an Ajax request to the server with the state object\n\t\t *          $.ajax( {\n\t\t *            \"url\": \"/state_save\",\n\t\t *            \"data\": data,\n\t\t *            \"dataType\": \"json\",\n\t\t *            \"method\": \"POST\"\n\t\t *            \"success\": function () {}\n\t\t *          } );\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnStateSaveCallback\": function ( settings, data ) {\n\t\t\ttry {\n\t\t\t\t(settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(\n\t\t\t\t\t'DataTables_'+settings.sInstance+'_'+location.pathname,\n\t\t\t\t\tJSON.stringify( data )\n\t\t\t\t);\n\t\t\t} catch (e) {}\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * Callback which allows modification of the state to be saved. Called when the table\n\t\t * has changed state a new state save is required. This method allows modification of\n\t\t * the state saving object prior to actually doing the save, including addition or\n\t\t * other state properties or modification. Note that for plug-in authors, you should\n\t\t * use the `stateSaveParams` event to save parameters for a plug-in.\n\t\t *  @type function\n\t\t *  @param {object} settings DataTables settings object\n\t\t *  @param {object} data The state object to be saved\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.stateSaveParams\n\t\t *\n\t\t *  @example\n\t\t *    // Remove a saved filter, so filtering is never saved\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateSave\": true,\n\t\t *        \"stateSaveParams\": function (settings, data) {\n\t\t *          data.oSearch.sSearch = \"\";\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnStateSaveParams\": null,\n\t\n\t\n\t\t/**\n\t\t * Duration for which the saved state information is considered valid. After this period\n\t\t * has elapsed the state will be returned to the default.\n\t\t * Value is given in seconds.\n\t\t *  @type int\n\t\t *  @default 7200 <i>(2 hours)</i>\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.stateDuration\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateDuration\": 60*60*24; // 1 day\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"iStateDuration\": 7200,\n\t\n\t\n\t\t/**\n\t\t * When enabled DataTables will not make a request to the server for the first\n\t\t * page draw - rather it will use the data already on the page (no sorting etc\n\t\t * will be applied to it), thus saving on an XHR at load time. `deferLoading`\n\t\t * is used to indicate that deferred loading is required, but it is also used\n\t\t * to tell DataTables how many records there are in the full table (allowing\n\t\t * the information element and pagination to be displayed correctly). In the case\n\t\t * where a filtering is applied to the table on initial load, this can be\n\t\t * indicated by giving the parameter as an array, where the first element is\n\t\t * the number of records available after filtering and the second element is the\n\t\t * number of records without filtering (allowing the table information element\n\t\t * to be shown correctly).\n\t\t *  @type int | array\n\t\t *  @default null\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.deferLoading\n\t\t *\n\t\t *  @example\n\t\t *    // 57 records available in the table, no filtering applied\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"serverSide\": true,\n\t\t *        \"ajax\": \"scripts/server_processing.php\",\n\t\t *        \"deferLoading\": 57\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // 57 records after filtering, 100 without filtering (an initial filter applied)\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"serverSide\": true,\n\t\t *        \"ajax\": \"scripts/server_processing.php\",\n\t\t *        \"deferLoading\": [ 57, 100 ],\n\t\t *        \"search\": {\n\t\t *          \"search\": \"my_filter\"\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"iDeferLoading\": null,\n\t\n\t\n\t\t/**\n\t\t * Number of rows to display on a single page when using pagination. If\n\t\t * feature enabled (`lengthChange`) then the end user will be able to override\n\t\t * this to a custom setting using a pop-up menu.\n\t\t *  @type int\n\t\t *  @default 10\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.pageLength\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"pageLength\": 50\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"iDisplayLength\": 10,\n\t\n\t\n\t\t/**\n\t\t * Define the starting point for data display when using DataTables with\n\t\t * pagination. Note that this parameter is the number of records, rather than\n\t\t * the page number, so if you have 10 records per page and want to start on\n\t\t * the third page, it should be \"20\".\n\t\t *  @type int\n\t\t *  @default 0\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.displayStart\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"displayStart\": 20\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"iDisplayStart\": 0,\n\t\n\t\n\t\t/**\n\t\t * By default DataTables allows keyboard navigation of the table (sorting, paging,\n\t\t * and filtering) by adding a `tabindex` attribute to the required elements. This\n\t\t * allows you to tab through the controls and press the enter key to activate them.\n\t\t * The tabindex is default 0, meaning that the tab follows the flow of the document.\n\t\t * You can overrule this using this parameter if you wish. Use a value of -1 to\n\t\t * disable built-in keyboard navigation.\n\t\t *  @type int\n\t\t *  @default 0\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.tabIndex\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"tabIndex\": 1\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"iTabIndex\": 0,\n\t\n\t\n\t\t/**\n\t\t * Classes that DataTables assigns to the various components and features\n\t\t * that it adds to the HTML table. This allows classes to be configured\n\t\t * during initialisation in addition to through the static\n\t\t * {@link DataTable.ext.oStdClasses} object).\n\t\t *  @namespace\n\t\t *  @name DataTable.defaults.classes\n\t\t */\n\t\t\"oClasses\": {},\n\t\n\t\n\t\t/**\n\t\t * All strings that DataTables uses in the user interface that it creates\n\t\t * are defined in this object, allowing you to modified them individually or\n\t\t * completely replace them all as required.\n\t\t *  @namespace\n\t\t *  @name DataTable.defaults.language\n\t\t */\n\t\t\"oLanguage\": {\n\t\t\t/**\n\t\t\t * Strings that are used for WAI-ARIA labels and controls only (these are not\n\t\t\t * actually visible on the page, but will be read by screenreaders, and thus\n\t\t\t * must be internationalised as well).\n\t\t\t *  @namespace\n\t\t\t *  @name DataTable.defaults.language.aria\n\t\t\t */\n\t\t\t\"oAria\": {\n\t\t\t\t/**\n\t\t\t\t * ARIA label that is added to the table headers when the column may be\n\t\t\t\t * sorted ascending by activing the column (click or return when focused).\n\t\t\t\t * Note that the column header is prefixed to this string.\n\t\t\t\t *  @type string\n\t\t\t\t *  @default : activate to sort column ascending\n\t\t\t\t *\n\t\t\t\t *  @dtopt Language\n\t\t\t\t *  @name DataTable.defaults.language.aria.sortAscending\n\t\t\t\t *\n\t\t\t\t *  @example\n\t\t\t\t *    $(document).ready( function() {\n\t\t\t\t *      $('#example').dataTable( {\n\t\t\t\t *        \"language\": {\n\t\t\t\t *          \"aria\": {\n\t\t\t\t *            \"sortAscending\": \" - click/return to sort ascending\"\n\t\t\t\t *          }\n\t\t\t\t *        }\n\t\t\t\t *      } );\n\t\t\t\t *    } );\n\t\t\t\t */\n\t\t\t\t\"sSortAscending\": \": activate to sort column ascending\",\n\t\n\t\t\t\t/**\n\t\t\t\t * ARIA label that is added to the table headers when the column may be\n\t\t\t\t * sorted descending by activing the column (click or return when focused).\n\t\t\t\t * Note that the column header is prefixed to this string.\n\t\t\t\t *  @type string\n\t\t\t\t *  @default : activate to sort column ascending\n\t\t\t\t *\n\t\t\t\t *  @dtopt Language\n\t\t\t\t *  @name DataTable.defaults.language.aria.sortDescending\n\t\t\t\t *\n\t\t\t\t *  @example\n\t\t\t\t *    $(document).ready( function() {\n\t\t\t\t *      $('#example').dataTable( {\n\t\t\t\t *        \"language\": {\n\t\t\t\t *          \"aria\": {\n\t\t\t\t *            \"sortDescending\": \" - click/return to sort descending\"\n\t\t\t\t *          }\n\t\t\t\t *        }\n\t\t\t\t *      } );\n\t\t\t\t *    } );\n\t\t\t\t */\n\t\t\t\t\"sSortDescending\": \": activate to sort column descending\"\n\t\t\t},\n\t\n\t\t\t/**\n\t\t\t * Pagination string used by DataTables for the built-in pagination\n\t\t\t * control types.\n\t\t\t *  @namespace\n\t\t\t *  @name DataTable.defaults.language.paginate\n\t\t\t */\n\t\t\t\"oPaginate\": {\n\t\t\t\t/**\n\t\t\t\t * Text to use when using the 'full_numbers' type of pagination for the\n\t\t\t\t * button to take the user to the first page.\n\t\t\t\t *  @type string\n\t\t\t\t *  @default First\n\t\t\t\t *\n\t\t\t\t *  @dtopt Language\n\t\t\t\t *  @name DataTable.defaults.language.paginate.first\n\t\t\t\t *\n\t\t\t\t *  @example\n\t\t\t\t *    $(document).ready( function() {\n\t\t\t\t *      $('#example').dataTable( {\n\t\t\t\t *        \"language\": {\n\t\t\t\t *          \"paginate\": {\n\t\t\t\t *            \"first\": \"First page\"\n\t\t\t\t *          }\n\t\t\t\t *        }\n\t\t\t\t *      } );\n\t\t\t\t *    } );\n\t\t\t\t */\n\t\t\t\t\"sFirst\": \"First\",\n\t\n\t\n\t\t\t\t/**\n\t\t\t\t * Text to use when using the 'full_numbers' type of pagination for the\n\t\t\t\t * button to take the user to the last page.\n\t\t\t\t *  @type string\n\t\t\t\t *  @default Last\n\t\t\t\t *\n\t\t\t\t *  @dtopt Language\n\t\t\t\t *  @name DataTable.defaults.language.paginate.last\n\t\t\t\t *\n\t\t\t\t *  @example\n\t\t\t\t *    $(document).ready( function() {\n\t\t\t\t *      $('#example').dataTable( {\n\t\t\t\t *        \"language\": {\n\t\t\t\t *          \"paginate\": {\n\t\t\t\t *            \"last\": \"Last page\"\n\t\t\t\t *          }\n\t\t\t\t *        }\n\t\t\t\t *      } );\n\t\t\t\t *    } );\n\t\t\t\t */\n\t\t\t\t\"sLast\": \"Last\",\n\t\n\t\n\t\t\t\t/**\n\t\t\t\t * Text to use for the 'next' pagination button (to take the user to the\n\t\t\t\t * next page).\n\t\t\t\t *  @type string\n\t\t\t\t *  @default Next\n\t\t\t\t *\n\t\t\t\t *  @dtopt Language\n\t\t\t\t *  @name DataTable.defaults.language.paginate.next\n\t\t\t\t *\n\t\t\t\t *  @example\n\t\t\t\t *    $(document).ready( function() {\n\t\t\t\t *      $('#example').dataTable( {\n\t\t\t\t *        \"language\": {\n\t\t\t\t *          \"paginate\": {\n\t\t\t\t *            \"next\": \"Next page\"\n\t\t\t\t *          }\n\t\t\t\t *        }\n\t\t\t\t *      } );\n\t\t\t\t *    } );\n\t\t\t\t */\n\t\t\t\t\"sNext\": \"Next\",\n\t\n\t\n\t\t\t\t/**\n\t\t\t\t * Text to use for the 'previous' pagination button (to take the user to\n\t\t\t\t * the previous page).\n\t\t\t\t *  @type string\n\t\t\t\t *  @default Previous\n\t\t\t\t *\n\t\t\t\t *  @dtopt Language\n\t\t\t\t *  @name DataTable.defaults.language.paginate.previous\n\t\t\t\t *\n\t\t\t\t *  @example\n\t\t\t\t *    $(document).ready( function() {\n\t\t\t\t *      $('#example').dataTable( {\n\t\t\t\t *        \"language\": {\n\t\t\t\t *          \"paginate\": {\n\t\t\t\t *            \"previous\": \"Previous page\"\n\t\t\t\t *          }\n\t\t\t\t *        }\n\t\t\t\t *      } );\n\t\t\t\t *    } );\n\t\t\t\t */\n\t\t\t\t\"sPrevious\": \"Previous\"\n\t\t\t},\n\t\n\t\t\t/**\n\t\t\t * This string is shown in preference to `zeroRecords` when the table is\n\t\t\t * empty of data (regardless of filtering). Note that this is an optional\n\t\t\t * parameter - if it is not given, the value of `zeroRecords` will be used\n\t\t\t * instead (either the default or given value).\n\t\t\t *  @type string\n\t\t\t *  @default No data available in table\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.emptyTable\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"emptyTable\": \"No data available in table\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sEmptyTable\": \"No data available in table\",\n\t\n\t\n\t\t\t/**\n\t\t\t * This string gives information to the end user about the information\n\t\t\t * that is current on display on the page. The following tokens can be\n\t\t\t * used in the string and will be dynamically replaced as the table\n\t\t\t * display updates. This tokens can be placed anywhere in the string, or\n\t\t\t * removed as needed by the language requires:\n\t\t\t *\n\t\t\t * * `\\_START\\_` - Display index of the first record on the current page\n\t\t\t * * `\\_END\\_` - Display index of the last record on the current page\n\t\t\t * * `\\_TOTAL\\_` - Number of records in the table after filtering\n\t\t\t * * `\\_MAX\\_` - Number of records in the table without filtering\n\t\t\t * * `\\_PAGE\\_` - Current page number\n\t\t\t * * `\\_PAGES\\_` - Total number of pages of data in the table\n\t\t\t *\n\t\t\t *  @type string\n\t\t\t *  @default Showing _START_ to _END_ of _TOTAL_ entries\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.info\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"info\": \"Showing page _PAGE_ of _PAGES_\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sInfo\": \"Showing _START_ to _END_ of _TOTAL_ entries\",\n\t\n\t\n\t\t\t/**\n\t\t\t * Display information string for when the table is empty. Typically the\n\t\t\t * format of this string should match `info`.\n\t\t\t *  @type string\n\t\t\t *  @default Showing 0 to 0 of 0 entries\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.infoEmpty\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"infoEmpty\": \"No entries to show\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sInfoEmpty\": \"Showing 0 to 0 of 0 entries\",\n\t\n\t\n\t\t\t/**\n\t\t\t * When a user filters the information in a table, this string is appended\n\t\t\t * to the information (`info`) to give an idea of how strong the filtering\n\t\t\t * is. The variable _MAX_ is dynamically updated.\n\t\t\t *  @type string\n\t\t\t *  @default (filtered from _MAX_ total entries)\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.infoFiltered\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"infoFiltered\": \" - filtering from _MAX_ records\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sInfoFiltered\": \"(filtered from _MAX_ total entries)\",\n\t\n\t\n\t\t\t/**\n\t\t\t * If can be useful to append extra information to the info string at times,\n\t\t\t * and this variable does exactly that. This information will be appended to\n\t\t\t * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are\n\t\t\t * being used) at all times.\n\t\t\t *  @type string\n\t\t\t *  @default <i>Empty string</i>\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.infoPostFix\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"infoPostFix\": \"All records shown are derived from real information.\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sInfoPostFix\": \"\",\n\t\n\t\n\t\t\t/**\n\t\t\t * This decimal place operator is a little different from the other\n\t\t\t * language options since DataTables doesn't output floating point\n\t\t\t * numbers, so it won't ever use this for display of a number. Rather,\n\t\t\t * what this parameter does is modify the sort methods of the table so\n\t\t\t * that numbers which are in a format which has a character other than\n\t\t\t * a period (`.`) as a decimal place will be sorted numerically.\n\t\t\t *\n\t\t\t * Note that numbers with different decimal places cannot be shown in\n\t\t\t * the same table and still be sortable, the table must be consistent.\n\t\t\t * However, multiple different tables on the page can use different\n\t\t\t * decimal place characters.\n\t\t\t *  @type string\n\t\t\t *  @default \n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.decimal\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"decimal\": \",\"\n\t\t\t *          \"thousands\": \".\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sDecimal\": \"\",\n\t\n\t\n\t\t\t/**\n\t\t\t * DataTables has a build in number formatter (`formatNumber`) which is\n\t\t\t * used to format large numbers that are used in the table information.\n\t\t\t * By default a comma is used, but this can be trivially changed to any\n\t\t\t * character you wish with this parameter.\n\t\t\t *  @type string\n\t\t\t *  @default ,\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.thousands\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"thousands\": \"'\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sThousands\": \",\",\n\t\n\t\n\t\t\t/**\n\t\t\t * Detail the action that will be taken when the drop down menu for the\n\t\t\t * pagination length option is changed. The '_MENU_' variable is replaced\n\t\t\t * with a default select list of 10, 25, 50 and 100, and can be replaced\n\t\t\t * with a custom select box if required.\n\t\t\t *  @type string\n\t\t\t *  @default Show _MENU_ entries\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.lengthMenu\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    // Language change only\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"lengthMenu\": \"Display _MENU_ records\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    // Language and options change\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"lengthMenu\": 'Display <select>'+\n\t\t\t *            '<option value=\"10\">10</option>'+\n\t\t\t *            '<option value=\"20\">20</option>'+\n\t\t\t *            '<option value=\"30\">30</option>'+\n\t\t\t *            '<option value=\"40\">40</option>'+\n\t\t\t *            '<option value=\"50\">50</option>'+\n\t\t\t *            '<option value=\"-1\">All</option>'+\n\t\t\t *            '</select> records'\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sLengthMenu\": \"Show _MENU_ entries\",\n\t\n\t\n\t\t\t/**\n\t\t\t * When using Ajax sourced data and during the first draw when DataTables is\n\t\t\t * gathering the data, this message is shown in an empty row in the table to\n\t\t\t * indicate to the end user the the data is being loaded. Note that this\n\t\t\t * parameter is not used when loading data by server-side processing, just\n\t\t\t * Ajax sourced data with client-side processing.\n\t\t\t *  @type string\n\t\t\t *  @default Loading...\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.loadingRecords\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"loadingRecords\": \"Please wait - loading...\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sLoadingRecords\": \"Loading...\",\n\t\n\t\n\t\t\t/**\n\t\t\t * Text which is displayed when the table is processing a user action\n\t\t\t * (usually a sort command or similar).\n\t\t\t *  @type string\n\t\t\t *  @default Processing...\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.processing\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"processing\": \"DataTables is currently busy\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sProcessing\": \"Processing...\",\n\t\n\t\n\t\t\t/**\n\t\t\t * Details the actions that will be taken when the user types into the\n\t\t\t * filtering input text box. The variable \"_INPUT_\", if used in the string,\n\t\t\t * is replaced with the HTML text box for the filtering input allowing\n\t\t\t * control over where it appears in the string. If \"_INPUT_\" is not given\n\t\t\t * then the input box is appended to the string automatically.\n\t\t\t *  @type string\n\t\t\t *  @default Search:\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.search\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    // Input text box will be appended at the end automatically\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"search\": \"Filter records:\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    // Specify where the filter should appear\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"search\": \"Apply filter _INPUT_ to table\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sSearch\": \"Search:\",\n\t\n\t\n\t\t\t/**\n\t\t\t * Assign a `placeholder` attribute to the search `input` element\n\t\t\t *  @type string\n\t\t\t *  @default \n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.searchPlaceholder\n\t\t\t */\n\t\t\t\"sSearchPlaceholder\": \"\",\n\t\n\t\n\t\t\t/**\n\t\t\t * All of the language information can be stored in a file on the\n\t\t\t * server-side, which DataTables will look up if this parameter is passed.\n\t\t\t * It must store the URL of the language file, which is in a JSON format,\n\t\t\t * and the object has the same properties as the oLanguage object in the\n\t\t\t * initialiser object (i.e. the above parameters). Please refer to one of\n\t\t\t * the example language files to see how this works in action.\n\t\t\t *  @type string\n\t\t\t *  @default <i>Empty string - i.e. disabled</i>\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.url\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"url\": \"http://www.sprymedia.co.uk/dataTables/lang.txt\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sUrl\": \"\",\n\t\n\t\n\t\t\t/**\n\t\t\t * Text shown inside the table records when the is no information to be\n\t\t\t * displayed after filtering. `emptyTable` is shown when there is simply no\n\t\t\t * information in the table at all (regardless of filtering).\n\t\t\t *  @type string\n\t\t\t *  @default No matching records found\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.zeroRecords\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"zeroRecords\": \"No records to display\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sZeroRecords\": \"No matching records found\"\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * This parameter allows you to have define the global filtering state at\n\t\t * initialisation time. As an object the `search` parameter must be\n\t\t * defined, but all other parameters are optional. When `regex` is true,\n\t\t * the search string will be treated as a regular expression, when false\n\t\t * (default) it will be treated as a straight string. When `smart`\n\t\t * DataTables will use it's smart filtering methods (to word match at\n\t\t * any point in the data), when false this will not be done.\n\t\t *  @namespace\n\t\t *  @extends DataTable.models.oSearch\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.search\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"search\": {\"search\": \"Initial search\"}\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"oSearch\": $.extend( {}, DataTable.models.oSearch ),\n\t\n\t\n\t\t/**\n\t\t * __Deprecated__ The functionality provided by this parameter has now been\n\t\t * superseded by that provided through `ajax`, which should be used instead.\n\t\t *\n\t\t * By default DataTables will look for the property `data` (or `aaData` for\n\t\t * compatibility with DataTables 1.9-) when obtaining data from an Ajax\n\t\t * source or for server-side processing - this parameter allows that\n\t\t * property to be changed. You can use Javascript dotted object notation to\n\t\t * get a data source for multiple levels of nesting.\n\t\t *  @type string\n\t\t *  @default data\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @dtopt Server-side\n\t\t *  @name DataTable.defaults.ajaxDataProp\n\t\t *\n\t\t *  @deprecated 1.10. Please use `ajax` for this functionality now.\n\t\t */\n\t\t\"sAjaxDataProp\": \"data\",\n\t\n\t\n\t\t/**\n\t\t * __Deprecated__ The functionality provided by this parameter has now been\n\t\t * superseded by that provided through `ajax`, which should be used instead.\n\t\t *\n\t\t * You can instruct DataTables to load data from an external\n\t\t * source using this parameter (use aData if you want to pass data in you\n\t\t * already have). Simply provide a url a JSON object can be obtained from.\n\t\t *  @type string\n\t\t *  @default null\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @dtopt Server-side\n\t\t *  @name DataTable.defaults.ajaxSource\n\t\t *\n\t\t *  @deprecated 1.10. Please use `ajax` for this functionality now.\n\t\t */\n\t\t\"sAjaxSource\": null,\n\t\n\t\n\t\t/**\n\t\t * This initialisation variable allows you to specify exactly where in the\n\t\t * DOM you want DataTables to inject the various controls it adds to the page\n\t\t * (for example you might want the pagination controls at the top of the\n\t\t * table). DIV elements (with or without a custom class) can also be added to\n\t\t * aid styling. The follow syntax is used:\n\t\t *   <ul>\n\t\t *     <li>The following options are allowed:\n\t\t *       <ul>\n\t\t *         <li>'l' - Length changing</li>\n\t\t *         <li>'f' - Filtering input</li>\n\t\t *         <li>'t' - The table!</li>\n\t\t *         <li>'i' - Information</li>\n\t\t *         <li>'p' - Pagination</li>\n\t\t *         <li>'r' - pRocessing</li>\n\t\t *       </ul>\n\t\t *     </li>\n\t\t *     <li>The following constants are allowed:\n\t\t *       <ul>\n\t\t *         <li>'H' - jQueryUI theme \"header\" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>\n\t\t *         <li>'F' - jQueryUI theme \"footer\" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>\n\t\t *       </ul>\n\t\t *     </li>\n\t\t *     <li>The following syntax is expected:\n\t\t *       <ul>\n\t\t *         <li>'&lt;' and '&gt;' - div elements</li>\n\t\t *         <li>'&lt;\"class\" and '&gt;' - div with a class</li>\n\t\t *         <li>'&lt;\"#id\" and '&gt;' - div with an ID</li>\n\t\t *       </ul>\n\t\t *     </li>\n\t\t *     <li>Examples:\n\t\t *       <ul>\n\t\t *         <li>'&lt;\"wrapper\"flipt&gt;'</li>\n\t\t *         <li>'&lt;lf&lt;t&gt;ip&gt;'</li>\n\t\t *       </ul>\n\t\t *     </li>\n\t\t *   </ul>\n\t\t *  @type string\n\t\t *  @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b>\n\t\t *    <\"H\"lfr>t<\"F\"ip> <i>(when `jQueryUI` is true)</i>\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.dom\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"dom\": '&lt;\"top\"i&gt;rt&lt;\"bottom\"flp&gt;&lt;\"clear\"&gt;'\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sDom\": \"lfrtip\",\n\t\n\t\n\t\t/**\n\t\t * Search delay option. This will throttle full table searches that use the\n\t\t * DataTables provided search input element (it does not effect calls to\n\t\t * `dt-api search()`, providing a delay before the search is made.\n\t\t *  @type integer\n\t\t *  @default 0\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.searchDelay\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"searchDelay\": 200\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"searchDelay\": null,\n\t\n\t\n\t\t/**\n\t\t * DataTables features four different built-in options for the buttons to\n\t\t * display for pagination control:\n\t\t *\n\t\t * * `simple` - 'Previous' and 'Next' buttons only\n\t\t * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers\n\t\t * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons\n\t\t * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus\n\t\t *   page numbers\n\t\t *  \n\t\t * Further methods can be added using {@link DataTable.ext.oPagination}.\n\t\t *  @type string\n\t\t *  @default simple_numbers\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.pagingType\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"pagingType\": \"full_numbers\"\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"sPaginationType\": \"simple_numbers\",\n\t\n\t\n\t\t/**\n\t\t * Enable horizontal scrolling. When a table is too wide to fit into a\n\t\t * certain layout, or you have a large number of columns in the table, you\n\t\t * can enable x-scrolling to show the table in a viewport, which can be\n\t\t * scrolled. This property can be `true` which will allow the table to\n\t\t * scroll horizontally when needed, or any CSS unit, or a number (in which\n\t\t * case it will be treated as a pixel measurement). Setting as simply `true`\n\t\t * is recommended.\n\t\t *  @type boolean|string\n\t\t *  @default <i>blank string - i.e. disabled</i>\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.scrollX\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"scrollX\": true,\n\t\t *        \"scrollCollapse\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sScrollX\": \"\",\n\t\n\t\n\t\t/**\n\t\t * This property can be used to force a DataTable to use more width than it\n\t\t * might otherwise do when x-scrolling is enabled. For example if you have a\n\t\t * table which requires to be well spaced, this parameter is useful for\n\t\t * \"over-sizing\" the table, and thus forcing scrolling. This property can by\n\t\t * any CSS unit, or a number (in which case it will be treated as a pixel\n\t\t * measurement).\n\t\t *  @type string\n\t\t *  @default <i>blank string - i.e. disabled</i>\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.scrollXInner\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"scrollX\": \"100%\",\n\t\t *        \"scrollXInner\": \"110%\"\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sScrollXInner\": \"\",\n\t\n\t\n\t\t/**\n\t\t * Enable vertical scrolling. Vertical scrolling will constrain the DataTable\n\t\t * to the given height, and enable scrolling for any data which overflows the\n\t\t * current viewport. This can be used as an alternative to paging to display\n\t\t * a lot of data in a small area (although paging and scrolling can both be\n\t\t * enabled at the same time). This property can be any CSS unit, or a number\n\t\t * (in which case it will be treated as a pixel measurement).\n\t\t *  @type string\n\t\t *  @default <i>blank string - i.e. disabled</i>\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.scrollY\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"scrollY\": \"200px\",\n\t\t *        \"paginate\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sScrollY\": \"\",\n\t\n\t\n\t\t/**\n\t\t * __Deprecated__ The functionality provided by this parameter has now been\n\t\t * superseded by that provided through `ajax`, which should be used instead.\n\t\t *\n\t\t * Set the HTTP method that is used to make the Ajax call for server-side\n\t\t * processing or Ajax sourced data.\n\t\t *  @type string\n\t\t *  @default GET\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @dtopt Server-side\n\t\t *  @name DataTable.defaults.serverMethod\n\t\t *\n\t\t *  @deprecated 1.10. Please use `ajax` for this functionality now.\n\t\t */\n\t\t\"sServerMethod\": \"GET\",\n\t\n\t\n\t\t/**\n\t\t * DataTables makes use of renderers when displaying HTML elements for\n\t\t * a table. These renderers can be added or modified by plug-ins to\n\t\t * generate suitable mark-up for a site. For example the Bootstrap\n\t\t * integration plug-in for DataTables uses a paging button renderer to\n\t\t * display pagination buttons in the mark-up required by Bootstrap.\n\t\t *\n\t\t * For further information about the renderers available see\n\t\t * DataTable.ext.renderer\n\t\t *  @type string|object\n\t\t *  @default null\n\t\t *\n\t\t *  @name DataTable.defaults.renderer\n\t\t *\n\t\t */\n\t\t\"renderer\": null,\n\t\n\t\n\t\t/**\n\t\t * Set the data property name that DataTables should use to get a row's id\n\t\t * to set as the `id` property in the node.\n\t\t *  @type string\n\t\t *  @default DT_RowId\n\t\t *\n\t\t *  @name DataTable.defaults.rowId\n\t\t */\n\t\t\"rowId\": \"DT_RowId\"\n\t};\n\t\n\t_fnHungarianMap( DataTable.defaults );\n\t\n\t\n\t\n\t/*\n\t * Developer note - See note in model.defaults.js about the use of Hungarian\n\t * notation and camel case.\n\t */\n\t\n\t/**\n\t * Column options that can be given to DataTables at initialisation time.\n\t *  @namespace\n\t */\n\tDataTable.defaults.column = {\n\t\t/**\n\t\t * Define which column(s) an order will occur on for this column. This\n\t\t * allows a column's ordering to take multiple columns into account when\n\t\t * doing a sort or use the data from a different column. For example first\n\t\t * name / last name columns make sense to do a multi-column sort over the\n\t\t * two columns.\n\t\t *  @type array|int\n\t\t *  @default null <i>Takes the value of the column index automatically</i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.orderData\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"orderData\": [ 0, 1 ], \"targets\": [ 0 ] },\n\t\t *          { \"orderData\": [ 1, 0 ], \"targets\": [ 1 ] },\n\t\t *          { \"orderData\": 2, \"targets\": [ 2 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"orderData\": [ 0, 1 ] },\n\t\t *          { \"orderData\": [ 1, 0 ] },\n\t\t *          { \"orderData\": 2 },\n\t\t *          null,\n\t\t *          null\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"aDataSort\": null,\n\t\t\"iDataSort\": -1,\n\t\n\t\n\t\t/**\n\t\t * You can control the default ordering direction, and even alter the\n\t\t * behaviour of the sort handler (i.e. only allow ascending ordering etc)\n\t\t * using this parameter.\n\t\t *  @type array\n\t\t *  @default [ 'asc', 'desc' ]\n\t\t *\n\t\t *  @name DataTable.defaults.column.orderSequence\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"orderSequence\": [ \"asc\" ], \"targets\": [ 1 ] },\n\t\t *          { \"orderSequence\": [ \"desc\", \"asc\", \"asc\" ], \"targets\": [ 2 ] },\n\t\t *          { \"orderSequence\": [ \"desc\" ], \"targets\": [ 3 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          null,\n\t\t *          { \"orderSequence\": [ \"asc\" ] },\n\t\t *          { \"orderSequence\": [ \"desc\", \"asc\", \"asc\" ] },\n\t\t *          { \"orderSequence\": [ \"desc\" ] },\n\t\t *          null\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"asSorting\": [ 'asc', 'desc' ],\n\t\n\t\n\t\t/**\n\t\t * Enable or disable filtering on the data in this column.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @name DataTable.defaults.column.searchable\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"searchable\": false, \"targets\": [ 0 ] }\n\t\t *        ] } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"searchable\": false },\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          null\n\t\t *        ] } );\n\t\t *    } );\n\t\t */\n\t\t\"bSearchable\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable ordering on this column.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @name DataTable.defaults.column.orderable\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"orderable\": false, \"targets\": [ 0 ] }\n\t\t *        ] } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"orderable\": false },\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          null\n\t\t *        ] } );\n\t\t *    } );\n\t\t */\n\t\t\"bSortable\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable the display of this column.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @name DataTable.defaults.column.visible\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"visible\": false, \"targets\": [ 0 ] }\n\t\t *        ] } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"visible\": false },\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          null\n\t\t *        ] } );\n\t\t *    } );\n\t\t */\n\t\t\"bVisible\": true,\n\t\n\t\n\t\t/**\n\t\t * Developer definable function that is called whenever a cell is created (Ajax source,\n\t\t * etc) or processed for input (DOM source). This can be used as a compliment to mRender\n\t\t * allowing you to modify the DOM element (add background colour for example) when the\n\t\t * element is available.\n\t\t *  @type function\n\t\t *  @param {element} td The TD node that has been created\n\t\t *  @param {*} cellData The Data for the cell\n\t\t *  @param {array|object} rowData The data for the whole row\n\t\t *  @param {int} row The row index for the aoData data store\n\t\t *  @param {int} col The column index for aoColumns\n\t\t *\n\t\t *  @name DataTable.defaults.column.createdCell\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [3],\n\t\t *          \"createdCell\": function (td, cellData, rowData, row, col) {\n\t\t *            if ( cellData == \"1.7\" ) {\n\t\t *              $(td).css('color', 'blue')\n\t\t *            }\n\t\t *          }\n\t\t *        } ]\n\t\t *      });\n\t\t *    } );\n\t\t */\n\t\t\"fnCreatedCell\": null,\n\t\n\t\n\t\t/**\n\t\t * This parameter has been replaced by `data` in DataTables to ensure naming\n\t\t * consistency. `dataProp` can still be used, as there is backwards\n\t\t * compatibility in DataTables for this option, but it is strongly\n\t\t * recommended that you use `data` in preference to `dataProp`.\n\t\t *  @name DataTable.defaults.column.dataProp\n\t\t */\n\t\n\t\n\t\t/**\n\t\t * This property can be used to read data from any data source property,\n\t\t * including deeply nested objects / properties. `data` can be given in a\n\t\t * number of different ways which effect its behaviour:\n\t\t *\n\t\t * * `integer` - treated as an array index for the data source. This is the\n\t\t *   default that DataTables uses (incrementally increased for each column).\n\t\t * * `string` - read an object property from the data source. There are\n\t\t *   three 'special' options that can be used in the string to alter how\n\t\t *   DataTables reads the data from the source object:\n\t\t *    * `.` - Dotted Javascript notation. Just as you use a `.` in\n\t\t *      Javascript to read from nested objects, so to can the options\n\t\t *      specified in `data`. For example: `browser.version` or\n\t\t *      `browser.name`. If your object parameter name contains a period, use\n\t\t *      `\\\\` to escape it - i.e. `first\\\\.name`.\n\t\t *    * `[]` - Array notation. DataTables can automatically combine data\n\t\t *      from and array source, joining the data with the characters provided\n\t\t *      between the two brackets. For example: `name[, ]` would provide a\n\t\t *      comma-space separated list from the source array. If no characters\n\t\t *      are provided between the brackets, the original array source is\n\t\t *      returned.\n\t\t *    * `()` - Function notation. Adding `()` to the end of a parameter will\n\t\t *      execute a function of the name given. For example: `browser()` for a\n\t\t *      simple function on the data source, `browser.version()` for a\n\t\t *      function in a nested property or even `browser().version` to get an\n\t\t *      object property if the function called returns an object. Note that\n\t\t *      function notation is recommended for use in `render` rather than\n\t\t *      `data` as it is much simpler to use as a renderer.\n\t\t * * `null` - use the original data source for the row rather than plucking\n\t\t *   data directly from it. This action has effects on two other\n\t\t *   initialisation options:\n\t\t *    * `defaultContent` - When null is given as the `data` option and\n\t\t *      `defaultContent` is specified for the column, the value defined by\n\t\t *      `defaultContent` will be used for the cell.\n\t\t *    * `render` - When null is used for the `data` option and the `render`\n\t\t *      option is specified for the column, the whole data source for the\n\t\t *      row is used for the renderer.\n\t\t * * `function` - the function given will be executed whenever DataTables\n\t\t *   needs to set or get the data for a cell in the column. The function\n\t\t *   takes three parameters:\n\t\t *    * Parameters:\n\t\t *      * `{array|object}` The data source for the row\n\t\t *      * `{string}` The type call data requested - this will be 'set' when\n\t\t *        setting data or 'filter', 'display', 'type', 'sort' or undefined\n\t\t *        when gathering data. Note that when `undefined` is given for the\n\t\t *        type DataTables expects to get the raw data for the object back<\n\t\t *      * `{*}` Data to set when the second parameter is 'set'.\n\t\t *    * Return:\n\t\t *      * The return value from the function is not required when 'set' is\n\t\t *        the type of call, but otherwise the return is what will be used\n\t\t *        for the data requested.\n\t\t *\n\t\t * Note that `data` is a getter and setter option. If you just require\n\t\t * formatting of data for output, you will likely want to use `render` which\n\t\t * is simply a getter and thus simpler to use.\n\t\t *\n\t\t * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The\n\t\t * name change reflects the flexibility of this property and is consistent\n\t\t * with the naming of mRender. If 'mDataProp' is given, then it will still\n\t\t * be used by DataTables, as it automatically maps the old name to the new\n\t\t * if required.\n\t\t *\n\t\t *  @type string|int|function|null\n\t\t *  @default null <i>Use automatically calculated column index</i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.data\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Read table data from objects\n\t\t *    // JSON structure for each row:\n\t\t *    //   {\n\t\t *    //      \"engine\": {value},\n\t\t *    //      \"browser\": {value},\n\t\t *    //      \"platform\": {value},\n\t\t *    //      \"version\": {value},\n\t\t *    //      \"grade\": {value}\n\t\t *    //   }\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"ajaxSource\": \"sources/objects.txt\",\n\t\t *        \"columns\": [\n\t\t *          { \"data\": \"engine\" },\n\t\t *          { \"data\": \"browser\" },\n\t\t *          { \"data\": \"platform\" },\n\t\t *          { \"data\": \"version\" },\n\t\t *          { \"data\": \"grade\" }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Read information from deeply nested objects\n\t\t *    // JSON structure for each row:\n\t\t *    //   {\n\t\t *    //      \"engine\": {value},\n\t\t *    //      \"browser\": {value},\n\t\t *    //      \"platform\": {\n\t\t *    //         \"inner\": {value}\n\t\t *    //      },\n\t\t *    //      \"details\": [\n\t\t *    //         {value}, {value}\n\t\t *    //      ]\n\t\t *    //   }\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"ajaxSource\": \"sources/deep.txt\",\n\t\t *        \"columns\": [\n\t\t *          { \"data\": \"engine\" },\n\t\t *          { \"data\": \"browser\" },\n\t\t *          { \"data\": \"platform.inner\" },\n\t\t *          { \"data\": \"platform.details.0\" },\n\t\t *          { \"data\": \"platform.details.1\" }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `data` as a function to provide different information for\n\t\t *    // sorting, filtering and display. In this case, currency (price)\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [ 0 ],\n\t\t *          \"data\": function ( source, type, val ) {\n\t\t *            if (type === 'set') {\n\t\t *              source.price = val;\n\t\t *              // Store the computed dislay and filter values for efficiency\n\t\t *              source.price_display = val==\"\" ? \"\" : \"$\"+numberFormat(val);\n\t\t *              source.price_filter  = val==\"\" ? \"\" : \"$\"+numberFormat(val)+\" \"+val;\n\t\t *              return;\n\t\t *            }\n\t\t *            else if (type === 'display') {\n\t\t *              return source.price_display;\n\t\t *            }\n\t\t *            else if (type === 'filter') {\n\t\t *              return source.price_filter;\n\t\t *            }\n\t\t *            // 'sort', 'type' and undefined all just use the integer\n\t\t *            return source.price;\n\t\t *          }\n\t\t *        } ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using default content\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [ 0 ],\n\t\t *          \"data\": null,\n\t\t *          \"defaultContent\": \"Click to edit\"\n\t\t *        } ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using array notation - outputting a list from an array\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [ 0 ],\n\t\t *          \"data\": \"name[, ]\"\n\t\t *        } ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t */\n\t\t\"mData\": null,\n\t\n\t\n\t\t/**\n\t\t * This property is the rendering partner to `data` and it is suggested that\n\t\t * when you want to manipulate data for display (including filtering,\n\t\t * sorting etc) without altering the underlying data for the table, use this\n\t\t * property. `render` can be considered to be the the read only companion to\n\t\t * `data` which is read / write (then as such more complex). Like `data`\n\t\t * this option can be given in a number of different ways to effect its\n\t\t * behaviour:\n\t\t *\n\t\t * * `integer` - treated as an array index for the data source. This is the\n\t\t *   default that DataTables uses (incrementally increased for each column).\n\t\t * * `string` - read an object property from the data source. There are\n\t\t *   three 'special' options that can be used in the string to alter how\n\t\t *   DataTables reads the data from the source object:\n\t\t *    * `.` - Dotted Javascript notation. Just as you use a `.` in\n\t\t *      Javascript to read from nested objects, so to can the options\n\t\t *      specified in `data`. For example: `browser.version` or\n\t\t *      `browser.name`. If your object parameter name contains a period, use\n\t\t *      `\\\\` to escape it - i.e. `first\\\\.name`.\n\t\t *    * `[]` - Array notation. DataTables can automatically combine data\n\t\t *      from and array source, joining the data with the characters provided\n\t\t *      between the two brackets. For example: `name[, ]` would provide a\n\t\t *      comma-space separated list from the source array. If no characters\n\t\t *      are provided between the brackets, the original array source is\n\t\t *      returned.\n\t\t *    * `()` - Function notation. Adding `()` to the end of a parameter will\n\t\t *      execute a function of the name given. For example: `browser()` for a\n\t\t *      simple function on the data source, `browser.version()` for a\n\t\t *      function in a nested property or even `browser().version` to get an\n\t\t *      object property if the function called returns an object.\n\t\t * * `object` - use different data for the different data types requested by\n\t\t *   DataTables ('filter', 'display', 'type' or 'sort'). The property names\n\t\t *   of the object is the data type the property refers to and the value can\n\t\t *   defined using an integer, string or function using the same rules as\n\t\t *   `render` normally does. Note that an `_` option _must_ be specified.\n\t\t *   This is the default value to use if you haven't specified a value for\n\t\t *   the data type requested by DataTables.\n\t\t * * `function` - the function given will be executed whenever DataTables\n\t\t *   needs to set or get the data for a cell in the column. The function\n\t\t *   takes three parameters:\n\t\t *    * Parameters:\n\t\t *      * {array|object} The data source for the row (based on `data`)\n\t\t *      * {string} The type call data requested - this will be 'filter',\n\t\t *        'display', 'type' or 'sort'.\n\t\t *      * {array|object} The full data source for the row (not based on\n\t\t *        `data`)\n\t\t *    * Return:\n\t\t *      * The return value from the function is what will be used for the\n\t\t *        data requested.\n\t\t *\n\t\t *  @type string|int|function|object|null\n\t\t *  @default null Use the data source value.\n\t\t *\n\t\t *  @name DataTable.defaults.column.render\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Create a comma separated list from an array of objects\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"ajaxSource\": \"sources/deep.txt\",\n\t\t *        \"columns\": [\n\t\t *          { \"data\": \"engine\" },\n\t\t *          { \"data\": \"browser\" },\n\t\t *          {\n\t\t *            \"data\": \"platform\",\n\t\t *            \"render\": \"[, ].name\"\n\t\t *          }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Execute a function to obtain data\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [ 0 ],\n\t\t *          \"data\": null, // Use the full data source object for the renderer's source\n\t\t *          \"render\": \"browserName()\"\n\t\t *        } ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // As an object, extracting different data for the different types\n\t\t *    // This would be used with a data source such as:\n\t\t *    //   { \"phone\": 5552368, \"phone_filter\": \"5552368 555-2368\", \"phone_display\": \"555-2368\" }\n\t\t *    // Here the `phone` integer is used for sorting and type detection, while `phone_filter`\n\t\t *    // (which has both forms) is used for filtering for if a user inputs either format, while\n\t\t *    // the formatted phone number is the one that is shown in the table.\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [ 0 ],\n\t\t *          \"data\": null, // Use the full data source object for the renderer's source\n\t\t *          \"render\": {\n\t\t *            \"_\": \"phone\",\n\t\t *            \"filter\": \"phone_filter\",\n\t\t *            \"display\": \"phone_display\"\n\t\t *          }\n\t\t *        } ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Use as a function to create a link from the data source\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [ 0 ],\n\t\t *          \"data\": \"download_link\",\n\t\t *          \"render\": function ( data, type, full ) {\n\t\t *            return '<a href=\"'+data+'\">Download</a>';\n\t\t *          }\n\t\t *        } ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"mRender\": null,\n\t\n\t\n\t\t/**\n\t\t * Change the cell type created for the column - either TD cells or TH cells. This\n\t\t * can be useful as TH cells have semantic meaning in the table body, allowing them\n\t\t * to act as a header for a row (you may wish to add scope='row' to the TH elements).\n\t\t *  @type string\n\t\t *  @default td\n\t\t *\n\t\t *  @name DataTable.defaults.column.cellType\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Make the first column use TH cells\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [ 0 ],\n\t\t *          \"cellType\": \"th\"\n\t\t *        } ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sCellType\": \"td\",\n\t\n\t\n\t\t/**\n\t\t * Class to give to each cell in this column.\n\t\t *  @type string\n\t\t *  @default <i>Empty string</i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.class\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"class\": \"my_class\", \"targets\": [ 0 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"class\": \"my_class\" },\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          null\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sClass\": \"\",\n\t\n\t\t/**\n\t\t * When DataTables calculates the column widths to assign to each column,\n\t\t * it finds the longest string in each column and then constructs a\n\t\t * temporary table and reads the widths from that. The problem with this\n\t\t * is that \"mmm\" is much wider then \"iiii\", but the latter is a longer\n\t\t * string - thus the calculation can go wrong (doing it properly and putting\n\t\t * it into an DOM object and measuring that is horribly(!) slow). Thus as\n\t\t * a \"work around\" we provide this option. It will append its value to the\n\t\t * text that is found to be the longest string for the column - i.e. padding.\n\t\t * Generally you shouldn't need this!\n\t\t *  @type string\n\t\t *  @default <i>Empty string<i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.contentPadding\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          {\n\t\t *            \"contentPadding\": \"mmm\"\n\t\t *          }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sContentPadding\": \"\",\n\t\n\t\n\t\t/**\n\t\t * Allows a default value to be given for a column's data, and will be used\n\t\t * whenever a null data source is encountered (this can be because `data`\n\t\t * is set to null, or because the data source itself is null).\n\t\t *  @type string\n\t\t *  @default null\n\t\t *\n\t\t *  @name DataTable.defaults.column.defaultContent\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          {\n\t\t *            \"data\": null,\n\t\t *            \"defaultContent\": \"Edit\",\n\t\t *            \"targets\": [ -1 ]\n\t\t *          }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          {\n\t\t *            \"data\": null,\n\t\t *            \"defaultContent\": \"Edit\"\n\t\t *          }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sDefaultContent\": null,\n\t\n\t\n\t\t/**\n\t\t * This parameter is only used in DataTables' server-side processing. It can\n\t\t * be exceptionally useful to know what columns are being displayed on the\n\t\t * client side, and to map these to database fields. When defined, the names\n\t\t * also allow DataTables to reorder information from the server if it comes\n\t\t * back in an unexpected order (i.e. if you switch your columns around on the\n\t\t * client-side, your server-side code does not also need updating).\n\t\t *  @type string\n\t\t *  @default <i>Empty string</i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.name\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"name\": \"engine\", \"targets\": [ 0 ] },\n\t\t *          { \"name\": \"browser\", \"targets\": [ 1 ] },\n\t\t *          { \"name\": \"platform\", \"targets\": [ 2 ] },\n\t\t *          { \"name\": \"version\", \"targets\": [ 3 ] },\n\t\t *          { \"name\": \"grade\", \"targets\": [ 4 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"name\": \"engine\" },\n\t\t *          { \"name\": \"browser\" },\n\t\t *          { \"name\": \"platform\" },\n\t\t *          { \"name\": \"version\" },\n\t\t *          { \"name\": \"grade\" }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sName\": \"\",\n\t\n\t\n\t\t/**\n\t\t * Defines a data source type for the ordering which can be used to read\n\t\t * real-time information from the table (updating the internally cached\n\t\t * version) prior to ordering. This allows ordering to occur on user\n\t\t * editable elements such as form inputs.\n\t\t *  @type string\n\t\t *  @default std\n\t\t *\n\t\t *  @name DataTable.defaults.column.orderDataType\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"orderDataType\": \"dom-text\", \"targets\": [ 2, 3 ] },\n\t\t *          { \"type\": \"numeric\", \"targets\": [ 3 ] },\n\t\t *          { \"orderDataType\": \"dom-select\", \"targets\": [ 4 ] },\n\t\t *          { \"orderDataType\": \"dom-checkbox\", \"targets\": [ 5 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          null,\n\t\t *          null,\n\t\t *          { \"orderDataType\": \"dom-text\" },\n\t\t *          { \"orderDataType\": \"dom-text\", \"type\": \"numeric\" },\n\t\t *          { \"orderDataType\": \"dom-select\" },\n\t\t *          { \"orderDataType\": \"dom-checkbox\" }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sSortDataType\": \"std\",\n\t\n\t\n\t\t/**\n\t\t * The title of this column.\n\t\t *  @type string\n\t\t *  @default null <i>Derived from the 'TH' value for this column in the\n\t\t *    original HTML table.</i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.title\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"title\": \"My column title\", \"targets\": [ 0 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"title\": \"My column title\" },\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          null\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sTitle\": null,\n\t\n\t\n\t\t/**\n\t\t * The type allows you to specify how the data for this column will be\n\t\t * ordered. Four types (string, numeric, date and html (which will strip\n\t\t * HTML tags before ordering)) are currently available. Note that only date\n\t\t * formats understood by Javascript's Date() object will be accepted as type\n\t\t * date. For example: \"Mar 26, 2008 5:03 PM\". May take the values: 'string',\n\t\t * 'numeric', 'date' or 'html' (by default). Further types can be adding\n\t\t * through plug-ins.\n\t\t *  @type string\n\t\t *  @default null <i>Auto-detected from raw data</i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.type\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"type\": \"html\", \"targets\": [ 0 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"type\": \"html\" },\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          null\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sType\": null,\n\t\n\t\n\t\t/**\n\t\t * Defining the width of the column, this parameter may take any CSS value\n\t\t * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not\n\t\t * been given a specific width through this interface ensuring that the table\n\t\t * remains readable.\n\t\t *  @type string\n\t\t *  @default null <i>Automatic</i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.width\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"width\": \"20%\", \"targets\": [ 0 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"width\": \"20%\" },\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          null\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sWidth\": null\n\t};\n\t\n\t_fnHungarianMap( DataTable.defaults.column );\n\t\n\t\n\t\n\t/**\n\t * DataTables settings object - this holds all the information needed for a\n\t * given table, including configuration, data and current application of the\n\t * table options. DataTables does not have a single instance for each DataTable\n\t * with the settings attached to that instance, but rather instances of the\n\t * DataTable \"class\" are created on-the-fly as needed (typically by a\n\t * $().dataTable() call) and the settings object is then applied to that\n\t * instance.\n\t *\n\t * Note that this object is related to {@link DataTable.defaults} but this\n\t * one is the internal data store for DataTables's cache of columns. It should\n\t * NOT be manipulated outside of DataTables. Any configuration should be done\n\t * through the initialisation options.\n\t *  @namespace\n\t *  @todo Really should attach the settings object to individual instances so we\n\t *    don't need to create new instances on each $().dataTable() call (if the\n\t *    table already exists). It would also save passing oSettings around and\n\t *    into every single function. However, this is a very significant\n\t *    architecture change for DataTables and will almost certainly break\n\t *    backwards compatibility with older installations. This is something that\n\t *    will be done in 2.0.\n\t */\n\tDataTable.models.oSettings = {\n\t\t/**\n\t\t * Primary features of DataTables and their enablement state.\n\t\t *  @namespace\n\t\t */\n\t\t\"oFeatures\": {\n\t\n\t\t\t/**\n\t\t\t * Flag to say if DataTables should automatically try to calculate the\n\t\t\t * optimum table and columns widths (true) or not (false).\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bAutoWidth\": null,\n\t\n\t\t\t/**\n\t\t\t * Delay the creation of TR and TD elements until they are actually\n\t\t\t * needed by a driven page draw. This can give a significant speed\n\t\t\t * increase for Ajax source and Javascript source data, but makes no\n\t\t\t * difference at all fro DOM and server-side processing tables.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bDeferRender\": null,\n\t\n\t\t\t/**\n\t\t\t * Enable filtering on the table or not. Note that if this is disabled\n\t\t\t * then there is no filtering at all on the table, including fnFilter.\n\t\t\t * To just remove the filtering input use sDom and remove the 'f' option.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bFilter\": null,\n\t\n\t\t\t/**\n\t\t\t * Table information element (the 'Showing x of y records' div) enable\n\t\t\t * flag.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bInfo\": null,\n\t\n\t\t\t/**\n\t\t\t * Present a user control allowing the end user to change the page size\n\t\t\t * when pagination is enabled.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bLengthChange\": null,\n\t\n\t\t\t/**\n\t\t\t * Pagination enabled or not. Note that if this is disabled then length\n\t\t\t * changing must also be disabled.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bPaginate\": null,\n\t\n\t\t\t/**\n\t\t\t * Processing indicator enable flag whenever DataTables is enacting a\n\t\t\t * user request - typically an Ajax request for server-side processing.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bProcessing\": null,\n\t\n\t\t\t/**\n\t\t\t * Server-side processing enabled flag - when enabled DataTables will\n\t\t\t * get all data from the server for every draw - there is no filtering,\n\t\t\t * sorting or paging done on the client-side.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bServerSide\": null,\n\t\n\t\t\t/**\n\t\t\t * Sorting enablement flag.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bSort\": null,\n\t\n\t\t\t/**\n\t\t\t * Multi-column sorting\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bSortMulti\": null,\n\t\n\t\t\t/**\n\t\t\t * Apply a class to the columns which are being sorted to provide a\n\t\t\t * visual highlight or not. This can slow things down when enabled since\n\t\t\t * there is a lot of DOM interaction.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bSortClasses\": null,\n\t\n\t\t\t/**\n\t\t\t * State saving enablement flag.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bStateSave\": null\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * Scrolling settings for a table.\n\t\t *  @namespace\n\t\t */\n\t\t\"oScroll\": {\n\t\t\t/**\n\t\t\t * When the table is shorter in height than sScrollY, collapse the\n\t\t\t * table container down to the height of the table (when true).\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bCollapse\": null,\n\t\n\t\t\t/**\n\t\t\t * Width of the scrollbar for the web-browser's platform. Calculated\n\t\t\t * during table initialisation.\n\t\t\t *  @type int\n\t\t\t *  @default 0\n\t\t\t */\n\t\t\t\"iBarWidth\": 0,\n\t\n\t\t\t/**\n\t\t\t * Viewport width for horizontal scrolling. Horizontal scrolling is\n\t\t\t * disabled if an empty string.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type string\n\t\t\t */\n\t\t\t\"sX\": null,\n\t\n\t\t\t/**\n\t\t\t * Width to expand the table to when using x-scrolling. Typically you\n\t\t\t * should not need to use this.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type string\n\t\t\t *  @deprecated\n\t\t\t */\n\t\t\t\"sXInner\": null,\n\t\n\t\t\t/**\n\t\t\t * Viewport height for vertical scrolling. Vertical scrolling is disabled\n\t\t\t * if an empty string.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type string\n\t\t\t */\n\t\t\t\"sY\": null\n\t\t},\n\t\n\t\t/**\n\t\t * Language information for the table.\n\t\t *  @namespace\n\t\t *  @extends DataTable.defaults.oLanguage\n\t\t */\n\t\t\"oLanguage\": {\n\t\t\t/**\n\t\t\t * Information callback function. See\n\t\t\t * {@link DataTable.defaults.fnInfoCallback}\n\t\t\t *  @type function\n\t\t\t *  @default null\n\t\t\t */\n\t\t\t\"fnInfoCallback\": null\n\t\t},\n\t\n\t\t/**\n\t\t * Browser support parameters\n\t\t *  @namespace\n\t\t */\n\t\t\"oBrowser\": {\n\t\t\t/**\n\t\t\t * Indicate if the browser incorrectly calculates width:100% inside a\n\t\t\t * scrolling element (IE6/7)\n\t\t\t *  @type boolean\n\t\t\t *  @default false\n\t\t\t */\n\t\t\t\"bScrollOversize\": false,\n\t\n\t\t\t/**\n\t\t\t * Determine if the vertical scrollbar is on the right or left of the\n\t\t\t * scrolling container - needed for rtl language layout, although not\n\t\t\t * all browsers move the scrollbar (Safari).\n\t\t\t *  @type boolean\n\t\t\t *  @default false\n\t\t\t */\n\t\t\t\"bScrollbarLeft\": false,\n\t\n\t\t\t/**\n\t\t\t * Flag for if `getBoundingClientRect` is fully supported or not\n\t\t\t *  @type boolean\n\t\t\t *  @default false\n\t\t\t */\n\t\t\t\"bBounding\": false,\n\t\n\t\t\t/**\n\t\t\t * Browser scrollbar width\n\t\t\t *  @type integer\n\t\t\t *  @default 0\n\t\t\t */\n\t\t\t\"barWidth\": 0\n\t\t},\n\t\n\t\n\t\t\"ajax\": null,\n\t\n\t\n\t\t/**\n\t\t * Array referencing the nodes which are used for the features. The\n\t\t * parameters of this object match what is allowed by sDom - i.e.\n\t\t *   <ul>\n\t\t *     <li>'l' - Length changing</li>\n\t\t *     <li>'f' - Filtering input</li>\n\t\t *     <li>'t' - The table!</li>\n\t\t *     <li>'i' - Information</li>\n\t\t *     <li>'p' - Pagination</li>\n\t\t *     <li>'r' - pRocessing</li>\n\t\t *   </ul>\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aanFeatures\": [],\n\t\n\t\t/**\n\t\t * Store data information - see {@link DataTable.models.oRow} for detailed\n\t\t * information.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoData\": [],\n\t\n\t\t/**\n\t\t * Array of indexes which are in the current display (after filtering etc)\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aiDisplay\": [],\n\t\n\t\t/**\n\t\t * Array of indexes for display - no filtering\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aiDisplayMaster\": [],\n\t\n\t\t/**\n\t\t * Map of row ids to data indexes\n\t\t *  @type object\n\t\t *  @default {}\n\t\t */\n\t\t\"aIds\": {},\n\t\n\t\t/**\n\t\t * Store information about each column that is in use\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoColumns\": [],\n\t\n\t\t/**\n\t\t * Store information about the table's header\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoHeader\": [],\n\t\n\t\t/**\n\t\t * Store information about the table's footer\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoFooter\": [],\n\t\n\t\t/**\n\t\t * Store the applied global search information in case we want to force a\n\t\t * research or compare the old search to a new one.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @namespace\n\t\t *  @extends DataTable.models.oSearch\n\t\t */\n\t\t\"oPreviousSearch\": {},\n\t\n\t\t/**\n\t\t * Store the applied search for each column - see\n\t\t * {@link DataTable.models.oSearch} for the format that is used for the\n\t\t * filtering information for each column.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoPreSearchCols\": [],\n\t\n\t\t/**\n\t\t * Sorting that is applied to the table. Note that the inner arrays are\n\t\t * used in the following manner:\n\t\t * <ul>\n\t\t *   <li>Index 0 - column number</li>\n\t\t *   <li>Index 1 - current sorting direction</li>\n\t\t * </ul>\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type array\n\t\t *  @todo These inner arrays should really be objects\n\t\t */\n\t\t\"aaSorting\": null,\n\t\n\t\t/**\n\t\t * Sorting that is always applied to the table (i.e. prefixed in front of\n\t\t * aaSorting).\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aaSortingFixed\": [],\n\t\n\t\t/**\n\t\t * Classes to use for the striping of a table.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"asStripeClasses\": null,\n\t\n\t\t/**\n\t\t * If restoring a table - we should restore its striping classes as well\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"asDestroyStripes\": [],\n\t\n\t\t/**\n\t\t * If restoring a table - we should restore its width\n\t\t *  @type int\n\t\t *  @default 0\n\t\t */\n\t\t\"sDestroyWidth\": 0,\n\t\n\t\t/**\n\t\t * Callback functions array for every time a row is inserted (i.e. on a draw).\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoRowCallback\": [],\n\t\n\t\t/**\n\t\t * Callback functions for the header on each draw.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoHeaderCallback\": [],\n\t\n\t\t/**\n\t\t * Callback function for the footer on each draw.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoFooterCallback\": [],\n\t\n\t\t/**\n\t\t * Array of callback functions for draw callback functions\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoDrawCallback\": [],\n\t\n\t\t/**\n\t\t * Array of callback functions for row created function\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoRowCreatedCallback\": [],\n\t\n\t\t/**\n\t\t * Callback functions for just before the table is redrawn. A return of\n\t\t * false will be used to cancel the draw.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoPreDrawCallback\": [],\n\t\n\t\t/**\n\t\t * Callback functions for when the table has been initialised.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoInitComplete\": [],\n\t\n\t\n\t\t/**\n\t\t * Callbacks for modifying the settings to be stored for state saving, prior to\n\t\t * saving state.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoStateSaveParams\": [],\n\t\n\t\t/**\n\t\t * Callbacks for modifying the settings that have been stored for state saving\n\t\t * prior to using the stored values to restore the state.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoStateLoadParams\": [],\n\t\n\t\t/**\n\t\t * Callbacks for operating on the settings object once the saved state has been\n\t\t * loaded\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoStateLoaded\": [],\n\t\n\t\t/**\n\t\t * Cache the table ID for quick access\n\t\t *  @type string\n\t\t *  @default <i>Empty string</i>\n\t\t */\n\t\t\"sTableId\": \"\",\n\t\n\t\t/**\n\t\t * The TABLE node for the main table\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTable\": null,\n\t\n\t\t/**\n\t\t * Permanent ref to the thead element\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTHead\": null,\n\t\n\t\t/**\n\t\t * Permanent ref to the tfoot element - if it exists\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTFoot\": null,\n\t\n\t\t/**\n\t\t * Permanent ref to the tbody element\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTBody\": null,\n\t\n\t\t/**\n\t\t * Cache the wrapper node (contains all DataTables controlled elements)\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTableWrapper\": null,\n\t\n\t\t/**\n\t\t * Indicate if when using server-side processing the loading of data\n\t\t * should be deferred until the second draw.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t */\n\t\t\"bDeferLoading\": false,\n\t\n\t\t/**\n\t\t * Indicate if all required information has been read in\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t */\n\t\t\"bInitialised\": false,\n\t\n\t\t/**\n\t\t * Information about open rows. Each object in the array has the parameters\n\t\t * 'nTr' and 'nParent'\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoOpenRows\": [],\n\t\n\t\t/**\n\t\t * Dictate the positioning of DataTables' control elements - see\n\t\t * {@link DataTable.model.oInit.sDom}.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sDom\": null,\n\t\n\t\t/**\n\t\t * Search delay (in mS)\n\t\t *  @type integer\n\t\t *  @default null\n\t\t */\n\t\t\"searchDelay\": null,\n\t\n\t\t/**\n\t\t * Which type of pagination should be used.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type string\n\t\t *  @default two_button\n\t\t */\n\t\t\"sPaginationType\": \"two_button\",\n\t\n\t\t/**\n\t\t * The state duration (for `stateSave`) in seconds.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type int\n\t\t *  @default 0\n\t\t */\n\t\t\"iStateDuration\": 0,\n\t\n\t\t/**\n\t\t * Array of callback functions for state saving. Each array element is an\n\t\t * object with the following parameters:\n\t\t *   <ul>\n\t\t *     <li>function:fn - function to call. Takes two parameters, oSettings\n\t\t *       and the JSON string to save that has been thus far created. Returns\n\t\t *       a JSON string to be inserted into a json object\n\t\t *       (i.e. '\"param\": [ 0, 1, 2]')</li>\n\t\t *     <li>string:sName - name of callback</li>\n\t\t *   </ul>\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoStateSave\": [],\n\t\n\t\t/**\n\t\t * Array of callback functions for state loading. Each array element is an\n\t\t * object with the following parameters:\n\t\t *   <ul>\n\t\t *     <li>function:fn - function to call. Takes two parameters, oSettings\n\t\t *       and the object stored. May return false to cancel state loading</li>\n\t\t *     <li>string:sName - name of callback</li>\n\t\t *   </ul>\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoStateLoad\": [],\n\t\n\t\t/**\n\t\t * State that was saved. Useful for back reference\n\t\t *  @type object\n\t\t *  @default null\n\t\t */\n\t\t\"oSavedState\": null,\n\t\n\t\t/**\n\t\t * State that was loaded. Useful for back reference\n\t\t *  @type object\n\t\t *  @default null\n\t\t */\n\t\t\"oLoadedState\": null,\n\t\n\t\t/**\n\t\t * Source url for AJAX data for the table.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sAjaxSource\": null,\n\t\n\t\t/**\n\t\t * Property from a given object from which to read the table data from. This\n\t\t * can be an empty string (when not server-side processing), in which case\n\t\t * it is  assumed an an array is given directly.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type string\n\t\t */\n\t\t\"sAjaxDataProp\": null,\n\t\n\t\t/**\n\t\t * Note if draw should be blocked while getting data\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t */\n\t\t\"bAjaxDataGet\": true,\n\t\n\t\t/**\n\t\t * The last jQuery XHR object that was used for server-side data gathering.\n\t\t * This can be used for working with the XHR information in one of the\n\t\t * callbacks\n\t\t *  @type object\n\t\t *  @default null\n\t\t */\n\t\t\"jqXHR\": null,\n\t\n\t\t/**\n\t\t * JSON returned from the server in the last Ajax request\n\t\t *  @type object\n\t\t *  @default undefined\n\t\t */\n\t\t\"json\": undefined,\n\t\n\t\t/**\n\t\t * Data submitted as part of the last Ajax request\n\t\t *  @type object\n\t\t *  @default undefined\n\t\t */\n\t\t\"oAjaxData\": undefined,\n\t\n\t\t/**\n\t\t * Function to get the server-side data.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type function\n\t\t */\n\t\t\"fnServerData\": null,\n\t\n\t\t/**\n\t\t * Functions which are called prior to sending an Ajax request so extra\n\t\t * parameters can easily be sent to the server\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoServerParams\": [],\n\t\n\t\t/**\n\t\t * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if\n\t\t * required).\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type string\n\t\t */\n\t\t\"sServerMethod\": null,\n\t\n\t\t/**\n\t\t * Format numbers for display.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type function\n\t\t */\n\t\t\"fnFormatNumber\": null,\n\t\n\t\t/**\n\t\t * List of options that can be used for the user selectable length menu.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aLengthMenu\": null,\n\t\n\t\t/**\n\t\t * Counter for the draws that the table does. Also used as a tracker for\n\t\t * server-side processing\n\t\t *  @type int\n\t\t *  @default 0\n\t\t */\n\t\t\"iDraw\": 0,\n\t\n\t\t/**\n\t\t * Indicate if a redraw is being done - useful for Ajax\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t */\n\t\t\"bDrawing\": false,\n\t\n\t\t/**\n\t\t * Draw index (iDraw) of the last error when parsing the returned data\n\t\t *  @type int\n\t\t *  @default -1\n\t\t */\n\t\t\"iDrawError\": -1,\n\t\n\t\t/**\n\t\t * Paging display length\n\t\t *  @type int\n\t\t *  @default 10\n\t\t */\n\t\t\"_iDisplayLength\": 10,\n\t\n\t\t/**\n\t\t * Paging start point - aiDisplay index\n\t\t *  @type int\n\t\t *  @default 0\n\t\t */\n\t\t\"_iDisplayStart\": 0,\n\t\n\t\t/**\n\t\t * Server-side processing - number of records in the result set\n\t\t * (i.e. before filtering), Use fnRecordsTotal rather than\n\t\t * this property to get the value of the number of records, regardless of\n\t\t * the server-side processing setting.\n\t\t *  @type int\n\t\t *  @default 0\n\t\t *  @private\n\t\t */\n\t\t\"_iRecordsTotal\": 0,\n\t\n\t\t/**\n\t\t * Server-side processing - number of records in the current display set\n\t\t * (i.e. after filtering). Use fnRecordsDisplay rather than\n\t\t * this property to get the value of the number of records, regardless of\n\t\t * the server-side processing setting.\n\t\t *  @type boolean\n\t\t *  @default 0\n\t\t *  @private\n\t\t */\n\t\t\"_iRecordsDisplay\": 0,\n\t\n\t\t/**\n\t\t * Flag to indicate if jQuery UI marking and classes should be used.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type boolean\n\t\t */\n\t\t\"bJUI\": null,\n\t\n\t\t/**\n\t\t * The classes to use for the table\n\t\t *  @type object\n\t\t *  @default {}\n\t\t */\n\t\t\"oClasses\": {},\n\t\n\t\t/**\n\t\t * Flag attached to the settings object so you can check in the draw\n\t\t * callback if filtering has been done in the draw. Deprecated in favour of\n\t\t * events.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *  @deprecated\n\t\t */\n\t\t\"bFiltered\": false,\n\t\n\t\t/**\n\t\t * Flag attached to the settings object so you can check in the draw\n\t\t * callback if sorting has been done in the draw. Deprecated in favour of\n\t\t * events.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *  @deprecated\n\t\t */\n\t\t\"bSorted\": false,\n\t\n\t\t/**\n\t\t * Indicate that if multiple rows are in the header and there is more than\n\t\t * one unique cell per column, if the top one (true) or bottom one (false)\n\t\t * should be used for sorting / title by DataTables.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type boolean\n\t\t */\n\t\t\"bSortCellsTop\": null,\n\t\n\t\t/**\n\t\t * Initialisation object that is used for the table\n\t\t *  @type object\n\t\t *  @default null\n\t\t */\n\t\t\"oInit\": null,\n\t\n\t\t/**\n\t\t * Destroy callback functions - for plug-ins to attach themselves to the\n\t\t * destroy so they can clean up markup and events.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoDestroyCallback\": [],\n\t\n\t\n\t\t/**\n\t\t * Get the number of records in the current record set, before filtering\n\t\t *  @type function\n\t\t */\n\t\t\"fnRecordsTotal\": function ()\n\t\t{\n\t\t\treturn _fnDataSource( this ) == 'ssp' ?\n\t\t\t\tthis._iRecordsTotal * 1 :\n\t\t\t\tthis.aiDisplayMaster.length;\n\t\t},\n\t\n\t\t/**\n\t\t * Get the number of records in the current record set, after filtering\n\t\t *  @type function\n\t\t */\n\t\t\"fnRecordsDisplay\": function ()\n\t\t{\n\t\t\treturn _fnDataSource( this ) == 'ssp' ?\n\t\t\t\tthis._iRecordsDisplay * 1 :\n\t\t\t\tthis.aiDisplay.length;\n\t\t},\n\t\n\t\t/**\n\t\t * Get the display end point - aiDisplay index\n\t\t *  @type function\n\t\t */\n\t\t\"fnDisplayEnd\": function ()\n\t\t{\n\t\t\tvar\n\t\t\t\tlen      = this._iDisplayLength,\n\t\t\t\tstart    = this._iDisplayStart,\n\t\t\t\tcalc     = start + len,\n\t\t\t\trecords  = this.aiDisplay.length,\n\t\t\t\tfeatures = this.oFeatures,\n\t\t\t\tpaginate = features.bPaginate;\n\t\n\t\t\tif ( features.bServerSide ) {\n\t\t\t\treturn paginate === false || len === -1 ?\n\t\t\t\t\tstart + records :\n\t\t\t\t\tMath.min( start+len, this._iRecordsDisplay );\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn ! paginate || calc>records || len===-1 ?\n\t\t\t\t\trecords :\n\t\t\t\t\tcalc;\n\t\t\t}\n\t\t},\n\t\n\t\t/**\n\t\t * The DataTables object for this table\n\t\t *  @type object\n\t\t *  @default null\n\t\t */\n\t\t\"oInstance\": null,\n\t\n\t\t/**\n\t\t * Unique identifier for each instance of the DataTables object. If there\n\t\t * is an ID on the table node, then it takes that value, otherwise an\n\t\t * incrementing internal counter is used.\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sInstance\": null,\n\t\n\t\t/**\n\t\t * tabindex attribute value that is added to DataTables control elements, allowing\n\t\t * keyboard navigation of the table and its controls.\n\t\t */\n\t\t\"iTabIndex\": 0,\n\t\n\t\t/**\n\t\t * DIV container for the footer scrolling table if scrolling\n\t\t */\n\t\t\"nScrollHead\": null,\n\t\n\t\t/**\n\t\t * DIV container for the footer scrolling table if scrolling\n\t\t */\n\t\t\"nScrollFoot\": null,\n\t\n\t\t/**\n\t\t * Last applied sort\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aLastSort\": [],\n\t\n\t\t/**\n\t\t * Stored plug-in instances\n\t\t *  @type object\n\t\t *  @default {}\n\t\t */\n\t\t\"oPlugins\": {},\n\t\n\t\t/**\n\t\t * Function used to get a row's id from the row's data\n\t\t *  @type function\n\t\t *  @default null\n\t\t */\n\t\t\"rowIdFn\": null,\n\t\n\t\t/**\n\t\t * Data location where to store a row's id\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"rowId\": null\n\t};\n\n\t/**\n\t * Extension object for DataTables that is used to provide all extension\n\t * options.\n\t *\n\t * Note that the `DataTable.ext` object is available through\n\t * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is\n\t * also aliased to `jQuery.fn.dataTableExt` for historic reasons.\n\t *  @namespace\n\t *  @extends DataTable.models.ext\n\t */\n\t\n\t\n\t/**\n\t * DataTables extensions\n\t * \n\t * This namespace acts as a collection area for plug-ins that can be used to\n\t * extend DataTables capabilities. Indeed many of the build in methods\n\t * use this method to provide their own capabilities (sorting methods for\n\t * example).\n\t *\n\t * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy\n\t * reasons\n\t *\n\t *  @namespace\n\t */\n\tDataTable.ext = _ext = {\n\t\t/**\n\t\t * Buttons. For use with the Buttons extension for DataTables. This is\n\t\t * defined here so other extensions can define buttons regardless of load\n\t\t * order. It is _not_ used by DataTables core.\n\t\t *\n\t\t *  @type object\n\t\t *  @default {}\n\t\t */\n\t\tbuttons: {},\n\t\n\t\n\t\t/**\n\t\t * Element class names\n\t\t *\n\t\t *  @type object\n\t\t *  @default {}\n\t\t */\n\t\tclasses: {},\n\t\n\t\n\t\t/**\n\t\t * DataTables build type (expanded by the download builder)\n\t\t *\n\t\t *  @type string\n\t\t */\n\t\tbuilder: \"-source-\",\n\t\n\t\n\t\t/**\n\t\t * Error reporting.\n\t\t * \n\t\t * How should DataTables report an error. Can take the value 'alert',\n\t\t * 'throw', 'none' or a function.\n\t\t *\n\t\t *  @type string|function\n\t\t *  @default alert\n\t\t */\n\t\terrMode: \"alert\",\n\t\n\t\n\t\t/**\n\t\t * Feature plug-ins.\n\t\t * \n\t\t * This is an array of objects which describe the feature plug-ins that are\n\t\t * available to DataTables. These feature plug-ins are then available for\n\t\t * use through the `dom` initialisation option.\n\t\t * \n\t\t * Each feature plug-in is described by an object which must have the\n\t\t * following properties:\n\t\t * \n\t\t * * `fnInit` - function that is used to initialise the plug-in,\n\t\t * * `cFeature` - a character so the feature can be enabled by the `dom`\n\t\t *   instillation option. This is case sensitive.\n\t\t *\n\t\t * The `fnInit` function has the following input parameters:\n\t\t *\n\t\t * 1. `{object}` DataTables settings object: see\n\t\t *    {@link DataTable.models.oSettings}\n\t\t *\n\t\t * And the following return is expected:\n\t\t * \n\t\t * * {node|null} The element which contains your feature. Note that the\n\t\t *   return may also be void if your plug-in does not require to inject any\n\t\t *   DOM elements into DataTables control (`dom`) - for example this might\n\t\t *   be useful when developing a plug-in which allows table control via\n\t\t *   keyboard entry\n\t\t *\n\t\t *  @type array\n\t\t *\n\t\t *  @example\n\t\t *    $.fn.dataTable.ext.features.push( {\n\t\t *      \"fnInit\": function( oSettings ) {\n\t\t *        return new TableTools( { \"oDTSettings\": oSettings } );\n\t\t *      },\n\t\t *      \"cFeature\": \"T\"\n\t\t *    } );\n\t\t */\n\t\tfeature: [],\n\t\n\t\n\t\t/**\n\t\t * Row searching.\n\t\t * \n\t\t * This method of searching is complimentary to the default type based\n\t\t * searching, and a lot more comprehensive as it allows you complete control\n\t\t * over the searching logic. Each element in this array is a function\n\t\t * (parameters described below) that is called for every row in the table,\n\t\t * and your logic decides if it should be included in the searching data set\n\t\t * or not.\n\t\t *\n\t\t * Searching functions have the following input parameters:\n\t\t *\n\t\t * 1. `{object}` DataTables settings object: see\n\t\t *    {@link DataTable.models.oSettings}\n\t\t * 2. `{array|object}` Data for the row to be processed (same as the\n\t\t *    original format that was passed in as the data source, or an array\n\t\t *    from a DOM data source\n\t\t * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which\n\t\t *    can be useful to retrieve the `TR` element if you need DOM interaction.\n\t\t *\n\t\t * And the following return is expected:\n\t\t *\n\t\t * * {boolean} Include the row in the searched result set (true) or not\n\t\t *   (false)\n\t\t *\n\t\t * Note that as with the main search ability in DataTables, technically this\n\t\t * is \"filtering\", since it is subtractive. However, for consistency in\n\t\t * naming we call it searching here.\n\t\t *\n\t\t *  @type array\n\t\t *  @default []\n\t\t *\n\t\t *  @example\n\t\t *    // The following example shows custom search being applied to the\n\t\t *    // fourth column (i.e. the data[3] index) based on two input values\n\t\t *    // from the end-user, matching the data in a certain range.\n\t\t *    $.fn.dataTable.ext.search.push(\n\t\t *      function( settings, data, dataIndex ) {\n\t\t *        var min = document.getElementById('min').value * 1;\n\t\t *        var max = document.getElementById('max').value * 1;\n\t\t *        var version = data[3] == \"-\" ? 0 : data[3]*1;\n\t\t *\n\t\t *        if ( min == \"\" && max == \"\" ) {\n\t\t *          return true;\n\t\t *        }\n\t\t *        else if ( min == \"\" && version < max ) {\n\t\t *          return true;\n\t\t *        }\n\t\t *        else if ( min < version && \"\" == max ) {\n\t\t *          return true;\n\t\t *        }\n\t\t *        else if ( min < version && version < max ) {\n\t\t *          return true;\n\t\t *        }\n\t\t *        return false;\n\t\t *      }\n\t\t *    );\n\t\t */\n\t\tsearch: [],\n\t\n\t\n\t\t/**\n\t\t * Selector extensions\n\t\t *\n\t\t * The `selector` option can be used to extend the options available for the\n\t\t * selector modifier options (`selector-modifier` object data type) that\n\t\t * each of the three built in selector types offer (row, column and cell +\n\t\t * their plural counterparts). For example the Select extension uses this\n\t\t * mechanism to provide an option to select only rows, columns and cells\n\t\t * that have been marked as selected by the end user (`{selected: true}`),\n\t\t * which can be used in conjunction with the existing built in selector\n\t\t * options.\n\t\t *\n\t\t * Each property is an array to which functions can be pushed. The functions\n\t\t * take three attributes:\n\t\t *\n\t\t * * Settings object for the host table\n\t\t * * Options object (`selector-modifier` object type)\n\t\t * * Array of selected item indexes\n\t\t *\n\t\t * The return is an array of the resulting item indexes after the custom\n\t\t * selector has been applied.\n\t\t *\n\t\t *  @type object\n\t\t */\n\t\tselector: {\n\t\t\tcell: [],\n\t\t\tcolumn: [],\n\t\t\trow: []\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * Internal functions, exposed for used in plug-ins.\n\t\t * \n\t\t * Please note that you should not need to use the internal methods for\n\t\t * anything other than a plug-in (and even then, try to avoid if possible).\n\t\t * The internal function may change between releases.\n\t\t *\n\t\t *  @type object\n\t\t *  @default {}\n\t\t */\n\t\tinternal: {},\n\t\n\t\n\t\t/**\n\t\t * Legacy configuration options. Enable and disable legacy options that\n\t\t * are available in DataTables.\n\t\t *\n\t\t *  @type object\n\t\t */\n\t\tlegacy: {\n\t\t\t/**\n\t\t\t * Enable / disable DataTables 1.9 compatible server-side processing\n\t\t\t * requests\n\t\t\t *\n\t\t\t *  @type boolean\n\t\t\t *  @default null\n\t\t\t */\n\t\t\tajax: null\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * Pagination plug-in methods.\n\t\t * \n\t\t * Each entry in this object is a function and defines which buttons should\n\t\t * be shown by the pagination rendering method that is used for the table:\n\t\t * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the\n\t\t * buttons are displayed in the document, while the functions here tell it\n\t\t * what buttons to display. This is done by returning an array of button\n\t\t * descriptions (what each button will do).\n\t\t *\n\t\t * Pagination types (the four built in options and any additional plug-in\n\t\t * options defined here) can be used through the `paginationType`\n\t\t * initialisation parameter.\n\t\t *\n\t\t * The functions defined take two parameters:\n\t\t *\n\t\t * 1. `{int} page` The current page index\n\t\t * 2. `{int} pages` The number of pages in the table\n\t\t *\n\t\t * Each function is expected to return an array where each element of the\n\t\t * array can be one of:\n\t\t *\n\t\t * * `first` - Jump to first page when activated\n\t\t * * `last` - Jump to last page when activated\n\t\t * * `previous` - Show previous page when activated\n\t\t * * `next` - Show next page when activated\n\t\t * * `{int}` - Show page of the index given\n\t\t * * `{array}` - A nested array containing the above elements to add a\n\t\t *   containing 'DIV' element (might be useful for styling).\n\t\t *\n\t\t * Note that DataTables v1.9- used this object slightly differently whereby\n\t\t * an object with two functions would be defined for each plug-in. That\n\t\t * ability is still supported by DataTables 1.10+ to provide backwards\n\t\t * compatibility, but this option of use is now decremented and no longer\n\t\t * documented in DataTables 1.10+.\n\t\t *\n\t\t *  @type object\n\t\t *  @default {}\n\t\t *\n\t\t *  @example\n\t\t *    // Show previous, next and current page buttons only\n\t\t *    $.fn.dataTableExt.oPagination.current = function ( page, pages ) {\n\t\t *      return [ 'previous', page, 'next' ];\n\t\t *    };\n\t\t */\n\t\tpager: {},\n\t\n\t\n\t\trenderer: {\n\t\t\tpageButton: {},\n\t\t\theader: {}\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * Ordering plug-ins - custom data source\n\t\t * \n\t\t * The extension options for ordering of data available here is complimentary\n\t\t * to the default type based ordering that DataTables typically uses. It\n\t\t * allows much greater control over the the data that is being used to\n\t\t * order a column, but is necessarily therefore more complex.\n\t\t * \n\t\t * This type of ordering is useful if you want to do ordering based on data\n\t\t * live from the DOM (for example the contents of an 'input' element) rather\n\t\t * than just the static string that DataTables knows of.\n\t\t * \n\t\t * The way these plug-ins work is that you create an array of the values you\n\t\t * wish to be ordering for the column in question and then return that\n\t\t * array. The data in the array much be in the index order of the rows in\n\t\t * the table (not the currently ordering order!). Which order data gathering\n\t\t * function is run here depends on the `dt-init columns.orderDataType`\n\t\t * parameter that is used for the column (if any).\n\t\t *\n\t\t * The functions defined take two parameters:\n\t\t *\n\t\t * 1. `{object}` DataTables settings object: see\n\t\t *    {@link DataTable.models.oSettings}\n\t\t * 2. `{int}` Target column index\n\t\t *\n\t\t * Each function is expected to return an array:\n\t\t *\n\t\t * * `{array}` Data for the column to be ordering upon\n\t\t *\n\t\t *  @type array\n\t\t *\n\t\t *  @example\n\t\t *    // Ordering using `input` node values\n\t\t *    $.fn.dataTable.ext.order['dom-text'] = function  ( settings, col )\n\t\t *    {\n\t\t *      return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {\n\t\t *        return $('input', td).val();\n\t\t *      } );\n\t\t *    }\n\t\t */\n\t\torder: {},\n\t\n\t\n\t\t/**\n\t\t * Type based plug-ins.\n\t\t *\n\t\t * Each column in DataTables has a type assigned to it, either by automatic\n\t\t * detection or by direct assignment using the `type` option for the column.\n\t\t * The type of a column will effect how it is ordering and search (plug-ins\n\t\t * can also make use of the column type if required).\n\t\t *\n\t\t * @namespace\n\t\t */\n\t\ttype: {\n\t\t\t/**\n\t\t\t * Type detection functions.\n\t\t\t *\n\t\t\t * The functions defined in this object are used to automatically detect\n\t\t\t * a column's type, making initialisation of DataTables super easy, even\n\t\t\t * when complex data is in the table.\n\t\t\t *\n\t\t\t * The functions defined take two parameters:\n\t\t\t *\n\t\t     *  1. `{*}` Data from the column cell to be analysed\n\t\t     *  2. `{settings}` DataTables settings object. This can be used to\n\t\t     *     perform context specific type detection - for example detection\n\t\t     *     based on language settings such as using a comma for a decimal\n\t\t     *     place. Generally speaking the options from the settings will not\n\t\t     *     be required\n\t\t\t *\n\t\t\t * Each function is expected to return:\n\t\t\t *\n\t\t\t * * `{string|null}` Data type detected, or null if unknown (and thus\n\t\t\t *   pass it on to the other type detection functions.\n\t\t\t *\n\t\t\t *  @type array\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    // Currency type detection plug-in:\n\t\t\t *    $.fn.dataTable.ext.type.detect.push(\n\t\t\t *      function ( data, settings ) {\n\t\t\t *        // Check the numeric part\n\t\t\t *        if ( ! $.isNumeric( data.substring(1) ) ) {\n\t\t\t *          return null;\n\t\t\t *        }\n\t\t\t *\n\t\t\t *        // Check prefixed by currency\n\t\t\t *        if ( data.charAt(0) == '$' || data.charAt(0) == '&pound;' ) {\n\t\t\t *          return 'currency';\n\t\t\t *        }\n\t\t\t *        return null;\n\t\t\t *      }\n\t\t\t *    );\n\t\t\t */\n\t\t\tdetect: [],\n\t\n\t\n\t\t\t/**\n\t\t\t * Type based search formatting.\n\t\t\t *\n\t\t\t * The type based searching functions can be used to pre-format the\n\t\t\t * data to be search on. For example, it can be used to strip HTML\n\t\t\t * tags or to de-format telephone numbers for numeric only searching.\n\t\t\t *\n\t\t\t * Note that is a search is not defined for a column of a given type,\n\t\t\t * no search formatting will be performed.\n\t\t\t * \n\t\t\t * Pre-processing of searching data plug-ins - When you assign the sType\n\t\t\t * for a column (or have it automatically detected for you by DataTables\n\t\t\t * or a type detection plug-in), you will typically be using this for\n\t\t\t * custom sorting, but it can also be used to provide custom searching\n\t\t\t * by allowing you to pre-processing the data and returning the data in\n\t\t\t * the format that should be searched upon. This is done by adding\n\t\t\t * functions this object with a parameter name which matches the sType\n\t\t\t * for that target column. This is the corollary of <i>afnSortData</i>\n\t\t\t * for searching data.\n\t\t\t *\n\t\t\t * The functions defined take a single parameter:\n\t\t\t *\n\t\t     *  1. `{*}` Data from the column cell to be prepared for searching\n\t\t\t *\n\t\t\t * Each function is expected to return:\n\t\t\t *\n\t\t\t * * `{string|null}` Formatted string that will be used for the searching.\n\t\t\t *\n\t\t\t *  @type object\n\t\t\t *  @default {}\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {\n\t\t\t *      return d.replace(/\\n/g,\" \").replace( /<.*?>/g, \"\" );\n\t\t\t *    }\n\t\t\t */\n\t\t\tsearch: {},\n\t\n\t\n\t\t\t/**\n\t\t\t * Type based ordering.\n\t\t\t *\n\t\t\t * The column type tells DataTables what ordering to apply to the table\n\t\t\t * when a column is sorted upon. The order for each type that is defined,\n\t\t\t * is defined by the functions available in this object.\n\t\t\t *\n\t\t\t * Each ordering option can be described by three properties added to\n\t\t\t * this object:\n\t\t\t *\n\t\t\t * * `{type}-pre` - Pre-formatting function\n\t\t\t * * `{type}-asc` - Ascending order function\n\t\t\t * * `{type}-desc` - Descending order function\n\t\t\t *\n\t\t\t * All three can be used together, only `{type}-pre` or only\n\t\t\t * `{type}-asc` and `{type}-desc` together. It is generally recommended\n\t\t\t * that only `{type}-pre` is used, as this provides the optimal\n\t\t\t * implementation in terms of speed, although the others are provided\n\t\t\t * for compatibility with existing Javascript sort functions.\n\t\t\t *\n\t\t\t * `{type}-pre`: Functions defined take a single parameter:\n\t\t\t *\n\t\t     *  1. `{*}` Data from the column cell to be prepared for ordering\n\t\t\t *\n\t\t\t * And return:\n\t\t\t *\n\t\t\t * * `{*}` Data to be sorted upon\n\t\t\t *\n\t\t\t * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort\n\t\t\t * functions, taking two parameters:\n\t\t\t *\n\t\t     *  1. `{*}` Data to compare to the second parameter\n\t\t     *  2. `{*}` Data to compare to the first parameter\n\t\t\t *\n\t\t\t * And returning:\n\t\t\t *\n\t\t\t * * `{*}` Ordering match: <0 if first parameter should be sorted lower\n\t\t\t *   than the second parameter, ===0 if the two parameters are equal and\n\t\t\t *   >0 if the first parameter should be sorted height than the second\n\t\t\t *   parameter.\n\t\t\t * \n\t\t\t *  @type object\n\t\t\t *  @default {}\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    // Numeric ordering of formatted numbers with a pre-formatter\n\t\t\t *    $.extend( $.fn.dataTable.ext.type.order, {\n\t\t\t *      \"string-pre\": function(x) {\n\t\t\t *        a = (a === \"-\" || a === \"\") ? 0 : a.replace( /[^\\d\\-\\.]/g, \"\" );\n\t\t\t *        return parseFloat( a );\n\t\t\t *      }\n\t\t\t *    } );\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    // Case-sensitive string ordering, with no pre-formatting method\n\t\t\t *    $.extend( $.fn.dataTable.ext.order, {\n\t\t\t *      \"string-case-asc\": function(x,y) {\n\t\t\t *        return ((x < y) ? -1 : ((x > y) ? 1 : 0));\n\t\t\t *      },\n\t\t\t *      \"string-case-desc\": function(x,y) {\n\t\t\t *        return ((x < y) ? 1 : ((x > y) ? -1 : 0));\n\t\t\t *      }\n\t\t\t *    } );\n\t\t\t */\n\t\t\torder: {}\n\t\t},\n\t\n\t\t/**\n\t\t * Unique DataTables instance counter\n\t\t *\n\t\t * @type int\n\t\t * @private\n\t\t */\n\t\t_unique: 0,\n\t\n\t\n\t\t//\n\t\t// Depreciated\n\t\t// The following properties are retained for backwards compatiblity only.\n\t\t// The should not be used in new projects and will be removed in a future\n\t\t// version\n\t\t//\n\t\n\t\t/**\n\t\t * Version check function.\n\t\t *  @type function\n\t\t *  @depreciated Since 1.10\n\t\t */\n\t\tfnVersionCheck: DataTable.fnVersionCheck,\n\t\n\t\n\t\t/**\n\t\t * Index for what 'this' index API functions should use\n\t\t *  @type int\n\t\t *  @deprecated Since v1.10\n\t\t */\n\t\tiApiIndex: 0,\n\t\n\t\n\t\t/**\n\t\t * jQuery UI class container\n\t\t *  @type object\n\t\t *  @deprecated Since v1.10\n\t\t */\n\t\toJUIClasses: {},\n\t\n\t\n\t\t/**\n\t\t * Software version\n\t\t *  @type string\n\t\t *  @deprecated Since v1.10\n\t\t */\n\t\tsVersion: DataTable.version\n\t};\n\t\n\t\n\t//\n\t// Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts\n\t//\n\t$.extend( _ext, {\n\t\tafnFiltering: _ext.search,\n\t\taTypes:       _ext.type.detect,\n\t\tofnSearch:    _ext.type.search,\n\t\toSort:        _ext.type.order,\n\t\tafnSortData:  _ext.order,\n\t\taoFeatures:   _ext.feature,\n\t\toApi:         _ext.internal,\n\t\toStdClasses:  _ext.classes,\n\t\toPagination:  _ext.pager\n\t} );\n\t\n\t\n\t$.extend( DataTable.ext.classes, {\n\t\t\"sTable\": \"dataTable\",\n\t\t\"sNoFooter\": \"no-footer\",\n\t\n\t\t/* Paging buttons */\n\t\t\"sPageButton\": \"paginate_button\",\n\t\t\"sPageButtonActive\": \"current\",\n\t\t\"sPageButtonDisabled\": \"disabled\",\n\t\n\t\t/* Striping classes */\n\t\t\"sStripeOdd\": \"odd\",\n\t\t\"sStripeEven\": \"even\",\n\t\n\t\t/* Empty row */\n\t\t\"sRowEmpty\": \"dataTables_empty\",\n\t\n\t\t/* Features */\n\t\t\"sWrapper\": \"dataTables_wrapper\",\n\t\t\"sFilter\": \"dataTables_filter\",\n\t\t\"sInfo\": \"dataTables_info\",\n\t\t\"sPaging\": \"dataTables_paginate paging_\", /* Note that the type is postfixed */\n\t\t\"sLength\": \"dataTables_length\",\n\t\t\"sProcessing\": \"dataTables_processing\",\n\t\n\t\t/* Sorting */\n\t\t\"sSortAsc\": \"sorting_asc\",\n\t\t\"sSortDesc\": \"sorting_desc\",\n\t\t\"sSortable\": \"sorting\", /* Sortable in both directions */\n\t\t\"sSortableAsc\": \"sorting_asc_disabled\",\n\t\t\"sSortableDesc\": \"sorting_desc_disabled\",\n\t\t\"sSortableNone\": \"sorting_disabled\",\n\t\t\"sSortColumn\": \"sorting_\", /* Note that an int is postfixed for the sorting order */\n\t\n\t\t/* Filtering */\n\t\t\"sFilterInput\": \"\",\n\t\n\t\t/* Page length */\n\t\t\"sLengthSelect\": \"\",\n\t\n\t\t/* Scrolling */\n\t\t\"sScrollWrapper\": \"dataTables_scroll\",\n\t\t\"sScrollHead\": \"dataTables_scrollHead\",\n\t\t\"sScrollHeadInner\": \"dataTables_scrollHeadInner\",\n\t\t\"sScrollBody\": \"dataTables_scrollBody\",\n\t\t\"sScrollFoot\": \"dataTables_scrollFoot\",\n\t\t\"sScrollFootInner\": \"dataTables_scrollFootInner\",\n\t\n\t\t/* Misc */\n\t\t\"sHeaderTH\": \"\",\n\t\t\"sFooterTH\": \"\",\n\t\n\t\t// Deprecated\n\t\t\"sSortJUIAsc\": \"\",\n\t\t\"sSortJUIDesc\": \"\",\n\t\t\"sSortJUI\": \"\",\n\t\t\"sSortJUIAscAllowed\": \"\",\n\t\t\"sSortJUIDescAllowed\": \"\",\n\t\t\"sSortJUIWrapper\": \"\",\n\t\t\"sSortIcon\": \"\",\n\t\t\"sJUIHeader\": \"\",\n\t\t\"sJUIFooter\": \"\"\n\t} );\n\t\n\t\n\t(function() {\n\t\n\t// Reused strings for better compression. Closure compiler appears to have a\n\t// weird edge case where it is trying to expand strings rather than use the\n\t// variable version. This results in about 200 bytes being added, for very\n\t// little preference benefit since it this run on script load only.\n\tvar _empty = '';\n\t_empty = '';\n\t\n\tvar _stateDefault = _empty + 'ui-state-default';\n\tvar _sortIcon     = _empty + 'css_right ui-icon ui-icon-';\n\tvar _headerFooter = _empty + 'fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix';\n\t\n\t$.extend( DataTable.ext.oJUIClasses, DataTable.ext.classes, {\n\t\t/* Full numbers paging buttons */\n\t\t\"sPageButton\":         \"fg-button ui-button \"+_stateDefault,\n\t\t\"sPageButtonActive\":   \"ui-state-disabled\",\n\t\t\"sPageButtonDisabled\": \"ui-state-disabled\",\n\t\n\t\t/* Features */\n\t\t\"sPaging\": \"dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi \"+\n\t\t\t\"ui-buttonset-multi paging_\", /* Note that the type is postfixed */\n\t\n\t\t/* Sorting */\n\t\t\"sSortAsc\":            _stateDefault+\" sorting_asc\",\n\t\t\"sSortDesc\":           _stateDefault+\" sorting_desc\",\n\t\t\"sSortable\":           _stateDefault+\" sorting\",\n\t\t\"sSortableAsc\":        _stateDefault+\" sorting_asc_disabled\",\n\t\t\"sSortableDesc\":       _stateDefault+\" sorting_desc_disabled\",\n\t\t\"sSortableNone\":       _stateDefault+\" sorting_disabled\",\n\t\t\"sSortJUIAsc\":         _sortIcon+\"triangle-1-n\",\n\t\t\"sSortJUIDesc\":        _sortIcon+\"triangle-1-s\",\n\t\t\"sSortJUI\":            _sortIcon+\"carat-2-n-s\",\n\t\t\"sSortJUIAscAllowed\":  _sortIcon+\"carat-1-n\",\n\t\t\"sSortJUIDescAllowed\": _sortIcon+\"carat-1-s\",\n\t\t\"sSortJUIWrapper\":     \"DataTables_sort_wrapper\",\n\t\t\"sSortIcon\":           \"DataTables_sort_icon\",\n\t\n\t\t/* Scrolling */\n\t\t\"sScrollHead\": \"dataTables_scrollHead \"+_stateDefault,\n\t\t\"sScrollFoot\": \"dataTables_scrollFoot \"+_stateDefault,\n\t\n\t\t/* Misc */\n\t\t\"sHeaderTH\":  _stateDefault,\n\t\t\"sFooterTH\":  _stateDefault,\n\t\t\"sJUIHeader\": _headerFooter+\" ui-corner-tl ui-corner-tr\",\n\t\t\"sJUIFooter\": _headerFooter+\" ui-corner-bl ui-corner-br\"\n\t} );\n\t\n\t}());\n\t\n\t\n\t\n\tvar extPagination = DataTable.ext.pager;\n\t\n\tfunction _numbers ( page, pages ) {\n\t\tvar\n\t\t\tnumbers = [],\n\t\t\tbuttons = extPagination.numbers_length,\n\t\t\thalf = Math.floor( buttons / 2 ),\n\t\t\ti = 1;\n\t\n\t\tif ( pages <= buttons ) {\n\t\t\tnumbers = _range( 0, pages );\n\t\t}\n\t\telse if ( page <= half ) {\n\t\t\tnumbers = _range( 0, buttons-2 );\n\t\t\tnumbers.push( 'ellipsis' );\n\t\t\tnumbers.push( pages-1 );\n\t\t}\n\t\telse if ( page >= pages - 1 - half ) {\n\t\t\tnumbers = _range( pages-(buttons-2), pages );\n\t\t\tnumbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6\n\t\t\tnumbers.splice( 0, 0, 0 );\n\t\t}\n\t\telse {\n\t\t\tnumbers = _range( page-half+2, page+half-1 );\n\t\t\tnumbers.push( 'ellipsis' );\n\t\t\tnumbers.push( pages-1 );\n\t\t\tnumbers.splice( 0, 0, 'ellipsis' );\n\t\t\tnumbers.splice( 0, 0, 0 );\n\t\t}\n\t\n\t\tnumbers.DT_el = 'span';\n\t\treturn numbers;\n\t}\n\t\n\t\n\t$.extend( extPagination, {\n\t\tsimple: function ( page, pages ) {\n\t\t\treturn [ 'previous', 'next' ];\n\t\t},\n\t\n\t\tfull: function ( page, pages ) {\n\t\t\treturn [  'first', 'previous', 'next', 'last' ];\n\t\t},\n\t\n\t\tnumbers: function ( page, pages ) {\n\t\t\treturn [ _numbers(page, pages) ];\n\t\t},\n\t\n\t\tsimple_numbers: function ( page, pages ) {\n\t\t\treturn [ 'previous', _numbers(page, pages), 'next' ];\n\t\t},\n\t\n\t\tfull_numbers: function ( page, pages ) {\n\t\t\treturn [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ];\n\t\t},\n\t\n\t\t// For testing and plug-ins to use\n\t\t_numbers: _numbers,\n\t\n\t\t// Number of number buttons (including ellipsis) to show. _Must be odd!_\n\t\tnumbers_length: 7\n\t} );\n\t\n\t\n\t$.extend( true, DataTable.ext.renderer, {\n\t\tpageButton: {\n\t\t\t_: function ( settings, host, idx, buttons, page, pages ) {\n\t\t\t\tvar classes = settings.oClasses;\n\t\t\t\tvar lang = settings.oLanguage.oPaginate;\n\t\t\t\tvar aria = settings.oLanguage.oAria.paginate || {};\n\t\t\t\tvar btnDisplay, btnClass, counter=0;\n\t\n\t\t\t\tvar attach = function( container, buttons ) {\n\t\t\t\t\tvar i, ien, node, button;\n\t\t\t\t\tvar clickHandler = function ( e ) {\n\t\t\t\t\t\t_fnPageChange( settings, e.data.action, true );\n\t\t\t\t\t};\n\t\n\t\t\t\t\tfor ( i=0, ien=buttons.length ; i<ien ; i++ ) {\n\t\t\t\t\t\tbutton = buttons[i];\n\t\n\t\t\t\t\t\tif ( $.isArray( button ) ) {\n\t\t\t\t\t\t\tvar inner = $( '<'+(button.DT_el || 'div')+'/>' )\n\t\t\t\t\t\t\t\t.appendTo( container );\n\t\t\t\t\t\t\tattach( inner, button );\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tbtnDisplay = null;\n\t\t\t\t\t\t\tbtnClass = '';\n\t\n\t\t\t\t\t\t\tswitch ( button ) {\n\t\t\t\t\t\t\t\tcase 'ellipsis':\n\t\t\t\t\t\t\t\t\tcontainer.append('<span class=\"ellipsis\">&#x2026;</span>');\n\t\t\t\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\t\t\tcase 'first':\n\t\t\t\t\t\t\t\t\tbtnDisplay = lang.sFirst;\n\t\t\t\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t\t\t\t'' : ' '+classes.sPageButtonDisabled);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\t\t\tcase 'previous':\n\t\t\t\t\t\t\t\t\tbtnDisplay = lang.sPrevious;\n\t\t\t\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t\t\t\t'' : ' '+classes.sPageButtonDisabled);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\t\t\tcase 'next':\n\t\t\t\t\t\t\t\t\tbtnDisplay = lang.sNext;\n\t\t\t\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t\t\t\t'' : ' '+classes.sPageButtonDisabled);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\t\t\tcase 'last':\n\t\t\t\t\t\t\t\t\tbtnDisplay = lang.sLast;\n\t\t\t\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t\t\t\t'' : ' '+classes.sPageButtonDisabled);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\tbtnDisplay = button + 1;\n\t\t\t\t\t\t\t\t\tbtnClass = page === button ?\n\t\t\t\t\t\t\t\t\t\tclasses.sPageButtonActive : '';\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t\tif ( btnDisplay !== null ) {\n\t\t\t\t\t\t\t\tnode = $('<a>', {\n\t\t\t\t\t\t\t\t\t\t'class': classes.sPageButton+' '+btnClass,\n\t\t\t\t\t\t\t\t\t\t'aria-controls': settings.sTableId,\n\t\t\t\t\t\t\t\t\t\t'aria-label': aria[ button ],\n\t\t\t\t\t\t\t\t\t\t'data-dt-idx': counter,\n\t\t\t\t\t\t\t\t\t\t'tabindex': settings.iTabIndex,\n\t\t\t\t\t\t\t\t\t\t'id': idx === 0 && typeof button === 'string' ?\n\t\t\t\t\t\t\t\t\t\t\tsettings.sTableId +'_'+ button :\n\t\t\t\t\t\t\t\t\t\t\tnull\n\t\t\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t\t\t.html( btnDisplay )\n\t\t\t\t\t\t\t\t\t.appendTo( container );\n\t\n\t\t\t\t\t\t\t\t_fnBindAction(\n\t\t\t\t\t\t\t\t\tnode, {action: button}, clickHandler\n\t\t\t\t\t\t\t\t);\n\t\n\t\t\t\t\t\t\t\tcounter++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\t\n\t\t\t\t// IE9 throws an 'unknown error' if document.activeElement is used\n\t\t\t\t// inside an iframe or frame. Try / catch the error. Not good for\n\t\t\t\t// accessibility, but neither are frames.\n\t\t\t\tvar activeEl;\n\t\n\t\t\t\ttry {\n\t\t\t\t\t// Because this approach is destroying and recreating the paging\n\t\t\t\t\t// elements, focus is lost on the select button which is bad for\n\t\t\t\t\t// accessibility. So we want to restore focus once the draw has\n\t\t\t\t\t// completed\n\t\t\t\t\tactiveEl = $(host).find(document.activeElement).data('dt-idx');\n\t\t\t\t}\n\t\t\t\tcatch (e) {}\n\t\n\t\t\t\tattach( $(host).empty(), buttons );\n\t\n\t\t\t\tif ( activeEl ) {\n\t\t\t\t\t$(host).find( '[data-dt-idx='+activeEl+']' ).focus();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} );\n\t\n\t\n\t\n\t// Built in type detection. See model.ext.aTypes for information about\n\t// what is required from this methods.\n\t$.extend( DataTable.ext.type.detect, [\n\t\t// Plain numbers - first since V8 detects some plain numbers as dates\n\t\t// e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...).\n\t\tfunction ( d, settings )\n\t\t{\n\t\t\tvar decimal = settings.oLanguage.sDecimal;\n\t\t\treturn _isNumber( d, decimal ) ? 'num'+decimal : null;\n\t\t},\n\t\n\t\t// Dates (only those recognised by the browser's Date.parse)\n\t\tfunction ( d, settings )\n\t\t{\n\t\t\t// V8 will remove any unknown characters at the start and end of the\n\t\t\t// expression, leading to false matches such as `$245.12` or `10%` being\n\t\t\t// a valid date. See forum thread 18941 for detail.\n\t\t\tif ( d && !(d instanceof Date) && ( ! _re_date_start.test(d) || ! _re_date_end.test(d) ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tvar parsed = Date.parse(d);\n\t\t\treturn (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null;\n\t\t},\n\t\n\t\t// Formatted numbers\n\t\tfunction ( d, settings )\n\t\t{\n\t\t\tvar decimal = settings.oLanguage.sDecimal;\n\t\t\treturn _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null;\n\t\t},\n\t\n\t\t// HTML numeric\n\t\tfunction ( d, settings )\n\t\t{\n\t\t\tvar decimal = settings.oLanguage.sDecimal;\n\t\t\treturn _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null;\n\t\t},\n\t\n\t\t// HTML numeric, formatted\n\t\tfunction ( d, settings )\n\t\t{\n\t\t\tvar decimal = settings.oLanguage.sDecimal;\n\t\t\treturn _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null;\n\t\t},\n\t\n\t\t// HTML (this is strict checking - there must be html)\n\t\tfunction ( d, settings )\n\t\t{\n\t\t\treturn _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ?\n\t\t\t\t'html' : null;\n\t\t}\n\t] );\n\t\n\t\n\t\n\t// Filter formatting functions. See model.ext.ofnSearch for information about\n\t// what is required from these methods.\n\t// \n\t// Note that additional search methods are added for the html numbers and\n\t// html formatted numbers by `_addNumericSort()` when we know what the decimal\n\t// place is\n\t\n\t\n\t$.extend( DataTable.ext.type.search, {\n\t\thtml: function ( data ) {\n\t\t\treturn _empty(data) ?\n\t\t\t\tdata :\n\t\t\t\ttypeof data === 'string' ?\n\t\t\t\t\tdata\n\t\t\t\t\t\t.replace( _re_new_lines, \" \" )\n\t\t\t\t\t\t.replace( _re_html, \"\" ) :\n\t\t\t\t\t'';\n\t\t},\n\t\n\t\tstring: function ( data ) {\n\t\t\treturn _empty(data) ?\n\t\t\t\tdata :\n\t\t\t\ttypeof data === 'string' ?\n\t\t\t\t\tdata.replace( _re_new_lines, \" \" ) :\n\t\t\t\t\tdata;\n\t\t}\n\t} );\n\t\n\t\n\t\n\tvar __numericReplace = function ( d, decimalPlace, re1, re2 ) {\n\t\tif ( d !== 0 && (!d || d === '-') ) {\n\t\t\treturn -Infinity;\n\t\t}\n\t\n\t\t// If a decimal place other than `.` is used, it needs to be given to the\n\t\t// function so we can detect it and replace with a `.` which is the only\n\t\t// decimal place Javascript recognises - it is not locale aware.\n\t\tif ( decimalPlace ) {\n\t\t\td = _numToDecimal( d, decimalPlace );\n\t\t}\n\t\n\t\tif ( d.replace ) {\n\t\t\tif ( re1 ) {\n\t\t\t\td = d.replace( re1, '' );\n\t\t\t}\n\t\n\t\t\tif ( re2 ) {\n\t\t\t\td = d.replace( re2, '' );\n\t\t\t}\n\t\t}\n\t\n\t\treturn d * 1;\n\t};\n\t\n\t\n\t// Add the numeric 'deformatting' functions for sorting and search. This is done\n\t// in a function to provide an easy ability for the language options to add\n\t// additional methods if a non-period decimal place is used.\n\tfunction _addNumericSort ( decimalPlace ) {\n\t\t$.each(\n\t\t\t{\n\t\t\t\t// Plain numbers\n\t\t\t\t\"num\": function ( d ) {\n\t\t\t\t\treturn __numericReplace( d, decimalPlace );\n\t\t\t\t},\n\t\n\t\t\t\t// Formatted numbers\n\t\t\t\t\"num-fmt\": function ( d ) {\n\t\t\t\t\treturn __numericReplace( d, decimalPlace, _re_formatted_numeric );\n\t\t\t\t},\n\t\n\t\t\t\t// HTML numeric\n\t\t\t\t\"html-num\": function ( d ) {\n\t\t\t\t\treturn __numericReplace( d, decimalPlace, _re_html );\n\t\t\t\t},\n\t\n\t\t\t\t// HTML numeric, formatted\n\t\t\t\t\"html-num-fmt\": function ( d ) {\n\t\t\t\t\treturn __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric );\n\t\t\t\t}\n\t\t\t},\n\t\t\tfunction ( key, fn ) {\n\t\t\t\t// Add the ordering method\n\t\t\t\t_ext.type.order[ key+decimalPlace+'-pre' ] = fn;\n\t\n\t\t\t\t// For HTML types add a search formatter that will strip the HTML\n\t\t\t\tif ( key.match(/^html\\-/) ) {\n\t\t\t\t\t_ext.type.search[ key+decimalPlace ] = _ext.type.search.html;\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t}\n\t\n\t\n\t// Default sort methods\n\t$.extend( _ext.type.order, {\n\t\t// Dates\n\t\t\"date-pre\": function ( d ) {\n\t\t\treturn Date.parse( d ) || 0;\n\t\t},\n\t\n\t\t// html\n\t\t\"html-pre\": function ( a ) {\n\t\t\treturn _empty(a) ?\n\t\t\t\t'' :\n\t\t\t\ta.replace ?\n\t\t\t\t\ta.replace( /<.*?>/g, \"\" ).toLowerCase() :\n\t\t\t\t\ta+'';\n\t\t},\n\t\n\t\t// string\n\t\t\"string-pre\": function ( a ) {\n\t\t\t// This is a little complex, but faster than always calling toString,\n\t\t\t// http://jsperf.com/tostring-v-check\n\t\t\treturn _empty(a) ?\n\t\t\t\t'' :\n\t\t\t\ttypeof a === 'string' ?\n\t\t\t\t\ta.toLowerCase() :\n\t\t\t\t\t! a.toString ?\n\t\t\t\t\t\t'' :\n\t\t\t\t\t\ta.toString();\n\t\t},\n\t\n\t\t// string-asc and -desc are retained only for compatibility with the old\n\t\t// sort methods\n\t\t\"string-asc\": function ( x, y ) {\n\t\t\treturn ((x < y) ? -1 : ((x > y) ? 1 : 0));\n\t\t},\n\t\n\t\t\"string-desc\": function ( x, y ) {\n\t\t\treturn ((x < y) ? 1 : ((x > y) ? -1 : 0));\n\t\t}\n\t} );\n\t\n\t\n\t// Numeric sorting types - order doesn't matter here\n\t_addNumericSort( '' );\n\t\n\t\n\t$.extend( true, DataTable.ext.renderer, {\n\t\theader: {\n\t\t\t_: function ( settings, cell, column, classes ) {\n\t\t\t\t// No additional mark-up required\n\t\t\t\t// Attach a sort listener to update on sort - note that using the\n\t\t\t\t// `DT` namespace will allow the event to be removed automatically\n\t\t\t\t// on destroy, while the `dt` namespaced event is the one we are\n\t\t\t\t// listening for\n\t\t\t\t$(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {\n\t\t\t\t\tif ( settings !== ctx ) { // need to check this this is the host\n\t\t\t\t\t\treturn;               // table, not a nested one\n\t\t\t\t\t}\n\t\n\t\t\t\t\tvar colIdx = column.idx;\n\t\n\t\t\t\t\tcell\n\t\t\t\t\t\t.removeClass(\n\t\t\t\t\t\t\tcolumn.sSortingClass +' '+\n\t\t\t\t\t\t\tclasses.sSortAsc +' '+\n\t\t\t\t\t\t\tclasses.sSortDesc\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.addClass( columns[ colIdx ] == 'asc' ?\n\t\t\t\t\t\t\tclasses.sSortAsc : columns[ colIdx ] == 'desc' ?\n\t\t\t\t\t\t\t\tclasses.sSortDesc :\n\t\t\t\t\t\t\t\tcolumn.sSortingClass\n\t\t\t\t\t\t);\n\t\t\t\t} );\n\t\t\t},\n\t\n\t\t\tjqueryui: function ( settings, cell, column, classes ) {\n\t\t\t\t$('<div/>')\n\t\t\t\t\t.addClass( classes.sSortJUIWrapper )\n\t\t\t\t\t.append( cell.contents() )\n\t\t\t\t\t.append( $('<span/>')\n\t\t\t\t\t\t.addClass( classes.sSortIcon+' '+column.sSortingClassJUI )\n\t\t\t\t\t)\n\t\t\t\t\t.appendTo( cell );\n\t\n\t\t\t\t// Attach a sort listener to update on sort\n\t\t\t\t$(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {\n\t\t\t\t\tif ( settings !== ctx ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\n\t\t\t\t\tvar colIdx = column.idx;\n\t\n\t\t\t\t\tcell\n\t\t\t\t\t\t.removeClass( classes.sSortAsc +\" \"+classes.sSortDesc )\n\t\t\t\t\t\t.addClass( columns[ colIdx ] == 'asc' ?\n\t\t\t\t\t\t\tclasses.sSortAsc : columns[ colIdx ] == 'desc' ?\n\t\t\t\t\t\t\t\tclasses.sSortDesc :\n\t\t\t\t\t\t\t\tcolumn.sSortingClass\n\t\t\t\t\t\t);\n\t\n\t\t\t\t\tcell\n\t\t\t\t\t\t.find( 'span.'+classes.sSortIcon )\n\t\t\t\t\t\t.removeClass(\n\t\t\t\t\t\t\tclasses.sSortJUIAsc +\" \"+\n\t\t\t\t\t\t\tclasses.sSortJUIDesc +\" \"+\n\t\t\t\t\t\t\tclasses.sSortJUI +\" \"+\n\t\t\t\t\t\t\tclasses.sSortJUIAscAllowed +\" \"+\n\t\t\t\t\t\t\tclasses.sSortJUIDescAllowed\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.addClass( columns[ colIdx ] == 'asc' ?\n\t\t\t\t\t\t\tclasses.sSortJUIAsc : columns[ colIdx ] == 'desc' ?\n\t\t\t\t\t\t\t\tclasses.sSortJUIDesc :\n\t\t\t\t\t\t\t\tcolumn.sSortingClassJUI\n\t\t\t\t\t\t);\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t} );\n\t\n\t/*\n\t * Public helper functions. These aren't used internally by DataTables, or\n\t * called by any of the options passed into DataTables, but they can be used\n\t * externally by developers working with DataTables. They are helper functions\n\t * to make working with DataTables a little bit easier.\n\t */\n\t\n\tvar __htmlEscapeEntities = function ( d ) {\n\t\treturn typeof d === 'string' ?\n\t\t\td.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;') :\n\t\t\td;\n\t};\n\t\n\t/**\n\t * Helpers for `columns.render`.\n\t *\n\t * The options defined here can be used with the `columns.render` initialisation\n\t * option to provide a display renderer. The following functions are defined:\n\t *\n\t * * `number` - Will format numeric data (defined by `columns.data`) for\n\t *   display, retaining the original unformatted data for sorting and filtering.\n\t *   It takes 5 parameters:\n\t *   * `string` - Thousands grouping separator\n\t *   * `string` - Decimal point indicator\n\t *   * `integer` - Number of decimal points to show\n\t *   * `string` (optional) - Prefix.\n\t *   * `string` (optional) - Postfix (/suffix).\n\t * * `text` - Escape HTML to help prevent XSS attacks. It has no optional\n\t *   parameters.\n\t *\n\t * @example\n\t *   // Column definition using the number renderer\n\t *   {\n\t *     data: \"salary\",\n\t *     render: $.fn.dataTable.render.number( '\\'', '.', 0, '$' )\n\t *   }\n\t *\n\t * @namespace\n\t */\n\tDataTable.render = {\n\t\tnumber: function ( thousands, decimal, precision, prefix, postfix ) {\n\t\t\treturn {\n\t\t\t\tdisplay: function ( d ) {\n\t\t\t\t\tif ( typeof d !== 'number' && typeof d !== 'string' ) {\n\t\t\t\t\t\treturn d;\n\t\t\t\t\t}\n\t\n\t\t\t\t\tvar negative = d < 0 ? '-' : '';\n\t\t\t\t\tvar flo = parseFloat( d );\n\t\n\t\t\t\t\t// If NaN then there isn't much formatting that we can do - just\n\t\t\t\t\t// return immediately, escaping any HTML (this was supposed to\n\t\t\t\t\t// be a number after all)\n\t\t\t\t\tif ( isNaN( flo ) ) {\n\t\t\t\t\t\treturn __htmlEscapeEntities( d );\n\t\t\t\t\t}\n\t\n\t\t\t\t\td = Math.abs( flo );\n\t\n\t\t\t\t\tvar intPart = parseInt( d, 10 );\n\t\t\t\t\tvar floatPart = precision ?\n\t\t\t\t\t\tdecimal+(d - intPart).toFixed( precision ).substring( 2 ):\n\t\t\t\t\t\t'';\n\t\n\t\t\t\t\treturn negative + (prefix||'') +\n\t\t\t\t\t\tintPart.toString().replace(\n\t\t\t\t\t\t\t/\\B(?=(\\d{3})+(?!\\d))/g, thousands\n\t\t\t\t\t\t) +\n\t\t\t\t\t\tfloatPart +\n\t\t\t\t\t\t(postfix||'');\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\t\n\t\ttext: function () {\n\t\t\treturn {\n\t\t\t\tdisplay: __htmlEscapeEntities\n\t\t\t};\n\t\t}\n\t};\n\t\n\t\n\t/*\n\t * This is really a good bit rubbish this method of exposing the internal methods\n\t * publicly... - To be fixed in 2.0 using methods on the prototype\n\t */\n\t\n\t\n\t/**\n\t * Create a wrapper function for exporting an internal functions to an external API.\n\t *  @param {string} fn API function name\n\t *  @returns {function} wrapped function\n\t *  @memberof DataTable#internal\n\t */\n\tfunction _fnExternApiFunc (fn)\n\t{\n\t\treturn function() {\n\t\t\tvar args = [_fnSettingsFromNode( this[DataTable.ext.iApiIndex] )].concat(\n\t\t\t\tArray.prototype.slice.call(arguments)\n\t\t\t);\n\t\t\treturn DataTable.ext.internal[fn].apply( this, args );\n\t\t};\n\t}\n\t\n\t\n\t/**\n\t * Reference to internal functions for use by plug-in developers. Note that\n\t * these methods are references to internal functions and are considered to be\n\t * private. If you use these methods, be aware that they are liable to change\n\t * between versions.\n\t *  @namespace\n\t */\n\t$.extend( DataTable.ext.internal, {\n\t\t_fnExternApiFunc: _fnExternApiFunc,\n\t\t_fnBuildAjax: _fnBuildAjax,\n\t\t_fnAjaxUpdate: _fnAjaxUpdate,\n\t\t_fnAjaxParameters: _fnAjaxParameters,\n\t\t_fnAjaxUpdateDraw: _fnAjaxUpdateDraw,\n\t\t_fnAjaxDataSrc: _fnAjaxDataSrc,\n\t\t_fnAddColumn: _fnAddColumn,\n\t\t_fnColumnOptions: _fnColumnOptions,\n\t\t_fnAdjustColumnSizing: _fnAdjustColumnSizing,\n\t\t_fnVisibleToColumnIndex: _fnVisibleToColumnIndex,\n\t\t_fnColumnIndexToVisible: _fnColumnIndexToVisible,\n\t\t_fnVisbleColumns: _fnVisbleColumns,\n\t\t_fnGetColumns: _fnGetColumns,\n\t\t_fnColumnTypes: _fnColumnTypes,\n\t\t_fnApplyColumnDefs: _fnApplyColumnDefs,\n\t\t_fnHungarianMap: _fnHungarianMap,\n\t\t_fnCamelToHungarian: _fnCamelToHungarian,\n\t\t_fnLanguageCompat: _fnLanguageCompat,\n\t\t_fnBrowserDetect: _fnBrowserDetect,\n\t\t_fnAddData: _fnAddData,\n\t\t_fnAddTr: _fnAddTr,\n\t\t_fnNodeToDataIndex: _fnNodeToDataIndex,\n\t\t_fnNodeToColumnIndex: _fnNodeToColumnIndex,\n\t\t_fnGetCellData: _fnGetCellData,\n\t\t_fnSetCellData: _fnSetCellData,\n\t\t_fnSplitObjNotation: _fnSplitObjNotation,\n\t\t_fnGetObjectDataFn: _fnGetObjectDataFn,\n\t\t_fnSetObjectDataFn: _fnSetObjectDataFn,\n\t\t_fnGetDataMaster: _fnGetDataMaster,\n\t\t_fnClearTable: _fnClearTable,\n\t\t_fnDeleteIndex: _fnDeleteIndex,\n\t\t_fnInvalidate: _fnInvalidate,\n\t\t_fnGetRowElements: _fnGetRowElements,\n\t\t_fnCreateTr: _fnCreateTr,\n\t\t_fnBuildHead: _fnBuildHead,\n\t\t_fnDrawHead: _fnDrawHead,\n\t\t_fnDraw: _fnDraw,\n\t\t_fnReDraw: _fnReDraw,\n\t\t_fnAddOptionsHtml: _fnAddOptionsHtml,\n\t\t_fnDetectHeader: _fnDetectHeader,\n\t\t_fnGetUniqueThs: _fnGetUniqueThs,\n\t\t_fnFeatureHtmlFilter: _fnFeatureHtmlFilter,\n\t\t_fnFilterComplete: _fnFilterComplete,\n\t\t_fnFilterCustom: _fnFilterCustom,\n\t\t_fnFilterColumn: _fnFilterColumn,\n\t\t_fnFilter: _fnFilter,\n\t\t_fnFilterCreateSearch: _fnFilterCreateSearch,\n\t\t_fnEscapeRegex: _fnEscapeRegex,\n\t\t_fnFilterData: _fnFilterData,\n\t\t_fnFeatureHtmlInfo: _fnFeatureHtmlInfo,\n\t\t_fnUpdateInfo: _fnUpdateInfo,\n\t\t_fnInfoMacros: _fnInfoMacros,\n\t\t_fnInitialise: _fnInitialise,\n\t\t_fnInitComplete: _fnInitComplete,\n\t\t_fnLengthChange: _fnLengthChange,\n\t\t_fnFeatureHtmlLength: _fnFeatureHtmlLength,\n\t\t_fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate,\n\t\t_fnPageChange: _fnPageChange,\n\t\t_fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing,\n\t\t_fnProcessingDisplay: _fnProcessingDisplay,\n\t\t_fnFeatureHtmlTable: _fnFeatureHtmlTable,\n\t\t_fnScrollDraw: _fnScrollDraw,\n\t\t_fnApplyToChildren: _fnApplyToChildren,\n\t\t_fnCalculateColumnWidths: _fnCalculateColumnWidths,\n\t\t_fnThrottle: _fnThrottle,\n\t\t_fnConvertToWidth: _fnConvertToWidth,\n\t\t_fnGetWidestNode: _fnGetWidestNode,\n\t\t_fnGetMaxLenString: _fnGetMaxLenString,\n\t\t_fnStringToCss: _fnStringToCss,\n\t\t_fnSortFlatten: _fnSortFlatten,\n\t\t_fnSort: _fnSort,\n\t\t_fnSortAria: _fnSortAria,\n\t\t_fnSortListener: _fnSortListener,\n\t\t_fnSortAttachListener: _fnSortAttachListener,\n\t\t_fnSortingClasses: _fnSortingClasses,\n\t\t_fnSortData: _fnSortData,\n\t\t_fnSaveState: _fnSaveState,\n\t\t_fnLoadState: _fnLoadState,\n\t\t_fnSettingsFromNode: _fnSettingsFromNode,\n\t\t_fnLog: _fnLog,\n\t\t_fnMap: _fnMap,\n\t\t_fnBindAction: _fnBindAction,\n\t\t_fnCallbackReg: _fnCallbackReg,\n\t\t_fnCallbackFire: _fnCallbackFire,\n\t\t_fnLengthOverflow: _fnLengthOverflow,\n\t\t_fnRenderer: _fnRenderer,\n\t\t_fnDataSource: _fnDataSource,\n\t\t_fnRowAttributes: _fnRowAttributes,\n\t\t_fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant\n\t\t                                // in 1.10, so this dead-end function is\n\t\t                                // added to prevent errors\n\t} );\n\t\n\n\t// jQuery access\n\t$.fn.dataTable = DataTable;\n\n\t// Provide access to the host jQuery object (circular reference)\n\tDataTable.$ = $;\n\n\t// Legacy aliases\n\t$.fn.dataTableSettings = DataTable.settings;\n\t$.fn.dataTableExt = DataTable.ext;\n\n\t// With a capital `D` we return a DataTables API instance rather than a\n\t// jQuery object\n\t$.fn.DataTable = function ( opts ) {\n\t\treturn $(this).dataTable( opts ).api();\n\t};\n\n\t// All properties that are available to $.fn.dataTable should also be\n\t// available on $.fn.DataTable\n\t$.each( DataTable, function ( prop, val ) {\n\t\t$.fn.DataTable[ prop ] = val;\n\t} );\n\n\n\t// Information about events fired by DataTables - for documentation.\n\t/**\n\t * Draw event, fired whenever the table is redrawn on the page, at the same\n\t * point as fnDrawCallback. This may be useful for binding events or\n\t * performing calculations when the table is altered at all.\n\t *  @name DataTable#draw.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t */\n\n\t/**\n\t * Search event, fired when the searching applied to the table (using the\n\t * built-in global search, or column filters) is altered.\n\t *  @name DataTable#search.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t */\n\n\t/**\n\t * Page change event, fired when the paging of the table is altered.\n\t *  @name DataTable#page.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t */\n\n\t/**\n\t * Order event, fired when the ordering applied to the table is altered.\n\t *  @name DataTable#order.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t */\n\n\t/**\n\t * DataTables initialisation complete event, fired when the table is fully\n\t * drawn, including Ajax data loaded, if Ajax data is required.\n\t *  @name DataTable#init.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} oSettings DataTables settings object\n\t *  @param {object} json The JSON object request from the server - only\n\t *    present if client-side Ajax sourced data is used</li></ol>\n\t */\n\n\t/**\n\t * State save event, fired when the table has changed state a new state save\n\t * is required. This event allows modification of the state saving object\n\t * prior to actually doing the save, including addition or other state\n\t * properties (for plug-ins) or modification of a DataTables core property.\n\t *  @name DataTable#stateSaveParams.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} oSettings DataTables settings object\n\t *  @param {object} json The state information to be saved\n\t */\n\n\t/**\n\t * State load event, fired when the table is loading state from the stored\n\t * data, but prior to the settings object being modified by the saved state\n\t * - allowing modification of the saved state is required or loading of\n\t * state for a plug-in.\n\t *  @name DataTable#stateLoadParams.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} oSettings DataTables settings object\n\t *  @param {object} json The saved state information\n\t */\n\n\t/**\n\t * State loaded event, fired when state has been loaded from stored data and\n\t * the settings object has been modified by the loaded data.\n\t *  @name DataTable#stateLoaded.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} oSettings DataTables settings object\n\t *  @param {object} json The saved state information\n\t */\n\n\t/**\n\t * Processing event, fired when DataTables is doing some kind of processing\n\t * (be it, order, searcg or anything else). It can be used to indicate to\n\t * the end user that there is something happening, or that something has\n\t * finished.\n\t *  @name DataTable#processing.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} oSettings DataTables settings object\n\t *  @param {boolean} bShow Flag for if DataTables is doing processing or not\n\t */\n\n\t/**\n\t * Ajax (XHR) event, fired whenever an Ajax request is completed from a\n\t * request to made to the server for new data. This event is called before\n\t * DataTables processed the returned data, so it can also be used to pre-\n\t * process the data returned from the server, if needed.\n\t *\n\t * Note that this trigger is called in `fnServerData`, if you override\n\t * `fnServerData` and which to use this event, you need to trigger it in you\n\t * success function.\n\t *  @name DataTable#xhr.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t *  @param {object} json JSON returned from the server\n\t *\n\t *  @example\n\t *     // Use a custom property returned from the server in another DOM element\n\t *     $('#table').dataTable().on('xhr.dt', function (e, settings, json) {\n\t *       $('#status').html( json.status );\n\t *     } );\n\t *\n\t *  @example\n\t *     // Pre-process the data returned from the server\n\t *     $('#table').dataTable().on('xhr.dt', function (e, settings, json) {\n\t *       for ( var i=0, ien=json.aaData.length ; i<ien ; i++ ) {\n\t *         json.aaData[i].sum = json.aaData[i].one + json.aaData[i].two;\n\t *       }\n\t *       // Note no return - manipulate the data directly in the JSON object.\n\t *     } );\n\t */\n\n\t/**\n\t * Destroy event, fired when the DataTable is destroyed by calling fnDestroy\n\t * or passing the bDestroy:true parameter in the initialisation object. This\n\t * can be used to remove bound events, added DOM nodes, etc.\n\t *  @name DataTable#destroy.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t */\n\n\t/**\n\t * Page length change event, fired when number of records to show on each\n\t * page (the length) is changed.\n\t *  @name DataTable#length.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t *  @param {integer} len New length\n\t */\n\n\t/**\n\t * Column sizing has changed.\n\t *  @name DataTable#column-sizing.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t */\n\n\t/**\n\t * Column visibility has changed.\n\t *  @name DataTable#column-visibility.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t *  @param {int} column Column index\n\t *  @param {bool} vis `false` if column now hidden, or `true` if visible\n\t */\n\n\treturn $.fn.dataTable;\n}));\n"
  },
  {
    "path": "static/plugins/layer/layer.js",
    "content": "/*! layer-v2.4 弹层组件 License LGPL  http://layer.layui.com/ By 贤心 */\n;!function(a,b){\"use strict\";var c,d,e={getPath:function(){var a=document.scripts,b=a[a.length-1],c=b.src;if(!b.getAttribute(\"merge\"))return c.substring(0,c.lastIndexOf(\"/\")+1)}(),enter:function(a){13===a.keyCode&&a.preventDefault()},config:{},end:{},btn:[\"&#x786E;&#x5B9A;\",\"&#x53D6;&#x6D88;\"],type:[\"dialog\",\"page\",\"iframe\",\"loading\",\"tips\"]},f={v:\"2.4\",ie6:!!a.ActiveXObject&&!a.XMLHttpRequest,index:0,path:e.getPath,config:function(a,b){var d=0;return a=a||{},f.cache=e.config=c.extend(e.config,a),f.path=e.config.path||f.path,\"string\"==typeof a.extend&&(a.extend=[a.extend]),f.use(\"skin/layer.css\",a.extend&&a.extend.length>0?function g(){var c=a.extend;f.use(c[c[d]?d:d-1],d<c.length?function(){return++d,g}():b)}():b),this},use:function(a,b,d){var e=c(\"head\")[0],a=a.replace(/\\s/g,\"\"),g=/\\.css$/.test(a),h=document.createElement(g?\"link\":\"script\"),i=\"layui_layer_\"+a.replace(/\\.|\\//g,\"\");return f.path?(g&&(h.rel=\"stylesheet\"),h[g?\"href\":\"src\"]=/^http:\\/\\//.test(a)?a:f.path+a,h.id=i,c(\"#\"+i)[0]||e.appendChild(h),function j(){(g?1989===parseInt(c(\"#\"+i).css(\"width\")):f[d||i])?function(){b&&b();try{g||e.removeChild(h)}catch(a){}}():setTimeout(j,100)}(),this):void 0},ready:function(a,b){var d=\"function\"==typeof a;return d&&(b=a),f.config(c.extend(e.config,function(){return d?{}:{path:a}}()),b),this},alert:function(a,b,d){var e=\"function\"==typeof b;return e&&(d=b),f.open(c.extend({content:a,yes:d},e?{}:b))},confirm:function(a,b,d,g){var h=\"function\"==typeof b;return h&&(g=d,d=b),f.open(c.extend({content:a,btn:e.btn,yes:d,btn2:g},h?{}:b))},msg:function(a,d,g){var i=\"function\"==typeof d,j=e.config.skin,k=(j?j+\" \"+j+\"-msg\":\"\")||\"layui-layer-msg\",l=h.anim.length-1;return i&&(g=d),f.open(c.extend({content:a,time:3e3,shade:!1,skin:k,title:!1,closeBtn:!1,btn:!1,end:g},i&&!e.config.skin?{skin:k+\" layui-layer-hui\",shift:l}:function(){return d=d||{},(-1===d.icon||d.icon===b&&!e.config.skin)&&(d.skin=k+\" \"+(d.skin||\"layui-layer-hui\")),d}()))},load:function(a,b){return f.open(c.extend({type:3,icon:a||0,shade:.01},b))},tips:function(a,b,d){return f.open(c.extend({type:4,content:[a,b],closeBtn:!1,time:3e3,shade:!1,fix:!1,maxWidth:210},d))}},g=function(a){var b=this;b.index=++f.index,b.config=c.extend({},b.config,e.config,a),b.creat()};g.pt=g.prototype;var h=[\"layui-layer\",\".layui-layer-title\",\".layui-layer-main\",\".layui-layer-dialog\",\"layui-layer-iframe\",\"layui-layer-content\",\"layui-layer-btn\",\"layui-layer-close\"];h.anim=[\"layer-anim\",\"layer-anim-01\",\"layer-anim-02\",\"layer-anim-03\",\"layer-anim-04\",\"layer-anim-05\",\"layer-anim-06\"],g.pt.config={type:0,shade:.3,fix:!0,move:h[1],title:\"&#x4FE1;&#x606F;\",offset:\"auto\",area:\"auto\",closeBtn:1,time:0,zIndex:19891014,maxWidth:360,shift:0,icon:-1,scrollbar:!0,tips:2},g.pt.vessel=function(a,b){var c=this,d=c.index,f=c.config,g=f.zIndex+d,i=\"object\"==typeof f.title,j=f.maxmin&&(1===f.type||2===f.type),k=f.title?'<div class=\"layui-layer-title\" style=\"'+(i?f.title[1]:\"\")+'\">'+(i?f.title[0]:f.title)+\"</div>\":\"\";return f.zIndex=g,b([f.shade?'<div class=\"layui-layer-shade\" id=\"layui-layer-shade'+d+'\" times=\"'+d+'\" style=\"'+(\"z-index:\"+(g-1)+\"; background-color:\"+(f.shade[1]||\"#000\")+\"; opacity:\"+(f.shade[0]||f.shade)+\"; filter:alpha(opacity=\"+(100*f.shade[0]||100*f.shade)+\");\")+'\"></div>':\"\",'<div class=\"'+h[0]+(\" layui-layer-\"+e.type[f.type])+(0!=f.type&&2!=f.type||f.shade?\"\":\" layui-layer-border\")+\" \"+(f.skin||\"\")+'\" id=\"'+h[0]+d+'\" type=\"'+e.type[f.type]+'\" times=\"'+d+'\" showtime=\"'+f.time+'\" conType=\"'+(a?\"object\":\"string\")+'\" style=\"z-index: '+g+\"; width:\"+f.area[0]+\";height:\"+f.area[1]+(f.fix?\"\":\";position:absolute;\")+'\">'+(a&&2!=f.type?\"\":k)+'<div id=\"'+(f.id||\"\")+'\" class=\"layui-layer-content'+(0==f.type&&-1!==f.icon?\" layui-layer-padding\":\"\")+(3==f.type?\" layui-layer-loading\"+f.icon:\"\")+'\">'+(0==f.type&&-1!==f.icon?'<i class=\"layui-layer-ico layui-layer-ico'+f.icon+'\"></i>':\"\")+(1==f.type&&a?\"\":f.content||\"\")+'</div><span class=\"layui-layer-setwin\">'+function(){var a=j?'<a class=\"layui-layer-min\" href=\"javascript:;\"><cite></cite></a><a class=\"layui-layer-ico layui-layer-max\" href=\"javascript:;\"></a>':\"\";return f.closeBtn&&(a+='<a class=\"layui-layer-ico '+h[7]+\" \"+h[7]+(f.title?f.closeBtn:4==f.type?\"1\":\"2\")+'\" href=\"javascript:;\"></a>'),a}()+\"</span>\"+(f.btn?function(){var a=\"\";\"string\"==typeof f.btn&&(f.btn=[f.btn]);for(var b=0,c=f.btn.length;c>b;b++)a+='<a class=\"'+h[6]+b+'\">'+f.btn[b]+\"</a>\";return'<div class=\"'+h[6]+'\">'+a+\"</div>\"}():\"\")+\"</div>\"],k),c},g.pt.creat=function(){var a=this,b=a.config,g=a.index,i=b.content,j=\"object\"==typeof i;if(!c(\"#\"+b.id)[0]){switch(\"string\"==typeof b.area&&(b.area=\"auto\"===b.area?[\"\",\"\"]:[b.area,\"\"]),b.type){case 0:b.btn=\"btn\"in b?b.btn:e.btn[0],f.closeAll(\"dialog\");break;case 2:var i=b.content=j?b.content:[b.content||\"http://layer.layui.com\",\"auto\"];b.content='<iframe scrolling=\"'+(b.content[1]||\"auto\")+'\" allowtransparency=\"true\" id=\"'+h[4]+g+'\" name=\"'+h[4]+g+'\" onload=\"this.className=\\'\\';\" class=\"layui-layer-load\" frameborder=\"0\" src=\"'+b.content[0]+'\"></iframe>';break;case 3:b.title=!1,b.closeBtn=!1,-1===b.icon&&0===b.icon,f.closeAll(\"loading\");break;case 4:j||(b.content=[b.content,\"body\"]),b.follow=b.content[1],b.content=b.content[0]+'<i class=\"layui-layer-TipsG\"></i>',b.title=!1,b.tips=\"object\"==typeof b.tips?b.tips:[b.tips,!0],b.tipsMore||f.closeAll(\"tips\")}a.vessel(j,function(d,e){c(\"body\").append(d[0]),j?function(){2==b.type||4==b.type?function(){c(\"body\").append(d[1])}():function(){i.parents(\".\"+h[0])[0]||(i.show().addClass(\"layui-layer-wrap\").wrap(d[1]),c(\"#\"+h[0]+g).find(\".\"+h[5]).before(e))}()}():c(\"body\").append(d[1]),a.layero=c(\"#\"+h[0]+g),b.scrollbar||h.html.css(\"overflow\",\"hidden\").attr(\"layer-full\",g)}).auto(g),2==b.type&&f.ie6&&a.layero.find(\"iframe\").attr(\"src\",i[0]),c(document).off(\"keydown\",e.enter).on(\"keydown\",e.enter),a.layero.on(\"keydown\",function(a){c(document).off(\"keydown\",e.enter)}),4==b.type?a.tips():a.offset(),b.fix&&d.on(\"resize\",function(){a.offset(),(/^\\d+%$/.test(b.area[0])||/^\\d+%$/.test(b.area[1]))&&a.auto(g),4==b.type&&a.tips()}),b.time<=0||setTimeout(function(){f.close(a.index)},b.time),a.move().callback(),h.anim[b.shift]&&a.layero.addClass(h.anim[b.shift])}},g.pt.auto=function(a){function b(a){a=g.find(a),a.height(i[1]-j-k-2*(0|parseFloat(a.css(\"padding\"))))}var e=this,f=e.config,g=c(\"#\"+h[0]+a);\"\"===f.area[0]&&f.maxWidth>0&&(/MSIE 7/.test(navigator.userAgent)&&f.btn&&g.width(g.innerWidth()),g.outerWidth()>f.maxWidth&&g.width(f.maxWidth));var i=[g.innerWidth(),g.innerHeight()],j=g.find(h[1]).outerHeight()||0,k=g.find(\".\"+h[6]).outerHeight()||0;switch(f.type){case 2:b(\"iframe\");break;default:\"\"===f.area[1]?f.fix&&i[1]>=d.height()&&(i[1]=d.height(),b(\".\"+h[5])):b(\".\"+h[5])}return e},g.pt.offset=function(){var a=this,b=a.config,c=a.layero,e=[c.outerWidth(),c.outerHeight()],f=\"object\"==typeof b.offset;a.offsetTop=(d.height()-e[1])/2,a.offsetLeft=(d.width()-e[0])/2,f?(a.offsetTop=b.offset[0],a.offsetLeft=b.offset[1]||a.offsetLeft):\"auto\"!==b.offset&&(a.offsetTop=b.offset,\"rb\"===b.offset&&(a.offsetTop=d.height()-e[1],a.offsetLeft=d.width()-e[0])),b.fix||(a.offsetTop=/%$/.test(a.offsetTop)?d.height()*parseFloat(a.offsetTop)/100:parseFloat(a.offsetTop),a.offsetLeft=/%$/.test(a.offsetLeft)?d.width()*parseFloat(a.offsetLeft)/100:parseFloat(a.offsetLeft),a.offsetTop+=d.scrollTop(),a.offsetLeft+=d.scrollLeft()),c.css({top:a.offsetTop,left:a.offsetLeft})},g.pt.tips=function(){var a=this,b=a.config,e=a.layero,f=[e.outerWidth(),e.outerHeight()],g=c(b.follow);g[0]||(g=c(\"body\"));var i={width:g.outerWidth(),height:g.outerHeight(),top:g.offset().top,left:g.offset().left},j=e.find(\".layui-layer-TipsG\"),k=b.tips[0];b.tips[1]||j.remove(),i.autoLeft=function(){i.left+f[0]-d.width()>0?(i.tipLeft=i.left+i.width-f[0],j.css({right:12,left:\"auto\"})):i.tipLeft=i.left},i.where=[function(){i.autoLeft(),i.tipTop=i.top-f[1]-10,j.removeClass(\"layui-layer-TipsB\").addClass(\"layui-layer-TipsT\").css(\"border-right-color\",b.tips[1])},function(){i.tipLeft=i.left+i.width+10,i.tipTop=i.top,j.removeClass(\"layui-layer-TipsL\").addClass(\"layui-layer-TipsR\").css(\"border-bottom-color\",b.tips[1])},function(){i.autoLeft(),i.tipTop=i.top+i.height+10,j.removeClass(\"layui-layer-TipsT\").addClass(\"layui-layer-TipsB\").css(\"border-right-color\",b.tips[1])},function(){i.tipLeft=i.left-f[0]-10,i.tipTop=i.top,j.removeClass(\"layui-layer-TipsR\").addClass(\"layui-layer-TipsL\").css(\"border-bottom-color\",b.tips[1])}],i.where[k-1](),1===k?i.top-(d.scrollTop()+f[1]+16)<0&&i.where[2]():2===k?d.width()-(i.left+i.width+f[0]+16)>0||i.where[3]():3===k?i.top-d.scrollTop()+i.height+f[1]+16-d.height()>0&&i.where[0]():4===k&&f[0]+16-i.left>0&&i.where[1](),e.find(\".\"+h[5]).css({\"background-color\":b.tips[1],\"padding-right\":b.closeBtn?\"30px\":\"\"}),e.css({left:i.tipLeft-(b.fix?d.scrollLeft():0),top:i.tipTop-(b.fix?d.scrollTop():0)})},g.pt.move=function(){var a=this,b=a.config,e={setY:0,moveLayer:function(){var a=e.layero,b=parseInt(a.css(\"margin-left\")),c=parseInt(e.move.css(\"left\"));0===b||(c-=b),\"fixed\"!==a.css(\"position\")&&(c-=a.parent().offset().left,e.setY=0),a.css({left:c,top:parseInt(e.move.css(\"top\"))-e.setY})}},f=a.layero.find(b.move);return b.move&&f.attr(\"move\",\"ok\"),f.css({cursor:b.move?\"move\":\"auto\"}),c(b.move).on(\"mousedown\",function(a){if(a.preventDefault(),\"ok\"===c(this).attr(\"move\")){e.ismove=!0,e.layero=c(this).parents(\".\"+h[0]);var f=e.layero.offset().left,g=e.layero.offset().top,i=e.layero.outerWidth()-6,j=e.layero.outerHeight()-6;c(\"#layui-layer-moves\")[0]||c(\"body\").append('<div id=\"layui-layer-moves\" class=\"layui-layer-moves\" style=\"left:'+f+\"px; top:\"+g+\"px; width:\"+i+\"px; height:\"+j+'px; z-index:2147483584\"></div>'),e.move=c(\"#layui-layer-moves\"),b.moveType&&e.move.css({visibility:\"hidden\"}),e.moveX=a.pageX-e.move.position().left,e.moveY=a.pageY-e.move.position().top,\"fixed\"!==e.layero.css(\"position\")||(e.setY=d.scrollTop())}}),c(document).mousemove(function(a){if(e.ismove){var c=a.pageX-e.moveX,f=a.pageY-e.moveY;if(a.preventDefault(),!b.moveOut){e.setY=d.scrollTop();var g=d.width()-e.move.outerWidth(),h=e.setY;0>c&&(c=0),c>g&&(c=g),h>f&&(f=h),f>d.height()-e.move.outerHeight()+e.setY&&(f=d.height()-e.move.outerHeight()+e.setY)}e.move.css({left:c,top:f}),b.moveType&&e.moveLayer(),c=f=g=h=null}}).mouseup(function(){try{e.ismove&&(e.moveLayer(),e.move.remove(),b.moveEnd&&b.moveEnd()),e.ismove=!1}catch(a){e.ismove=!1}}),a},g.pt.callback=function(){function a(){var a=g.cancel&&g.cancel(b.index,d);a===!1||f.close(b.index)}var b=this,d=b.layero,g=b.config;b.openLayer(),g.success&&(2==g.type?d.find(\"iframe\").on(\"load\",function(){g.success(d,b.index)}):g.success(d,b.index)),f.ie6&&b.IE6(d),d.find(\".\"+h[6]).children(\"a\").on(\"click\",function(){var a=c(this).index();if(0===a)g.yes?g.yes(b.index,d):g.btn1?g.btn1(b.index,d):f.close(b.index);else{var e=g[\"btn\"+(a+1)]&&g[\"btn\"+(a+1)](b.index,d);e===!1||f.close(b.index)}}),d.find(\".\"+h[7]).on(\"click\",a),g.shadeClose&&c(\"#layui-layer-shade\"+b.index).on(\"click\",function(){f.close(b.index)}),d.find(\".layui-layer-min\").on(\"click\",function(){var a=g.min&&g.min(d);a===!1||f.min(b.index,g)}),d.find(\".layui-layer-max\").on(\"click\",function(){c(this).hasClass(\"layui-layer-maxmin\")?(f.restore(b.index),g.restore&&g.restore(d)):(f.full(b.index,g),setTimeout(function(){g.full&&g.full(d)},100))}),g.end&&(e.end[b.index]=g.end)},e.reselect=function(){c.each(c(\"select\"),function(a,b){var d=c(this);d.parents(\".\"+h[0])[0]||1==d.attr(\"layer\")&&c(\".\"+h[0]).length<1&&d.removeAttr(\"layer\").show(),d=null})},g.pt.IE6=function(a){function b(){a.css({top:f+(e.config.fix?d.scrollTop():0)})}var e=this,f=a.offset().top;b(),d.scroll(b),c(\"select\").each(function(a,b){var d=c(this);d.parents(\".\"+h[0])[0]||\"none\"===d.css(\"display\")||d.attr({layer:\"1\"}).hide(),d=null})},g.pt.openLayer=function(){var a=this;f.zIndex=a.config.zIndex,f.setTop=function(a){var b=function(){f.zIndex++,a.css(\"z-index\",f.zIndex+1)};return f.zIndex=parseInt(a[0].style.zIndex),a.on(\"mousedown\",b),f.zIndex}},e.record=function(a){var b=[a.width(),a.height(),a.position().top,a.position().left+parseFloat(a.css(\"margin-left\"))];a.find(\".layui-layer-max\").addClass(\"layui-layer-maxmin\"),a.attr({area:b})},e.rescollbar=function(a){h.html.attr(\"layer-full\")==a&&(h.html[0].style.removeProperty?h.html[0].style.removeProperty(\"overflow\"):h.html[0].style.removeAttribute(\"overflow\"),h.html.removeAttr(\"layer-full\"))},a.layer=f,f.getChildFrame=function(a,b){return b=b||c(\".\"+h[4]).attr(\"times\"),c(\"#\"+h[0]+b).find(\"iframe\").contents().find(a)},f.getFrameIndex=function(a){return c(\"#\"+a).parents(\".\"+h[4]).attr(\"times\")},f.iframeAuto=function(a){if(a){var b=f.getChildFrame(\"html\",a).outerHeight(),d=c(\"#\"+h[0]+a),e=d.find(h[1]).outerHeight()||0,g=d.find(\".\"+h[6]).outerHeight()||0;d.css({height:b+e+g}),d.find(\"iframe\").css({height:b})}},f.iframeSrc=function(a,b){c(\"#\"+h[0]+a).find(\"iframe\").attr(\"src\",b)},f.style=function(a,b){var d=c(\"#\"+h[0]+a),f=d.attr(\"type\"),g=d.find(h[1]).outerHeight()||0,i=d.find(\".\"+h[6]).outerHeight()||0;(f===e.type[1]||f===e.type[2])&&(d.css(b),f===e.type[2]&&d.find(\"iframe\").css({height:parseFloat(b.height)-g-i}))},f.min=function(a,b){var d=c(\"#\"+h[0]+a),g=d.find(h[1]).outerHeight()||0;e.record(d),f.style(a,{width:180,height:g,overflow:\"hidden\"}),d.find(\".layui-layer-min\").hide(),\"page\"===d.attr(\"type\")&&d.find(h[4]).hide(),e.rescollbar(a)},f.restore=function(a){var b=c(\"#\"+h[0]+a),d=b.attr(\"area\").split(\",\");b.attr(\"type\");f.style(a,{width:parseFloat(d[0]),height:parseFloat(d[1]),top:parseFloat(d[2]),left:parseFloat(d[3]),overflow:\"visible\"}),b.find(\".layui-layer-max\").removeClass(\"layui-layer-maxmin\"),b.find(\".layui-layer-min\").show(),\"page\"===b.attr(\"type\")&&b.find(h[4]).show(),e.rescollbar(a)},f.full=function(a){var b,g=c(\"#\"+h[0]+a);e.record(g),h.html.attr(\"layer-full\")||h.html.css(\"overflow\",\"hidden\").attr(\"layer-full\",a),clearTimeout(b),b=setTimeout(function(){var b=\"fixed\"===g.css(\"position\");f.style(a,{top:b?0:d.scrollTop(),left:b?0:d.scrollLeft(),width:d.width(),height:d.height()}),g.find(\".layui-layer-min\").hide()},100)},f.title=function(a,b){var d=c(\"#\"+h[0]+(b||f.index)).find(h[1]);d.html(a)},f.close=function(a){var b=c(\"#\"+h[0]+a),d=b.attr(\"type\");if(b[0]){if(d===e.type[1]&&\"object\"===b.attr(\"conType\")){b.children(\":not(.\"+h[5]+\")\").remove();for(var g=0;2>g;g++)b.find(\".layui-layer-wrap\").unwrap().hide()}else{if(d===e.type[2])try{var i=c(\"#\"+h[4]+a)[0];i.contentWindow.document.write(\"\"),i.contentWindow.close(),b.find(\".\"+h[5])[0].removeChild(i)}catch(j){}b[0].innerHTML=\"\",b.remove()}c(\"#layui-layer-moves, #layui-layer-shade\"+a).remove(),f.ie6&&e.reselect(),e.rescollbar(a),c(document).off(\"keydown\",e.enter),\"function\"==typeof e.end[a]&&e.end[a](),delete e.end[a]}},f.closeAll=function(a){c.each(c(\".\"+h[0]),function(){var b=c(this),d=a?b.attr(\"type\")===a:1;d&&f.close(b.attr(\"times\")),d=null})};var i=f.cache||{},j=function(a){return i.skin?\" \"+i.skin+\" \"+i.skin+\"-\"+a:\"\"};f.prompt=function(a,b){a=a||{},\"function\"==typeof a&&(b=a);var d,e=2==a.formType?'<textarea class=\"layui-layer-input\">'+(a.value||\"\")+\"</textarea>\":function(){return'<input type=\"'+(1==a.formType?\"password\":\"text\")+'\" class=\"layui-layer-input\" value=\"'+(a.value||\"\")+'\">'}();return f.open(c.extend({btn:[\"&#x786E;&#x5B9A;\",\"&#x53D6;&#x6D88;\"],content:e,skin:\"layui-layer-prompt\"+j(\"prompt\"),success:function(a){d=a.find(\".layui-layer-input\"),d.focus()},yes:function(c){var e=d.val();\"\"===e?d.focus():e.length>(a.maxlength||500)?f.tips(\"&#x6700;&#x591A;&#x8F93;&#x5165;\"+(a.maxlength||500)+\"&#x4E2A;&#x5B57;&#x6570;\",d,{tips:1}):b&&b(e,c,d)}},a))},f.tab=function(a){a=a||{};var b=a.tab||{};return f.open(c.extend({type:1,skin:\"layui-layer-tab\"+j(\"tab\"),title:function(){var a=b.length,c=1,d=\"\";if(a>0)for(d='<span class=\"layui-layer-tabnow\">'+b[0].title+\"</span>\";a>c;c++)d+=\"<span>\"+b[c].title+\"</span>\";return d}(),content:'<ul class=\"layui-layer-tabmain\">'+function(){var a=b.length,c=1,d=\"\";if(a>0)for(d='<li class=\"layui-layer-tabli xubox_tab_layer\">'+(b[0].content||\"no content\")+\"</li>\";a>c;c++)d+='<li class=\"layui-layer-tabli\">'+(b[c].content||\"no  content\")+\"</li>\";return d}()+\"</ul>\",success:function(b){var d=b.find(\".layui-layer-title\").children(),e=b.find(\".layui-layer-tabmain\").children();d.on(\"mousedown\",function(b){b.stopPropagation?b.stopPropagation():b.cancelBubble=!0;var d=c(this),f=d.index();d.addClass(\"layui-layer-tabnow\").siblings().removeClass(\"layui-layer-tabnow\"),e.eq(f).show().siblings().hide(),\"function\"==typeof a.change&&a.change(f)})}},a))},f.photos=function(b,d,e){function g(a,b,c){var d=new Image;return d.src=a,d.complete?b(d):(d.onload=function(){d.onload=null,b(d)},void(d.onerror=function(a){d.onerror=null,c(a)}))}var h={};if(b=b||{},b.photos){var i=b.photos.constructor===Object,k=i?b.photos:{},l=k.data||[],m=k.start||0;if(h.imgIndex=(0|m)+1,b.img=b.img||\"img\",i){if(0===l.length)return f.msg(\"&#x6CA1;&#x6709;&#x56FE;&#x7247;\")}else{var n=c(b.photos),o=function(){l=[],n.find(b.img).each(function(a){var b=c(this);b.attr(\"layer-index\",a),l.push({alt:b.attr(\"alt\"),pid:b.attr(\"layer-pid\"),src:b.attr(\"layer-src\")||b.attr(\"src\"),thumb:b.attr(\"src\")})})};if(o(),0===l.length)return;if(d||n.on(\"click\",b.img,function(){var a=c(this),d=a.attr(\"layer-index\");f.photos(c.extend(b,{photos:{start:d,data:l,tab:b.tab},full:b.full}),!0),o()}),!d)return}h.imgprev=function(a){h.imgIndex--,h.imgIndex<1&&(h.imgIndex=l.length),h.tabimg(a)},h.imgnext=function(a,b){h.imgIndex++,h.imgIndex>l.length&&(h.imgIndex=1,b)||h.tabimg(a)},h.keyup=function(a){if(!h.end){var b=a.keyCode;a.preventDefault(),37===b?h.imgprev(!0):39===b?h.imgnext(!0):27===b&&f.close(h.index)}},h.tabimg=function(a){l.length<=1||(k.start=h.imgIndex-1,f.close(h.index),f.photos(b,!0,a))},h.event=function(){h.bigimg.hover(function(){h.imgsee.show()},function(){h.imgsee.hide()}),h.bigimg.find(\".layui-layer-imgprev\").on(\"click\",function(a){a.preventDefault(),h.imgprev()}),h.bigimg.find(\".layui-layer-imgnext\").on(\"click\",function(a){a.preventDefault(),h.imgnext()}),c(document).on(\"keyup\",h.keyup)},h.loadi=f.load(1,{shade:\"shade\"in b?!1:.9,scrollbar:!1}),g(l[m].src,function(d){f.close(h.loadi),h.index=f.open(c.extend({type:1,area:function(){var e=[d.width,d.height],f=[c(a).width()-50,c(a).height()-50];return!b.full&&e[0]>f[0]&&(e[0]=f[0],e[1]=e[0]*d.height/d.width),[e[0]+\"px\",e[1]+\"px\"]}(),title:!1,shade:.9,shadeClose:!0,closeBtn:!1,move:\".layui-layer-phimg img\",moveType:1,scrollbar:!1,moveOut:!0,shift:5*Math.random()|0,skin:\"layui-layer-photos\"+j(\"photos\"),content:'<div class=\"layui-layer-phimg\"><img src=\"'+l[m].src+'\" alt=\"'+(l[m].alt||\"\")+'\" layer-pid=\"'+l[m].pid+'\"><div class=\"layui-layer-imgsee\">'+(l.length>1?'<span class=\"layui-layer-imguide\"><a href=\"javascript:;\" class=\"layui-layer-iconext layui-layer-imgprev\"></a><a href=\"javascript:;\" class=\"layui-layer-iconext layui-layer-imgnext\"></a></span>':\"\")+'<div class=\"layui-layer-imgbar\" style=\"display:'+(e?\"block\":\"\")+'\"><span class=\"layui-layer-imgtit\"><a href=\"javascript:;\">'+(l[m].alt||\"\")+\"</a><em>\"+h.imgIndex+\"/\"+l.length+\"</em></span></div></div></div>\",success:function(a,c){h.bigimg=a.find(\".layui-layer-phimg\"),h.imgsee=a.find(\".layui-layer-imguide,.layui-layer-imgbar\"),h.event(a),b.tab&&b.tab(l[m],a)},end:function(){h.end=!0,c(document).off(\"keyup\",h.keyup)}},b))},function(){f.close(h.loadi),f.msg(\"&#x5F53;&#x524D;&#x56FE;&#x7247;&#x5730;&#x5740;&#x5F02;&#x5E38;<br>&#x662F;&#x5426;&#x7EE7;&#x7EED;&#x67E5;&#x770B;&#x4E0B;&#x4E00;&#x5F20;&#xFF1F;\",{time:3e4,btn:[\"&#x4E0B;&#x4E00;&#x5F20;\",\"&#x4E0D;&#x770B;&#x4E86;\"],yes:function(){l.length>1&&h.imgnext(!0,!0)}})})}},e.run=function(){c=jQuery,d=c(a),h.html=c(\"html\"),f.open=function(a){var b=new g(a);return b.index}},\"function\"==typeof define?define(function(){return e.run(),f}):function(){e.run(),f.use(\"skin/layer.css\")}()}(window);"
  },
  {
    "path": "static/plugins/layer/skin/layer.css",
    "content": "/*!\r\n \r\n @Name: layer's style\r\n @Author: 贤心\r\n @Blog： sentsin.com\r\n \r\n */.layui-layer-imgbar,.layui-layer-imgtit a,.layui-layer-tab .layui-layer-title span,.layui-layer-title{text-overflow:ellipsis;white-space:nowrap}*html{background-image:url(about:blank);background-attachment:fixed}html #layui_layer_skinlayercss{display:none;position:absolute;width:1989px}.layui-layer,.layui-layer-shade{position:fixed;_position:absolute;pointer-events:auto}.layui-layer-shade{top:0;left:0;width:100%;height:100%;_height:expression(document.body.offsetHeight+\"px\")}.layui-layer{-webkit-overflow-scrolling:touch;top:150px;left:0;margin:0;padding:0;background-color:#fff;-webkit-background-clip:content;box-shadow:1px 1px 50px rgba(0,0,0,.3);border-radius:2px;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.3s;animation-duration:.3s}.layui-layer-close{position:absolute}.layui-layer-content{position:relative}.layui-layer-border{border:1px solid #B2B2B2;border:1px solid rgba(0,0,0,.3);box-shadow:1px 1px 5px rgba(0,0,0,.2)}.layui-layer-moves{position:absolute;border:3px solid #666;border:3px solid rgba(0,0,0,.5);cursor:move;background-color:#fff;background-color:rgba(255,255,255,.3);filter:alpha(opacity=50)}.layui-layer-load{background:url(default/loading-0.gif) center center no-repeat #fff}.layui-layer-ico{background:url(default/icon.png) no-repeat}.layui-layer-btn a,.layui-layer-dialog .layui-layer-ico,.layui-layer-setwin a{display:inline-block;*display:inline;*zoom:1;vertical-align:top}@-webkit-keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.5);-ms-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim{-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes bounceOut{100%{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.03);transform:scale(1.03)}0%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes bounceOut{100%{opacity:0;-webkit-transform:scale(.7);-ms-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.03);-ms-transform:scale(1.03);transform:scale(1.03)}0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-close{-webkit-animation-name:bounceOut;animation-name:bounceOut;-webkit-animation-duration:.2s;animation-duration:.2s}@-webkit-keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);-ms-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);-ms-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-01{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.layer-anim-02{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);-ms-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);-ms-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-03{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}@keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);-ms-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);-ms-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}.layer-anim-04{-webkit-animation-name:rollIn;animation-name:rollIn}@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.layer-anim-05{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.layer-anim-06{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.layui-layer-title{padding:0 80px 0 20px;height:42px;line-height:42px;border-bottom:1px solid #eee;font-size:14px;color:#333;overflow:hidden;background-color:#F8F8F8;border-radius:2px 2px 0 0}.layui-layer-setwin{position:absolute;right:15px;*right:0;top:15px;font-size:0;line-height:initial}.layui-layer-setwin a{position:relative;width:16px;height:16px;margin-left:10px;font-size:12px;_overflow:hidden}.layui-layer-setwin .layui-layer-min cite{position:absolute;width:14px;height:2px;left:0;top:50%;margin-top:-1px;background-color:#2E2D3C;cursor:pointer;_overflow:hidden}.layui-layer-setwin .layui-layer-min:hover cite{background-color:#2D93CA}.layui-layer-setwin .layui-layer-max{background-position:-32px -40px}.layui-layer-setwin .layui-layer-max:hover{background-position:-16px -40px}.layui-layer-setwin .layui-layer-maxmin{background-position:-65px -40px}.layui-layer-setwin .layui-layer-maxmin:hover{background-position:-49px -40px}.layui-layer-setwin .layui-layer-close1{background-position:0 -40px;cursor:pointer}.layui-layer-setwin .layui-layer-close1:hover{opacity:.7}.layui-layer-setwin .layui-layer-close2{position:absolute;right:-28px;top:-28px;width:30px;height:30px;margin-left:0;background-position:-149px -31px;*right:-18px;_display:none}.layui-layer-setwin .layui-layer-close2:hover{background-position:-180px -31px}.layui-layer-btn{text-align:right;padding:0 10px 12px;pointer-events:auto}.layui-layer-btn a{height:28px;line-height:28px;margin:0 6px;padding:0 15px;border:1px solid #dedede;background-color:#f1f1f1;color:#333;border-radius:2px;font-weight:400;cursor:pointer;text-decoration:none}.layui-layer-btn a:hover{opacity:.9;text-decoration:none}.layui-layer-btn a:active{opacity:.7}.layui-layer-btn .layui-layer-btn0{border-color:#4898d5;background-color:#2e8ded;color:#fff}.layui-layer-dialog{min-width:260px}.layui-layer-dialog .layui-layer-content{position:relative;padding:20px;line-height:24px;word-break:break-all;overflow:hidden;font-size:14px;overflow-x:hidden;overflow-y:auto}.layui-layer-dialog .layui-layer-content .layui-layer-ico{position:absolute;top:16px;left:15px;_left:-40px;width:30px;height:30px}.layui-layer-ico1{background-position:-30px 0}.layui-layer-ico2{background-position:-60px 0}.layui-layer-ico3{background-position:-90px 0}.layui-layer-ico4{background-position:-120px 0}.layui-layer-ico5{background-position:-150px 0}.layui-layer-ico6{background-position:-180px 0}.layui-layer-rim{border:6px solid #8D8D8D;border:6px solid rgba(0,0,0,.3);border-radius:5px;box-shadow:none}.layui-layer-msg{min-width:180px;border:1px solid #D3D4D3;box-shadow:none}.layui-layer-hui{min-width:100px;background-color:#000;filter:alpha(opacity=60);background-color:rgba(0,0,0,.6);color:#fff;border:none}.layui-layer-hui .layui-layer-content{padding:12px 25px;text-align:center}.layui-layer-dialog .layui-layer-padding{padding:20px 20px 20px 55px;text-align:left}.layui-layer-page .layui-layer-content{position:relative;overflow:auto}.layui-layer-iframe .layui-layer-btn,.layui-layer-page .layui-layer-btn{padding-top:10px}.layui-layer-nobg{background:0 0}.layui-layer-iframe .layui-layer-content{overflow:hidden}.layui-layer-iframe iframe{display:block;width:100%}.layui-layer-loading{border-radius:100%;background:0 0;box-shadow:none;border:none}.layui-layer-loading .layui-layer-content{width:60px;height:24px;background:url(default/loading-0.gif) no-repeat}.layui-layer-loading .layui-layer-loading1{width:37px;height:37px;background:url(default/loading-1.gif) no-repeat}.layui-layer-ico16,.layui-layer-loading .layui-layer-loading2{width:32px;height:32px;background:url(default/loading-2.gif) no-repeat}.layui-layer-tips{background:0 0;box-shadow:none;border:none}.layui-layer-tips .layui-layer-content{position:relative;line-height:22px;min-width:12px;padding:5px 10px;font-size:12px;_float:left;border-radius:3px;box-shadow:1px 1px 3px rgba(0,0,0,.3);background-color:#F90;color:#fff}.layui-layer-tips .layui-layer-close{right:-2px;top:-1px}.layui-layer-tips i.layui-layer-TipsG{position:absolute;width:0;height:0;border-width:8px;border-color:transparent;border-style:dashed;*overflow:hidden}.layui-layer-tips i.layui-layer-TipsB,.layui-layer-tips i.layui-layer-TipsT{left:5px;border-right-style:solid;border-right-color:#F90}.layui-layer-tips i.layui-layer-TipsT{bottom:-8px}.layui-layer-tips i.layui-layer-TipsB{top:-8px}.layui-layer-tips i.layui-layer-TipsL,.layui-layer-tips i.layui-layer-TipsR{top:1px;border-bottom-style:solid;border-bottom-color:#F90}.layui-layer-tips i.layui-layer-TipsR{left:-8px}.layui-layer-tips i.layui-layer-TipsL{right:-8px}.layui-layer-lan[type=dialog]{min-width:280px}.layui-layer-lan .layui-layer-title{background:#4476A7;color:#fff;border:none}.layui-layer-lan .layui-layer-btn{padding:10px;text-align:right;border-top:1px solid #E9E7E7}.layui-layer-lan .layui-layer-btn a{background:#BBB5B5;border:none}.layui-layer-lan .layui-layer-btn .layui-layer-btn1{background:#C9C5C5}.layui-layer-molv .layui-layer-title{background:#009f95;color:#fff;border:none}.layui-layer-molv .layui-layer-btn a{background:#009f95}.layui-layer-molv .layui-layer-btn .layui-layer-btn1{background:#92B8B1}.layui-layer-iconext{background:url(default/icon-ext.png) no-repeat}.layui-layer-prompt .layui-layer-input{display:block;width:220px;height:30px;margin:0 auto;line-height:30px;padding:0 5px;border:1px solid #ccc;box-shadow:1px 1px 5px rgba(0,0,0,.1) inset;color:#333}.layui-layer-prompt textarea.layui-layer-input{width:300px;height:100px;line-height:20px}.layui-layer-tab{box-shadow:1px 1px 50px rgba(0,0,0,.4)}.layui-layer-tab .layui-layer-title{padding-left:0;border-bottom:1px solid #ccc;background-color:#eee;overflow:visible}.layui-layer-tab .layui-layer-title span{position:relative;float:left;min-width:80px;max-width:260px;padding:0 20px;text-align:center;cursor:default;overflow:hidden}.layui-layer-tab .layui-layer-title span.layui-layer-tabnow{height:43px;border-left:1px solid #ccc;border-right:1px solid #ccc;background-color:#fff;z-index:10}.layui-layer-tab .layui-layer-title span:first-child{border-left:none}.layui-layer-tabmain{line-height:24px;clear:both}.layui-layer-tabmain .layui-layer-tabli{display:none}.layui-layer-tabmain .layui-layer-tabli.xubox_tab_layer{display:block}.xubox_tabclose{position:absolute;right:10px;top:5px;cursor:pointer}.layui-layer-photos{-webkit-animation-duration:1s;animation-duration:1s}.layui-layer-photos .layui-layer-content{overflow:hidden;text-align:center}.layui-layer-photos .layui-layer-phimg img{position:relative;width:100%;display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-imgbar,.layui-layer-imguide{display:none}.layui-layer-imgnext,.layui-layer-imgprev{position:absolute;top:50%;width:27px;_width:44px;height:44px;margin-top:-22px;outline:0;blr:expression(this.onFocus=this.blur())}.layui-layer-imgprev{left:10px;background-position:-5px -5px;_background-position:-70px -5px}.layui-layer-imgprev:hover{background-position:-33px -5px;_background-position:-120px -5px}.layui-layer-imgnext{right:10px;_right:8px;background-position:-5px -50px;_background-position:-70px -50px}.layui-layer-imgnext:hover{background-position:-33px -50px;_background-position:-120px -50px}.layui-layer-imgbar{position:absolute;left:0;bottom:0;width:100%;height:32px;line-height:32px;background-color:rgba(0,0,0,.8);background-color:#000\\9;filter:Alpha(opacity=80);color:#fff;overflow:hidden;font-size:0}.layui-layer-imgtit *{display:inline-block;*display:inline;*zoom:1;vertical-align:top;font-size:12px}.layui-layer-imgtit a{max-width:65%;overflow:hidden;color:#fff}.layui-layer-imgtit a:hover{color:#fff;text-decoration:underline}.layui-layer-imgtit em{padding-left:10px;font-style:normal}"
  },
  {
    "path": "static/template/bootstrap/css/bootstrap.css",
    "content": "/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n  font-family: sans-serif;\n  -webkit-text-size-adjust: 100%;\n      -ms-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  margin: .67em 0;\n  font-size: 2em;\n}\nmark {\n  color: #000;\n  background: #ff0;\n}\nsmall {\n  font-size: 80%;\n}\nsub,\nsup {\n  position: relative;\n  font-size: 75%;\n  line-height: 0;\n  vertical-align: baseline;\n}\nsup {\n  top: -.5em;\n}\nsub {\n  bottom: -.25em;\n}\nimg {\n  border: 0;\n}\nsvg:not(:root) {\n  overflow: hidden;\n}\nfigure {\n  margin: 1em 40px;\n}\nhr {\n  height: 0;\n  -webkit-box-sizing: content-box;\n     -moz-box-sizing: content-box;\n          box-sizing: content-box;\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  margin: 0;\n  font: inherit;\n  color: inherit;\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  padding: 0;\n  border: 0;\n}\ninput {\n  line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\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-box-sizing: content-box;\n     -moz-box-sizing: content-box;\n          box-sizing: content-box;\n  -webkit-appearance: textfield;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\nfieldset {\n  padding: .35em .625em .75em;\n  margin: 0 2px;\n  border: 1px solid #c0c0c0;\n}\nlegend {\n  padding: 0;\n  border: 0;\n}\ntextarea {\n  overflow: auto;\n}\noptgroup {\n  font-weight: bold;\n}\ntable {\n  border-spacing: 0;\n  border-collapse: collapse;\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    color: #000 !important;\n    text-shadow: none !important;\n    background: transparent !important;\n    -webkit-box-shadow: none !important;\n            box-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\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  .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\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.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');\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\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n  content: \"\\002a\";\n}\n.glyphicon-plus:before {\n  content: \"\\002b\";\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.glyphicon-cd:before {\n  content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n  content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n  content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n  content: \"\\e204\";\n}\n.glyphicon-copy:before {\n  content: \"\\e205\";\n}\n.glyphicon-paste:before {\n  content: \"\\e206\";\n}\n.glyphicon-alert:before {\n  content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n  content: \"\\e210\";\n}\n.glyphicon-king:before {\n  content: \"\\e211\";\n}\n.glyphicon-queen:before {\n  content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n  content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n  content: \"\\e214\";\n}\n.glyphicon-knight:before {\n  content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n  content: \"\\e216\";\n}\n.glyphicon-tent:before {\n  content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n  content: \"\\e218\";\n}\n.glyphicon-bed:before {\n  content: \"\\e219\";\n}\n.glyphicon-apple:before {\n  content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n  content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n  content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n  content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n  content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n  content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n  content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n  content: \"\\e227\";\n}\n.glyphicon-btc:before {\n  content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n  content: \"\\e227\";\n}\n.glyphicon-yen:before {\n  content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n  content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n  content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n  content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n  content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n  content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n  content: \"\\e232\";\n}\n.glyphicon-education:before {\n  content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n  content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n  content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n  content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n  content: \"\\e237\";\n}\n.glyphicon-oil:before {\n  content: \"\\e238\";\n}\n.glyphicon-grain:before {\n  content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n  content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n  content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n  content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n  content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n  content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n  content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n  content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n  content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n  content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n  content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n  content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n  content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n  content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n  content: \"\\e253\";\n}\n.glyphicon-console:before {\n  content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n  content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n  content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n  content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n  content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n  content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n  content: \"\\e260\";\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\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: #333;\n  background-color: #fff;\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: 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  display: inline-block;\n  max-width: 100%;\n  height: auto;\n  padding: 4px;\n  line-height: 1.42857143;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 4px;\n  -webkit-transition: all .2s ease-in-out;\n       -o-transition: all .2s ease-in-out;\n          transition: all .2s ease-in-out;\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 #eee;\n}\n.sr-only {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  padding: 0;\n  margin: -1px;\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}\n[role=\"button\"] {\n  cursor: pointer;\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: #777;\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  padding: .2em;\n  background-color: #fcf8e3;\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: #777;\n}\n.text-primary {\n  color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n  color: #286090;\n}\n.text-success {\n  color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n  color: #2b542c;\n}\n.text-info {\n  color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n  color: #245269;\n}\n.text-warning {\n  color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n  color: #66512c;\n}\n.text-danger {\n  color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n  color: #843534;\n}\n.bg-primary {\n  color: #fff;\n  background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n  background-color: #286090;\n}\n.bg-success {\n  background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n  background-color: #c1e2b3;\n}\n.bg-info {\n  background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n  background-color: #afd9ee;\n}\n.bg-warning {\n  background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n  background-color: #f7ecb5;\n}\n.bg-danger {\n  background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n  background-color: #e4b9b9;\n}\n.page-header {\n  padding-bottom: 9px;\n  margin: 40px 0 20px;\n  border-bottom: 1px solid #eee;\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  margin-left: -5px;\n  list-style: none;\n}\n.list-inline > li {\n  display: inline-block;\n  padding-right: 5px;\n  padding-left: 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    overflow: hidden;\n    clear: left;\n    text-align: right;\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 #777;\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 #eee;\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: #777;\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  text-align: right;\n  border-right: 5px solid #eee;\n  border-left: 0;\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: #fff;\n  background-color: #333;\n  border-radius: 3px;\n  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);\n          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);\n}\nkbd kbd {\n  padding: 0;\n  font-size: 100%;\n  font-weight: bold;\n  -webkit-box-shadow: none;\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  color: #333;\n  word-break: break-all;\n  word-wrap: break-word;\n  background-color: #f5f5f5;\n  border: 1px solid #ccc;\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  padding-right: 15px;\n  padding-left: 15px;\n  margin-right: auto;\n  margin-left: auto;\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  padding-right: 15px;\n  padding-left: 15px;\n  margin-right: auto;\n  margin-left: auto;\n}\n.row {\n  margin-right: -15px;\n  margin-left: -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-right: 15px;\n  padding-left: 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: #777;\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 #ddd;\n}\n.table > thead > tr > th {\n  vertical-align: bottom;\n  border-bottom: 2px solid #ddd;\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 #ddd;\n}\n.table .table {\n  background-color: #fff;\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 #ddd;\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 #ddd;\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-of-type(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  display: table-column;\n  float: none;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n  position: static;\n  display: table-cell;\n  float: none;\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  min-height: .01%;\n  overflow-x: auto;\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 #ddd;\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  min-width: 0;\n  padding: 0;\n  margin: 0;\n  border: 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: #333;\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: 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: #555;\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: #555;\n  background-color: #fff;\n  background-image: none;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n  -webkit-transition: border-color ease-in-out .15s, -webkit-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, .6);\n          box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);\n}\n.form-control::-moz-placeholder {\n  color: #999;\n  opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n  color: #999;\n}\n.form-control::-webkit-input-placeholder {\n  color: #999;\n}\n.form-control::-ms-expand {\n  background-color: transparent;\n  border: 0;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n  background-color: #eee;\n  opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n  cursor: not-allowed;\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\"].form-control,\n  input[type=\"time\"].form-control,\n  input[type=\"datetime-local\"].form-control,\n  input[type=\"month\"].form-control {\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  .input-group-sm input[type=\"date\"],\n  .input-group-sm input[type=\"time\"],\n  .input-group-sm input[type=\"datetime-local\"],\n  .input-group-sm input[type=\"month\"] {\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  .input-group-lg input[type=\"date\"],\n  .input-group-lg input[type=\"time\"],\n  .input-group-lg input[type=\"datetime-local\"],\n  .input-group-lg input[type=\"month\"] {\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-top: 4px \\9;\n  margin-left: -20px;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n  margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n  position: relative;\n  display: inline-block;\n  padding-left: 20px;\n  margin-bottom: 0;\n  font-weight: normal;\n  vertical-align: middle;\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  min-height: 34px;\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-right: 0;\n  padding-left: 0;\n}\n.input-sm {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\nselect.input-sm {\n  height: 30px;\n  line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n  height: auto;\n}\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}\n.form-group-sm select.form-control {\n  height: 30px;\n  line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n  height: auto;\n}\n.form-group-sm .form-control-static {\n  height: 30px;\n  min-height: 32px;\n  padding: 6px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n}\n.input-lg {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\nselect.input-lg {\n  height: 46px;\n  line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n  height: auto;\n}\n.form-group-lg .form-control {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\n.form-group-lg select.form-control {\n  height: 46px;\n  line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n  height: auto;\n}\n.form-group-lg .form-control-static {\n  height: 46px;\n  min-height: 38px;\n  padding: 11px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\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.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n  width: 46px;\n  height: 46px;\n  line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .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, .075);\n          box-shadow: inset 0 1px 1px rgba(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, .075), 0 0 6px #67b168;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #3c763d;\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, .075);\n          box-shadow: inset 0 1px 1px rgba(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, .075), 0 0 6px #c0a16b;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #8a6d3b;\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, .075);\n          box-shadow: inset 0 1px 1px rgba(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, .075), 0 0 6px #ce8483;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #a94442;\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  padding-top: 7px;\n  margin-top: 0;\n  margin-bottom: 0;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n  min-height: 27px;\n}\n.form-horizontal .form-group {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n@media (min-width: 768px) {\n  .form-horizontal .control-label {\n    padding-top: 7px;\n    margin-bottom: 0;\n    text-align: right;\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: 11px;\n    font-size: 18px;\n  }\n}\n@media (min-width: 768px) {\n  .form-horizontal .form-group-sm .control-label {\n    padding-top: 6px;\n    font-size: 12px;\n  }\n}\n.btn {\n  display: inline-block;\n  padding: 6px 12px;\n  margin-bottom: 0;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: middle;\n  -ms-touch-action: manipulation;\n      touch-action: manipulation;\n  cursor: pointer;\n  -webkit-user-select: none;\n     -moz-user-select: none;\n      -ms-user-select: none;\n          user-select: none;\n  background-image: none;\n  border: 1px solid transparent;\n  border-radius: 4px;\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: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n  color: #333;\n  text-decoration: none;\n}\n.btn:active,\n.btn.active {\n  background-image: none;\n  outline: 0;\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n  cursor: not-allowed;\n  filter: alpha(opacity=65);\n  -webkit-box-shadow: none;\n          box-shadow: none;\n  opacity: .65;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n  pointer-events: none;\n}\n.btn-default {\n  color: #333;\n  background-color: #fff;\n  border-color: #ccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #8c8c8c;\n}\n.btn-default:hover {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n  color: #333;\n  background-color: #d4d4d4;\n  border-color: #8c8c8c;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n  background-image: none;\n}\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  background-color: #fff;\n  border-color: #ccc;\n}\n.btn-default .badge {\n  color: #fff;\n  background-color: #333;\n}\n.btn-primary {\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n  color: #fff;\n  background-color: #286090;\n  border-color: #122b40;\n}\n.btn-primary:hover {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n  color: #fff;\n  background-color: #204d74;\n  border-color: #122b40;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n  background-image: none;\n}\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  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.btn-primary .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.btn-success {\n  color: #fff;\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #255625;\n}\n.btn-success:hover {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n  color: #fff;\n  background-color: #398439;\n  border-color: #255625;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n  background-image: none;\n}\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  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.btn-success .badge {\n  color: #5cb85c;\n  background-color: #fff;\n}\n.btn-info {\n  color: #fff;\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #1b6d85;\n}\n.btn-info:hover {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n  color: #fff;\n  background-color: #269abc;\n  border-color: #1b6d85;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n  background-image: none;\n}\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  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n.btn-info .badge {\n  color: #5bc0de;\n  background-color: #fff;\n}\n.btn-warning {\n  color: #fff;\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #985f0d;\n}\n.btn-warning:hover {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n  color: #fff;\n  background-color: #d58512;\n  border-color: #985f0d;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n  background-image: none;\n}\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  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.btn-warning .badge {\n  color: #f0ad4e;\n  background-color: #fff;\n}\n.btn-danger {\n  color: #fff;\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #761c19;\n}\n.btn-danger:hover {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n  color: #fff;\n  background-color: #ac2925;\n  border-color: #761c19;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n  background-image: none;\n}\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  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.btn-danger .badge {\n  color: #d9534f;\n  background-color: #fff;\n}\n.btn-link {\n  font-weight: normal;\n  color: #337ab7;\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: #777;\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.3333333;\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 .15s linear;\n       -o-transition: opacity .15s linear;\n          transition: opacity .15s linear;\n}\n.fade.in {\n  opacity: 1;\n}\n.collapse {\n  display: none;\n}\n.collapse.in {\n  display: block;\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-timing-function: ease;\n       -o-transition-timing-function: ease;\n          transition-timing-function: ease;\n  -webkit-transition-duration: .35s;\n       -o-transition-duration: .35s;\n          transition-duration: .35s;\n  -webkit-transition-property: height, visibility;\n       -o-transition-property: height, visibility;\n          transition-property: height, visibility;\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 dashed;\n  border-top: 4px solid \\9;\n  border-right: 4px solid transparent;\n  border-left: 4px solid transparent;\n}\n.dropup,\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  font-size: 14px;\n  text-align: left;\n  list-style: none;\n  background-color: #fff;\n  -webkit-background-clip: padding-box;\n          background-clip: padding-box;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, .15);\n  border-radius: 4px;\n  -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);\n          box-shadow: 0 6px 12px rgba(0, 0, 0, .175);\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: #333;\n  white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n  color: #262626;\n  text-decoration: none;\n  background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  color: #fff;\n  text-decoration: none;\n  background-color: #337ab7;\n  outline: 0;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  color: #777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  text-decoration: none;\n  cursor: not-allowed;\n  background-color: transparent;\n  background-image: none;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n}\n.open > .dropdown-menu {\n  display: block;\n}\n.open > a {\n  outline: 0;\n}\n.dropdown-menu-right {\n  right: 0;\n  left: auto;\n}\n.dropdown-menu-left {\n  right: auto;\n  left: 0;\n}\n.dropdown-header {\n  display: block;\n  padding: 3px 20px;\n  font-size: 12px;\n  line-height: 1.42857143;\n  color: #777;\n  white-space: nowrap;\n}\n.dropdown-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 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  content: \"\";\n  border-top: 0;\n  border-bottom: 4px dashed;\n  border-bottom: 4px solid \\9;\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n  top: auto;\n  bottom: 100%;\n  margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n  .navbar-right .dropdown-menu {\n    right: 0;\n    left: auto;\n  }\n  .navbar-right .dropdown-menu-left {\n    right: auto;\n    left: 0;\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,\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-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n  border-top-left-radius: 0;\n  border-bottom-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:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  border-top-left-radius: 0;\n  border-bottom-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-right: 8px;\n  padding-left: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n  padding-right: 12px;\n  padding-left: 12px;\n}\n.btn-group.open .dropdown-toggle {\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n          box-shadow: inset 0 3px 5px rgba(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-left-radius: 4px;\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-top-left-radius: 0;\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 4px;\n  border-bottom-left-radius: 4px;\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-left-radius: 0;\n  border-top-right-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  display: table-cell;\n  float: none;\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-right: 0;\n  padding-left: 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 .form-control:focus {\n  z-index: 3;\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.3333333;\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: #555;\n  text-align: center;\n  background-color: #eee;\n  border: 1px solid #ccc;\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-top-right-radius: 0;\n  border-bottom-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-top-left-radius: 0;\n  border-bottom-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  z-index: 2;\n  margin-left: -1px;\n}\n.nav {\n  padding-left: 0;\n  margin-bottom: 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: #eee;\n}\n.nav > li.disabled > a {\n  color: #777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n  color: #777;\n  text-decoration: none;\n  cursor: not-allowed;\n  background-color: transparent;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n  background-color: #eee;\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 #ddd;\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: #eee #eee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n  color: #555;\n  cursor: default;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-bottom-color: transparent;\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  margin-bottom: 5px;\n  text-align: center;\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 #ddd;\n}\n@media (min-width: 768px) {\n  .nav-tabs.nav-justified > li > a {\n    border-bottom: 1px solid #ddd;\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: #fff;\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: #fff;\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  margin-bottom: 5px;\n  text-align: center;\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 #ddd;\n}\n@media (min-width: 768px) {\n  .nav-tabs-justified > li > a {\n    border-bottom: 1px solid #ddd;\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: #fff;\n  }\n}\n.tab-content > .tab-pane {\n  display: none;\n}\n.tab-content > .active {\n  display: block;\n}\n.nav-tabs .dropdown-menu {\n  margin-top: -1px;\n  border-top-left-radius: 0;\n  border-top-right-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  padding-right: 15px;\n  padding-left: 15px;\n  overflow-x: visible;\n  -webkit-overflow-scrolling: touch;\n  border-top: 1px solid transparent;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);\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    -webkit-box-shadow: none;\n            box-shadow: none;\n  }\n  .navbar-collapse.collapse {\n    display: block !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-right: 0;\n    padding-left: 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  height: 50px;\n  padding: 15px 15px;\n  font-size: 18px;\n  line-height: 20px;\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  padding: 9px 10px;\n  margin-top: 8px;\n  margin-right: 15px;\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    -webkit-box-shadow: none;\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  padding: 10px 15px;\n  margin-top: 8px;\n  margin-right: -15px;\n  margin-bottom: 8px;\n  margin-left: -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, .1), 0 1px 0 rgba(255, 255, 255, .1);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);\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    padding-top: 0;\n    padding-bottom: 0;\n    margin-right: 0;\n    margin-left: 0;\n    border: 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-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n  margin-bottom: 0;\n  border-top-left-radius: 4px;\n  border-top-right-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-right: 15px;\n    margin-left: 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: #777;\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: #777;\n}\n.navbar-default .navbar-nav > li > a {\n  color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n  color: #333;\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: #555;\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: #ccc;\n  background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n  border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n  background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n  background-color: #888;\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  color: #555;\n  background-color: #e7e7e7;\n}\n@media (max-width: 767px) {\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n    color: #777;\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: #333;\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: #555;\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: #ccc;\n    background-color: transparent;\n  }\n}\n.navbar-default .navbar-link {\n  color: #777;\n}\n.navbar-default .navbar-link:hover {\n  color: #333;\n}\n.navbar-default .btn-link {\n  color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n  color: #333;\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: #ccc;\n}\n.navbar-inverse {\n  background-color: #222;\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: #fff;\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: #fff;\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: #fff;\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: #444;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n  border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n  background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n  background-color: #fff;\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  color: #fff;\n  background-color: #080808;\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: #fff;\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: #fff;\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: #444;\n    background-color: transparent;\n  }\n}\n.navbar-inverse .navbar-link {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n  color: #fff;\n}\n.navbar-inverse .btn-link {\n  color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n  color: #fff;\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: #444;\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  padding: 0 5px;\n  color: #ccc;\n  content: \"/\\00a0\";\n}\n.breadcrumb > .active {\n  color: #777;\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  margin-left: -1px;\n  line-height: 1.42857143;\n  color: #337ab7;\n  text-decoration: none;\n  background-color: #fff;\n  border: 1px solid #ddd;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n  margin-left: 0;\n  border-top-left-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n  border-top-right-radius: 4px;\n  border-bottom-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  z-index: 2;\n  color: #23527c;\n  background-color: #eee;\n  border-color: #ddd;\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: 3;\n  color: #fff;\n  cursor: default;\n  background-color: #337ab7;\n  border-color: #337ab7;\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: #777;\n  cursor: not-allowed;\n  background-color: #fff;\n  border-color: #ddd;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n  border-top-left-radius: 6px;\n  border-bottom-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n  border-top-right-radius: 6px;\n  border-bottom-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n  border-top-left-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n  border-top-right-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n.pager {\n  padding-left: 0;\n  margin: 20px 0;\n  text-align: center;\n  list-style: none;\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: #fff;\n  border: 1px solid #ddd;\n  border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n  text-decoration: none;\n  background-color: #eee;\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: #777;\n  cursor: not-allowed;\n  background-color: #fff;\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: #fff;\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: #fff;\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: #777;\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  line-height: 1;\n  color: #fff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: middle;\n  background-color: #777;\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.btn-group-xs > .btn .badge {\n  top: 0;\n  padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n  color: #fff;\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: #fff;\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-top: 30px;\n  padding-bottom: 30px;\n  margin-bottom: 30px;\n  color: inherit;\n  background-color: #eee;\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  padding-right: 15px;\n  padding-left: 15px;\n  border-radius: 6px;\n}\n.jumbotron .container {\n  max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n  .jumbotron {\n    padding-top: 48px;\n    padding-bottom: 48px;\n  }\n  .container .jumbotron,\n  .container-fluid .jumbotron {\n    padding-right: 60px;\n    padding-left: 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: #fff;\n  border: 1px solid #ddd;\n  border-radius: 4px;\n  -webkit-transition: border .2s ease-in-out;\n       -o-transition: border .2s ease-in-out;\n          transition: border .2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n  margin-right: auto;\n  margin-left: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n  border-color: #337ab7;\n}\n.thumbnail .caption {\n  padding: 9px;\n  color: #333;\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  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n.alert-success hr {\n  border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n  color: #2b542c;\n}\n.alert-info {\n  color: #31708f;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n.alert-info hr {\n  border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n  color: #245269;\n}\n.alert-warning {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n}\n.alert-warning hr {\n  border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n  color: #66512c;\n}\n.alert-danger {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #ebccd1;\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@-o-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  height: 20px;\n  margin-bottom: 20px;\n  overflow: hidden;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);\n          box-shadow: inset 0 1px 2px rgba(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: #fff;\n  text-align: center;\n  background-color: #337ab7;\n  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);\n          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);\n  -webkit-transition: width .6s ease;\n       -o-transition: width .6s ease;\n          transition: width .6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n  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);\n  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);\n  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);\n  -webkit-background-size: 40px 40px;\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, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  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);\n  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);\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, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  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);\n  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);\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, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  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);\n  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);\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, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  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);\n  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);\n}\n.media {\n  margin-top: 15px;\n}\n.media:first-child {\n  margin-top: 0;\n}\n.media,\n.media-body {\n  overflow: hidden;\n  zoom: 1;\n}\n.media-body {\n  width: 10000px;\n}\n.media-object {\n  display: block;\n}\n.media-object.img-thumbnail {\n  max-width: none;\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  padding-left: 0;\n  margin-bottom: 20px;\n}\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n  margin-bottom: -1px;\n  background-color: #fff;\n  border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n  border-top-left-radius: 4px;\n  border-top-right-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,\nbutton.list-group-item {\n  color: #555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n  color: #333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n  color: #555;\n  text-decoration: none;\n  background-color: #f5f5f5;\n}\nbutton.list-group-item {\n  width: 100%;\n  text-align: left;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n  color: #777;\n  cursor: not-allowed;\n  background-color: #eee;\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: #777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n  z-index: 2;\n  color: #fff;\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,\nbutton.list-group-item-success {\n  color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n  color: #3c763d;\n  background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.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,\nbutton.list-group-item-info {\n  color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n  color: #31708f;\n  background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.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,\nbutton.list-group-item-warning {\n  color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n  color: #8a6d3b;\n  background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.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,\nbutton.list-group-item-danger {\n  color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n  color: #a94442;\n  background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.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: #fff;\n  border: 1px solid transparent;\n  border-radius: 4px;\n  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);\n          box-shadow: 0 1px 1px rgba(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-left-radius: 3px;\n  border-top-right-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.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n  color: inherit;\n}\n.panel-footer {\n  padding: 10px 15px;\n  background-color: #f5f5f5;\n  border-top: 1px solid #ddd;\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-left-radius: 3px;\n  border-top-right-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 > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\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-right: 15px;\n  padding-left: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table: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,\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-right-radius: 3px;\n  border-bottom-left-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 #ddd;\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  margin-bottom: 0;\n  border: 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 #ddd;\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 #ddd;\n}\n.panel-default {\n  border-color: #ddd;\n}\n.panel-default > .panel-heading {\n  color: #333;\n  background-color: #f5f5f5;\n  border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n  color: #f5f5f5;\n  background-color: #333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #ddd;\n}\n.panel-primary {\n  border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n  color: #fff;\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: #fff;\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  bottom: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  border: 0;\n}\n.embed-responsive-16by9 {\n  padding-bottom: 56.25%;\n}\n.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, .05);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);\n}\n.well blockquote {\n  border-color: #ddd;\n  border-color: rgba(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: #000;\n  text-shadow: 0 1px 0 #fff;\n  filter: alpha(opacity=20);\n  opacity: .2;\n}\n.close:hover,\n.close:focus {\n  color: #000;\n  text-decoration: none;\n  cursor: pointer;\n  filter: alpha(opacity=50);\n  opacity: .5;\n}\nbutton.close {\n  -webkit-appearance: none;\n  padding: 0;\n  cursor: pointer;\n  background: transparent;\n  border: 0;\n}\n.modal-open {\n  overflow: hidden;\n}\n.modal {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1050;\n  display: none;\n  overflow: hidden;\n  -webkit-overflow-scrolling: touch;\n  outline: 0;\n}\n.modal.fade .modal-dialog {\n  -webkit-transition: -webkit-transform .3s ease-out;\n       -o-transition:      -o-transform .3s ease-out;\n          transition:         transform .3s ease-out;\n  -webkit-transform: translate(0, -25%);\n      -ms-transform: translate(0, -25%);\n       -o-transform: translate(0, -25%);\n          transform: translate(0, -25%);\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: #fff;\n  -webkit-background-clip: padding-box;\n          background-clip: padding-box;\n  border: 1px solid #999;\n  border: 1px solid rgba(0, 0, 0, .2);\n  border-radius: 6px;\n  outline: 0;\n  -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);\n          box-shadow: 0 3px 9px rgba(0, 0, 0, .5);\n}\n.modal-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1040;\n  background-color: #000;\n}\n.modal-backdrop.fade {\n  filter: alpha(opacity=0);\n  opacity: 0;\n}\n.modal-backdrop.in {\n  filter: alpha(opacity=50);\n  opacity: .5;\n}\n.modal-header {\n  padding: 15px;\n  border-bottom: 1px solid #e5e5e5;\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-bottom: 0;\n  margin-left: 5px;\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, .5);\n            box-shadow: 0 5px 15px rgba(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  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 12px;\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  word-spacing: normal;\n  word-wrap: normal;\n  white-space: normal;\n  filter: alpha(opacity=0);\n  opacity: 0;\n\n  line-break: auto;\n}\n.tooltip.in {\n  filter: alpha(opacity=90);\n  opacity: .9;\n}\n.tooltip.top {\n  padding: 5px 0;\n  margin-top: -3px;\n}\n.tooltip.right {\n  padding: 0 5px;\n  margin-left: 3px;\n}\n.tooltip.bottom {\n  padding: 5px 0;\n  margin-top: 3px;\n}\n.tooltip.left {\n  padding: 0 5px;\n  margin-left: -3px;\n}\n.tooltip-inner {\n  max-width: 200px;\n  padding: 3px 8px;\n  color: #fff;\n  text-align: center;\n  background-color: #000;\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: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n  right: 5px;\n  bottom: 0;\n  margin-bottom: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\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: #000;\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: #000;\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: #000;\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: #000;\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: #000;\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: #000;\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-style: normal;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  word-spacing: normal;\n  word-wrap: normal;\n  white-space: normal;\n  background-color: #fff;\n  -webkit-background-clip: padding-box;\n          background-clip: padding-box;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, .2);\n  border-radius: 6px;\n  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);\n          box-shadow: 0 5px 10px rgba(0, 0, 0, .2);\n\n  line-break: auto;\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  padding: 8px 14px;\n  margin: 0;\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  content: \"\";\n  border-width: 10px;\n}\n.popover.top > .arrow {\n  bottom: -11px;\n  left: 50%;\n  margin-left: -11px;\n  border-top-color: #999;\n  border-top-color: rgba(0, 0, 0, .25);\n  border-bottom-width: 0;\n}\n.popover.top > .arrow:after {\n  bottom: 1px;\n  margin-left: -10px;\n  content: \" \";\n  border-top-color: #fff;\n  border-bottom-width: 0;\n}\n.popover.right > .arrow {\n  top: 50%;\n  left: -11px;\n  margin-top: -11px;\n  border-right-color: #999;\n  border-right-color: rgba(0, 0, 0, .25);\n  border-left-width: 0;\n}\n.popover.right > .arrow:after {\n  bottom: -10px;\n  left: 1px;\n  content: \" \";\n  border-right-color: #fff;\n  border-left-width: 0;\n}\n.popover.bottom > .arrow {\n  top: -11px;\n  left: 50%;\n  margin-left: -11px;\n  border-top-width: 0;\n  border-bottom-color: #999;\n  border-bottom-color: rgba(0, 0, 0, .25);\n}\n.popover.bottom > .arrow:after {\n  top: 1px;\n  margin-left: -10px;\n  content: \" \";\n  border-top-width: 0;\n  border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n  top: 50%;\n  right: -11px;\n  margin-top: -11px;\n  border-right-width: 0;\n  border-left-color: #999;\n  border-left-color: rgba(0, 0, 0, .25);\n}\n.popover.left > .arrow:after {\n  right: 1px;\n  bottom: -10px;\n  content: \" \";\n  border-right-width: 0;\n  border-left-color: #fff;\n}\n.carousel {\n  position: relative;\n}\n.carousel-inner {\n  position: relative;\n  width: 100%;\n  overflow: hidden;\n}\n.carousel-inner > .item {\n  position: relative;\n  display: none;\n  -webkit-transition: .6s ease-in-out left;\n       -o-transition: .6s ease-in-out left;\n          transition: .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    -webkit-transition: -webkit-transform .6s ease-in-out;\n         -o-transition:      -o-transform .6s ease-in-out;\n            transition:         transform .6s ease-in-out;\n\n    -webkit-backface-visibility: hidden;\n            backface-visibility: hidden;\n    -webkit-perspective: 1000px;\n            perspective: 1000px;\n  }\n  .carousel-inner > .item.next,\n  .carousel-inner > .item.active.right {\n    left: 0;\n    -webkit-transform: translate3d(100%, 0, 0);\n            transform: translate3d(100%, 0, 0);\n  }\n  .carousel-inner > .item.prev,\n  .carousel-inner > .item.active.left {\n    left: 0;\n    -webkit-transform: translate3d(-100%, 0, 0);\n            transform: translate3d(-100%, 0, 0);\n  }\n  .carousel-inner > .item.next.left,\n  .carousel-inner > .item.prev.right,\n  .carousel-inner > .item.active {\n    left: 0;\n    -webkit-transform: translate3d(0, 0, 0);\n            transform: translate3d(0, 0, 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  bottom: 0;\n  left: 0;\n  width: 15%;\n  font-size: 20px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);\n  background-color: rgba(0, 0, 0, 0);\n  filter: alpha(opacity=50);\n  opacity: .5;\n}\n.carousel-control.left {\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n  background-image:      -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001)));\n  background-image:         linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n  background-repeat: repeat-x;\n}\n.carousel-control.right {\n  right: 0;\n  left: auto;\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n  background-image:      -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5)));\n  background-image:         linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n  background-repeat: repeat-x;\n}\n.carousel-control:hover,\n.carousel-control:focus {\n  color: #fff;\n  text-decoration: none;\n  filter: alpha(opacity=90);\n  outline: 0;\n  opacity: .9;\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  margin-top: -10px;\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  font-family: serif;\n  line-height: 1;\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  padding-left: 0;\n  margin-left: -30%;\n  text-align: center;\n  list-style: none;\n}\n.carousel-indicators li {\n  display: inline-block;\n  width: 10px;\n  height: 10px;\n  margin: 1px;\n  text-indent: -999px;\n  cursor: pointer;\n  background-color: #000 \\9;\n  background-color: rgba(0, 0, 0, 0);\n  border: 1px solid #fff;\n  border-radius: 10px;\n}\n.carousel-indicators .active {\n  width: 12px;\n  height: 12px;\n  margin: 0;\n  background-color: #fff;\n}\n.carousel-caption {\n  position: absolute;\n  right: 15%;\n  bottom: 20px;\n  left: 15%;\n  z-index: 10;\n  padding-top: 20px;\n  padding-bottom: 20px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(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: -10px;\n    font-size: 30px;\n  }\n  .carousel-control .glyphicon-chevron-left,\n  .carousel-control .icon-prev {\n    margin-left: -10px;\n  }\n  .carousel-control .glyphicon-chevron-right,\n  .carousel-control .icon-next {\n    margin-right: -10px;\n  }\n  .carousel-caption {\n    right: 20%;\n    left: 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-header:before,\n.modal-header:after,\n.modal-footer:before,\n.modal-footer:after {\n  display: table;\n  content: \" \";\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-header:after,\n.modal-footer:after {\n  clear: both;\n}\n.center-block {\n  display: block;\n  margin-right: auto;\n  margin-left: 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}\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 !important;\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 !important;\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 !important;\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 !important;\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 !important;\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 */\n"
  },
  {
    "path": "static/template/css/bootstrap-datepicker.css",
    "content": "/*!\n * Datepicker for Bootstrap v1.7.0-dev (https://github.com/uxsolutions/bootstrap-datepicker)\n *\n * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)\n */\n\n.datepicker {\n  padding: 4px;\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n  direction: ltr;\n}\n.datepicker-inline {\n  width: 220px;\n}\n.datepicker.datepicker-rtl {\n  direction: rtl;\n}\n.datepicker.datepicker-rtl.dropdown-menu {\n  left: auto;\n}\n.datepicker.datepicker-rtl table tr td span {\n  float: right;\n}\n.datepicker-dropdown {\n  top: 0;\n  left: 0;\n}\n.datepicker-dropdown:before {\n  content: '';\n  display: inline-block;\n  border-left: 7px solid transparent;\n  border-right: 7px solid transparent;\n  border-bottom: 7px solid #999999;\n  border-top: 0;\n  border-bottom-color: rgba(0, 0, 0, 0.2);\n  position: absolute;\n}\n.datepicker-dropdown:after {\n  content: '';\n  display: inline-block;\n  border-left: 6px solid transparent;\n  border-right: 6px solid transparent;\n  border-bottom: 6px solid #ffffff;\n  border-top: 0;\n  position: absolute;\n}\n.datepicker-dropdown.datepicker-orient-left:before {\n  left: 6px;\n}\n.datepicker-dropdown.datepicker-orient-left:after {\n  left: 7px;\n}\n.datepicker-dropdown.datepicker-orient-right:before {\n  right: 6px;\n}\n.datepicker-dropdown.datepicker-orient-right:after {\n  right: 7px;\n}\n.datepicker-dropdown.datepicker-orient-bottom:before {\n  top: -7px;\n}\n.datepicker-dropdown.datepicker-orient-bottom:after {\n  top: -6px;\n}\n.datepicker-dropdown.datepicker-orient-top:before {\n  bottom: -7px;\n  border-bottom: 0;\n  border-top: 7px solid #999999;\n}\n.datepicker-dropdown.datepicker-orient-top:after {\n  bottom: -6px;\n  border-bottom: 0;\n  border-top: 6px solid #ffffff;\n}\n.datepicker table {\n  margin: 0;\n  -webkit-touch-callout: none;\n  -webkit-user-select: none;\n  -khtml-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n}\n.datepicker td,\n.datepicker th {\n  text-align: center;\n  width: 20px;\n  height: 20px;\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n  border: none;\n}\n.table-striped .datepicker table tr td,\n.table-striped .datepicker table tr th {\n  background-color: transparent;\n}\n.datepicker table tr td.day:hover,\n.datepicker table tr td.day.focused {\n  background: #eeeeee;\n  cursor: pointer;\n}\n.datepicker table tr td.old,\n.datepicker table tr td.new {\n  color: #999999;\n}\n.datepicker table tr td.disabled,\n.datepicker table tr td.disabled:hover {\n  background: none;\n  color: #999999;\n  cursor: default;\n}\n.datepicker table tr td.highlighted {\n  background: #d9edf7;\n  border-radius: 0;\n}\n.datepicker table tr td.today,\n.datepicker table tr td.today:hover,\n.datepicker table tr td.today.disabled,\n.datepicker table tr td.today.disabled:hover {\n  background-color: #fde19a;\n  background-image: -moz-linear-gradient(to bottom, #fdd49a, #fdf59a);\n  background-image: -ms-linear-gradient(to bottom, #fdd49a, #fdf59a);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));\n  background-image: -webkit-linear-gradient(to bottom, #fdd49a, #fdf59a);\n  background-image: -o-linear-gradient(to bottom, #fdd49a, #fdf59a);\n  background-image: linear-gradient(to bottom, #fdd49a, #fdf59a);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);\n  border-color: #fdf59a #fdf59a #fbed50;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n  color: #000;\n}\n.datepicker table tr td.today:hover,\n.datepicker table tr td.today:hover:hover,\n.datepicker table tr td.today.disabled:hover,\n.datepicker table tr td.today.disabled:hover:hover,\n.datepicker table tr td.today:active,\n.datepicker table tr td.today:hover:active,\n.datepicker table tr td.today.disabled:active,\n.datepicker table tr td.today.disabled:hover:active,\n.datepicker table tr td.today.active,\n.datepicker table tr td.today:hover.active,\n.datepicker table tr td.today.disabled.active,\n.datepicker table tr td.today.disabled:hover.active,\n.datepicker table tr td.today.disabled,\n.datepicker table tr td.today:hover.disabled,\n.datepicker table tr td.today.disabled.disabled,\n.datepicker table tr td.today.disabled:hover.disabled,\n.datepicker table tr td.today[disabled],\n.datepicker table tr td.today:hover[disabled],\n.datepicker table tr td.today.disabled[disabled],\n.datepicker table tr td.today.disabled:hover[disabled] {\n  background-color: #fdf59a;\n}\n.datepicker table tr td.today:active,\n.datepicker table tr td.today:hover:active,\n.datepicker table tr td.today.disabled:active,\n.datepicker table tr td.today.disabled:hover:active,\n.datepicker table tr td.today.active,\n.datepicker table tr td.today:hover.active,\n.datepicker table tr td.today.disabled.active,\n.datepicker table tr td.today.disabled:hover.active {\n  background-color: #fbf069 \\9;\n}\n.datepicker table tr td.today:hover:hover {\n  color: #000;\n}\n.datepicker table tr td.today.active:hover {\n  color: #fff;\n}\n.datepicker table tr td.range,\n.datepicker table tr td.range:hover,\n.datepicker table tr td.range.disabled,\n.datepicker table tr td.range.disabled:hover {\n  background: #eeeeee;\n  -webkit-border-radius: 0;\n  -moz-border-radius: 0;\n  border-radius: 0;\n}\n.datepicker table tr td.range.today,\n.datepicker table tr td.range.today:hover,\n.datepicker table tr td.range.today.disabled,\n.datepicker table tr td.range.today.disabled:hover {\n  background-color: #f3d17a;\n  background-image: -moz-linear-gradient(to bottom, #f3c17a, #f3e97a);\n  background-image: -ms-linear-gradient(to bottom, #f3c17a, #f3e97a);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f3c17a), to(#f3e97a));\n  background-image: -webkit-linear-gradient(to bottom, #f3c17a, #f3e97a);\n  background-image: -o-linear-gradient(to bottom, #f3c17a, #f3e97a);\n  background-image: linear-gradient(to bottom, #f3c17a, #f3e97a);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3c17a', endColorstr='#f3e97a', GradientType=0);\n  border-color: #f3e97a #f3e97a #edde34;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n  -webkit-border-radius: 0;\n  -moz-border-radius: 0;\n  border-radius: 0;\n}\n.datepicker table tr td.range.today:hover,\n.datepicker table tr td.range.today:hover:hover,\n.datepicker table tr td.range.today.disabled:hover,\n.datepicker table tr td.range.today.disabled:hover:hover,\n.datepicker table tr td.range.today:active,\n.datepicker table tr td.range.today:hover:active,\n.datepicker table tr td.range.today.disabled:active,\n.datepicker table tr td.range.today.disabled:hover:active,\n.datepicker table tr td.range.today.active,\n.datepicker table tr td.range.today:hover.active,\n.datepicker table tr td.range.today.disabled.active,\n.datepicker table tr td.range.today.disabled:hover.active,\n.datepicker table tr td.range.today.disabled,\n.datepicker table tr td.range.today:hover.disabled,\n.datepicker table tr td.range.today.disabled.disabled,\n.datepicker table tr td.range.today.disabled:hover.disabled,\n.datepicker table tr td.range.today[disabled],\n.datepicker table tr td.range.today:hover[disabled],\n.datepicker table tr td.range.today.disabled[disabled],\n.datepicker table tr td.range.today.disabled:hover[disabled] {\n  background-color: #f3e97a;\n}\n.datepicker table tr td.range.today:active,\n.datepicker table tr td.range.today:hover:active,\n.datepicker table tr td.range.today.disabled:active,\n.datepicker table tr td.range.today.disabled:hover:active,\n.datepicker table tr td.range.today.active,\n.datepicker table tr td.range.today:hover.active,\n.datepicker table tr td.range.today.disabled.active,\n.datepicker table tr td.range.today.disabled:hover.active {\n  background-color: #efe24b \\9;\n}\n.datepicker table tr td.selected,\n.datepicker table tr td.selected:hover,\n.datepicker table tr td.selected.disabled,\n.datepicker table tr td.selected.disabled:hover {\n  background-color: #9e9e9e;\n  background-image: -moz-linear-gradient(to bottom, #b3b3b3, #808080);\n  background-image: -ms-linear-gradient(to bottom, #b3b3b3, #808080);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b3b3b3), to(#808080));\n  background-image: -webkit-linear-gradient(to bottom, #b3b3b3, #808080);\n  background-image: -o-linear-gradient(to bottom, #b3b3b3, #808080);\n  background-image: linear-gradient(to bottom, #b3b3b3, #808080);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b3b3b3', endColorstr='#808080', GradientType=0);\n  border-color: #808080 #808080 #595959;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n  color: #fff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.datepicker table tr td.selected:hover,\n.datepicker table tr td.selected:hover:hover,\n.datepicker table tr td.selected.disabled:hover,\n.datepicker table tr td.selected.disabled:hover:hover,\n.datepicker table tr td.selected:active,\n.datepicker table tr td.selected:hover:active,\n.datepicker table tr td.selected.disabled:active,\n.datepicker table tr td.selected.disabled:hover:active,\n.datepicker table tr td.selected.active,\n.datepicker table tr td.selected:hover.active,\n.datepicker table tr td.selected.disabled.active,\n.datepicker table tr td.selected.disabled:hover.active,\n.datepicker table tr td.selected.disabled,\n.datepicker table tr td.selected:hover.disabled,\n.datepicker table tr td.selected.disabled.disabled,\n.datepicker table tr td.selected.disabled:hover.disabled,\n.datepicker table tr td.selected[disabled],\n.datepicker table tr td.selected:hover[disabled],\n.datepicker table tr td.selected.disabled[disabled],\n.datepicker table tr td.selected.disabled:hover[disabled] {\n  background-color: #808080;\n}\n.datepicker table tr td.selected:active,\n.datepicker table tr td.selected:hover:active,\n.datepicker table tr td.selected.disabled:active,\n.datepicker table tr td.selected.disabled:hover:active,\n.datepicker table tr td.selected.active,\n.datepicker table tr td.selected:hover.active,\n.datepicker table tr td.selected.disabled.active,\n.datepicker table tr td.selected.disabled:hover.active {\n  background-color: #666666 \\9;\n}\n.datepicker table tr td.active,\n.datepicker table tr td.active:hover,\n.datepicker table tr td.active.disabled,\n.datepicker table tr td.active.disabled:hover {\n  background-color: #006dcc;\n  background-image: -moz-linear-gradient(to bottom, #0088cc, #0044cc);\n  background-image: -ms-linear-gradient(to bottom, #0088cc, #0044cc);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));\n  background-image: -webkit-linear-gradient(to bottom, #0088cc, #0044cc);\n  background-image: -o-linear-gradient(to bottom, #0088cc, #0044cc);\n  background-image: linear-gradient(to bottom, #0088cc, #0044cc);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);\n  border-color: #0044cc #0044cc #002a80;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n  color: #fff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.datepicker table tr td.active:hover,\n.datepicker table tr td.active:hover:hover,\n.datepicker table tr td.active.disabled:hover,\n.datepicker table tr td.active.disabled:hover:hover,\n.datepicker table tr td.active:active,\n.datepicker table tr td.active:hover:active,\n.datepicker table tr td.active.disabled:active,\n.datepicker table tr td.active.disabled:hover:active,\n.datepicker table tr td.active.active,\n.datepicker table tr td.active:hover.active,\n.datepicker table tr td.active.disabled.active,\n.datepicker table tr td.active.disabled:hover.active,\n.datepicker table tr td.active.disabled,\n.datepicker table tr td.active:hover.disabled,\n.datepicker table tr td.active.disabled.disabled,\n.datepicker table tr td.active.disabled:hover.disabled,\n.datepicker table tr td.active[disabled],\n.datepicker table tr td.active:hover[disabled],\n.datepicker table tr td.active.disabled[disabled],\n.datepicker table tr td.active.disabled:hover[disabled] {\n  background-color: #0044cc;\n}\n.datepicker table tr td.active:active,\n.datepicker table tr td.active:hover:active,\n.datepicker table tr td.active.disabled:active,\n.datepicker table tr td.active.disabled:hover:active,\n.datepicker table tr td.active.active,\n.datepicker table tr td.active:hover.active,\n.datepicker table tr td.active.disabled.active,\n.datepicker table tr td.active.disabled:hover.active {\n  background-color: #003399 \\9;\n}\n.datepicker table tr td span {\n  display: block;\n  width: 23%;\n  height: 54px;\n  line-height: 54px;\n  float: left;\n  margin: 1%;\n  cursor: pointer;\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n}\n.datepicker table tr td span:hover,\n.datepicker table tr td span.focused {\n  background: #eeeeee;\n}\n.datepicker table tr td span.disabled,\n.datepicker table tr td span.disabled:hover {\n  background: none;\n  color: #999999;\n  cursor: default;\n}\n.datepicker table tr td span.active,\n.datepicker table tr td span.active:hover,\n.datepicker table tr td span.active.disabled,\n.datepicker table tr td span.active.disabled:hover {\n  background-color: #006dcc;\n  background-image: -moz-linear-gradient(to bottom, #0088cc, #0044cc);\n  background-image: -ms-linear-gradient(to bottom, #0088cc, #0044cc);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));\n  background-image: -webkit-linear-gradient(to bottom, #0088cc, #0044cc);\n  background-image: -o-linear-gradient(to bottom, #0088cc, #0044cc);\n  background-image: linear-gradient(to bottom, #0088cc, #0044cc);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);\n  border-color: #0044cc #0044cc #002a80;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n  color: #fff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.datepicker table tr td span.active:hover,\n.datepicker table tr td span.active:hover:hover,\n.datepicker table tr td span.active.disabled:hover,\n.datepicker table tr td span.active.disabled:hover:hover,\n.datepicker table tr td span.active:active,\n.datepicker table tr td span.active:hover:active,\n.datepicker table tr td span.active.disabled:active,\n.datepicker table tr td span.active.disabled:hover:active,\n.datepicker table tr td span.active.active,\n.datepicker table tr td span.active:hover.active,\n.datepicker table tr td span.active.disabled.active,\n.datepicker table tr td span.active.disabled:hover.active,\n.datepicker table tr td span.active.disabled,\n.datepicker table tr td span.active:hover.disabled,\n.datepicker table tr td span.active.disabled.disabled,\n.datepicker table tr td span.active.disabled:hover.disabled,\n.datepicker table tr td span.active[disabled],\n.datepicker table tr td span.active:hover[disabled],\n.datepicker table tr td span.active.disabled[disabled],\n.datepicker table tr td span.active.disabled:hover[disabled] {\n  background-color: #0044cc;\n}\n.datepicker table tr td span.active:active,\n.datepicker table tr td span.active:hover:active,\n.datepicker table tr td span.active.disabled:active,\n.datepicker table tr td span.active.disabled:hover:active,\n.datepicker table tr td span.active.active,\n.datepicker table tr td span.active:hover.active,\n.datepicker table tr td span.active.disabled.active,\n.datepicker table tr td span.active.disabled:hover.active {\n  background-color: #003399 \\9;\n}\n.datepicker table tr td span.old,\n.datepicker table tr td span.new {\n  color: #999999;\n}\n.datepicker .datepicker-switch {\n  width: 145px;\n}\n.datepicker .datepicker-switch,\n.datepicker .prev,\n.datepicker .next,\n.datepicker tfoot tr th {\n  cursor: pointer;\n}\n.datepicker .datepicker-switch:hover,\n.datepicker .prev:hover,\n.datepicker .next:hover,\n.datepicker tfoot tr th:hover {\n  background: #eeeeee;\n}\n.datepicker .prev.disabled,\n.datepicker .next.disabled {\n  visibility: hidden;\n}\n.datepicker .cw {\n  font-size: 10px;\n  width: 12px;\n  padding: 0 2px 0 5px;\n  vertical-align: middle;\n}\n.input-append.date .add-on,\n.input-prepend.date .add-on {\n  cursor: pointer;\n}\n.input-append.date .add-on i,\n.input-prepend.date .add-on i {\n  margin-top: 3px;\n}\n.input-daterange input {\n  text-align: center;\n}\n.input-daterange input:first-child {\n  -webkit-border-radius: 3px 0 0 3px;\n  -moz-border-radius: 3px 0 0 3px;\n  border-radius: 3px 0 0 3px;\n}\n.input-daterange input:last-child {\n  -webkit-border-radius: 0 3px 3px 0;\n  -moz-border-radius: 0 3px 3px 0;\n  border-radius: 0 3px 3px 0;\n}\n.input-daterange .add-on {\n  display: inline-block;\n  width: auto;\n  min-width: 16px;\n  height: 18px;\n  padding: 4px 5px;\n  font-weight: normal;\n  line-height: 18px;\n  text-align: center;\n  text-shadow: 0 1px 0 #ffffff;\n  vertical-align: middle;\n  background-color: #eeeeee;\n  border: 1px solid #ccc;\n  margin-left: -5px;\n  margin-right: -5px;\n}\n/*# sourceMappingURL=bootstrap-datepicker.css.map */"
  },
  {
    "path": "static/template/css/bootstrap-timepicker.css",
    "content": "/*!\n * Timepicker Component for Twitter Bootstrap\n *\n * Copyright 2013 Joris de Wit\n *\n * Contributors https://github.com/jdewit/bootstrap-timepicker/graphs/contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n.bootstrap-timepicker {\n  position: relative;\n}\n.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu {\n  left: auto;\n  right: 0;\n}\n.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu:before {\n  left: auto;\n  right: 12px;\n}\n.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu:after {\n  left: auto;\n  right: 13px;\n}\n.bootstrap-timepicker .add-on {\n  cursor: pointer;\n}\n.bootstrap-timepicker .add-on i {\n  display: inline-block;\n  width: 16px;\n  height: 16px;\n}\n.bootstrap-timepicker-widget.dropdown-menu {\n  padding: 2px 3px 2px 2px;\n}\n.bootstrap-timepicker-widget.dropdown-menu.open {\n  display: inline-block;\n}\n.bootstrap-timepicker-widget.dropdown-menu:before {\n  border-bottom: 7px solid rgba(0, 0, 0, 0.2);\n  border-left: 7px solid transparent;\n  border-right: 7px solid transparent;\n  content: \"\";\n  display: inline-block;\n  left: 9px;\n  position: absolute;\n  top: -7px;\n}\n.bootstrap-timepicker-widget.dropdown-menu:after {\n  border-bottom: 6px solid #FFFFFF;\n  border-left: 6px solid transparent;\n  border-right: 6px solid transparent;\n  content: \"\";\n  display: inline-block;\n  left: 10px;\n  position: absolute;\n  top: -6px;\n}\n.bootstrap-timepicker-widget a.btn,\n.bootstrap-timepicker-widget input {\n  border-radius: 4px;\n}\n.bootstrap-timepicker-widget table {\n  width: 100%;\n  margin: 0;\n}\n.bootstrap-timepicker-widget table td {\n  text-align: center;\n  height: 30px;\n  margin: 0;\n  padding: 2px;\n}\n.bootstrap-timepicker-widget table td:not(.separator) {\n  min-width: 30px;\n}\n.bootstrap-timepicker-widget table td span {\n  width: 100%;\n}\n.bootstrap-timepicker-widget table td a {\n  border: 1px transparent solid;\n  width: 100%;\n  display: inline-block;\n  margin: 0;\n  padding: 8px 0;\n  outline: 0;\n  color: #333;\n}\n.bootstrap-timepicker-widget table td a:hover {\n  text-decoration: none;\n  background-color: #eee;\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n  border-color: #ddd;\n}\n.bootstrap-timepicker-widget table td a i {\n  margin-top: 2px;\n}\n.bootstrap-timepicker-widget table td input {\n  width: 25px;\n  margin: 0;\n  text-align: center;\n}\n.bootstrap-timepicker-widget .modal-content {\n  padding: 4px;\n}\n@media (min-width: 767px) {\n  .bootstrap-timepicker-widget.modal {\n    width: 200px;\n    margin-left: -100px;\n  }\n}\n@media (max-width: 767px) {\n  .bootstrap-timepicker {\n    width: 100%;\n  }\n  .bootstrap-timepicker .dropdown-menu {\n    width: 100%;\n  }\n}\n"
  },
  {
    "path": "static/template/css/bootstrap-wysihtml5.css",
    "content": "ul.wysihtml5-toolbar {\n\tmargin: 0;\n\tpadding: 0;\n\tdisplay: block;\n}\n\nul.wysihtml5-toolbar::after {\n\tclear: both;\n\tdisplay: table;\n\tcontent: \"\";\n}\n\nul.wysihtml5-toolbar > li {\n\tfloat: left;\n\tdisplay: list-item;\n\tlist-style: none;\n\tmargin: 0 5px 10px 0;\n}\n\nul.wysihtml5-toolbar a[data-wysihtml5-command=bold] {\n\tfont-weight: bold;\n}\n\nul.wysihtml5-toolbar a[data-wysihtml5-command=italic] {\n\tfont-style: italic;\n}\n\nul.wysihtml5-toolbar a[data-wysihtml5-command=underline] {\n\ttext-decoration: underline;\n}\n\nul.wysihtml5-toolbar a.btn.wysihtml5-command-active {\n\tbackground-image: none;\n\t-webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);\n\t-moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);\n\tbox-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);\n\tbackground-color: #E6E6E6;\n\tbackground-color: #D9D9D9;\n\toutline: 0;\n}\n\nul.wysihtml5-commands-disabled .dropdown-menu {\n\tdisplay: none !important;\n}\n\nul.wysihtml5-toolbar div.wysihtml5-colors {\n  display:block;\n  width: 50px;\n  height: 20px;\n  margin-top: 2px;\n  margin-left: 5px;\n  position: absolute;\n  pointer-events: none;\n}\n\nul.wysihtml5-toolbar a.wysihtml5-colors-title {\n  padding-left: 70px;\n}\n\nul.wysihtml5-toolbar div[data-wysihtml5-command-value=\"black\"] {\n  background: black !important;\n}\n\nul.wysihtml5-toolbar div[data-wysihtml5-command-value=\"silver\"] {\n  background: silver !important;\n}\n\nul.wysihtml5-toolbar div[data-wysihtml5-command-value=\"gray\"] {\n  background: gray !important;\n}\n\nul.wysihtml5-toolbar div[data-wysihtml5-command-value=\"maroon\"] {\n  background: maroon !important;\n}\n\nul.wysihtml5-toolbar div[data-wysihtml5-command-value=\"red\"] {\n  background: red !important;\n}\n\nul.wysihtml5-toolbar div[data-wysihtml5-command-value=\"purple\"] {\n  background: purple !important;\n}\n\nul.wysihtml5-toolbar div[data-wysihtml5-command-value=\"green\"] {\n  background: green !important;\n}\n\nul.wysihtml5-toolbar div[data-wysihtml5-command-value=\"olive\"] {\n  background: olive !important;\n}\n\nul.wysihtml5-toolbar div[data-wysihtml5-command-value=\"navy\"] {\n  background: navy !important;\n}\n\nul.wysihtml5-toolbar div[data-wysihtml5-command-value=\"blue\"] {\n  background: blue !important;\n}\n\nul.wysihtml5-toolbar div[data-wysihtml5-command-value=\"orange\"] {\n  background: orange !important;\n}\n"
  },
  {
    "path": "static/template/css/colorbox/colorbox.css",
    "content": "/*\n    Colorbox Core Style:\n    The following CSS is consistent between example themes and should not be altered.\n*/\n#colorbox, #cboxOverlay, #cboxWrapper{position:absolute; top:0; left:0; z-index:9999; overflow:hidden;}\n#cboxOverlay{position:fixed; width:100%; height:100%;}\n#cboxMiddleLeft, #cboxBottomLeft{clear:left;}\n#cboxContent{position:relative;}\n#cboxLoadedContent{overflow:auto; -webkit-overflow-scrolling: touch;}\n#cboxTitle{margin:0;}\n#cboxLoadingOverlay, #cboxLoadingGraphic{position:absolute; top:0; left:0; width:100%; height:100%;}\n#cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{cursor:pointer;}\n.cboxPhoto{float:left; margin:auto; border:0; display:block; max-width:none; -ms-interpolation-mode:bicubic;}\n.cboxIframe{width:100%; height:100%; display:block; border:0;}\n#colorbox, #cboxContent, #cboxLoadedContent{box-sizing:content-box; -moz-box-sizing:content-box; -webkit-box-sizing:content-box;}\n\n/* \n    User Style:\n    Change the following styles to modify the appearance of Colorbox.  They are\n    ordered & tabbed in a way that represents the nesting of the generated HTML.\n*/\n#cboxOverlay{background:url(images/overlay.png) repeat 0 0;}\n#colorbox{outline:0;}\n    #cboxTopLeft{width:21px; height:21px; background:url(images/controls.png) no-repeat -101px 0;}\n    #cboxTopRight{width:21px; height:21px; background:url(images/controls.png) no-repeat -130px 0;}\n    #cboxBottomLeft{width:21px; height:21px; background:url(images/controls.png) no-repeat -101px -29px;}\n    #cboxBottomRight{width:21px; height:21px; background:url(images/controls.png) no-repeat -130px -29px;}\n    #cboxMiddleLeft{width:21px; background:url(images/controls.png) left top repeat-y;}\n    #cboxMiddleRight{width:21px; background:url(images/controls.png) right top repeat-y;}\n    #cboxTopCenter{height:21px; background:url(images/border.png) 0 0 repeat-x;}\n    #cboxBottomCenter{height:21px; background:url(images/border.png) 0 -29px repeat-x;}\n    #cboxContent{background:#fff; overflow:hidden;}\n        .cboxIframe{background:#fff;}\n        #cboxError{padding:50px; border:1px solid #ccc;}\n        #cboxLoadedContent{margin-bottom:28px;}\n        #cboxTitle{position:absolute; bottom:4px; left:0; text-align:center; width:100%; color:#949494;}\n        #cboxCurrent{position:absolute; bottom:4px; left:58px; color:#949494;}\n        #cboxLoadingOverlay{background:url(images/loading_background.png) no-repeat center center;}\n        #cboxLoadingGraphic{background:url(images/loading.gif) no-repeat center center;}\n\n        /* these elements are buttons, and may need to have additional styles reset to avoid unwanted base styles */\n        #cboxPrevious, #cboxNext, #cboxSlideshow, #cboxClose {border:0; padding:0; margin:0; overflow:visible; width:auto; background:none; }\n        \n        /* avoid outlines on :active (mouseclick), but preserve outlines on :focus (tabbed navigating) */\n        #cboxPrevious:active, #cboxNext:active, #cboxSlideshow:active, #cboxClose:active {outline:0;}\n\n        #cboxSlideshow{position:absolute; bottom:4px; right:30px; color:#0092ef;}\n        #cboxPrevious{position:absolute; bottom:0; left:0; background:url(images/controls.png) no-repeat -75px 0; width:25px; height:25px; text-indent:-9999px;}\n        #cboxPrevious:hover{background-position:-75px -25px;}\n        #cboxNext{position:absolute; bottom:0; left:27px; background:url(images/controls.png) no-repeat -50px 0; width:25px; height:25px; text-indent:-9999px;}\n        #cboxNext:hover{background-position:-50px -25px;}\n        #cboxClose{position:absolute; bottom:0; right:0; background:url(images/controls.png) no-repeat -25px 0; width:25px; height:25px; text-indent:-9999px;}\n        #cboxClose:hover{background-position:-25px -25px;}\n\n/*\n  The following fixes a problem where IE7 and IE8 replace a PNG's alpha transparency with a black fill\n  when an alpha filter (opacity change) is set on the element or ancestor element.  This style is not applied to or needed in IE9.\n  See: http://jacklmoore.com/notes/ie-transparency-problems/\n*/\n.cboxIE #cboxTopLeft,\n.cboxIE #cboxTopCenter,\n.cboxIE #cboxTopRight,\n.cboxIE #cboxBottomLeft,\n.cboxIE #cboxBottomCenter,\n.cboxIE #cboxBottomRight,\n.cboxIE #cboxMiddleLeft,\n.cboxIE #cboxMiddleRight {\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF);\n}"
  },
  {
    "path": "static/template/css/datepicker.css",
    "content": "/*!\n * Datepicker for Bootstrap\n *\n * Copyright 2012 Stefan Petre\n * Licensed under the Apache License v2.0\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n */\n.datepicker {\n  top: 0;\n  left: 0;\n  padding: 4px;\n  margin-top: 1px;\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n  /*.dow {\n    border-top: 1px solid #ddd !important;\n  }*/\n\n}\n.datepicker:before {\n  content: '';\n  display: inline-block;\n  border-left: 7px solid transparent;\n  border-right: 7px solid transparent;\n  border-bottom: 7px solid #ccc;\n  border-bottom-color: rgba(0, 0, 0, 0.2);\n  position: absolute;\n  top: -7px;\n  left: 6px;\n}\n.datepicker:after {\n  content: '';\n  display: inline-block;\n  border-left: 6px solid transparent;\n  border-right: 6px solid transparent;\n  border-bottom: 6px solid #ffffff;\n  position: absolute;\n  top: -6px;\n  left: 7px;\n}\n.datepicker > div {\n  display: none;\n}\n.datepicker table {\n  width: 100%;\n  margin: 0;\n}\n.datepicker td,\n.datepicker th {\n  text-align: center;\n  width: 20px;\n  height: 20px;\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n}\n.datepicker td.day:hover {\n  background: #eeeeee;\n  cursor: pointer;\n}\n.datepicker td.day.disabled {\n  color: #eeeeee;\n}\n.datepicker td.old,\n.datepicker td.new {\n  color: #999999;\n}\n.datepicker td.active,\n.datepicker td.active:hover {\n  color: #ffffff;\n  background-color: #006dcc;\n  background-image: -moz-linear-gradient(top, #0088cc, #0044cc);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));\n  background-image: -webkit-linear-gradient(top, #A9E2F3, #A9E2F3);\n  background-image: -o-linear-gradient(top, #0088cc, #0044cc);\n  background-image: linear-gradient(to bottom, #0088ff, #0088ff);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);\n  border-color: #0044cc #0044cc #002a80;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  *background-color: #0044cc;\n  /* Darken IE7 buttons by default so they stand out more given they won't have borders */\n\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  color: #fff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.datepicker td.active:hover,\n.datepicker td.active:hover:hover,\n.datepicker td.active:focus,\n.datepicker td.active:hover:focus,\n.datepicker td.active:active,\n.datepicker td.active:hover:active,\n.datepicker td.active.active,\n.datepicker td.active:hover.active,\n.datepicker td.active.disabled,\n.datepicker td.active:hover.disabled,\n.datepicker td.active[disabled],\n.datepicker td.active:hover[disabled] {\n  color: #ffffff;\n  background-color: #0044cc;\n  *background-color: #003bb3;\n}\n.datepicker td.active:active,\n.datepicker td.active:hover:active,\n.datepicker td.active.active,\n.datepicker td.active:hover.active {\n  background-color: #003399 \\9;\n}\n.datepicker td span {\n  display: block;\n  width: 47px;\n  height: 54px;\n  line-height: 54px;\n  float: left;\n  margin: 2px;\n  cursor: pointer;\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n}\n.datepicker td span:hover {\n  background: #eeeeee;\n}\n.datepicker td span.active {\n  color: #ffffff;\n  background-color: #006dcc;\n  background-image: -moz-linear-gradient(top, #0088cc, #0044cc);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));\n  background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);\n  background-image: -o-linear-gradient(top, #0088cc, #0044cc);\n  background-image: linear-gradient(to bottom, #0088cc, #0044cc);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);\n  border-color: #0044cc #0044cc #002a80;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  *background-color: #0044cc;\n  /* Darken IE7 buttons by default so they stand out more given they won't have borders */\n\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  color: #fff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.datepicker td span.active:hover,\n.datepicker td span.active:focus,\n.datepicker td span.active:active,\n.datepicker td span.active.active,\n.datepicker td span.active.disabled,\n.datepicker td span.active[disabled] {\n  color: #ffffff;\n  background-color: #0044cc;\n  *background-color: #003bb3;\n}\n.datepicker td span.active:active,\n.datepicker td span.active.active {\n  background-color: #003399 \\9;\n}\n.datepicker td span.old {\n  color: #999999;\n}\n.datepicker th.switch {\n  width: 145px;\n}\n.datepicker th.next,\n.datepicker th.prev {\n  font-size: 21px;\n}\n.datepicker thead tr:first-child th {\n  cursor: pointer;\n}\n.datepicker thead tr:first-child th:hover {\n  background: #eeeeee;\n}\n.input-append.date .add-on i,\n.input-prepend.date .add-on i {\n  display: block;\n  cursor: pointer;\n  width: 16px;\n  height: 16px;\n}"
  },
  {
    "path": "static/template/css/dropzone/dropzone.css",
    "content": "/* The MIT License */\n.dropzone,\n.dropzone *,\n.dropzone-previews,\n.dropzone-previews * {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n}\n.dropzone {\n  position: relative;\n  border: 1px solid rgba(0,0,0,0.08);\n  background: rgba(0,0,0,0.02);\n  padding: 1em;\n}\n.dropzone.dz-clickable {\n  cursor: pointer;\n}\n.dropzone.dz-clickable .dz-message,\n.dropzone.dz-clickable .dz-message span {\n  cursor: pointer;\n}\n.dropzone.dz-clickable * {\n  cursor: default;\n}\n.dropzone .dz-message {\n  opacity: 1;\n  -ms-filter: none;\n  filter: none;\n}\n.dropzone.dz-drag-hover {\n  border-color: rgba(0,0,0,0.15);\n  background: rgba(0,0,0,0.04);\n}\n.dropzone.dz-started .dz-message {\n  display: none;\n}\n.dropzone .dz-preview,\n.dropzone-previews .dz-preview {\n  background: rgba(255,255,255,0.8);\n  position: relative;\n  display: inline-block;\n  margin: 17px;\n  vertical-align: top;\n  border: 1px solid #acacac;\n  padding: 6px 6px 6px 6px;\n}\n.dropzone .dz-preview.dz-file-preview [data-dz-thumbnail],\n.dropzone-previews .dz-preview.dz-file-preview [data-dz-thumbnail] {\n  display: none;\n}\n.dropzone .dz-preview .dz-details,\n.dropzone-previews .dz-preview .dz-details {\n  width: 100px;\n  height: 100px;\n  position: relative;\n  background: #ebebeb;\n  padding: 5px;\n  margin-bottom: 22px;\n}\n.dropzone .dz-preview .dz-details .dz-filename,\n.dropzone-previews .dz-preview .dz-details .dz-filename {\n  overflow: hidden;\n  height: 100%;\n}\n.dropzone .dz-preview .dz-details img,\n.dropzone-previews .dz-preview .dz-details img {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100px;\n  height: 100px;\n}\n.dropzone .dz-preview .dz-details .dz-size,\n.dropzone-previews .dz-preview .dz-details .dz-size {\n  position: absolute;\n  bottom: -28px;\n  left: 3px;\n  height: 28px;\n  line-height: 28px;\n}\n.dropzone .dz-preview.dz-error .dz-error-mark,\n.dropzone-previews .dz-preview.dz-error .dz-error-mark {\n  display: block;\n}\n.dropzone .dz-preview.dz-success .dz-success-mark,\n.dropzone-previews .dz-preview.dz-success .dz-success-mark {\n  display: block;\n}\n.dropzone .dz-preview:hover .dz-details img,\n.dropzone-previews .dz-preview:hover .dz-details img {\n  display: none;\n}\n.dropzone .dz-preview .dz-success-mark,\n.dropzone-previews .dz-preview .dz-success-mark,\n.dropzone .dz-preview .dz-error-mark,\n.dropzone-previews .dz-preview .dz-error-mark {\n  display: none;\n  position: absolute;\n  width: 40px;\n  height: 40px;\n  font-size: 30px;\n  text-align: center;\n  right: -10px;\n  top: -10px;\n}\n.dropzone .dz-preview .dz-success-mark,\n.dropzone-previews .dz-preview .dz-success-mark {\n  color: #8cc657;\n}\n.dropzone .dz-preview .dz-error-mark,\n.dropzone-previews .dz-preview .dz-error-mark {\n  color: #ee162d;\n}\n.dropzone .dz-preview .dz-progress,\n.dropzone-previews .dz-preview .dz-progress {\n  position: absolute;\n  top: 100px;\n  left: 6px;\n  right: 6px;\n  height: 6px;\n  background: #d7d7d7;\n  display: none;\n}\n.dropzone .dz-preview .dz-progress .dz-upload,\n.dropzone-previews .dz-preview .dz-progress .dz-upload {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  width: 0%;\n  background-color: #8cc657;\n}\n.dropzone .dz-preview.dz-processing .dz-progress,\n.dropzone-previews .dz-preview.dz-processing .dz-progress {\n  display: block;\n}\n.dropzone .dz-preview .dz-error-message,\n.dropzone-previews .dz-preview .dz-error-message {\n  display: none;\n  position: absolute;\n  top: -5px;\n  left: -20px;\n  background: rgba(245,245,245,0.8);\n  padding: 8px 10px;\n  color: #800;\n  min-width: 140px;\n  max-width: 500px;\n  z-index: 500;\n}\n.dropzone .dz-preview:hover.dz-error .dz-error-message,\n.dropzone-previews .dz-preview:hover.dz-error .dz-error-message {\n  display: block;\n}\n.dropzone {\n  border: 1px solid rgba(0,0,0,0.03);\n  min-height: 360px;\n  -webkit-border-radius: 3px;\n  border-radius: 3px;\n  background: rgba(0,0,0,0.03);\n  padding: 23px;\n}\n.dropzone .dz-default.dz-message {\n  opacity: 1;\n  -ms-filter: none;\n  filter: none;\n  -webkit-transition: opacity 0.3s ease-in-out;\n  -moz-transition: opacity 0.3s ease-in-out;\n  -o-transition: opacity 0.3s ease-in-out;\n  -ms-transition: opacity 0.3s ease-in-out;\n  transition: opacity 0.3s ease-in-out;\n  background-image: url(\"images/spritemap.png\");\n  background-repeat: no-repeat;\n  background-position: 0 0;\n  position: absolute;\n  width: 428px;\n  height: 123px;\n  margin-left: -214px;\n  margin-top: -61.5px;\n  top: 50%;\n  left: 50%;\n}\n@media all and (-webkit-min-device-pixel-ratio:1.5),(min--moz-device-pixel-ratio:1.5),(-o-min-device-pixel-ratio:1.5/1),(min-device-pixel-ratio:1.5),(min-resolution:138dpi),(min-resolution:1.5dppx) {\n  .dropzone .dz-default.dz-message {\n    background-image: url(\"images/spritemap@2x.png\");\n    -webkit-background-size: 428px 406px;\n    -moz-background-size: 428px 406px;\n    background-size: 428px 406px;\n  }\n}\n.dropzone .dz-default.dz-message span {\n  display: none;\n}\n.dropzone.dz-square .dz-default.dz-message {\n  background-position: 0 -123px;\n  width: 268px;\n  margin-left: -134px;\n  height: 174px;\n  margin-top: -87px;\n}\n.dropzone.dz-drag-hover .dz-message {\n  opacity: 0.15;\n  -ms-filter: \"progid:DXImageTransform.Microsoft.Alpha(Opacity=15)\";\n  filter: alpha(opacity=15);\n}\n.dropzone.dz-started .dz-message {\n  display: block;\n  opacity: 0;\n  -ms-filter: \"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)\";\n  filter: alpha(opacity=0);\n}\n.dropzone .dz-preview,\n.dropzone-previews .dz-preview {\n  -webkit-box-shadow: 1px 1px 4px rgba(0,0,0,0.16);\n  box-shadow: 1px 1px 4px rgba(0,0,0,0.16);\n  font-size: 14px;\n}\n.dropzone .dz-preview.dz-image-preview:hover .dz-details img,\n.dropzone-previews .dz-preview.dz-image-preview:hover .dz-details img {\n  display: block;\n  opacity: 0.1;\n  -ms-filter: \"progid:DXImageTransform.Microsoft.Alpha(Opacity=10)\";\n  filter: alpha(opacity=10);\n}\n.dropzone .dz-preview.dz-success .dz-success-mark,\n.dropzone-previews .dz-preview.dz-success .dz-success-mark {\n  opacity: 1;\n  -ms-filter: none;\n  filter: none;\n}\n.dropzone .dz-preview.dz-error .dz-error-mark,\n.dropzone-previews .dz-preview.dz-error .dz-error-mark {\n  opacity: 1;\n  -ms-filter: none;\n  filter: none;\n}\n.dropzone .dz-preview.dz-error .dz-progress .dz-upload,\n.dropzone-previews .dz-preview.dz-error .dz-progress .dz-upload {\n  background: #ee1e2d;\n}\n.dropzone .dz-preview .dz-error-mark,\n.dropzone-previews .dz-preview .dz-error-mark,\n.dropzone .dz-preview .dz-success-mark,\n.dropzone-previews .dz-preview .dz-success-mark {\n  display: block;\n  opacity: 0;\n  -ms-filter: \"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)\";\n  filter: alpha(opacity=0);\n  -webkit-transition: opacity 0.4s ease-in-out;\n  -moz-transition: opacity 0.4s ease-in-out;\n  -o-transition: opacity 0.4s ease-in-out;\n  -ms-transition: opacity 0.4s ease-in-out;\n  transition: opacity 0.4s ease-in-out;\n  background-image: url(\"images/spritemap.png\");\n  background-repeat: no-repeat;\n}\n@media all and (-webkit-min-device-pixel-ratio:1.5),(min--moz-device-pixel-ratio:1.5),(-o-min-device-pixel-ratio:1.5/1),(min-device-pixel-ratio:1.5),(min-resolution:138dpi),(min-resolution:1.5dppx) {\n  .dropzone .dz-preview .dz-error-mark,\n  .dropzone-previews .dz-preview .dz-error-mark,\n  .dropzone .dz-preview .dz-success-mark,\n  .dropzone-previews .dz-preview .dz-success-mark {\n    background-image: url(\"images/spritemap@2x.png\");\n    -webkit-background-size: 428px 406px;\n    -moz-background-size: 428px 406px;\n    background-size: 428px 406px;\n  }\n}\n.dropzone .dz-preview .dz-error-mark span,\n.dropzone-previews .dz-preview .dz-error-mark span,\n.dropzone .dz-preview .dz-success-mark span,\n.dropzone-previews .dz-preview .dz-success-mark span {\n  display: none;\n}\n.dropzone .dz-preview .dz-error-mark,\n.dropzone-previews .dz-preview .dz-error-mark {\n  background-position: -268px -123px;\n}\n.dropzone .dz-preview .dz-success-mark,\n.dropzone-previews .dz-preview .dz-success-mark {\n  background-position: -268px -163px;\n}\n.dropzone .dz-preview .dz-progress .dz-upload,\n.dropzone-previews .dz-preview .dz-progress .dz-upload {\n  -webkit-animation: loading 0.4s linear infinite;\n  -moz-animation: loading 0.4s linear infinite;\n  -o-animation: loading 0.4s linear infinite;\n  -ms-animation: loading 0.4s linear infinite;\n  animation: loading 0.4s linear infinite;\n  -webkit-transition: width 0.3s ease-in-out;\n  -moz-transition: width 0.3s ease-in-out;\n  -o-transition: width 0.3s ease-in-out;\n  -ms-transition: width 0.3s ease-in-out;\n  transition: width 0.3s ease-in-out;\n  -webkit-border-radius: 2px;\n  border-radius: 2px;\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 0%;\n  height: 100%;\n  background-image: url(\"images/spritemap.png\");\n  background-repeat: repeat-x;\n  background-position: 0px -400px;\n}\n@media all and (-webkit-min-device-pixel-ratio:1.5),(min--moz-device-pixel-ratio:1.5),(-o-min-device-pixel-ratio:1.5/1),(min-device-pixel-ratio:1.5),(min-resolution:138dpi),(min-resolution:1.5dppx) {\n  .dropzone .dz-preview .dz-progress .dz-upload,\n  .dropzone-previews .dz-preview .dz-progress .dz-upload {\n    background-image: url(\"images/spritemap@2x.png\");\n    -webkit-background-size: 428px 406px;\n    -moz-background-size: 428px 406px;\n    background-size: 428px 406px;\n  }\n}\n.dropzone .dz-preview.dz-success .dz-progress,\n.dropzone-previews .dz-preview.dz-success .dz-progress {\n  display: block;\n  opacity: 0;\n  -ms-filter: \"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)\";\n  filter: alpha(opacity=0);\n  -webkit-transition: opacity 0.4s ease-in-out;\n  -moz-transition: opacity 0.4s ease-in-out;\n  -o-transition: opacity 0.4s ease-in-out;\n  -ms-transition: opacity 0.4s ease-in-out;\n  transition: opacity 0.4s ease-in-out;\n}\n.dropzone .dz-preview .dz-error-message,\n.dropzone-previews .dz-preview .dz-error-message {\n  display: block;\n  opacity: 0;\n  -ms-filter: \"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)\";\n  filter: alpha(opacity=0);\n  -webkit-transition: opacity 0.3s ease-in-out;\n  -moz-transition: opacity 0.3s ease-in-out;\n  -o-transition: opacity 0.3s ease-in-out;\n  -ms-transition: opacity 0.3s ease-in-out;\n  transition: opacity 0.3s ease-in-out;\n}\n.dropzone .dz-preview:hover.dz-error .dz-error-message,\n.dropzone-previews .dz-preview:hover.dz-error .dz-error-message {\n  opacity: 1;\n  -ms-filter: none;\n  filter: none;\n}\n.dropzone a.dz-remove,\n.dropzone-previews a.dz-remove {\n  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fafafa), color-stop(1, #eee));\n  background-image: -webkit-linear-gradient(top, #fafafa 0, #eee 100%);\n  background-image: -moz-linear-gradient(top, #fafafa 0, #eee 100%);\n  background-image: -o-linear-gradient(top, #fafafa 0, #eee 100%);\n  background-image: -ms-linear-gradient(top, #fafafa 0, #eee 100%);\n  background-image: linear-gradient(top, #fafafa 0, #eee 100%);\n  -webkit-border-radius: 2px;\n  border-radius: 2px;\n  border: 1px solid #eee;\n  text-decoration: none;\n  display: block;\n  padding: 4px 5px;\n  text-align: center;\n  color: #aaa;\n  margin-top: 26px;\n}\n.dropzone a.dz-remove:hover,\n.dropzone-previews a.dz-remove:hover {\n  color: #666;\n}\n@-moz-keyframes loading {\n  0% {\n    background-position: 0 -400px;\n  }\n\n  100% {\n    background-position: -7px -400px;\n  }\n}\n@-webkit-keyframes loading {\n  0% {\n    background-position: 0 -400px;\n  }\n\n  100% {\n    background-position: -7px -400px;\n  }\n}\n@-o-keyframes loading {\n  0% {\n    background-position: 0 -400px;\n  }\n\n  100% {\n    background-position: -7px -400px;\n  }\n}\n@-ms-keyframes loading {\n  0% {\n    background-position: 0 -400px;\n  }\n\n  100% {\n    background-position: -7px -400px;\n  }\n}\n@keyframes loading {\n  0% {\n    background-position: 0 -400px;\n  }\n\n  100% {\n    background-position: -7px -400px;\n  }\n}\n"
  },
  {
    "path": "static/template/css/endless-skin.css",
    "content": "aside.skin-1 {\n  background: #efefef;\n}\naside.skin-1 .brand {\n  background: #3c8dbc;\n  color: #fff;\n  border-bottom-color: #3b89b6;\n}\naside.skin-1 .size-toggle {\n  border-bottom-color: #dfdfdf;\n  box-shadow: 0 1px 0 #f4f4f4;\n  -moz-box-shadow: 0 1px 0 #f4f4f4;\n  -webkit-box-shadow: 0 1px 0 #f4f4f4;\n}\naside.skin-1 .size-toggle .btn {\n  color: #777;\n}\naside.skin-1 .size-toggle .btn:hover,\naside.skin-1 .size-toggle .btn:focus {\n  color: #333;\n}\naside.skin-1 .size-toggle .btn .icon-bar {\n  background-color: #777;\n}\naside.skin-1 .sidebar-inner {\n  border-right-color: #dfdfdf;\n}\naside.skin-1 .sidebar-inner .user-block {\n  border-bottom-color: #dfdfdf;\n  box-shadow: 0 1px 0 #f4f4f4;\n  -moz-box-shadow: 0 1px 0 #f4f4f4;\n  -webkit-box-shadow: 0 1px 0 #f4f4f4;\n}\naside.skin-1 .sidebar-inner .user-block .detail {\n  color: #777;\n}\naside.skin-1 .sidebar-inner .user-block ul li a {\n  color: #777;\n}\naside.skin-1 .sidebar-inner .user-block ul li a:hover,\naside.skin-1 .sidebar-inner .user-block ul li a:focus {\n  color: #333;\n}\naside.skin-1 .sidebar-inner .search-block {\n  border-bottom-color: #dfdfdf;\n  box-shadow: 0 1px 0 #f4f4f4;\n  -moz-box-shadow: 0 1px 0 #f4f4f4;\n  -webkit-box-shadow: 0 1px 0 #f4f4f4;\n}\naside.skin-1 .sidebar-inner .search-block input[type=\"text\"],\naside.skin-1 .sidebar-inner .search-block .btn {\n  background: #fff;\n  color: #777;\n  border-color: #dfdfdf;\n}\naside.skin-1 .main-menu > ul > li {\n  border-top-color: #f4f4f4;\n  border-bottom-color: #dfdfdf;\n}\naside.skin-1 .main-menu > ul > li.active,\naside.skin-1 .main-menu > ul > li.display {\n  border-top-color: #dfdfdf;\n}\naside.skin-1 .main-menu > ul > li.active > a,\naside.skin-1 .main-menu > ul > li.display > a {\n  background: #f9f9f9;\n}\naside.skin-1 .main-menu > ul > li > a {\n  color: #777;\n}\naside.skin-1 .main-menu > ul > li > a:hover,\naside.skin-1 .main-menu > ul > li > a:focus {\n  background: #f9f9f9;\n}\naside.skin-1 .main-menu > ul > li > a .menu-hover {\n  background: #3c8dbc;\n  box-shadow: 0 0 10px 0px #439bce;\n  -moz-box-shadow: 0 0 10px 0px #439bce;\n  -webkit-box-shadow: 0 0 10px 0px #439bce;\n}\naside.skin-1 .main-menu > ul > li > .submenu  li  a{\n  background-color: #e6e6e6;\n}\naside.skin-1 .main-menu > ul > li > .submenu  li a .submenu-label{\n  color: #777;\n}\naside.skin-1 .main-menu > ul > li > .submenu  li a:hover .submenu-label,\naside.skin-1 .main-menu > ul > li > .submenu  li a:focus .submenu-label {\n  color: #222;\n}\naside.skin-1 .main-menu > ul > li > .submenu  li.active a{\n  background: #f9f9f9;\n}\naside.skin-1 .main-menu > ul > li > .submenu  li.active a .submenu-label{\n  color: #555;\n}\n@media (max-width: 767px)   {\n    aside.skin-1 .main-menu > ul > li > .dropdown-menu li a {\n       color: #777;\n    }\n    \n    aside.skin-1 .main-menu > ul > li > .dropdown-menu li a:hover \n    ,aside.skin-1 .main-menu > ul > li > .dropdown-menu li a:focus {\n       color: #777;\n       background: #f9f9f9;\n    } \n}\n#top-nav.skin-1 {\n  background: #3c8dbc;\n  border-bottom-color: #3b89b6;\n}\n#top-nav.skin-1 .navbar-toggle .icon-bar {\n  background-color: #fff;\n}\n#top-nav.skin-1 .brand {\n  color: #c3e3f5;\t\n  background: #3c8dbc;\n}\n#top-nav.skin-1 .page-title {\n  color: #c3e3f5;\n}\n#top-nav.skin-1 .nav-notification > li.open {\n  background: #3b89b6;\n}\n#top-nav.skin-1 .nav-notification > li:hover {\n  background: #3b89b6;\n}\n#top-nav.skin-1 .nav-notification > li > a {\n  color: #c3e3f5;\n}\n#top-nav.skin-1 .nav-notification > li > a:hover,\n#top-nav.skin-1 .nav-notification > li > a:focus {\n  color: #fff;\n}\naside.skin-2 {\n  background: #3a3a3a;\n}\naside.skin-2 .brand {\n  background: #3a3a3a;\n  color: #fff;\n  border-bottom-color: #444;\n}\naside.skin-2 .size-toggle {\n  border-bottom-color: #333;\n  box-shadow: 0 1px 0 #444444;\n  -moz-box-shadow: 0 1px 0 #444444;\n  -webkit-box-shadow: 0 1px 0 #444444;\n}\naside.skin-2 .size-toggle .btn {\n  color: #777;\n}\naside.skin-2 .size-toggle .btn:hover,\naside.skin-2 .size-toggle .btn:focus {\n  color: #fff;\n}\naside.skin-2 .size-toggle .btn .icon-bar {\n  background-color: #777;\n}\naside.skin-2 .sidebar-inner {\n  border-right-color: #333;\n}\naside.skin-2 .sidebar-inner .user-block {\n  border-bottom-color: #333;\n  box-shadow: 0 1px 0 #444444;\n  -moz-box-shadow: 0 1px 0 #444444;\n  -webkit-box-shadow: 0 1px 0 #444444;\n}\naside.skin-2 .sidebar-inner .user-block .detail {\n  color: #777;\n}\naside.skin-2 .sidebar-inner .user-block ul li a {\n  color: #777;\n}\naside.skin-2 .sidebar-inner .user-block ul li a:hover,\naside.skin-2 .sidebar-inner .user-block ul li a:focus {\n  color: #fff;\n}\naside.skin-2 .sidebar-inner .search-block {\n  border-bottom-color: #333;\n  box-shadow: 0 1px 0 #444444;\n  -moz-box-shadow: 0 1px 0 #444444;\n  -webkit-box-shadow: 0 1px 0 #444444;\n}\naside.skin-2 .sidebar-inner .search-block input[type=\"text\"],\naside.skin-2 .sidebar-inner .search-block .btn {\n  background: #fff;\n  color: #777;\n  border-color: #dfdfdf;\n}\naside.skin-2 .main-menu > ul > li {\n  border-top-color: #444;\n  border-bottom-color: #333;\n}\naside.skin-2 .main-menu > ul > li.active,\naside.skin-2 .main-menu > ul > li.display {\n  border-top-color: #A93922;\n}\naside.skin-2 .main-menu > ul > li.active > a,\naside.skin-2 .main-menu > ul > li.display > a {\n  background: #BD3F26;\n  color: #fff;\n}\naside.skin-2 .main-menu > ul > li > a {\n  color: #777;\n}\naside.skin-2 .main-menu > ul > li > a:hover,\naside.skin-2 .main-menu > ul > li > a:focus {\n  background: #BD3F26;\n  color: #fff;\n}\naside.skin-2 .main-menu > ul > li > a .menu-hover {\n  background: #feffd8;\n  box-shadow: 0 0 10px 0px #ffffff;\n  -moz-box-shadow: 0 0 10px 0px #ffffff;\n  -webkit-box-shadow: 0 0 10px 0px #ffffff;\n}\naside.skin-2 .main-menu > ul > li > .submenu  li  a{\n  background-color: #333;\n}\naside.skin-2 .main-menu > ul > li > .submenu  li a .submenu-label{\n  color: #777;\n}\naside.skin-2 .main-menu > ul > li > .submenu  li a:hover .submenu-label,\naside.skin-2 .main-menu > ul > li > .submenu  li a:focus .submenu-label {\n  color: #fff;\n}\naside.skin-2 .main-menu > ul > li > .submenu  li.active a{\n  background: #BD3F26;\n}\naside.skin-2 .main-menu > ul > li > .submenu  li.active a .submenu-label{\n  color: #fff;\n}\n@media (max-width: 767px)   {\n    aside.skin-2 .main-menu > ul > li > .dropdown-menu li a {\n       color: #777;\n    }\n    \n    aside.skin-2 .main-menu > ul > li > .dropdown-menu li a:hover \n       ,aside.skin-2 .main-menu > ul > li > .dropdown-menu li a:focus {\n        color: #fff;\n        background: #bd3f26;\n    }\n}\n#top-nav.skin-2 {\n  background: #BD3F26;\n  border-bottom-color: #A93922;\n}\n#top-nav.skin-2 .navbar-toggle .icon-bar {\n  background-color: #fff;\n}\n#top-nav.skin-2 .brand {\n  color: #f4cdc5;\t\n  background: #BD3F26;\n}\n#top-nav.skin-2 .page-title {\n  color: #f4cdc5;\n}\n#top-nav.skin-2 .nav-notification > li.open {\n  background: #A93922;\n}\n#top-nav.skin-2 .nav-notification > li:hover {\n  background: #A93922;\n}\n#top-nav.skin-2 .nav-notification > li > a {\n  color: #f4cdc5;\n}\n#top-nav.skin-2 .nav-notification > li > a:hover,\n#top-nav.skin-2 .nav-notification > li > a:focus {\n  color: #fff;\n}\naside.skin-3 {\n  background: #3e6b96;\n}\naside.skin-3 .brand {\n  background: #3e6b96;\n  color: #D6E8F7;\n  border-bottom-color: #4577A5;\n}\naside.skin-3 .size-toggle {\n  border-bottom-color: #396389;\n  box-shadow: 0 1px 0 #4577a5;\n  -moz-box-shadow: 0 1px 0 #4577a5;\n  -webkit-box-shadow: 0 1px 0 #4577a5;\n}\naside.skin-3 .size-toggle .btn {\n  color: #D6E8F7;\n}\naside.skin-3 .size-toggle .btn:hover,\naside.skin-3 .size-toggle .btn:focus {\n  color: #fff;\n}\naside.skin-3 .size-toggle .btn .icon-bar {\n  background-color: #D6E8F7;\n}\naside.skin-3 .sidebar-inner {\n  border-right-color: #396389;\n}\naside.skin-3 .sidebar-inner .user-block {\n  border-bottom-color: #396389;\n  box-shadow: 0 1px 0 #4577a5;\n  -moz-box-shadow: 0 1px 0 #4577a5;\n  -webkit-box-shadow: 0 1px 0 #4577a5;\n}\naside.skin-3 .sidebar-inner .user-block .detail {\n  color: #D6E8F7;\n}\naside.skin-3 .sidebar-inner .user-block ul li a {\n  color: #D6E8F7;\n}\naside.skin-3 .sidebar-inner .user-block ul li a:hover,\naside.skin-3 .sidebar-inner .user-block ul li a:focus {\n  color: #fff;\n}\naside.skin-3 .sidebar-inner .search-block {\n  border-bottom-color: #396389;\n  box-shadow: 0 1px 0 #4577a5;\n  -moz-box-shadow: 0 1px 0 #4577a5;\n  -webkit-box-shadow: 0 1px 0 #4577a5;\n}\naside.skin-3 .sidebar-inner .search-block input[type=\"text\"],\naside.skin-3 .sidebar-inner .search-block .btn {\n  background: #fff;\n  color: #777;\n  border-color: #dfdfdf;\n}\naside.skin-3 .main-menu > ul > li {\n  border-top-color: #4577A5;\n  border-bottom-color: #396389;\n}\naside.skin-3 .main-menu > ul > li.active,\naside.skin-3 .main-menu > ul > li.display {\n  border-top-color: #396389;\n}\naside.skin-3 .main-menu > ul > li.active > a,\naside.skin-3 .main-menu > ul > li.display > a {\n  background: #396389;\n  color: #fff;\n}\naside.skin-3 .main-menu > ul > li > a {\n  color: #D6E8F7;\n}\naside.skin-3 .main-menu > ul > li > a:hover,\naside.skin-3 .main-menu > ul > li > a:focus {\n  background: #396389;\n  color: #fff;\n}\naside.skin-3 .main-menu > ul > li > a .menu-hover {\n  background: #feffd8;\n  box-shadow: 0 0 10px 0px #ffffff;\n  -moz-box-shadow: 0 0 10px 0px #ffffff;\n  -webkit-box-shadow: 0 0 10px 0px #ffffff;\n}\naside.skin-3 .main-menu > ul > li > .submenu  li  a{\n  background-color: #4577a5;\n}\naside.skin-3 .main-menu > ul > li > .submenu  li a .submenu-label{\n  color: #D6E8F7;\n}\naside.skin-3 .main-menu > ul > li > .submenu  li a:hover .submenu-label,\naside.skin-3 .main-menu > ul > li > .submenu  li a:focus .submenu-label {\n  color: #fff;\n}\naside.skin-3 .main-menu > ul > li > .submenu  li.active a{\n  background: #396389;\n}\naside.skin-3 .main-menu > ul > li > .submenu  li.active a .submenu-label{\n  color: #fff;\n}\n@media (max-width: 767px)   {\n    aside.skin-3 .main-menu > ul > li > .dropdown-menu li a {\n       color: #d6e8f7;\n    }\n    \n    aside.skin-3 .main-menu > ul > li > .dropdown-menu li a:hover \n    ,aside.skin-3 .main-menu > ul > li > .dropdown-menu li a:focus {\n        color: #fff;\n        background: #396389;\n    }\n}\n#top-nav.skin-3 {\n  background: #fff;\n  border-bottom-color: #eee;\n}\n#top-nav.skin-3 .navbar-toggle .icon-bar {\n  background-color: #999;\n}\n#top-nav.skin-3 .brand {\n  color: #fff;\n  background: #3e6b96;  \n}\n#top-nav.skin-3 .page-title {\n  color: #999;\n}\n#top-nav.skin-3 .nav-notification > li.open {\n  background: rgba(252, 252, 252, 0.9);\n}\n#top-nav.skin-3 .nav-notification > li:hover {\n  background: rgba(252, 252, 252, 0.9);\n}\n#top-nav.skin-3 .nav-notification > li > a {\n  color: #999;\n}\n#top-nav.skin-3 .nav-notification > li > a:hover,\n#top-nav.skin-3 .nav-notification > li > a:focus {\n  color: #777;\n}\naside.skin-4 {\n  background: #635247;\n}\naside.skin-4 .brand {\n  background: #635247;\n  color: #F7E4D7;\n  border-bottom-color: #55473E;\n}\naside.skin-4 .size-toggle {\n  border-bottom-color: #55473E;\n  box-shadow: 0 1px 0 #756155;\n  -moz-box-shadow: 0 1px 0 #756155;\n  -webkit-box-shadow: 0 1px 0 #756155;\n}\naside.skin-4 .size-toggle .btn {\n  color: #F7E4D7;\n}\naside.skin-4 .size-toggle .btn:hover,\naside.skin-4 .size-toggle .btn:focus {\n  color: #fff;\n}\naside.skin-4 .size-toggle .btn .icon-bar {\n  background-color: #F7E4D7;\n}\naside.skin-4 .sidebar-inner {\n  border-right-color: #55473E;\n}\naside.skin-4 .sidebar-inner .user-block {\n  border-bottom-color: #55473E;\n  box-shadow: 0 1px 0 #756155;\n  -moz-box-shadow: 0 1px 0 #756155;\n  -webkit-box-shadow: 0 1px 0 #756155;\n}\naside.skin-4 .sidebar-inner .user-block .detail {\n  color: #F7E4D7;\n}\naside.skin-4 .sidebar-inner .user-block ul li a {\n  color: #F7E4D7;\n}\naside.skin-4 .sidebar-inner .user-block ul li a:hover,\naside.skin-4 .sidebar-inner .user-block ul li a:focus {\n  color: #fff;\n}\naside.skin-4 .sidebar-inner .search-block {\n  border-bottom-color: #55473E;\n  box-shadow: 0 1px 0 #756155;\n  -moz-box-shadow: 0 1px 0 #756155;\n  -webkit-box-shadow: 0 1px 0 #756155;\n}\naside.skin-4 .sidebar-inner .search-block input[type=\"text\"],\naside.skin-4 .sidebar-inner .search-block .btn {\n  background: #fff;\n  color: #777;\n  border-color: #dfdfdf;\n}\naside.skin-4 .main-menu > ul > li {\n  border-top-color: #756155;\n  border-bottom-color: #55473E;\n}\naside.skin-4 .main-menu > ul > li.active,\naside.skin-4 .main-menu > ul > li.display {\n  border-top-color: #55473E;\n}\naside.skin-4 .main-menu > ul > li.active > a,\naside.skin-4 .main-menu > ul > li.display > a {\n  background: #55473E;\n  color: #fff;\n}\naside.skin-4 .main-menu > ul > li > a {\n  color: #F7E4D7;\n}\naside.skin-4 .main-menu > ul > li > a:hover,\naside.skin-4 .main-menu > ul > li > a:focus {\n  background: #55473E;\n  color: #fff;\n}\naside.skin-4 .main-menu > ul > li > a .menu-hover {\n  background: #feffd8;\n  box-shadow: 0 0 10px 0px #ffffff;\n  -moz-box-shadow: 0 0 10px 0px #ffffff;\n  -webkit-box-shadow: 0 0 10px 0px #ffffff;\n}\naside.skin-4 .main-menu > ul > li > .submenu  li  a{\n  background-color: #69594E;\n}\naside.skin-4 .main-menu > ul > li > .submenu  li a .submenu-label{\n  color: #F7E4D7;\n}\naside.skin-4 .main-menu > ul > li > .submenu  li a:hover .submenu-label,\naside.skin-4 .main-menu > ul > li > .submenu  li a:focus .submenu-label {\n  color: #fff;\n}\naside.skin-4 .main-menu > ul > li > .submenu  li.active a{\n  background: #55473E;\n}\naside.skin-4 .main-menu > ul > li > .submenu  li.active a .submenu-label{\n  color: #fff;\n}\n@media (max-width: 767px)   {\n    aside.skin-4 .main-menu > ul > li > .dropdown-menu li a {\n       color: #f7e4d7;\n    }\n    \n    aside.skin-4 .main-menu > ul > li > .dropdown-menu li a:hover \n    ,aside.skin-4 .main-menu > ul > li > .dropdown-menu li a:focus {\n        color: #fff;\n        background: #55473e;\n    }\n}\n#top-nav.skin-4 {\n  background: #635247;\n  border-bottom-color: #55473E;\n}\n#top-nav.skin-4 .navbar-toggle .icon-bar {\n  background-color: #F7E4D7;\n}\n#top-nav.skin-4 .brand {\n  color: #F7E4D7;\t\n  background: #635247;\n}\n#top-nav.skin-4 .page-title {\n  color: #F7E4D7;\n}\n#top-nav.skin-4 .nav-notification > li.open {\n  background: #55473E;\n}\n#top-nav.skin-4 .nav-notification > li:hover {\n  background: #55473E;\n}\n#top-nav.skin-4 .nav-notification > li > a {\n  color: #F7E4D7;\n}\n#top-nav.skin-4 .nav-notification > li > a:hover,\n#top-nav.skin-4 .nav-notification > li > a:focus {\n  color: #fff;\n}\n\naside.skin-5 {\n  background: #3a3a3a;\n}\naside.skin-5 .size-toggle {\n  border-bottom-color: #333;\n  box-shadow: 0 1px 0 #444444;\n  -moz-box-shadow: 0 1px 0 #444444;\n  -webkit-box-shadow: 0 1px 0 #444444;\n}\naside.skin-5 .size-toggle .btn {\n  color: #999;\n}\naside.skin-5 .size-toggle .btn:hover,\naside.skin-5 .size-toggle .btn:focus {\n  color: #fff;\n}\naside.skin-5 .size-toggle .btn .icon-bar {\n  background-color: #999;\n}\naside.skin-5 .sidebar-inner {\n  border-right-color: #333;\n}\naside.skin-5 .sidebar-inner .user-block {\n  border-bottom-color: #333;\n  box-shadow: 0 1px 0 #444444;\n  -moz-box-shadow: 0 1px 0 #444444;\n  -webkit-box-shadow: 0 1px 0 #444444;\n}\naside.skin-5 .sidebar-inner .user-block .detail {\n  color: #999;\n}\naside.skin-5 .sidebar-inner .user-block ul li a {\n  color: #999;\n}\naside.skin-5 .sidebar-inner .user-block ul li a:hover,\naside.skin-5 .sidebar-inner .user-block ul li a:focus {\n  color: #fff;\n}\naside.skin-5 .sidebar-inner .search-block {\n  border-bottom-color: #333;\n  box-shadow: 0 1px 0 #444444;\n  -moz-box-shadow: 0 1px 0 #444444;\n  -webkit-box-shadow: 0 1px 0 #444444;\n}\naside.skin-5 .sidebar-inner .search-block input[type=\"text\"],\naside.skin-5 .sidebar-inner .search-block .btn {\n  background: #fff;\n  color: #999;\n  border-color: #dfdfdf;\n}\naside.skin-5 .main-menu > ul > li {\n  border-top-color: #444;\n  border-bottom-color: #333;\n}\naside.skin-5 .main-menu > ul > li.active,\naside.skin-5 .main-menu > ul > li.display {\n  border-top-color: #333;\n}\naside.skin-5 .main-menu > ul > li.active > a,\naside.skin-5 .main-menu > ul > li.display > a {\n  background: #333;\n  color: #fff;\n}\naside.skin-5 .main-menu > ul > li > a {\n  color: #999;\n}\naside.skin-5 .main-menu > ul > li > a:hover,\naside.skin-5 .main-menu > ul > li > a:focus {\n  background: #333;\n  color: #fff;\n}\naside.skin-5 .main-menu > ul > li > a .menu-hover {\n  background: #feffd8;\n  box-shadow: 0 0 10px 0px #ffffff;\n  -moz-box-shadow: 0 0 10px 0px #ffffff;\n  -webkit-box-shadow: 0 0 10px 0px #ffffff;\n}\naside.skin-5 .main-menu > ul > li > .submenu  li  a{\n  background-color: #333;\n}\naside.skin-5 .main-menu > ul > li > .submenu  li a .submenu-label{\n  color: #999;\n}\naside.skin-5 .main-menu > ul > li > .submenu  li a:hover .submenu-label,\naside.skin-5 .main-menu > ul > li > .submenu  li a:focus .submenu-label {\n  color: #fff;\n}\naside.skin-5 .main-menu > ul > li > .submenu  li.active a{\n  background: #222;\n}\naside.skin-5 .main-menu > ul > li > .submenu  li.active a .submenu-label{\n  color: #fff;\n}\n@media (max-width: 767px)   {\n    aside.skin-5 .main-menu > ul > li > .dropdown-menu li a {\n       color: #999;\n    }\n    \n    aside.skin-5 .main-menu > ul > li > .dropdown-menu li a:hover \n       ,aside.skin-5 .main-menu > ul > li > .dropdown-menu li a:focus {\n        color: #fff;\n        background: #333;\n    }\n}\n#top-nav.skin-5 {\n  background: #3a3a3a;\n  border-bottom-color: #333;\n}\n#top-nav.skin-5 .navbar-toggle .icon-bar {\n  background-color: #fff;\n}\n#top-nav.skin-5 .brand {\n  color: #999;\t\n  background: #3a3a3a;\n}\n#top-nav.skin-5 .page-title {\n  color: #999;\n}\n#top-nav.skin-5 .nav-notification > li.open {\n  background: #333;\n}\n#top-nav.skin-5 .nav-notification > li:hover {\n  background: #333;\n}\n#top-nav.skin-5 .nav-notification > li > a {\n  color: #999;\n}\n#top-nav.skin-5 .nav-notification > li > a:hover,\n#top-nav.skin-5 .nav-notification > li > a:focus {\n  color: #fff;\n}\n\naside.skin-6 {\n  background: #495B6C;\n}\naside.skin-6 .size-toggle {\n  border-bottom-color: #415160;\n  box-shadow: 0 1px 0 #506274;\n  -moz-box-shadow: 0 1px 0 #506274;\n  -webkit-box-shadow: 0 1px 0 #506274;\n}\naside.skin-6 .size-toggle .btn {\n  color: #BECFE0;\n}\naside.skin-6 .size-toggle .btn:hover,\naside.skin-6 .size-toggle .btn:focus {\n  color: #fff;\n}\naside.skin-6 .size-toggle .btn .icon-bar {\n  background-color: #BECFE0;\n}\naside.skin-6 .sidebar-inner {\n  border-right-color: #415160;\n}\naside.skin-6 .sidebar-inner .user-block {\n  border-bottom-color: #415160;\n  box-shadow: 0 1px 0 #506274;\n  -moz-box-shadow: 0 1px 0 #506274;\n  -webkit-box-shadow: 0 1px 0 #506274;\n}\naside.skin-6 .sidebar-inner .user-block .detail {\n  color: #BECFE0;\n}\naside.skin-6 .sidebar-inner .user-block ul li a {\n  color: #BECFE0;\n}\naside.skin-6 .sidebar-inner .user-block ul li a:hover,\naside.skin-6 .sidebar-inner .user-block ul li a:focus {\n  color: #fff;\n}\naside.skin-6 .sidebar-inner .search-block {\n  border-bottom-color: #415160;\n  box-shadow: 0 1px 0 #506274;\n  -moz-box-shadow: 0 1px 0 #506274;\n  -webkit-box-shadow: 0 1px 0 #506274;\n}\naside.skin-6 .sidebar-inner .search-block input[type=\"text\"],\naside.skin-6 .sidebar-inner .search-block .btn {\n  background: #fff;\n  color: #BECFE0;\n  border-color: #dfdfdf;\n}\naside.skin-6 .main-menu > ul > li {\n  border-top-color: #506274;\n  border-bottom-color: #415160;\n}\naside.skin-6 .main-menu > ul > li.active,\naside.skin-6 .main-menu > ul > li.display {\n  border-top-color: #415160;\n}\naside.skin-6 .main-menu > ul > li.active > a,\naside.skin-6 .main-menu > ul > li.display > a {\n  background: #415160;\n  color: #fff;\n}\naside.skin-6 .main-menu > ul > li > a {\n  color: #BECFE0;\n}\naside.skin-6 .main-menu > ul > li > a:hover,\naside.skin-6 .main-menu > ul > li > a:focus {\n  background: #394754;\n  color: #fff;\n}\naside.skin-6 .main-menu > ul > li > a .menu-hover {\n  background: #feffd8;\n  box-shadow: 0 0 10px 0px #ffffff;\n  -moz-box-shadow: 0 0 10px 0px #ffffff;\n  -webkit-box-shadow: 0 0 10px 0px #ffffff;\n}\naside.skin-6 .main-menu > ul > li > .submenu  li  a{\n  background-color: #415160;\n}\naside.skin-6 .main-menu > ul > li > .submenu  li a .submenu-label{\n  color: #BECFE0;\n}\naside.skin-6 .main-menu > ul > li > .submenu  li a:hover .submenu-label,\naside.skin-6 .main-menu > ul > li > .submenu  li a:focus .submenu-label {\n  color: #fff;\n}\naside.skin-6 .main-menu > ul > li > .submenu  li.active a{\n  background: #2E3943;\n}\naside.skin-6 .main-menu > ul > li > .submenu  li.active a .submenu-label{\n  color: #fff;\n}\n@media (max-width: 767px)   {\n    aside.skin-6 .main-menu > ul > li > .dropdown-menu li a {\n       color: #BECFE0;\n    }\n    \n    aside.skin-6 .main-menu > ul > li > .dropdown-menu li a:hover \n       ,aside.skin-6 .main-menu > ul > li > .dropdown-menu li a:focus {\n        color: #fff;\n        background: #415160;\n    }\n}\n#top-nav.skin-6 {\n  background: #2B333C;\n  border-bottom-color: #415160;\n}\n#top-nav.skin-6 .navbar-toggle .icon-bar {\n  background-color: #fff;\n}\n#top-nav.skin-6 .brand {\n  color: #BECFE0;\t\n  background: #2B333C;\n}\n#top-nav.skin-6 .brand:hover\n,#top-nav.skin-6 .brand:focus {\n  color: #fff;\t\n}\n#top-nav.skin-6 .page-title {\n  color: #BECFE0;\n}\n#top-nav.skin-6 .nav-notification > li.open {\n  background: #415160;\n}\n#top-nav.skin-6 .nav-notification > li:hover {\n  background: #415160;\n}\n#top-nav.skin-6 .nav-notification > li > a {\n  color: #BECFE0;\n}\n#top-nav.skin-6 .nav-notification > li > a:hover,\n#top-nav.skin-6 .nav-notification > li > a:focus {\n  color: #fff;\n}\n"
  },
  {
    "path": "static/template/css/endless.css",
    "content": "@import url(http://fonts.googleapis.com/css?family=Open+Sans);\n#top-nav {\n  height: 45px;\n  padding-right: 10px;\n  background-color: #ffffff;\n  white-space: nowrap;\n  min-width: 310px;\n  border-bottom: 1px solid #f2f2f2;\n}\n#top-nav.fixed {\n  position: fixed;\n  left: 0;\n  right: 0;\n  z-index: 1000;\n}\n@media (max-width: 767px) {\n  #top-nav.fixed {\n    left: -194px;\n  }\n}\n#top-nav .brand {\n  display: block;\n  text-align: center;\n  font-size: 17px;\n  line-height: 45px;\n  width: 194px;\n  color: #999999;\n  background: #323447;\n  float: left;\n  transition: all 0.5s ease;\n  -webkit-transition: all 0.5s ease;\n  -moz-transition: all 0.5s ease;\n  -ms-transition: all 0.5s ease;\n  -o-transition: all 0.5s ease;\n}\n#top-nav .brand:hover,\n#top-nav .brand:focus {\n  color: #fff;\n  transition: all 0.5s ease;\n  -webkit-transition: all 0.5s ease;\n  -moz-transition: all 0.5s ease;\n  -ms-transition: all 0.5s ease;\n  -o-transition: all 0.5s ease;\n}\n#top-nav .page-title {\n  float: left;\n  line-height: 45px;\n  font-weight: 500;\n  color: #999999;\n}\n@media (max-width: 767px) {\n  #top-nav .page-title {\n    display: none;\n  }\n}\n#top-nav .navbar-toggle {\n  margin: 3px 0 0 0;\n}\n#top-nav .navbar-toggle.hide-menu {\n  display: block;\n  margin-top: 5px;\n}\n@media (max-width: 767px) {\n  #top-nav .navbar-toggle.hide-menu {\n    display: none;\n  }\n}\n#top-nav .navbar-toggle .icon-bar {\n  display: block;\n  width: 18px;\n  height: 2px;\n  margin-bottom: 3px;\n  background-color: #999999;\n  border-radius: 1px;\n  -moz-border-radius: 1px;\n  -webkit-border-radius: 1px;\n}\n#top-nav .navbar-toggle .icon-bar:last-child {\n  margin-bottom: 0;\n}\n#top-nav .nav-notification {\n  list-style: none;\n  margin: 0;\n  float: right;\n  white-space: nowrap;\n  font-size: 12px;\n}\n@media (max-width: 480px) {\n  #top-nav .nav-notification {\n    font-size: 11px;\n  }\n}\n#top-nav .nav-notification > li {\n  display: block;\n  position: relative;\n  float: left;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n#top-nav .nav-notification > li.open {\n  background: #fcfcfc;\n}\n#top-nav .nav-notification > li.open .dropdown-menu {\n  animation: fadeInUp 0.8s ease;\n  -webkit-animation: fadeInUp 0.8s ease;\n  -moz-animation: fadeInUp 0.8s ease;\n  -ms-animation: fadeInUp 0.8s ease;\n  -o-animation: fadeInUp 0.8s ease;\n}\n#top-nav .nav-notification > li:last-child {\n  border-right: none;\n}\n#top-nav .nav-notification > li:hover {\n  background: #fcfcfc;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n#top-nav .nav-notification > li.profile:hover a,\n#top-nav .nav-notification > li.profile:focus a {\n  animation: none;\n  -webkit-animation: none;\n  -moz-animation: none;\n  -ms-animation: none;\n  -o-animation: none;\n}\n#top-nav .nav-notification > li.profile:hover a > strong,\n#top-nav .nav-notification > li.profile:focus a > strong {\n  display: inline-block;\n  animation: fadeInRight 0.2s ease-in-out;\n  -webkit-animation: fadeInRight 0.2s ease-in-out;\n  -moz-animation: fadeInRight 0.2s ease-in-out;\n  -ms-animation: fadeInRight 0.2s ease-in-out;\n  -o-animation: fadeInRight 0.2s ease-in-out;\n}\n#top-nav .nav-notification > li.profile:hover a > span,\n#top-nav .nav-notification > li.profile:focus a > span {\n  display: inline-block;\n  animation: fadeInLeft 0.2s ease-in-out;\n  -webkit-animation: fadeInLeft 0.2s ease-in-out;\n  -moz-animation: fadeInLeft 0.2s ease-in-out;\n  -ms-animation: fadeInLeft 0.2s ease-in-out;\n  -o-animation: fadeInLeft 0.2s ease-in-out;\n}\n#top-nav .nav-notification > li.profile .dropdown-menu {\n  border-radius: 2px;\n  -moz-border-radius: 2px;\n  -webkit-border-radius: 2px;\n  min-width: 220px;\n}\n#top-nav .nav-notification > li.profile .dropdown-menu li:first-child {\n  margin-bottom: 10px;\n}\n#top-nav .nav-notification > li.profile .dropdown-menu li:first-child a:hover {\n  background: #fff;\n  color: #000;\n}\n#top-nav .nav-notification > li.profile .dropdown-menu li:not(:first-child) a {\n  transition: all 0.2s ease-in-out;\n  -webkit-transition: all 0.2s ease-in-out;\n  -moz-transition: all 0.2s ease-in-out;\n  -ms-transition: all 0.2s ease-in-out;\n  -o-transition: all 0.2s ease-in-out;\n}\n#top-nav .nav-notification > li.profile .dropdown-menu li:not(:first-child) a:hover,\n#top-nav .nav-notification > li.profile .dropdown-menu li:not(:first-child) a:focus {\n  transform: scale(1.05);\n  -webkit-transform: scale(1.05);\n  -moz-transform: scale(1.05);\n  -ms-transform: scale(1.05);\n  -o-transform: scale(1.05);\n  background: transparent;\n  color: #000;\n  transition: all 0.2s ease-in-out;\n  -webkit-transition: all 0.2s ease-in-out;\n  -moz-transition: all 0.2s ease-in-out;\n  -ms-transition: all 0.2s ease-in-out;\n  -o-transition: all 0.2s ease-in-out;\n}\n#top-nav .nav-notification > li > a {\n  display: block;\n  position: relative;\n  padding: 13px 15px;\n  color: #999999;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n#top-nav .nav-notification > li > a:hover,\n#top-nav .nav-notification > li > a:focus {\n  color: #777777;\n  text-decoration: none;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n@media (max-width: 480px) {\n  #top-nav .nav-notification > li > a {\n    padding: 14px 15px;\n  }\n}\n#top-nav .nav-notification .dropdown-menu {\n  right: 0;\n  left: auto;\n  top: 95%;\n  border-radius: 2px;\n  -moz-border-radius: 2px;\n  -webkit-border-radius: 2px;\n  border-color: #f1f5fc;\n}\n@media (max-width: 480px) {\n  #top-nav .nav-notification .dropdown-menu.dropdown-1 {\n    left: -50px !important;\n    right: auto !important;\n  }\n}\n@media (max-width: 480px) {\n  #top-nav .nav-notification .dropdown-menu.dropdown-2 {\n    left: -80px !important;\n    right: auto !important;\n  }\n}\n@media (max-width: 480px) {\n  #top-nav .nav-notification .dropdown-menu.dropdown-3 {\n    left: -120px !important;\n    right: auto !important;\n  }\n}\n#top-nav .nav-notification .dropdown-menu li {\n  border-bottom-color: #f1f5fc;\n}\n@media (max-width: 480px) {\n  #top-nav {\n    min-width: 310px;\n  }\n}\n@media (min-width: 481px) and (max-width: 550px) {\n  #top-nav {\n    min-width: 471px;\n  }\n}\n@media (min-width: 551px) and (max-width: 600px) {\n  #top-nav {\n    min-width: 541px;\n  }\n}\n@media (min-width: 601px) and (max-width: 670px) {\n  #top-nav {\n    min-width: 591px;\n  }\n}\n@media (max-width: 767px) {\n  #top-nav {\n    left: -194px;\n  }\n}\n@media (min-width: 768px) and (max-width: 868px) {\n  #top-nav {\n    transition: all 0.5s ease;\n    -webkit-transition: all 0.5s ease;\n    -moz-transition: all 0.5s ease;\n    -ms-transition: all 0.5s ease;\n    -o-transition: all 0.5s ease;\n  }\n  #top-nav .brand {\n    width: 90px;\n  }\n  #top-nav .brand .text-toggle {\n    display: none;\n  }\n}\n.breadcrumb {\n  border-radius: 0px;\n  -moz-border-radius: 0px;\n  -webkit-border-radius: 0px;\n  background: transparent;\n  padding: 5px 10px;\n  border-bottom: 1px solid #eee;\n  margin-bottom: 0;\n  font-size: 11px;\n  font-weight: bold;\n  box-shadow: 0 1px 0 #ffffff;\n  -moz-box-shadow: 0 1px 0 #ffffff;\n  -webkit-box-shadow: 0 1px 0 #ffffff;\n  text-shadow: 0 1px #ffffff;\n}\n.breadcrumb li {\n  line-height: 27px;\n  color: #777;\n}\n.breadcrumb a {\n  text-decoration: none;\n  color: #777;\n}\naside {\n  position: absolute;\n  display: block;\n  float: left;\n  width: 194px;\n  z-index: 100;\n  padding-top: 45px;\n  bottom: 0;\n  left: 0;\n  background-color: #323447;\n  height: 100%;\n}\naside::-webkit-scrollbar {\n  width: 3px;\n  height: 3px;\n}\naside::-webkit-scrollbar-thumb {\n  background-color: rgba(50, 50, 50, 0.4);\n}\naside.fixed {\n  position: fixed;\n}\naside .size-toggle {\n  padding: 10px;\n  border-bottom: 1px solid #2c2d3e;\n  box-shadow: 0 1px 0 #34364a;\n  -moz-box-shadow: 0 1px 0 #34364a;\n  -webkit-box-shadow: 0 1px 0 #34364a;\n}\n@media (max-width: 868px) {\n  aside .size-toggle {\n    display: none;\n  }\n}\naside .size-toggle .btn {\n  background-color: transparent;\n  color: #e6f1f7;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\naside .size-toggle .btn.pull-right {\n  margin-top: -3px;\n}\naside .size-toggle .btn .icon-bar {\n  background-color: #e6f1f7;\n  display: block;\n  width: 13px;\n  height: 2px;\n  margin-bottom: 2px;\n  border-radius: 1px;\n  -moz-border-radius: 1px;\n  -webkit-border-radius: 1px;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\naside .size-toggle .btn:hover,\naside .size-toggle .btn:focus {\n  color: #ffffff;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\naside .size-toggle .btn:hover .icon-bar,\naside .size-toggle .btn:focus .icon-bar {\n  background-color: #ffffff;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\naside .sidebar-inner {\n  border-right: 1px solid #272938;\n}\naside .sidebar-inner .user-block {\n  padding: 10px;\n  border-bottom: 1px solid #2c2d3e;\n  box-shadow: 0 1px 0 #34364a;\n  -moz-box-shadow: 0 1px 0 #34364a;\n  -webkit-box-shadow: 0 1px 0 #34364a;\n}\naside .sidebar-inner .user-block img {\n  float: left;\n  width: 45px;\n  height: 45px;\n  border-radius: 50em;\n  -moz-border-radius: 50em;\n  -webkit-border-radius: 50em;\n  animation: fadeInRotate 0.9s ease;\n  -webkit-animation: fadeInRotate 0.9s ease;\n  -moz-animation: fadeInRotate 0.9s ease;\n  -ms-animation: fadeInRotate 0.9s ease;\n  -o-animation: fadeInRotate 0.9s ease;\n}\naside .sidebar-inner .user-block .detail {\n  float: left;\n  color: #e6f1f7;\n  margin-left: 10px;\n}\naside .sidebar-inner .user-block ul {\n  margin-top: 5px;\n}\naside .sidebar-inner .user-block ul li {\n  padding: 0;\n}\naside .sidebar-inner .user-block ul li a {\n  font-size: 11px;\n  color: #e6f1f7;\n  margin-right: 10px;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\naside .sidebar-inner .user-block ul li a:hover,\naside .sidebar-inner .user-block ul li a:focus {\n  color: #ffffff;\n  text-decoration: none;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\naside .sidebar-inner .search-block {\n  padding: 10px;\n  border-bottom: 1px solid #2c2d3e;\n  box-shadow: 0 1px 0 #34364a;\n  -moz-box-shadow: 0 1px 0 #34364a;\n  -webkit-box-shadow: 0 1px 0 #34364a;\n}\naside .sidebar-inner .search-block input[type=\"text\"] {\n  background: #272938;\n  border: 1px solid #272938;\n  box-shadow: none;\n  -moz-box-shadow: none;\n  -webkit-box-shadow: none;\n}\naside .sidebar-inner .search-block input[type=\"text\"]:focus {\n  box-shadow: none;\n  -moz-box-shadow: none;\n  -webkit-box-shadow: none;\n}\naside .sidebar-inner .search-block input[type=\"text\"]::-webkit-input-placeholder,\naside .sidebar-inner .search-block input[type=\"text\"]:-moz-placeholder,\naside .sidebar-inner .search-block input[type=\"text\"]:-ms-input-placeholder {\n  color: #fff;\n}\naside .sidebar-inner .search-block .btn {\n  color: #ccc;\n  background: #272938;\n  border: 1px solid #272938;\n}\naside .main-menu {\n  height: 100%;\n}\naside .main-menu > ul {\n  margin: 0;\n  list-style: none;\n}\naside .main-menu > ul > li {\n  position: relative;\n  border-top: 1px solid #34364a;\n  border-bottom: 1px solid #2c2d3e;\n  transition: all 0.5s ease;\n  -webkit-transition: all 0.5s ease;\n  -moz-transition: all 0.5s ease;\n  -ms-transition: all 0.5s ease;\n  -o-transition: all 0.5s ease;\n}\naside .main-menu > ul > li.active {\n  border-top: 1px solid #323447;\n  transition: all 0.5s ease;\n  -webkit-transition: all 0.5s ease;\n  -moz-transition: all 0.5s ease;\n  -ms-transition: all 0.5s ease;\n  -o-transition: all 0.5s ease;\n}\naside .main-menu > ul > li.active > a {\n  color: #ffffff;\n  background: #2c2d3e;\n  box-shadow: 0 0 3px rgba(0, 0, 0, 0.15) inset;\n  -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15) inset;\n  -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15) inset;\n}\naside .main-menu > ul > li.active .menu-hover {\n  opacity: 1;\n}\naside .main-menu > ul > li.display {\n  transition: all 0.5s ease;\n  -webkit-transition: all 0.5s ease;\n  -moz-transition: all 0.5s ease;\n  -ms-transition: all 0.5s ease;\n  -o-transition: all 0.5s ease;\n}\naside .main-menu > ul > li.display > a {\n  color: #ffffff;\n  background: #2c2d3e;\n}\naside .main-menu > ul > li.display .menu-hover {\n  opacity: 1;\n}\naside .main-menu > ul > li > a {\n  position: relative;\n  display: block;\n  color: #e6f1f7;\n  font-size: 13px;\n  padding: 13px 10px 13px 13px;\n  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n  transition: color 0.5s ease, background 0.5s ease;\n  -webkit-transition: color 0.5s ease, background 0.5s ease;\n  -moz-transition: color 0.5s ease, background 0.5s ease;\n  -ms-transition: color 0.5s ease, background 0.5s ease;\n  -o-transition: color 0.5s ease, background 0.5s ease;\n}\naside .main-menu > ul > li > a:hover,\naside .main-menu > ul > li > a:focus {\n  text-decoration: none;\n  color: #ffffff;\n  transition: color 0.5s ease, background 0.5s ease;\n  -webkit-transition: color 0.5s ease, background 0.5s ease;\n  -moz-transition: color 0.5s ease, background 0.5s ease;\n  -ms-transition: color 0.5s ease, background 0.5s ease;\n  -o-transition: color 0.5s ease, background 0.5s ease;\n  background: #272938;\n}\naside .main-menu > ul > li > a:hover .menu-hover,\naside .main-menu > ul > li > a:focus .menu-hover {\n  opacity: 1;\n  transition: opacity 0.5s ease;\n  -webkit-transition: opacity 0.5s ease;\n  -moz-transition: opacity 0.5s ease;\n  -ms-transition: opacity 0.5s ease;\n  -o-transition: opacity 0.5s ease;\n}\naside .main-menu > ul > li > a .text {\n  margin-left: 10px;\n}\naside .main-menu > ul > li > a .badge {\n  position: absolute;\n  top: 12px;\n  right: 7px;\n}\naside .main-menu > ul > li > a .menu-hover {\n  position: absolute;\n  background: #feffd8;\n  box-shadow: 0 0 20px 0px #ffffff;\n  -moz-box-shadow: 0 0 20px 0px #ffffff;\n  -webkit-box-shadow: 0 0 20px 0px #ffffff;\n  opacity: 0;\n  top: -2px;\n  bottom: -2px;\n  left: 0px;\n  width: 3px;\n  transition: opacity 0.5s ease;\n  -webkit-transition: opacity 0.5s ease;\n  -moz-transition: opacity 0.5s ease;\n  -ms-transition: opacity 0.5s ease;\n  -o-transition: opacity 0.5s ease;\n}\naside .main-menu > ul > li .dropdown-menu {\n  animation: fadeIn 0.8s ease;\n  -webkit-animation: fadeIn 0.8s ease;\n  -moz-animation: fadeIn 0.8s ease;\n  -ms-animation: fadeIn 0.8s ease;\n  -o-animation: fadeIn 0.8s ease;\n}\n@media (min-width: 768px) {\n  aside .main-menu > ul > li .dropdown-menu {\n    right: -160px;\n    left: auto;\n    top: -5px;\n  }\n}\n@media (max-width: 767px) {\n  aside .main-menu > ul > li .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  aside .main-menu > ul > li .dropdown-menu li a {\n    color: #e6f1f7;\n  }\n  aside .main-menu > ul > li .dropdown-menu li a:hover {\n    color: #ffffff;\n    background: #1d1e29;\n  }\n}\naside .main-menu > ul > li .submenu {\n  display: none;\n}\naside .main-menu > ul > li .submenu.third-level li a {\n  padding-left: 40px;\n}\naside .main-menu > ul > li .submenu.fourth-level li a {\n  padding-left: 60px;\n}\naside .main-menu > ul > li .submenu li {\n  position: relative;\n}\naside .main-menu > ul > li .submenu li a {\n  display: block;\n  background-color: #383b50;\n  color: #fafcfd;\n  font-weight: normal;\n  padding: 9px 20px;\n  font-size: 12px;\n  transition: all 0.4s ease;\n  -webkit-transition: all 0.4s ease;\n  -moz-transition: all 0.4s ease;\n  -ms-transition: all 0.4s ease;\n  -o-transition: all 0.4s ease;\n}\naside .main-menu > ul > li .submenu li a .submenu-label {\n  display: inline-block;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\naside .main-menu > ul > li .submenu li a:hover .submenu-label {\n  color: #fff;\n  transform: translateX(5px);\n  -webkit-transform: translateX(5px);\n  -moz-transform: translateX(5px);\n  -ms-transform: translateX(5px);\n  -o-transform: translateX(5px);\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\naside .main-menu .alert {\n  border-radius: 0px;\n  -moz-border-radius: 0px;\n  -webkit-border-radius: 0px;\n  text-align: center;\n  animation: fadeInUp 1.2s ease;\n  -webkit-animation: fadeInUp 1.2s ease;\n  -moz-animation: fadeInUp 1.2s ease;\n  -ms-animation: fadeInUp 1.2s ease;\n  -o-animation: fadeInUp 1.2s ease;\n}\n@media (max-width: 767px) {\n  aside {\n    left: -194px;\n  }\n}\n@media (min-width: 768px) and (max-width: 868px) {\n  aside {\n    width: 90px;\n  }\n  aside .brand .text-toggle {\n    display: none;\n  }\n  aside .slimScrollDiv {\n    overflow: visible !important;\n  }\n  aside .slimScrollDiv .slimScrollBar {\n    opacity: 0 !important;\n  }\n  aside .slimScrollDiv .slimScrollRail {\n    opacity: 0 !important;\n  }\n  aside .sidebar-inner {\n    overflow: visible !important;\n  }\n  aside .sidebar-inner .size-toggle {\n    text-align: center;\n  }\n  aside .sidebar-inner .size-toggle .pull-right {\n    display: none;\n  }\n  aside .sidebar-inner .user-block {\n    text-align: center;\n  }\n  aside .sidebar-inner .user-block img {\n    float: none;\n  }\n  aside .sidebar-inner .user-block .detail {\n    display: none;\n  }\n  aside .sidebar-inner .search-block {\n    display: none;\n  }\n  aside .sidebar-inner .main-menu > ul > li > a {\n    text-align: center;\n    font-size: 11px;\n  }\n  aside .sidebar-inner .main-menu > ul > li > a .menu-icon {\n    display: block;\n  }\n  aside .sidebar-inner .main-menu > ul > li > a .text {\n    display: block;\n    margin-top: 5px;\n    margin-left: 0;\n  }\n  aside .sidebar-inner .main-menu > ul > li > a .badge {\n    display: none;\n  }\n  aside .sidebar-inner .alert {\n    display: none;\n  }\n}\n#wrapper {\n  position: relative;\n  overflow: hidden;\n  min-height: 800px;\n  background-color: #f9f9f9;\n}\n@media (min-width: 768px) {\n  #wrapper.sidebar-mini #top-nav .brand {\n    width: 90px;\n  }\n  #wrapper.sidebar-mini #top-nav .brand .text-toggle {\n    display: none;\n  }\n  #wrapper.sidebar-mini aside {\n    width: 90px;\n  }\n  #wrapper.sidebar-mini aside .slimScrollDiv {\n    overflow: visible !important;\n  }\n  #wrapper.sidebar-mini aside .slimScrollDiv .slimScrollBar {\n    opacity: 0 !important;\n  }\n  #wrapper.sidebar-mini aside .slimScrollDiv .slimScrollRail {\n    opacity: 0 !important;\n  }\n  #wrapper.sidebar-mini aside .sidebar-inner {\n    overflow: visible !important;\n  }\n  #wrapper.sidebar-mini aside .sidebar-inner .size-toggle {\n    text-align: center;\n  }\n  #wrapper.sidebar-mini aside .sidebar-inner .size-toggle .pull-right {\n    display: none;\n  }\n  #wrapper.sidebar-mini aside .sidebar-inner .user-block {\n    text-align: center;\n  }\n  #wrapper.sidebar-mini aside .sidebar-inner .user-block img {\n    float: none;\n  }\n  #wrapper.sidebar-mini aside .sidebar-inner .user-block .detail {\n    display: none;\n  }\n  #wrapper.sidebar-mini aside .sidebar-inner .search-block {\n    display: none;\n  }\n  #wrapper.sidebar-mini aside .sidebar-inner .main-menu > ul > li:hover .submenu {\n    display: block;\n    animation: fadeIn 0.4s ease;\n    -webkit-animation: fadeIn 0.4s ease;\n    -moz-animation: fadeIn 0.4s ease;\n    -ms-animation: fadeIn 0.4s ease;\n    -o-animation: fadeIn 0.4s ease;\n  }\n  #wrapper.sidebar-mini aside .sidebar-inner .main-menu > ul > li:hover .submenu.third-level,\n  #wrapper.sidebar-mini aside .sidebar-inner .main-menu > ul > li:hover .submenu.fourth-level {\n    display: none;\n  }\n  #wrapper.sidebar-mini aside .sidebar-inner .main-menu > ul > li > a {\n    text-align: center;\n    font-size: 11px;\n    padding: 13px 10px;\n  }\n  #wrapper.sidebar-mini aside .sidebar-inner .main-menu > ul > li > a .menu-icon {\n    display: block;\n  }\n  #wrapper.sidebar-mini aside .sidebar-inner .main-menu > ul > li > a .text {\n    display: block;\n    margin-top: 5px;\n    margin-left: 0;\n  }\n  #wrapper.sidebar-mini aside .sidebar-inner .main-menu > ul > li > a .badge {\n    display: none;\n  }\n  #wrapper.sidebar-mini aside .sidebar-inner .main-menu > ul > li .submenu {\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    font-size: 14px;\n    list-style: none;\n    background-color: #fff;\n    border: 1px solid #ccc;\n    border: 1px solid rgba(0, 0, 0, 0.15);\n    border-radius: 4px;\n    -moz-border-radius: 4px;\n    -webkit-border-radius: 4px;\n    right: -160px;\n    left: auto;\n    top: -5px;\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  #wrapper.sidebar-mini aside .sidebar-inner .main-menu > ul > li .submenu li {\n    position: relative;\n  }\n  #wrapper.sidebar-mini aside .sidebar-inner .main-menu > ul > li .submenu li:hover .submenu.third-level {\n    display: block;\n    animation: fadeIn 0.4s ease;\n    -webkit-animation: fadeIn 0.4s ease;\n    -moz-animation: fadeIn 0.4s ease;\n    -ms-animation: fadeIn 0.4s ease;\n    -o-animation: fadeIn 0.4s ease;\n  }\n  #wrapper.sidebar-mini aside .sidebar-inner .main-menu > ul > li .submenu li a {\n    background: #fff;\n    text-align: left;\n    padding: 4px 20px;\n    color: #333;\n  }\n  #wrapper.sidebar-mini aside .sidebar-inner .main-menu > ul > li .submenu li a .submenu-label {\n    color: #333 !important;\n  }\n  #wrapper.sidebar-mini aside .sidebar-inner .main-menu > ul > li .submenu li a:hover {\n    background-color: #f2f2f2;\n  }\n  #wrapper.sidebar-mini aside .sidebar-inner .main-menu > ul > li .submenu li a:hover .submenu-label {\n    color: #222 !important;\n  }\n  #wrapper.sidebar-mini aside .sidebar-inner .main-menu > ul > li .submenu.third-level li:hover .submenu.fourth-level {\n    display: block;\n    animation: fadeIn 0.4s ease;\n    -webkit-animation: fadeIn 0.4s ease;\n    -moz-animation: fadeIn 0.4s ease;\n    -ms-animation: fadeIn 0.4s ease;\n    -o-animation: fadeIn 0.4s ease;\n  }\n  #wrapper.sidebar-mini aside .sidebar-inner .alert {\n    display: none;\n  }\n  #wrapper.sidebar-mini #main-container,\n  #wrapper.sidebar-mini footer {\n    margin-left: 90px;\n  }\n}\n@media (max-width: 767px) {\n  #wrapper.sidebar-display aside {\n    left: 0;\n  }\n  #wrapper.sidebar-display #top-nav {\n    left: 0;\n    right: -194px;\n  }\n  #wrapper.sidebar-display #main-container,\n  #wrapper.sidebar-display footer {\n    left: 194px;\n    right: -194px;\n  }\n}\n@media (min-width: 768px) {\n  #wrapper.sidebar-hide aside {\n    left: -194px;\n  }\n  #wrapper.sidebar-hide #main-container,\n  #wrapper.sidebar-hide footer {\n    margin-left: 0;\n  }\n}\nbody {\n  padding-top: 0;\n  font-size: 12px;\n  color: #777777;\n  background: #f9f9f9;\n  font-family: 'Open Sans', sans-serif;\n}\nbody.dark {\n  background: #3a3a3a;\n}\n::-webkit-scrollbar {\n  width: 7px;\n  height: 7px;\n}\n::-webkit-scrollbar-thumb {\n  background-color: rgba(50, 50, 50, 0.3);\n}\n::-webkit-scrollbar-track {\n  background-color: rgba(50, 50, 50, 0.2);\n}\nimg {\n  max-width: 100%;\n}\nul {\n  padding: 0;\n}\n.well {\n  background-color: #e8e8e8;\n  background-image: -moz-linear-gradient(top, #f5f5f5, #e8e8e8);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#e8e8e8));\n  background-image: -webkit-linear-gradient(top, #f5f5f5, #e8e8e8);\n  background-image: -o-linear-gradient(top, #f5f5f5, #e8e8e8);\n  background-image: linear-gradient(to bottom, #f5f5f5, #e8e8e8);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#f5f5f5, endColorstr=#e8e8e8, GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\nhr {\n  border-top-color: #eee;\n  border-bottom-color: #fff;\n}\na {\n  color: #555;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\na:hover,\na:focus {\n  color: #999;\n  text-decoration: none;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.navbar.navbar-fixed-top {\n  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);\n}\n.navbar.navbar-inverse {\n  background-color: #111;\n}\n.list-group-item,\na.list-group-item {\n  border-color: #f1f5fc;\n  color: #777;\n}\n.pagination {\n  margin-bottom: 0;\n}\n.pagination.pagination-xs > li > a,\n.pagination.pagination-xs > li > span {\n  padding: 2px 7px;\n}\n.pagination.pagination-split li {\n  display: inline-block;\n  margin-right: 3px;\n}\n.pagination.pagination-split li a {\n  border-radius: 4px;\n  -moz-border-radius: 4px;\n  -webkit-border-radius: 4px;\n}\n.pagination li.active a,\n.pagination li.active a:hover,\n.pagination li.active a:focus {\n  background: #5a5a5a;\n  border-color: rgba(0, 0, 0, 0.2);\n  box-shadow: 0 0 3px rgba(0, 0, 0, 0.7) inset;\n  -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.7) inset;\n  -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.7) inset;\n}\n.pagination li a {\n  color: #777;\n}\n.pagination li a:hover,\n.pagination li a:focus {\n  background: #f2f2f2;\n}\n.progress {\n  border-radius: 10px;\n  -moz-border-radius: 10px;\n  -webkit-border-radius: 10px;\n  height: 12px;\n}\n.progress .progress-bar {\n  background-color: #6bafbd;\n}\n.progress .progress-bar.animated-bar {\n  animation: progress-start 3s linear;\n  -webkit-animation: progress-start 3s linear;\n  -moz-animation: progress-start 3s linear;\n  -ms-animation: progress-start 3s linear;\n  -o-animation: progress-start 3s linear;\n}\n.progress .progress-bar.progress-bar-success {\n  background-color: #65cea7;\n}\n.progress .progress-bar.progress-bar-warning {\n  background-color: #f3ce85;\n}\n.progress .progress-bar.progress-bar-danger {\n  background-color: #fc8675;\n}\n.label,\n.badge {\n  background-color: #F1F5FC;\n  color: #777;\n}\n.label-success,\n.badge-success {\n  background-color: #65cea7;\n  color: #fff;\n}\n.label-danger,\n.badge-danger {\n  background-color: #fc8675;\n  color: #fff;\n}\n.label-warning,\n.badge-warning {\n  background-color: #f3ce85;\n  color: #fff;\n}\n.label-info,\n.badge-info {\n  background-color: #6bafbd;\n  color: #fff;\n}\n.label-primary,\n.badge-primary {\n  background-color: #424f63;\n  color: #fff;\n}\n.alert {\n  color: #8B6420;\n  background: #fcf3e2;\n  border: 1px solid #f3ce85;\n  padding: 10px;\n}\n.alert.alert-info {\n  color: #0f5d84;\n  background: #b2d5dc;\n  border: 1px solid #6bafbd;\n}\n.alert.alert-success {\n  color: #1b601c;\n  background: #b2e7d3;\n  border: 1px solid #65cea7;\n}\n.alert.alert-danger {\n  color: #691715;\n  background: #feded9;\n  border: 1px solid #fc8675;\n}\n#theme-setting {\n  position: fixed;\n  top: 120px;\n  right: -212px;\n  color: #777;\n  z-index: 40;\n  display: inline-block;\n  width: 210px;\n  padding-bottom: 10px;\n  background: #fff;\n  box-shadow: 0 0 3px 0 rgba(0, 0, 0, 0.05);\n  -moz-box-shadow: 0 0 3px 0 rgba(0, 0, 0, 0.05);\n  -webkit-box-shadow: 0 0 3px 0 rgba(0, 0, 0, 0.05);\n  transition: all 0.3s ease-in-out;\n  -webkit-transition: all 0.3s ease-in-out;\n  -moz-transition: all 0.3s ease-in-out;\n  -ms-transition: all 0.3s ease-in-out;\n  -o-transition: all 0.3s ease-in-out;\n}\n#theme-setting.open {\n  right: 0px;\n  transition: all 0.3s ease-in-out;\n  -webkit-transition: all 0.3s ease-in-out;\n  -moz-transition: all 0.3s ease-in-out;\n  -ms-transition: all 0.3s ease-in-out;\n  -o-transition: all 0.3s ease-in-out;\n}\n#theme-setting .title {\n  padding: 5px;\n  color: #555;\n  text-align: center;\n  background-color: #fff;\n  border-bottom: 1px solid #f1f5fc;\n}\n#theme-setting strong {\n  display: block;\n  margin-bottom: 15px;\n}\n#theme-setting hr {\n  margin: 0;\n  border-top-color: #f1f5fc;\n  border-bottom: 1px solid #fff;\n}\n#theme-setting .theme-box {\n  padding: 10px 20px;\n}\n#theme-setting a {\n  cursor: pointer;\n}\n#theme-setting input {\n  height: auto;\n  width: 180px;\n  background: #fff;\n  color: #626262;\n}\n#theme-setting-icon {\n  position: fixed;\n  display: inline-block;\n  top: 159px;\n  right: 0px;\n  font-size: 18px;\n  color: #777;\n  z-index: 40;\n  cursor: pointer;\n  padding: 11px;\n  border-radius: 3px 0 0 3px;\n  -moz-border-radius: 3px 0 0 3px;\n  -webkit-border-radius: 3px 0 0 3px;\n  background: #fff;\n  border: 1px solid #f1f5fc;\n  border-width: 1px 0 1px 1px;\n  transition: all 0.3s ease-in-out;\n  -webkit-transition: all 0.3s ease-in-out;\n  -moz-transition: all 0.3s ease-in-out;\n  -ms-transition: all 0.3s ease-in-out;\n  -o-transition: all 0.3s ease-in-out;\n}\n#theme-setting-icon:hover,\n#theme-setting-icon:focus {\n  text-decoration: none;\n  color: #555;\n  transition: all 0.3s ease-in-out;\n  -webkit-transition: all 0.3s ease-in-out;\n  -moz-transition: all 0.3s ease-in-out;\n  -ms-transition: all 0.3s ease-in-out;\n  -o-transition: all 0.3s ease-in-out;\n}\n#theme-setting-icon.open {\n  right: 210px;\n  transition: all 0.3s ease-in-out;\n  -webkit-transition: all 0.3s ease-in-out;\n  -moz-transition: all 0.3s ease-in-out;\n  -ms-transition: all 0.3s ease-in-out;\n  -o-transition: all 0.3s ease-in-out;\n}\n.brand-name {\n  font-size: 16px;\n  line-height: 40px;\n  font-weight: 600;\n}\n.gmnoprint img {\n  max-width: none;\n}\n.avatar {\n  width: 60px;\n}\n.grey-container {\n  background: #eee;\n  padding: 15px;\n  border: 1px solid #dfdfdf;\n  border-width: 1px 0 1px 0;\n}\n.shortcut-wrapper {\n  text-align: center;\n}\n@media (max-width: 767px) {\n  .shortcut-wrapper {\n    text-align: left;\n  }\n}\n.shortcut-link {\n  display: inline-block;\n  color: #ccc;\n  margin-right: 20px;\n  text-shadow: 0 1px 0 #fff;\n  transition: color 0.2s ease;\n  -webkit-transition: color 0.2s ease;\n  -moz-transition: color 0.2s ease;\n  -ms-transition: color 0.2s ease;\n  -o-transition: color 0.2s ease;\n}\n.shortcut-link .shortcut-icon {\n  position: relative;\n  font-size: 30px;\n}\n.shortcut-link .shortcut-icon .shortcut-alert {\n  position: absolute;\n  border-radius: 50em;\n  -moz-border-radius: 50em;\n  -webkit-border-radius: 50em;\n  font-size: 11px;\n  color: #fff;\n  top: 0;\n  right: 0;\n  background: #fc8675;\n  border: 1px solid #fc8675;\n  text-shadow: none;\n  font-weight: bold;\n  line-height: 16px;\n  width: 18px;\n  height: 18px;\n  text-align: center;\n}\n.shortcut-link .text {\n  display: inline-block;\n  margin-left: 10px;\n  margin-top: -5px;\n  color: #626262;\n  font-weight: 600;\n}\n.shortcut-link:hover {\n  text-decoration: none;\n  color: #626262;\n  transition: color 0.2s ease;\n  -webkit-transition: color 0.2s ease;\n  -moz-transition: color 0.2s ease;\n  -ms-transition: color 0.2s ease;\n  -o-transition: color 0.2s ease;\n}\n.headline {\n  margin: 20px 0;\n  padding: 5px 0 10px 0;\n  border-bottom: 1px solid #eee;\n  font-weight: 500;\n}\n.headline.dark {\n  border-bottom: 1px solid #1a1a1a;\n}\n.headline .line {\n  display: block;\n  height: 3px;\n  background: #3c8dbc;\n  margin-top: 7px;\n  margin-bottom: -10px;\n  width: 50px;\n}\n.section-header {\n  position: relative;\n  text-align: center;\n  font-weight: bold;\n  margin: 30px 0;\n}\n.section-header span {\n  width: 30%;\n  display: block;\n  margin: 0 auto;\n  font-size: 22px;\n  line-height: 40px;\n  font-weight: bold;\n}\n@media (max-width: 767px) {\n  .section-header span {\n    width: 100%;\n    text-align: left;\n    padding-left: 20px;\n  }\n}\n.section-header hr {\n  position: absolute;\n  border-top: 1px solid #eee;\n  border-bottom: 1px solid #fff;\n  width: 35%;\n}\n.section-header hr.right {\n  right: 0px;\n  top: 0px;\n}\n.chart-container {\n  margin-bottom: 20px;\n  width: 100%;\n  height: 250px;\n}\n.notification-label {\n  position: absolute;\n  display: inline-block;\n  background: #fc8675;\n  width: 15px;\n  height: 15px;\n  padding: 2px;\n  color: #fff;\n  font-size: 9px;\n  text-align: center;\n  border-radius: 50em;\n  -moz-border-radius: 50em;\n  -webkit-border-radius: 50em;\n  top: 7px;\n  right: 5px;\n  line-height: 9px;\n  text-shadow: none;\n}\n#main-container {\n  position: relative;\n  min-height: 800px;\n  padding-top: 45px;\n  margin-left: 194px;\n}\n@media (max-width: 480px) {\n  #main-container {\n    min-width: 310px;\n  }\n}\n@media (min-width: 481px) and (max-width: 550px) {\n  #main-container {\n    min-width: 471px;\n  }\n}\n@media (min-width: 551px) and (max-width: 600px) {\n  #main-container {\n    min-width: 541px;\n  }\n}\n@media (min-width: 601px) and (max-width: 670px) {\n  #main-container {\n    min-width: 591px;\n  }\n}\n@media (max-width: 767px) {\n  #main-container {\n    left: 0;\n    margin-left: 0;\n  }\n}\n@media (min-width: 768px) and (max-width: 868px) {\n  #main-container {\n    margin-left: 90px;\n    transition: margin-left 0.5s ease;\n    -webkit-transition: margin-left 0.5s ease;\n    -moz-transition: margin-left 0.5s ease;\n    -ms-transition: margin-left 0.5s ease;\n    -o-transition: margin-left 0.5s ease;\n  }\n}\n#main-container.fade-out {\n  opacity: 0;\n  transform: translateX(-50px);\n  -webkit-transform: translateX(-50px);\n  -moz-transform: translateX(-50px);\n  -ms-transform: translateX(-50px);\n  -o-transform: translateX(-50px);\n  transition: all 1s ease;\n  -webkit-transition: all 1s ease;\n  -moz-transition: all 1s ease;\n  -ms-transition: all 1s ease;\n  -o-transition: all 1s ease;\n}\n.container-left {\n  position: absolute;\n  left: 0;\n  background: #000;\n  height: 100%;\n  width: 100px;\n}\n.theme-color,\n.theme-pattern {\n  display: inline-block;\n  width: 25px;\n  height: 25px;\n  cursor: pointer;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  margin: 5px 0 -5px 5px;\n  border-radius: 1px;\n  -moz-border-radius: 1px;\n  -webkit-border-radius: 1px;\n}\n.theme-layout {\n  cursor: pointer;\n  color: #626262;\n}\n.theme-layout:hover,\n.theme-layout:focus {\n  text-decoration: none;\n  color: #3c8dbc !important;\n}\n#scroll-to-top {\n  position: fixed;\n  cursor: pointer;\n  bottom: -1000px;\n  right: 3px;\n  color: #fff;\n  z-index: 1049;\n  border-radius: 50em;\n  -moz-border-radius: 50em;\n  -webkit-border-radius: 50em;\n  padding: 10px 14px;\n  background: rgba(60, 141, 188, 0.5);\n  transition: all 0.3s ease-in-out;\n  -webkit-transition: all 0.3s ease-in-out;\n  -moz-transition: all 0.3s ease-in-out;\n  -ms-transition: all 0.3s ease-in-out;\n  -o-transition: all 0.3s ease-in-out;\n}\n#scroll-to-top:hover,\n#scroll-to-top:focus {\n  text-decoration: none;\n  background: #3c8dbc;\n  color: #fff;\n  transition: all 0.3s linear;\n  -webkit-transition: all 0.3s linear;\n  -moz-transition: all 0.3s linear;\n  -ms-transition: all 0.3s linear;\n  -o-transition: all 0.3s linear;\n}\n.main-header {\n  padding: 20px;\n}\n.main-header .page-title {\n  float: left;\n}\n.main-header .page-title span {\n  display: block;\n  color: #999;\n  text-shadow: 0 1px 0 #fff;\n  font-size: 12px;\n  margin-top: 5px;\n}\n.main-header .page-stats {\n  float: right;\n  margin: 0;\n  padding: 0;\n  list-style: none;\n}\n@media (max-width: 480px) {\n  .main-header .page-stats {\n    display: none;\n  }\n}\n.main-header .page-stats li {\n  float: left;\n  display: block;\n  padding: 0 20px;\n  border-right: 1px solid #ccc;\n}\n.main-header .page-stats li:last-child {\n  border-right: none;\n}\n.main-header .page-stats li .sparkline {\n  float: right;\n  margin-top: 5px;\n}\n@media (max-width: 979px) {\n  .main-header .page-stats li .sparkline {\n    display: none;\n  }\n}\n.main-header .page-stats li .value {\n  float: left;\n  margin-right: 20px;\n}\n.main-header .page-stats li .value span {\n  font-size: 11px;\n  font-weight: 600;\n  color: #bbb;\n  text-shadow: 0 1px 0 #fff;\n  text-transform: uppercase;\n}\n.main-header .page-stats li .value h4 {\n  font-size: 20px;\n  line-height: 20px;\n  font-weight: 600;\n  color: #777;\n  margin: 5px 0;\n}\n.chart {\n  display: inline-block;\n}\nsvg {\n  width: 100% !important;\n}\n.toolbar {\n  float: right;\n}\n.toolbar > ul {\n  list-style: none;\n  display: block;\n  margin: 0;\n  margin-right: -15px;\n}\n.toolbar > ul > li {\n  display: inline-block;\n  float: right;\n}\n.toolbar > ul > li .btn {\n  color: #626262;\n  background: transparent;\n  margin-top: -10px;\n  padding: 10px 12px;\n  margin-left: -4px;\n  border-color: rgba(0, 0, 0, 0.2);\n  border-width: 0px 0px 0px 1px;\n  text-shadow: none;\n  border-radius: 0;\n  -moz-border-radius: 0;\n  -webkit-border-radius: 0;\n}\n.toolbar > ul > li .btn-group > .btn:first-child {\n  border-radius: 0 4px 0 0;\n  -moz-border-radius: 0 4px 0 0;\n  -webkit-border-radius: 0 4px 0 0;\n}\n.toolbar > ul > li .dropdown-menu {\n  right: 0;\n  left: auto;\n}\n.toolbar .label {\n  font-size: 11px;\n}\n.toolbar .progress {\n  width: 120px;\n  height: 10px;\n  margin-top: 5px;\n  margin-bottom: 0;\n}\n.toolbar .progress .progress-bar {\n  line-height: 10px;\n  font-size: 11px;\n  font-weight: normal;\n}\n.toolbar .accordion-toggle.collapsed i:before {\n  content: '\\f078';\n}\n.toolbar .accordion-toggle i:before {\n  content: '\\f077';\n}\n.task-list li.removed {\n  opacity: 0;\n  padding-top: 0;\n  padding-bottom: 0;\n  height: 0;\n  overflow: hidden;\n  border-top: 0px;\n  -moz-transition: opacity 0.25s linear, padding-top 0.1s linear 0.25s, padding-bottom 0.1s linear 0.25s, border-top 0.1s linear 0.25s, height 0.1s linear 0.25s;\n  -webkit-transition: opacity 0.25s linear, padding-top 0.1s linear 0.25s, padding-bottom 0.1s linear 0.25s, border-top 0.1s linear 0.25s, height 0.1s linear 0.25s;\n  -o-transition: opacity 0.25s linear, padding-top 0.1s linear 0.25s, padding-bottom 0.1s linear 0.25s, border-top 0.1s linear 0.25s, height 0.1s linear 0.25s;\n  transition: opacity 0.25s linear, padding-top 0.1s linear 0.25s, padding-bottom 0.1s linear 0.25s, border-top 0.1s linear 0.25s, height 0.1s linear 0.25s;\n}\n.task-list li.selected {\n  text-decoration: line-through;\n  color: #ccc;\n  background: #f1f5fc;\n}\n.task-list li .task-del:hover,\n.task-list li .task-del:focus {\n  text-decoration: none;\n}\n.alert-animated {\n  padding: 5px;\n  border: 1px solid #f1f5fc;\n  font-size: 12px;\n  border-radius: 4px;\n  text-align: center;\n  margin-bottom: 20px;\n  background-color: #f9f9f9;\n}\n.alert-inner {\n  border: 1px solid #f1f5fc;\n  width: 100%;\n  overflow: hidden;\n  white-space: nowrap;\n  background-color: #fff;\n  box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  -webkit-box-sizing: border-box;\n}\n.alert-message {\n  position: relative;\n  text-shadow: 0 1px #fff;\n  animation: text-moving 20s infinite;\n  -webkit-animation: text-moving 20s infinite;\n  -moz-animation: text-moving 20s infinite;\n  -ms-animation: text-moving 20s infinite;\n  -o-animation: text-moving 20s infinite;\n}\n.activity-icon {\n  display: inline-block;\n  background: #999;\n  float: left;\n  border: 2px solid rgba(0, 0, 0, 0.2);\n  border-color: rgba(255, 255, 255, 0.5) rgba(255, 255, 255, 0.5);\n  width: 59px;\n  height: 59px;\n  font-size: 30px;\n  color: #fff;\n  text-align: center;\n  border-radius: 50em;\n  -moz-border-radius: 50em;\n  -webkit-border-radius: 50em;\n  transition: all 0.2s ease-in-out;\n  -webkit-transition: all 0.2s ease-in-out;\n  -moz-transition: all 0.2s ease-in-out;\n  -ms-transition: all 0.2s ease-in-out;\n  -o-transition: all 0.2s ease-in-out;\n}\n.activity-icon [class*=\"fa-\"] {\n  line-height: 55px;\n}\n.activity-icon.small {\n  width: 42px;\n  height: 42px;\n  font-size: 20px;\n}\n.activity-icon.small [class*=\"fa-\"] {\n  line-height: 38px;\n}\n.img-demo {\n  position: relative;\n  float: left;\n  background: #3a3a3a;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  width: auto;\n  min-width: 40px;\n  padding: 5px 10px;\n  color: #fff;\n  text-align: center;\n  line-height: 40px;\n  font-size: 15px;\n  border-radius: 4px;\n}\n.img-demo img {\n  width: 40px;\n  height: 40px;\n}\n.img-demo.product {\n  float: none;\n  margin-right: 0;\n  width: 100%;\n  max-width: 200px;\n  height: 200px;\n}\n@media (min-width: 481px) and (max-width: 979px) {\n  .img-demo.product {\n    float: none;\n    margin-right: 0;\n    width: 100%;\n    height: 180px;\n  }\n}\n.img-demo.product [class*=\"fa-\"] {\n  line-height: 200px;\n  font-size: 40px;\n}\n@media (min-width: 481px) and (max-width: 979px) {\n  .img-demo.product [class*=\"fa-\"] {\n    line-height: 180px;\n    font-size: 40px;\n  }\n}\n.chat {\n  list-style: none;\n  margin: 0;\n}\n.chat li {\n  margin: 15px 0;\n}\n.chat li:first-child {\n  margin-top: 0;\n}\n.chat li.left .chat-body {\n  margin-left: 70px;\n  background-color: #fff;\n}\n.chat li.left .chat-body:before {\n  position: absolute;\n  top: 10px;\n  left: -8px;\n  display: inline-block;\n  background: #fff;\n  width: 16px;\n  height: 16px;\n  border-top: 1px solid #f1f5fc;\n  border-left: 1px solid #f1f5fc;\n  content: '';\n  transform: rotate(-45deg);\n  -webkit-transform: rotate(-45deg);\n  -moz-transform: rotate(-45deg);\n  -ms-transform: rotate(-45deg);\n  -o-transform: rotate(-45deg);\n}\n.chat li.right .chat-body {\n  margin-right: 70px;\n  background-color: #fff;\n}\n.chat li.right .chat-body:before {\n  position: absolute;\n  top: 10px;\n  right: -8px;\n  display: inline-block;\n  background: #fff;\n  width: 16px;\n  height: 16px;\n  border-top: 1px solid #f1f5fc;\n  border-right: 1px solid #f1f5fc;\n  content: '';\n  transform: rotate(45deg);\n  -webkit-transform: rotate(45deg);\n  -moz-transform: rotate(45deg);\n  -ms-transform: rotate(45deg);\n  -o-transform: rotate(45deg);\n}\n.chat li img {\n  width: 45px;\n  height: 45px;\n  border-radius: 50em;\n  -moz-border-radius: 50em;\n  -webkit-border-radius: 50em;\n}\n.chat li .chat-body {\n  position: relative;\n  font-size: 11px;\n  padding: 10px;\n  border: 1px solid #f1f5fc;\n  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n  -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.chat li .chat-body .header {\n  padding-bottom: 5px;\n  border-bottom: 1px solid #f1f5fc;\n}\n.chat li .chat-body p {\n  margin: 0;\n}\n.chat-toolbar {\n  padding: 7px 10px;\n  border-bottom: 1px solid #f1f5fc;\n  background: #fff;\n}\n.chat-toolbar .btn {\n  display: inline-block;\n  padding: 2px 7px;\n  border-radius: 4px;\n  -moz-border-radius: 4px;\n  -webkit-border-radius: 4px;\n  border: 1px solid #f1f5fc;\n  color: #626262;\n  background: transparent;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.chat-toolbar .btn:hover,\n.chat-toolbar .btn:focus {\n  text-decoration: none;\n  color: #3c8dbc;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.image-wrapper {\n  position: relative;\n  display: block;\n  overflow: hidden;\n}\n.image-wrapper img {\n  transition: all 0.4s ease;\n  -webkit-transition: all 0.4s ease;\n  -moz-transition: all 0.4s ease;\n  -ms-transition: all 0.4s ease;\n  -o-transition: all 0.4s ease;\n}\n.image-wrapper:hover,\n.image-wrapper.active {\n  -webkit-user-select: none;\n  -webkit-touch-callout: none;\n}\n.image-wrapper:hover img,\n.image-wrapper.active img {\n  transform: scale(1.1);\n  -webkit-transform: scale(1.1);\n  -moz-transform: scale(1.1);\n  -ms-transform: scale(1.1);\n  -o-transform: scale(1.1);\n  transition: all 0.4s ease;\n  -webkit-transition: all 0.4s ease;\n  -moz-transition: all 0.4s ease;\n  -ms-transition: all 0.4s ease;\n  -o-transition: all 0.4s ease;\n}\n.image-wrapper:hover .image-overlay,\n.image-wrapper.active .image-overlay {\n  opacity: 0.9;\n  transition: all 0.4s ease;\n  -webkit-transition: all 0.4s ease;\n  -moz-transition: all 0.4s ease;\n  -ms-transition: all 0.4s ease;\n  -o-transition: all 0.4s ease;\n  transform: translateX(0%);\n  -webkit-transform: translateX(0%);\n  -moz-transform: translateX(0%);\n  -ms-transform: translateX(0%);\n  -o-transform: translateX(0%);\n}\n.image-wrapper:hover .image-overlay .image-overlay-inner a,\n.image-wrapper.active .image-overlay .image-overlay-inner a {\n  opacity: 1;\n  transform: translateX(0%);\n  -webkit-transform: translateX(0%);\n  -moz-transform: translateX(0%);\n  -ms-transform: translateX(0%);\n  -o-transform: translateX(0%);\n  transform: translateY(0%);\n  -webkit-transform: translateY(0%);\n  -moz-transform: translateY(0%);\n  -ms-transform: translateY(0%);\n  -o-transform: translateY(0%);\n  transition: all 0.4s ease;\n  -webkit-transition: all 0.4s ease;\n  -moz-transition: all 0.4s ease;\n  -ms-transition: all 0.4s ease;\n  -o-transition: all 0.4s ease;\n}\n.image-overlay {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  opacity: 0;\n  background-color: #3c8dbc;\n  background-image: -moz-linear-gradient(top, #5fa4cc, #3c8dbc);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5fa4cc), to(#3c8dbc));\n  background-image: -webkit-linear-gradient(top, #5fa4cc, #3c8dbc);\n  background-image: -o-linear-gradient(top, #5fa4cc, #3c8dbc);\n  background-image: linear-gradient(to bottom, #5fa4cc, #3c8dbc);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#5fa4cc, endColorstr=#3c8dbc, GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n  border: 6px solid #296282;\n  transition: all 0.4s ease;\n  -webkit-transition: all 0.4s ease;\n  -moz-transition: all 0.4s ease;\n  -ms-transition: all 0.4s ease;\n  -o-transition: all 0.4s ease;\n}\n.image-overlay.left {\n  transform: translateX(-100%);\n  -webkit-transform: translateX(-100%);\n  -moz-transform: translateX(-100%);\n  -ms-transform: translateX(-100%);\n  -o-transform: translateX(-100%);\n}\n.image-overlay:before {\n  content: '';\n  display: inline-block;\n  height: 100%;\n  vertical-align: middle;\n}\n.image-overlay .image-info {\n  color: #ffffff;\n  position: absolute;\n  padding: 15px;\n  top: 0;\n  right: 0;\n  left: 0;\n  bottom: 0;\n}\n.image-overlay .image-info .image-time {\n  position: absolute;\n  bottom: 15px;\n}\n.image-overlay .image-info .image-like {\n  position: absolute;\n  bottom: 15px;\n  right: 15px;\n}\n.ribbon-wrapper {\n  position: absolute;\n  width: 75px;\n  height: 75px;\n  overflow: hidden;\n  top: -2px;\n  right: -2px;\n}\n.ribbon-wrapper .ribbon-inner {\n  display: block;\n  position: relative;\n  padding: 5px 0;\n  color: #fff;\n  font-size: 13px;\n  line-height: 17px;\n  font-weight: 600;\n  text-align: center;\n  width: 107px;\n  top: 11px;\n  left: -5px;\n  text-shadow: 0 1px rgba(0, 0, 0, 0.25);\n  box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.75);\n  -moz-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.75);\n  -webkit-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.75);\n  transform: rotate(45deg);\n  -webkit-transform: rotate(45deg);\n  -moz-transform: rotate(45deg);\n  -ms-transform: rotate(45deg);\n  -o-transform: rotate(45deg);\n}\n.ribbon-wrapper .ribbon-inner.blue {\n  background: #5276b3;\n}\n.ribbon-wrapper .ribbon-inner .yellow {\n  background: #faa732;\n}\n.ribbon-wrapper .ribbon-inner .green {\n  background: #76b752;\n}\n.icons-list {\n  list-style: none;\n  margin: 0px;\n}\n.icons-list li {\n  cursor: pointer;\n  line-height: 32px;\n  height: 32px;\n  padding-left: 12px;\n}\n.zoomOverlay {\n  position: absolute;\n  cursor: pointer;\n  top: 0;\n  left: 0;\n  bottom: 0;\n  right: 0;\n  display: block;\n  opacity: 0;\n  background: rgba(0, 0, 0, 0.5);\n  background-position: center;\n  border-radius: 3px;\n  -moz-border-radius: 3px;\n  -webkit-border-radius: 3px;\n  transition: all 0.2s linear;\n  -webkit-transition: all 0.2s linear;\n  -moz-transition: all 0.2s linear;\n  -ms-transition: all 0.2s linear;\n  -o-transition: all 0.2s linear;\n}\n.carousel-custom .carousel-inner .item img {\n  display: block;\n  margin: 0 auto 20px;\n}\n.carousel-custom .carousel-indicators {\n  left: 90%;\n}\n@media (max-width: 480px) {\n  .carousel-custom .carousel-indicators {\n    display: none;\n  }\n}\n@media (min-width: 481px) and (max-width: 767px) {\n  .carousel-custom .carousel-indicators {\n    top: 0;\n  }\n}\n.carousel-custom .carousel-indicators li {\n  background: #eee;\n}\n.carousel-custom .carousel-indicators li.active {\n  background: #65cea7;\n}\n.error-heading {\n  font-size: 180px;\n  font-weight: normal;\n  animation: bounceInDown 0.8s ease-out;\n  -webkit-animation: bounceInDown 0.8s ease-out;\n  -moz-animation: bounceInDown 0.8s ease-out;\n  -ms-animation: bounceInDown 0.8s ease-out;\n  -o-animation: bounceInDown 0.8s ease-out;\n}\n@media (max-width: 480px) {\n  .error-heading {\n    font-size: 160px;\n  }\n}\n.map {\n  width: 100%;\n  height: 450px;\n  margin-bottom: 30px;\n}\nfooter {\n  position: relative;\n  padding: 10px 15px;\n  background: #fefefe;\n  color: #777777;\n  margin-left: 194px;\n  transition: all 0.5s ease;\n  -webkit-transition: all 0.5s ease;\n  -moz-transition: all 0.5s ease;\n  -ms-transition: all 0.5s ease;\n  -o-transition: all 0.5s ease;\n}\nfooter.dark {\n  background: #1a1a1a;\n}\n@media (max-width: 767px) {\n  footer {\n    left: 0;\n    margin-left: 0;\n  }\n}\n@media (min-width: 768px) and (max-width: 868px) {\n  footer {\n    margin-left: 90px;\n    transition: all 0.5s ease;\n    -webkit-transition: all 0.5s ease;\n    -moz-transition: all 0.5s ease;\n    -ms-transition: all 0.5s ease;\n    -o-transition: all 0.5s ease;\n  }\n}\nfooter h5 {\n  color: #fff;\n  margin-top: 20px;\n  text-shadow: none;\n}\nfooter .footer-brand {\n  font-size: 18px;\n  margin-right: 20px;\n}\nfooter .footer-brand span {\n  font-size: 16px;\n}\nfooter p {\n  display: inline-block;\n}\nfooter hr {\n  border-top: 1px solid #242424;\n  border-bottom: 1px solid #575757;\n  margin-bottom: 0;\n}\n@media (max-width: 480px) {\n  footer hr {\n    margin-bottom: 10px;\n  }\n}\n.row.row-merge {\n  margin: 0;\n}\n.row.row-merge [class*=\"col-\"] {\n  padding: 0;\n}\n.slider.slider-horizontal .slider-track {\n  height: 5px;\n}\n.slider.slider-horizontal .slider-selection {\n  background: #65cea7;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\n.slider.slider-horizontal .slider-handle {\n  margin-top: -11px;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\n.slider.slider-vertical {\n  margin-right: 10px;\n}\n.slider.slider-vertical .slider-track {\n  width: 5px;\n}\n.slider.slider-vertical .slider-selection {\n  background: #65cea7;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\n.slider.slider-vertical .slider-handle {\n  margin-left: -11px;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\n.slider-handle {\n  background: #fff;\n  border: 1px solid #eee;\n  opacity: 1;\n  width: 25px;\n  height: 25px;\n}\n.social-connect {\n  display: inline-block;\n  border: 1px solid #f1f5fc;\n  background: #fff;\n  width: 25px;\n  height: 25px;\n  line-height: 25px;\n  border-radius: 50em;\n  -moz-border-radius: 50em;\n  -webkit-border-radius: 50em;\n  font-size: 16px;\n  text-align: center;\n  transition: all 0.4s linear;\n  -webkit-transition: all 0.4s linear;\n  -moz-transition: all 0.4s linear;\n  -ms-transition: all 0.4s linear;\n  -o-transition: all 0.4s linear;\n}\n.social-connect:hover,\n.social-connect:focus {\n  text-decoration: none;\n  color: #fff;\n  border-color: transparent;\n  transition: all 0.3s ease;\n  -webkit-transition: all 0.3s ease;\n  -moz-transition: all 0.3s ease;\n  -ms-transition: all 0.3s ease;\n  -o-transition: all 0.3s ease;\n}\n.search-options {\n  max-width: 920px;\n  padding: 10px;\n  margin-bottom: 20px;\n  background-color: #ffffff;\n  border: 1px solid rgba(0, 0, 0, 0.1);\n  border-radius: 6px;\n  -moz-border-radius: 6px;\n  -webkit-border-radius: 6px;\n}\n@media (max-width: 767px) {\n  .search-options {\n    text-align: center;\n  }\n}\n.search-options .search-pager {\n  float: right;\n}\n@media (max-width: 767px) {\n  .search-options .search-pager {\n    float: none;\n    text-align: center;\n    margin-top: 20px;\n  }\n}\n.search-filter {\n  padding-bottom: 10px;\n  margin-bottom: 30px;\n  border-bottom: 1px solid #ddd;\n  box-shadow: 0 1px 0 0 #ffffff;\n  -moz-box-shadow: 0 1px 0 0 #ffffff;\n  -webkit-box-shadow: 0 1px 0 0 #ffffff;\n}\n.search-filter ul {\n  padding: 0;\n  margin: 0;\n}\n.search-filter ul li {\n  display: inline-block;\n  margin-right: 10px;\n}\n.search-filter ul li.active a {\n  background: rgba(0, 0, 0, 0.05);\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  border-radius: 4px;\n  -moz-border-radius: 4px;\n  -webkit-border-radius: 4px;\n  box-shadow: 0 0 3px rgba(0, 0, 0, 0.25) inset;\n  -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.25) inset;\n  -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.25) inset;\n}\n.search-filter ul li a {\n  display: block;\n  padding: 10px 15px;\n  color: #777777;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.search-filter ul li a:hover,\n.search-filter ul li a:focus {\n  color: #3c8dbc;\n  text-decoration: none;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.search-container .search-header {\n  padding-bottom: 5px;\n  border-bottom: 1px solid #f1f5fc;\n}\n.loading-overlay {\n  position: absolute;\n  display: none;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  background: rgba(0, 0, 0, 0.4);\n  text-align: center;\n}\n.loading-overlay.active {\n  display: block;\n}\n.loading-overlay .loading-icon {\n  position: absolute;\n  top: 45%;\n  left: 50%;\n  color: #fff;\n  animation: spin 0.8s infinite linear;\n  -webkit-animation: spin 0.8s infinite linear;\n  -moz-animation: spin 0.8s infinite linear;\n  -ms-animation: spin 0.8s infinite linear;\n  -o-animation: spin 0.8s infinite linear;\n}\n.facebook-hover:hover {\n  background: #3b5998 !important;\n}\n.twitter-hover:hover {\n  background: #00aced !important;\n}\n.google-plus-hover:hover {\n  background: #d14836 !important;\n}\n.rss-hover:hover {\n  background: #ff8300 !important;\n}\n.tumblr-hover:hover {\n  background: #3b5998 !important;\n}\n.dribbble-hover:hover {\n  background: #ea4c89 !important;\n}\n.linkedin-hover:hover {\n  background: #007fb1 !important;\n}\n.pinterest-hover:hover {\n  background: #e0242a !important;\n}\n.custom-grid {\n  padding-bottom: 999px !important;\n  margin-bottom: -999px !important;\n}\n.btn {\n  transition: all 0.3s ease;\n  -webkit-transition: all 0.3s ease;\n  -moz-transition: all 0.3s ease;\n  -ms-transition: all 0.3s ease;\n  -o-transition: all 0.3s ease;\n}\n.btn.btn-transparent {\n  background: transparent;\n  border: none;\n}\n.btn.quick-btn {\n  padding: 5px 20px;\n  font-size: 40px;\n  border-radius: 6px;\n  -moz-border-radius: 6px;\n  -webkit-border-radius: 6px;\n}\n.btn.quick-btn span {\n  display: block;\n  font-size: 13px;\n  font-weight: 600;\n}\n.btn.btn-primary {\n  background: #424f63;\n  border: 1px solid #2e3744;\n}\n.btn.btn-primary:hover,\n.btn.btn-primary:focus,\n.btn.btn-primary:active,\n.btn.btn-primary.active {\n  background: #343e4e;\n  transition: all 0.3s ease;\n  -webkit-transition: all 0.3s ease;\n  -moz-transition: all 0.3s ease;\n  -ms-transition: all 0.3s ease;\n  -o-transition: all 0.3s ease;\n}\n.btn.btn-info {\n  background: #6bafbd;\n  border: 1px solid #4c99a9;\n}\n.btn.btn-info:hover,\n.btn.btn-info:focus,\n.btn.btn-info:active,\n.btn.btn-info.active {\n  background: #52a2b2;\n  transition: all 0.3s ease;\n  -webkit-transition: all 0.3s ease;\n  -moz-transition: all 0.3s ease;\n  -ms-transition: all 0.3s ease;\n  -o-transition: all 0.3s ease;\n}\n.btn.btn-success {\n  background: #65cea7;\n  border: 1px solid #3ec291;\n}\n.btn.btn-success:hover,\n.btn.btn-success:focus,\n.btn.btn-success:active,\n.btn.btn-success.active {\n  background: #4ac598;\n  transition: all 0.3s ease;\n  -webkit-transition: all 0.3s ease;\n  -moz-transition: all 0.3s ease;\n  -ms-transition: all 0.3s ease;\n  -o-transition: all 0.3s ease;\n}\n.btn.btn-warning {\n  background: #f3ce85;\n  border: 1px solid #eebb57;\n}\n.btn.btn-warning:hover,\n.btn.btn-warning:focus,\n.btn.btn-warning:active,\n.btn.btn-warning.active {\n  background: #f0c164;\n  transition: all 0.3s ease;\n  -webkit-transition: all 0.3s ease;\n  -moz-transition: all 0.3s ease;\n  -ms-transition: all 0.3s ease;\n  -o-transition: all 0.3s ease;\n}\n.btn.btn-danger {\n  background: #fc8675;\n  border: 1px solid #fb5a43;\n}\n.btn.btn-danger:hover,\n.btn.btn-danger:focus,\n.btn.btn-danger:active,\n.btn.btn-danger.active {\n  background: #fb6752;\n  transition: all 0.3s ease;\n  -webkit-transition: all 0.3s ease;\n  -moz-transition: all 0.3s ease;\n  -ms-transition: all 0.3s ease;\n  -o-transition: all 0.3s ease;\n}\n.open .dropdown-toggle.btn-primary {\n  background: #384354;\n  border-color: #343e4e;\n}\n.open .dropdown-toggle.btn-info {\n  background: #59a5b5;\n  border-color: #52a2b2;\n}\n.open .dropdown-toggle.btn-success {\n  background: #52c89c;\n  border-color: #4ac598;\n}\n.open .dropdown-toggle.btn-warning {\n  background: #f1c56e;\n  border-color: #f0c164;\n}\n.open .dropdown-toggle.btn-danger {\n  background: #fb705c;\n  border-color: #fb6752;\n}\n.open > .dropdown-menu.slidedown {\n  animation: slidedown 0.9s linear;\n  -webkit-animation: slidedown 0.9s linear;\n  -moz-animation: slidedown 0.9s linear;\n  -ms-animation: slidedown 0.9s linear;\n  -o-animation: slidedown 0.9s linear;\n  overflow: hidden;\n}\n.dropdown-menu {\n  font-size: 12px;\n}\n.dropdown-menu.dark {\n  background: #1a1a1a;\n}\n.dropdown-menu.dark .divider {\n  border-top: 1px solid #0a0c0e;\n  border-bottom: 1px solid #212121;\n}\n.dropdown-menu.dark li {\n  background: #1a1a1a;\n}\n.dropdown-menu.dark li a {\n  color: #fff;\n  text-shadow: 0 1px rgba(0, 0, 0, 0.25);\n}\n.dropdown-menu.dark li a:hover,\n.dropdown-menu.dark li a:focus {\n  background: #3c8dbc;\n}\n.dropdown-menu li a {\n  padding: 4px 20px;\n}\n.dropdown-menu li a:hover,\n.dropdown-menu li a:focus {\n  background: #3c8dbc;\n  color: #fff;\n}\n.dropdown-menu li a img {\n  float: left;\n  width: 40px;\n  height: 40px;\n  border-radius: 50em;\n  -moz-border-radius: 50em;\n  -webkit-border-radius: 50em;\n}\n.dropdown-menu li a .detail {\n  float: left;\n  margin-left: 10px;\n  white-space: normal;\n}\n.dropdown-menu li a .detail p {\n  margin-top: 0;\n}\n.dropdown-menu.message {\n  width: 280px;\n  padding: 0;\n}\n.dropdown-menu.message li {\n  border-bottom: 1px solid #ddd;\n}\n.dropdown-menu.message li:first-child a {\n  border-radius: 2px 2px 0 0;\n  -moz-border-radius: 2px 2px 0 0;\n  -webkit-border-radius: 2px 2px 0 0;\n  background: #fff;\n  color: #777;\n}\n.dropdown-menu.message li:first-child a:hover,\n.dropdown-menu.message li:first-child a:focus {\n  background: #fff;\n  color: #777;\n}\n.dropdown-menu.message li:last-child {\n  border: none;\n}\n.dropdown-menu.message li:last-child a {\n  border-radius: 0 0 2px 2px;\n  -moz-border-radius: 0 0 2px 2px;\n  -webkit-border-radius: 0 0 2px 2px;\n  background: #fff;\n  color: #777;\n}\n.dropdown-menu.message li a {\n  padding: 10px;\n}\n.dropdown-menu.message li a p {\n  text-overflow: ellipsis;\n  white-space: nowrap;\n  overflow: hidden;\n}\n.dropdown-menu.message li a img {\n  float: left;\n  width: 40px;\n  height: 40px;\n  border-radius: 50em;\n  -moz-border-radius: 50em;\n  -webkit-border-radius: 50em;\n}\n.dropdown-menu.message li a .detail {\n  float: left;\n  margin-left: 10px;\n  white-space: normal;\n}\n.dropdown-menu.message li a:hover,\n.dropdown-menu.message li a:focus {\n  background-color: #efefef;\n  color: #626262;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.dropdown-menu.task {\n  top: 95%;\n  padding: 0;\n  width: 250px;\n}\n.dropdown-menu.task li {\n  border-bottom: 1px solid #ddd;\n}\n.dropdown-menu.task li:first-child a {\n  border-radius: 2px 2px 0 0;\n  -moz-border-radius: 2px 2px 0 0;\n  -webkit-border-radius: 2px 2px 0 0;\n  background-color: #fff;\n  color: #777;\n}\n.dropdown-menu.task li:first-child a:hover,\n.dropdown-menu.task li:first-child a:focus {\n  background: #fff;\n  color: #777;\n}\n.dropdown-menu.task li:last-child {\n  border: none;\n}\n.dropdown-menu.task li:last-child a {\n  border-radius: 0 0 2px 2px;\n  -moz-border-radius: 0 0 2px 2px;\n  -webkit-border-radius: 0 0 2px 2px;\n  background-color: #fff;\n  color: #777;\n}\n.dropdown-menu.task li a {\n  padding: 10px;\n  cursor: pointer;\n}\n.dropdown-menu.task li a:hover,\n.dropdown-menu.task li a:focus {\n  background-color: #eee;\n  color: #777;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.dropdown-menu.task .progress {\n  height: 10px;\n  line-height: 10px;\n  margin: 0;\n}\n.dropdown-menu.task .progress .progress-bar {\n  font-size: 11px;\n}\n.dropdown-menu.notification {\n  top: 95%;\n  padding: 0;\n  width: 250px;\n}\n.dropdown-menu.notification li {\n  border-bottom: 1px solid #ddd;\n}\n.dropdown-menu.notification li:first-child a {\n  border-radius: 2px 2px 0 0;\n  -moz-border-radius: 2px 2px 0 0;\n  -webkit-border-radius: 2px 2px 0 0;\n  background-color: #fff;\n  color: #777;\n}\n.dropdown-menu.notification li:first-child a:hover,\n.dropdown-menu.notification li:first-child a:focus {\n  background: #fff;\n  color: #777;\n}\n.dropdown-menu.notification li:last-child {\n  border: none;\n}\n.dropdown-menu.notification li:last-child a {\n  border-radius: 0 0 2px 2px;\n  -moz-border-radius: 0 0 2px 2px;\n  -webkit-border-radius: 0 0 2px 2px;\n  background-color: #fff;\n  color: #777;\n}\n.dropdown-menu.notification li a {\n  padding: 10px;\n  cursor: pointer;\n  position: relative;\n}\n.dropdown-menu.notification li a:hover,\n.dropdown-menu.notification li a:focus {\n  background-color: #eee;\n  color: #777;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.dropdown-menu.notification li a .notification-icon {\n  display: inline-block;\n  width: 20px;\n  height: 20px;\n  text-align: center;\n  border-radius: 3px;\n  -moz-border-radius: 3px;\n  -webkit-border-radius: 3px;\n  font-size: 14px;\n}\n.dropdown-menu.notification li a .time {\n  position: absolute;\n  right: 5px;\n  top: 12px;\n}\n.dropdown-demo {\n  display: inline-block;\n  position: relative;\n  height: 180px;\n  width: 200px;\n}\n.dropdown-demo > .dropdown-menu {\n  display: block;\n  position: static;\n  text-shadow: none;\n}\n.panel {\n  position: relative;\n  background: #ffffff;\n}\n.panel.panel-dark {\n  background: #111111 !important;\n  border-color: #060606 !important;\n}\n.panel.panel-dark .panel-heading {\n  background: #111111 !important;\n  border-color: #060606 !important;\n}\n.panel.panel-dark .panel-heading .tool-bar li a {\n  color: #fff;\n}\n.panel.panel-dark .panel-footer {\n  background: #111111 !important;\n  border-color: #060606 !important;\n}\n.panel.panel-default {\n  border-color: #f1f5fc;\n}\n.panel.panel-default .panel-heading + .panel-collapse .panel-body {\n  border-top-color: #f1f5fc;\n}\n.panel.panel-default .panel-heading {\n  background: #fff;\n  color: #777777;\n  border-color: #f1f5fc;\n}\n.panel.panel-default .panel-title a {\n  font-size: 12px;\n}\n.panel.panel-default .panel-title a:hover,\n.panel.panel-default .panel-title a:focus {\n  text-decoration: none;\n  color: #aaa;\n}\n.panel.panel-default .panel-footer {\n  background: #fff;\n  border-color: #f1f5fc;\n  color: #777777;\n}\n.panel .tool-bar {\n  float: right;\n  list-style: none;\n  margin-bottom: 0;\n}\n.panel .tool-bar li {\n  display: inline-block;\n  float: left;\n}\n.panel .tool-bar li:last-child a {\n  margin-right: -15px;\n}\n.panel .tool-bar li a {\n  display: block;\n  padding: 10px 10px;\n  margin: -10px 0;\n  border-left: 1px solid rgba(0, 0, 0, 0.1);\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.panel .tool-bar li a:hover {\n  background-color: rgba(0, 0, 0, 0.02);\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.panel.bg-primary .panel-footer {\n  border-color: #2e3744;\n  background: rgba(20, 20, 20, 0.07);\n}\n.panel.bg-info .panel-footer {\n  border-color: #4c99a9;\n  background: rgba(20, 20, 20, 0.07);\n}\n.panel.bg-success .panel-footer {\n  border-color: #3ec291;\n  background: rgba(20, 20, 20, 0.07);\n}\n.panel.bg-warning .panel-footer {\n  border-color: #eebb57;\n  background: rgba(20, 20, 20, 0.07);\n}\n.panel.bg-danger .panel-footer {\n  border-color: #fb5a43;\n  background: rgba(20, 20, 20, 0.07);\n}\n.panel-group .panel-heading + .panel-collapse .panel-body {\n  border-top-color: #f1f5fc;\n}\n.panel-stat1 {\n  text-align: center;\n  cursor: pointer;\n  overflow: hidden;\n}\n.panel-stat1:hover .value {\n  transform: scale(1.2);\n  -webkit-transform: scale(1.2);\n  -moz-transform: scale(1.2);\n  -ms-transform: scale(1.2);\n  -o-transform: scale(1.2);\n  transition: transform 0.4s ease;\n  -webkit-transition: -webkit-transform 0.4s ease;\n  -moz-transition: -moz-transform 0.4s ease;\n  -ms-transition: -ms-transform 0.4s ease;\n  -o-transition: -o-transform 0.4s ease;\n}\n.panel-stat1:hover .title {\n  transform: scale(0.85);\n  -webkit-transform: scale(0.85);\n  -moz-transform: scale(0.85);\n  -ms-transform: scale(0.85);\n  -o-transform: scale(0.85);\n  transition: transform 0.4s ease;\n  -webkit-transition: -webkit-transform 0.4s ease;\n  -moz-transition: -moz-transform 0.4s ease;\n  -ms-transition: -ms-transform 0.4s ease;\n  -o-transition: -o-transform 0.4s ease;\n}\n.panel-stat1 .value {\n  font-size: 60px;\n  transition: all 0.4s ease;\n  -webkit-transition: all 0.4s ease;\n  -moz-transition: all 0.4s ease;\n  -ms-transition: all 0.4s ease;\n  -o-transition: all 0.4s ease;\n}\n.panel-stat1 .title {\n  font-size: 16px;\n  margin-top: -15px;\n  transition: all 0.4s ease;\n  -webkit-transition: all 0.4s ease;\n  -moz-transition: all 0.4s ease;\n  -ms-transition: all 0.4s ease;\n  -o-transition: all 0.4s ease;\n}\n.panel-stat2 {\n  cursor: pointer;\n  overflow: hidden;\n}\n.panel-stat2:hover .value {\n  transform: scale(1.2);\n  -webkit-transform: scale(1.2);\n  -moz-transform: scale(1.2);\n  -ms-transform: scale(1.2);\n  -o-transform: scale(1.2);\n  transition: all 0.4s ease;\n  -webkit-transition: all 0.4s ease;\n  -moz-transition: all 0.4s ease;\n  -ms-transition: all 0.4s ease;\n  -o-transition: all 0.4s ease;\n}\n.panel-stat2:hover .title {\n  transform: scale(0.85);\n  -webkit-transform: scale(0.85);\n  -moz-transform: scale(0.85);\n  -ms-transform: scale(0.85);\n  -o-transform: scale(0.85);\n  transition: all 0.4s ease;\n  -webkit-transition: all 0.4s ease;\n  -moz-transition: all 0.4s ease;\n  -ms-transition: all 0.4s ease;\n  -o-transition: all 0.4s ease;\n}\n.panel-stat2:hover .stat-icon {\n  transform: scale(1.5) rotate(60deg) translateX(30px) translateY(-15px);\n  -webkit-transform: scale(1.5) rotate(60deg) translateX(30px) translateY(-15px);\n  -moz-transform: scale(1.5) rotate(60deg) translateX(30px) translateY(-15px);\n  -ms-transform: scale(1.5) rotate(60deg) translateX(30px) translateY(-15px);\n  -o-transform: scale(1.5) rotate(60deg) translateX(30px) translateY(-15px);\n  opacity: 0.4;\n  transition: all 0.8s ease;\n  -webkit-transition: all 0.8s ease;\n  -moz-transition: all 0.8s ease;\n  -ms-transition: all 0.8s ease;\n  -o-transition: all 0.8s ease;\n}\n.panel-stat2 .stat-icon {\n  display: inline-block;\n  float: left;\n  font-size: 50px;\n  line-height: 83px;\n  transition: all 0.8s ease;\n  -webkit-transition: all 0.8s ease;\n  -moz-transition: all 0.8s ease;\n  -ms-transition: all 0.8s ease;\n  -o-transition: all 0.8s ease;\n}\n.panel-stat2 .value {\n  font-size: 60px;\n  transition: all 0.4s ease;\n  -webkit-transition: all 0.4s ease;\n  -moz-transition: all 0.4s ease;\n  -ms-transition: all 0.4s ease;\n  -o-transition: all 0.4s ease;\n}\n.panel-stat2 .title {\n  font-size: 16px;\n  margin-top: -15px;\n  margin-right: 10px;\n  transition: all 0.4s ease;\n  -webkit-transition: all 0.4s ease;\n  -moz-transition: all 0.4s ease;\n  -ms-transition: all 0.4s ease;\n  -o-transition: all 0.4s ease;\n}\n.panel-stat3 {\n  position: relative;\n  overflow: hidden;\n  padding: 25px 20px;\n  margin-bottom: 20px;\n  color: #fff;\n  cursor: pointer;\n  border-radius: 10px;\n  -moz-border-radius: 10px;\n  -webkit-border-radius: 10px;\n}\n.panel-stat3 .stat-icon {\n  position: absolute;\n  top: 20px;\n  right: 10px;\n  font-size: 30px;\n  opacity: 0.3;\n}\n.panel-stat3 .refresh-button {\n  position: absolute;\n  top: 10px;\n  right: 10px;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n  color: rgba(0, 0, 0, 0.3);\n}\n.panel-stat3 .refresh-button:hover {\n  color: #fff;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.panel-overview {\n  padding: 0;\n}\n.panel-overview:before,\n.panel-overview:after {\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n.panel-overview:after {\n  clear: both;\n}\n.panel-overview .overview-icon {\n  display: inline-block;\n  width: 50%;\n  float: left;\n  text-align: center;\n  padding: 10px;\n  font-size: 70px;\n}\n.panel-overview .overview-value {\n  display: inline-block;\n  width: 50%;\n  float: left;\n  text-align: center;\n  padding: 15px 10px 10px;\n}\n.panel-tab {\n  background: #f9f9f9;\n}\n.panel-tab:before,\n.panel-tab:after {\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n.panel-tab:after {\n  clear: both;\n}\n.tab-bar {\n  list-style: none;\n  margin: 0;\n}\n.tab-bar:before,\n.tab-bar:after {\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n.tab-bar:after {\n  clear: both;\n}\n.tab-bar.right > li {\n  float: right;\n}\n.tab-bar.right > li.active:first-child a {\n  border-right: none;\n}\n.tab-bar.grey-tab {\n  background: #e6e6e6;\n}\n.tab-bar.grey-tab li.active a {\n  border: transparent;\n  background: #f9f9f9;\n}\n.tab-bar.grey-tab li.active a:hover,\n.tab-bar.grey-tab li.active a:focus {\n  border: transparent;\n}\n.tab-bar.grey-tab li a {\n  color: #bbb;\n  border-radius: 0px;\n  -moz-border-radius: 0px;\n  -webkit-border-radius: 0px;\n  border: transparent;\n  text-shadow: 0 1px 0 #fff;\n}\n.tab-bar.bg-primary li:not(.active) a,\n.tab-bar.bg-info li:not(.active) a,\n.tab-bar.bg-success li:not(.active) a,\n.tab-bar.bg-warning li:not(.active) a,\n.tab-bar.bg-danger li:not(.active) a {\n  color: #fff;\n  text-shadow: none;\n  transition: color 0.2s ease;\n  -webkit-transition: color 0.2s ease;\n  -moz-transition: color 0.2s ease;\n  -ms-transition: color 0.2s ease;\n  -o-transition: color 0.2s ease;\n}\n.tab-bar.bg-primary li:not(.active) a:hover,\n.tab-bar.bg-info li:not(.active) a:hover,\n.tab-bar.bg-success li:not(.active) a:hover,\n.tab-bar.bg-warning li:not(.active) a:hover,\n.tab-bar.bg-danger li:not(.active) a:hover,\n.tab-bar.bg-primary li:not(.active) a:focus,\n.tab-bar.bg-info li:not(.active) a:focus,\n.tab-bar.bg-success li:not(.active) a:focus,\n.tab-bar.bg-warning li:not(.active) a:focus,\n.tab-bar.bg-danger li:not(.active) a:focus {\n  color: #eee;\n  transition: color 0.2s ease;\n  -webkit-transition: color 0.2s ease;\n  -moz-transition: color 0.2s ease;\n  -ms-transition: color 0.2s ease;\n  -o-transition: color 0.2s ease;\n}\n.tab-bar > li {\n  display: inline-block;\n  float: left;\n  margin-bottom: -1px;\n}\n.tab-bar > li.active:first-child a {\n  border-left: none;\n}\n.tab-bar > li.active a {\n  background: #fff;\n  color: #777;\n}\n.tab-bar > li a {\n  display: block;\n  padding: 10px;\n  color: #ccc;\n  text-shadow: 0 1px #fff;\n  transition: color 0.2s ease;\n  -webkit-transition: color 0.2s ease;\n  -moz-transition: color 0.2s ease;\n  -ms-transition: color 0.2s ease;\n  -o-transition: color 0.2s ease;\n}\n.tab-bar > li a:hover,\n.tab-bar > li a:focus {\n  text-decoration: none;\n  color: #777;\n  transition: color 0.2s ease;\n  -webkit-transition: color 0.2s ease;\n  -moz-transition: color 0.2s ease;\n  -ms-transition: color 0.2s ease;\n  -o-transition: color 0.2s ease;\n}\n.wizard-steps {\n  border-top: 1px solid #eee;\n  border-bottom: 1px solid #eee;\n  margin: 0;\n}\n.wizard-steps:before,\n.wizard-steps:after {\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n.wizard-steps:after {\n  clear: both;\n}\n.wizard-steps li {\n  display: inline-block;\n  position: relative;\n  float: left;\n  padding: 0 5px 0 20px;\n}\n.wizard-steps li.active {\n  background: #65cea7;\n}\n.wizard-steps li.active:after {\n  border-left-color: #65cea7;\n}\n.wizard-steps li.active a {\n  color: #fff;\n  font-weight: bold;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.wizard-steps li a {\n  display: block;\n  padding: 10px;\n  text-align: center;\n  color: #ccc;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.wizard-steps li a:hover,\n.wizard-steps li a:focus {\n  text-decoration: none;\n}\n.wizard-steps li:before,\n.wizard-steps li:after {\n  border: solid transparent;\n  content: \" \";\n  height: 0;\n  width: 0;\n  top: 0;\n  right: -36px;\n  position: absolute;\n  pointer-events: none;\n  bottom: 100%;\n}\n.wizard-steps li:after {\n  border-color: rgba(136, 183, 213, 0);\n  border-left-color: #f9f9f9;\n  border-width: 18px;\n  z-index: 2;\n}\n.wizard-steps li:before {\n  border-color: rgba(194, 225, 245, 0);\n  border-left-color: #eee;\n  border-width: 20px;\n  right: -40px;\n  top: -2px;\n  z-index: 1;\n}\n.tab-left:before,\n.tab-left:after {\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n.tab-left:after {\n  clear: both;\n}\n.tab-left .tab-bar {\n  float: left;\n}\n.tab-left .tab-bar > li {\n  display: block;\n  float: none;\n  margin-right: -1px;\n  border-right: 1px solid #eee;\n}\n.tab-left .tab-bar > li.active {\n  border-right: 1px solid #fff;\n  z-index: 2;\n}\n.tab-left .tab-bar > li.active:first-child a {\n  border-top: none;\n}\n.tab-left .tab-bar > li.active a {\n  border-top: 1px solid #eee;\n  border-bottom: 1px solid #eee;\n}\n.tab-left .tab-content {\n  overflow: auto;\n  padding: 15px 20px;\n  border-left: 1px solid #eee;\n}\n.tab-right:before,\n.tab-right:after {\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n.tab-right:after {\n  clear: both;\n}\n.tab-right .tab-bar {\n  float: right;\n}\n.tab-right .tab-bar > li {\n  display: block;\n  float: none;\n  margin-left: -1px;\n  border-left: 1px solid #eee;\n}\n.tab-right .tab-bar > li.active {\n  border-left: 1px solid #fff;\n  z-index: 2;\n}\n.tab-right .tab-bar > li.active:first-child a {\n  border-top: none;\n}\n.tab-right .tab-bar > li.active a {\n  border-top: 1px solid #eee;\n  border-bottom: 1px solid #eee;\n}\n.tab-right .tab-content {\n  overflow: auto;\n  padding: 15px 20px;\n  border-right: 1px solid #eee;\n}\n.table.table-vertical-center th,\n.table.table-vertical-center td {\n  vertical-align: middle;\n}\n.table thead > tr {\n  border: 1px solid #eee;\n}\n.table thead > tr > th {\n  border-color: #eee;\n}\n.table tbody > tr {\n  border: 1px solid #eee;\n}\n.table tbody > tr.selected > td {\n  background: #f1f5fc;\n}\n.table tbody > tr > td {\n  border-color: #eee;\n}\ntable th.text-center,\ntable td.text-center {\n  text-align: center;\n}\ntable th.text-right,\ntable td.text-right {\n  text-align: right;\n}\ntable.table-borderless th,\ntable.table-borderless td {\n  border: none !important;\n}\n/* Datatables */\ntable.dataTable tr.odd td.sorting_1 {\n  background-color: #f9f9f9;\n}\ntable.dataTable tr.even td.sorting_1 {\n  background-color: #fff;\n}\ntable.dataTable tr.odd {\n  background-color: #f9f9f9;\n}\n.paging_full_numbers {\n  margin-top: 5px;\n}\n.paging_full_numbers .ui-button {\n  border: 1px solid #eee;\n}\n.paging_full_numbers .ui-state-disabled {\n  cursor: default !important;\n  opacity: 0.35;\n}\ntable.dataTable thead th .DataTables_sort_wrapper span {\n  right: 6px !important;\n}\ntable.dataTable thead th .DataTables_sort_wrapper span:before {\n  font-family: FontAwesome;\n  color: #777;\n}\ntable.dataTable thead th .DataTables_sort_wrapper span.ui-icon-carat-2-n-s:before {\n  content: \"\\f0dc\";\n}\ntable.dataTable thead th .DataTables_sort_wrapper span.ui-icon-triangle-1-n {\n  top: 60% !important;\n}\ntable.dataTable thead th .DataTables_sort_wrapper span.ui-icon-triangle-1-n:before {\n  content: \"\\f0de\";\n}\ntable.dataTable thead th .DataTables_sort_wrapper span.ui-icon-triangle-1-s {\n  top: 30% !important;\n}\ntable.dataTable thead th .DataTables_sort_wrapper span.ui-icon-triangle-1-s:before {\n  content: \"\\f0dd\";\n}\nform.form-border .form-group {\n  margin-bottom: 0;\n  padding-top: 15px;\n  padding-bottom: 15px;\n  border-bottom: 1px solid #f1f5fc;\n}\nform.form-border .form-group:first-child {\n  padding-top: 0;\n}\nform.form-border .form-group:last-child {\n  padding-bottom: 0;\n  border-bottom: none;\n}\n.input-icon input[type=\"text\"] {\n  padding-left: 20px;\n}\nlabel,\ninput,\nbutton,\nselect,\ntextarea.form-control {\n  font-size: 12px;\n}\ninput[type=\"text\"],\ninput[type=\"password\"],\ninput[type=\"datetime\"],\ninput[type=\"datetime-local\"],\ninput[type=\"date\"],\ninput[type=\"month\"],\ninput[type=\"time\"],\ninput[type=\"week\"],\ninput[type=\"number\"],\ninput[type=\"email\"],\ninput[type=\"url\"],\ninput[type=\"search\"],\ninput[type=\"tel\"],\ninput[type=\"color\"],\n.uneditable-input {\n  font-size: 12px;\n  border-radius: 4px;\n  -moz-border-radius: 4px;\n  -webkit-border-radius: 4px;\n  margin: 0;\n}\ntextarea.form-control {\n  margin: 0;\n}\ntextarea.form-control:focus,\nselect[multiple]:focus,\ninput[type=\"text\"]:focus,\ninput[type=\"password\"]:focus,\ninput[type=\"datetime\"]:focus,\ninput[type=\"datetime-local\"]:focus,\ninput[type=\"date\"]:focus,\ninput[type=\"month\"]:focus,\ninput[type=\"time\"]:focus,\ninput[type=\"week\"]:focus,\ninput[type=\"number\"]:focus,\ninput[type=\"email\"]:focus,\ninput[type=\"url\"]:focus,\ninput[type=\"search\"]:focus,\ninput[type=\"tel\"]:focus,\ninput[type=\"color\"]:focus,\n.uneditable-input:focus {\n  border-color: rgba(250, 167, 34, 0.8);\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(250, 167, 34, 0.6);\n  -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(250, 167, 34, 0.6);\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(250, 167, 34, 0.6);\n}\ninput[type=\"text\"].dial {\n  box-shadow: none;\n  -moz-box-shadow: none;\n  -webkit-box-shadow: none;\n}\n.select-box {\n  display: inline-block;\n  list-style: none;\n  margin: 0;\n  background: #fff;\n  padding: 5px;\n  width: 40%;\n  height: 200px !important;\n  font-size: 12px;\n}\n.select-box-option {\n  position: absolute;\n  left: 50%;\n  top: 40%;\n  margin-left: -50px;\n  display: inline-block;\n  height: 200px;\n  width: 100px;\n  text-align: center;\n}\n.help-btn {\n  border-radius: 50em;\n  -moz-border-radius: 50em;\n  -webkit-border-radius: 50em;\n  padding: 0 6px;\n}\n.upload-file {\n  position: relative;\n  height: 20px;\n  padding: 4px 6px;\n  line-height: 20px;\n}\n.upload-file input[type=\"file\"] {\n  position: absolute;\n  opacity: 0;\n}\n.upload-file label {\n  display: block;\n  position: absolute;\n  top: 0;\n  left: 0;\n  right: 0;\n  border: 1px solid #ccc;\n  max-height: 28px;\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  border-radius: 4px;\n  -moz-border-radius: 4px;\n  -webkit-border-radius: 4px;\n  transition: all 0.2s linear;\n  -webkit-transition: all 0.2s linear;\n  -moz-transition: all 0.2s linear;\n  -ms-transition: all 0.2s linear;\n  -o-transition: all 0.2s linear;\n}\n.upload-file label:before {\n  display: inline-block;\n  content: attr(data-title);\n  position: absolute;\n  right: 0;\n  top: 0;\n  bottom: 0;\n  padding: 0 8px;\n  line-height: 26px;\n  text-align: center;\n  border-left: 1px solid #ccc;\n  border-radius: 0 4px 4px 0;\n  -moz-border-radius: 0 4px 4px 0;\n  -webkit-border-radius: 0 4px 4px 0;\n  background-color: #fff;\n}\n.upload-file label [class*=\"icon-\"] {\n  display: inline-block;\n  position: absolute;\n  left: 0;\n  top: 0;\n  bottom: 0;\n  text-align: center;\n  border-radius: 4px 0 0 4px;\n  -moz-border-radius: 4px 0 0 4px;\n  -webkit-border-radius: 4px 0 0 4px;\n  padding: 5px;\n  line-height: 13px;\n  color: #fff;\n  width: auto;\n}\n.upload-file label span {\n  display: inline-block;\n  height: 26px;\n  white-space: nowrap;\n  overflow: hidden;\n  line-height: 26px;\n  color: #777;\n  padding-left: 10px;\n}\n.upload-file label span:before {\n  content: attr(data-title);\n}\n.form-horizontal .label-checkbox {\n  padding-top: 5px;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  opacity: 0;\n  position: absolute;\n  width: 15px;\n  height: 15px;\n  z-index: 2;\n  cursor: pointer;\n}\ninput[type=\"radio\"] {\n  margin-top: 0;\n}\ninput[type=\"checkbox\"]:checked + .custom-checkbox,\ninput[type=\"radio\"]:checked + .custom-radio {\n  background-color: #f5f8fc;\n}\ninput[type=\"checkbox\"] + .custom-checkbox,\ninput[type=\"checkbox\"]:disabled + .custom-checkbox,\ninput[type=\"radio\"] + .custom-radio,\ninput[type=\"radio\"]:disabled + .custom-radio {\n  display: inline-block;\n  position: relative;\n  line-height: 13px;\n  background-color: #fafafa;\n  margin-right: 3px;\n  border-radius: 3px;\n  -moz-border-radius: 3px;\n  -webkit-border-radius: 3px;\n}\ninput[type=\"checkbox\"]:hover + .custom-checkbox,\ninput[type=\"radio\"]:hover + .custom-radio {\n  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);\n  -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);\n  -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);\n}\ninput[type=\"checkbox\"] + .custom-checkbox:before {\n  border-radius: 3px;\n  -moz-border-radius: 3px;\n  -webkit-border-radius: 3px;\n}\ninput[type=\"checkbox\"]:disabled + .custom-checkbox,\ninput[type=\"radio\"]:disabled + .custom-radio {\n  background-color: #ccc;\n  border-radius: 3px;\n  -moz-border-radius: 3px;\n  -webkit-border-radius: 3px;\n}\ninput[type=\"checkbox\"] + .custom-checkbox,\ninput[type=\"radio\"] + .custom-radio {\n  display: inline-block;\n  font-family: fontAwesome;\n  font-size: 12px;\n  content: \"\";\n  border: 1px solid #ccc;\n  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n  text-align: center;\n  width: 17px;\n  height: 17px;\n  line-height: 15px;\n  vertical-align: middle;\n}\ninput[type=\"checkbox\"]:checked + .custom-checkbox:before {\n  content: '\\f00c';\n  border-color: rgba(0, 0, 0, 0.2);\n  font-size: 12px;\n  color: #7a7a7a;\n  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), inset 0 -15px 10px -12px rgba(0, 0, 0, 0.05), inset 15px 10px -12px rgba(255, 255, 255, 0.1);\n  text-shadow: 0 1px #ffffff;\n}\ninput[type=\"radio\"] + .custom-radio,\ninput[type=\"radio\"]:disabled + .custom-radio {\n  border-radius: 50em;\n  -moz-border-radius: 50em;\n  -webkit-border-radius: 50em;\n  line-height: 0px;\n}\ninput[type=\"radio\"] + .custom-radio:before {\n  border-radius: 50em;\n  -moz-border-radius: 50em;\n  -webkit-border-radius: 50em;\n}\ninput[type=\"radio\"]:checked + .custom-radio:before {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 11px;\n  height: 11px;\n  top: 2px;\n  left: 2px;\n  background-color: #777;\n  border-color: #adb8c0;\n  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), inset 0 -15px 10px -12px rgba(0, 0, 0, 0.05), inset 15px 10px -12px rgba(255, 255, 255, 0.1);\n  text-shadow: 0 1px #ffffff;\n}\ninput[type=\"radio\"]:checked + .custom-radio.blue:before {\n  color: #0099CC;\n}\ninput[type=\"checkbox\"]:disabled:active + .custom-checkbox,\ninput[type=\"radio\"]:disabled:active + .custom-radio {\n  box-shadow: none;\n  -moz-box-shadow: none;\n  -webkit-box-shadow: none;\n}\ninput[type=\"checkbox\"]:active + .custom-checkbox,\ninput[type=\"radio\"]:active + .custom-radio {\n  border-radius: 3px;\n  -moz-border-radius: 3px;\n  -webkit-border-radius: 3px;\n  box-shadow: inset 0px 2px 3px rgba(0, 0, 0, 0.1);\n  -moz-box-shadow: inset 0px 2px 3px rgba(0, 0, 0, 0.1);\n  -webkit-box-shadow: inset 0px 2px 3px rgba(0, 0, 0, 0.1);\n}\ninput[type=\"radio\"]:active + .custom-radio {\n  border-radius: 50em;\n  -moz-border-radius: 50em;\n  -webkit-border-radius: 50em;\n}\n.label-checkbox,\n.label-radio {\n  display: block;\n  cursor: auto;\n  margin-bottom: 0;\n}\n.label-radio {\n  padding-top: 6px;\n}\n.label-checkbox.inline,\n.label-radio.inline {\n  display: inline-block;\n  margin-right: 5px;\n}\n.label-radio.inline {\n  padding-top: 5px;\n}\n#overlay {\n  background: #000000;\n  left: 0;\n  right: 0;\n  top: 0;\n  bottom: -100px;\n  position: fixed;\n  z-index: 9999;\n  opacity: 1;\n}\n#overlay.transparent {\n  background: rgba(0, 0, 0, 0.5);\n}\n.overlay-inner {\n  position: absolute;\n  top: 40%;\n  left: 45%;\n}\n@media (max-width: 767px) {\n  .overlay-inner {\n    left: 35%;\n  }\n}\n@media (max-width: 600px) {\n  .overlay-inner {\n    left: 25%;\n  }\n}\n@media (max-width: 480px) {\n  .overlay-inner {\n    left: 17%;\n  }\n}\n@media (max-width: 400px) {\n  .overlay-inner {\n    left: 5%;\n  }\n}\n@media (max-width: 767px) {\n  .overlay-inner.style2 {\n    left: 45%;\n  }\n}\n@media (max-width: 480px) {\n  .overlay-inner.style2 {\n    left: 42%;\n  }\n}\n#fountainTextG {\n  width: 240px;\n}\n.fountainTextG {\n  color: #000000;\n  font-size: 25px;\n  text-decoration: none;\n  font-weight: normal;\n  font-style: normal;\n  float: left;\n  -moz-animation-name: bounce_fountainTextG;\n  -moz-animation-duration: 1.82s;\n  -moz-animation-iteration-count: infinite;\n  -moz-animation-direction: linear;\n  -moz-transform: scale(0.5);\n  -webkit-animation-name: bounce_fountainTextG;\n  -webkit-animation-duration: 1.82s;\n  -webkit-animation-iteration-count: infinite;\n  -webkit-animation-direction: linear;\n  -webkit-transform: scale(0.5);\n  -ms-animation-name: bounce_fountainTextG;\n  -ms-animation-duration: 1.82s;\n  -ms-animation-iteration-count: infinite;\n  -ms-animation-direction: linear;\n  -ms-transform: scale(0.5);\n  -o-animation-name: bounce_fountainTextG;\n  -o-animation-duration: 1.82s;\n  -o-animation-iteration-count: infinite;\n  -o-animation-direction: linear;\n  -o-transform: scale(0.5);\n  animation-name: bounce_fountainTextG;\n  animation-duration: 1.82s;\n  animation-iteration-count: infinite;\n  animation-direction: linear;\n  transform: scale(0.5);\n}\n#fountainTextG_1 {\n  -moz-animation-delay: 0.52s;\n  -webkit-animation-delay: 0.52s;\n  -ms-animation-delay: 0.52s;\n  -o-animation-delay: 0.52s;\n  animation-delay: 0.52s;\n}\n#fountainTextG_2 {\n  -moz-animation-delay: 0.65s;\n  -webkit-animation-delay: 0.65s;\n  -ms-animation-delay: 0.65s;\n  -o-animation-delay: 0.65s;\n  animation-delay: 0.65s;\n}\n#fountainTextG_3 {\n  -moz-animation-delay: 0.78s;\n  -webkit-animation-delay: 0.78s;\n  -ms-animation-delay: 0.78s;\n  -o-animation-delay: 0.78s;\n  animation-delay: 0.78s;\n}\n#fountainTextG_4 {\n  -moz-animation-delay: 0.91s;\n  -webkit-animation-delay: 0.91s;\n  -ms-animation-delay: 0.91s;\n  -o-animation-delay: 0.91s;\n  animation-delay: 0.91s;\n}\n#fountainTextG_5 {\n  -moz-animation-delay: 1.04s;\n  -webkit-animation-delay: 1.04s;\n  -ms-animation-delay: 1.04s;\n  -o-animation-delay: 1.04s;\n  animation-delay: 1.04s;\n}\n#fountainTextG_6 {\n  -moz-animation-delay: 1.17s;\n  -webkit-animation-delay: 1.17s;\n  -ms-animation-delay: 1.17s;\n  -o-animation-delay: 1.17s;\n  animation-delay: 1.17s;\n}\n#fountainTextG_7 {\n  -moz-animation-delay: 1.3s;\n  -webkit-animation-delay: 1.3s;\n  -ms-animation-delay: 1.3s;\n  -o-animation-delay: 1.3s;\n  animation-delay: 1.3s;\n}\n#fountainTextG_8 {\n  -moz-animation-delay: 1.43s;\n  -webkit-animation-delay: 1.43s;\n  -ms-animation-delay: 1.43s;\n  -o-animation-delay: 1.43s;\n  animation-delay: 1.43s;\n}\n#fountainTextG_9 {\n  -moz-animation-delay: 1.56s;\n  -webkit-animation-delay: 1.56s;\n  -ms-animation-delay: 1.56s;\n  -o-animation-delay: 1.56s;\n  animation-delay: 1.56s;\n}\n#fountainTextG_10 {\n  -moz-animation-delay: 1.69s;\n  -webkit-animation-delay: 1.69s;\n  -ms-animation-delay: 1.69s;\n  -o-animation-delay: 1.69s;\n  animation-delay: 1.69s;\n}\n@-moz-keyframes bounce_fountainTextG {\n  0% {\n    -moz-transform: scale(1);\n    color: #000000;\n  }\n  100% {\n    -moz-transform: scale(0.5);\n    color: #FFFFFF;\n  }\n}\n@-webkit-keyframes bounce_fountainTextG {\n  0% {\n    -webkit-transform: scale(1);\n    color: #000000;\n  }\n  100% {\n    -webkit-transform: scale(0.5);\n    color: #FFFFFF;\n  }\n}\n@-ms-keyframes bounce_fountainTextG {\n  0% {\n    -ms-transform: scale(1);\n    color: #000000;\n  }\n  100% {\n    -ms-transform: scale(0.5);\n    color: #FFFFFF;\n  }\n}\n@-o-keyframes bounce_fountainTextG {\n  0% {\n    -o-transform: scale(1);\n    color: #000000;\n  }\n  100% {\n    -o-transform: scale(0.5);\n    color: #FFFFFF;\n  }\n}\n@keyframes bounce_fountainTextG {\n  0% {\n    transform: scale(1);\n    color: #000000;\n  }\n  100% {\n    transform: scale(0.5);\n    color: #FFFFFF;\n  }\n}\n#followingBallsG {\n  position: relative;\n  width: 256px;\n  height: 20px;\n}\n.followingBallsG {\n  background-color: #000000;\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 20px;\n  height: 20px;\n  border-radius: 10px;\n  -moz-border-radius: 10px;\n  -webkit-border-radius: 10px;\n  animation-name: bounce_followingBallsG;\n  -webkit-animation-name: bounce_followingBallsG;\n  -moz-animation-name: bounce_followingBallsG;\n  -ms-animation-name: bounce_followingBallsG;\n  -o-animation-name: bounce_followingBallsG;\n  animation-duration: 3.2s;\n  -webkit-animation-duration: 3.2s;\n  -moz-animation-duration: 3.2s;\n  -ms-animation-duration: 3.2s;\n  -o-animation-duration: 3.2s;\n  animation-iteration-count: infinite;\n  -webkit-animation-iteration-count: infinite;\n  -moz-animation-iteration-count: infinite;\n  -ms-animation-iteration-count: infinite;\n  -o-animation-iteration-count: infinite;\n  animation-direction: linear;\n  -webkit-animation-direction: linear;\n  -moz-animation-direction: linear;\n  -ms-animation-direction: linear;\n  -o-animation-direction: linear;\n}\n#followingBallsG_1 {\n  animation-delay: 0s;\n  -webkit-animation-delay: 0s;\n  -moz-animation-delay: 0s;\n  -ms-animation-delay: 0s;\n  -o-animation-delay: 0s;\n}\n#followingBallsG_2 {\n  animation-delay: 0.32s;\n  -webkit-animation-delay: 0.32s;\n  -moz-animation-delay: 0.32s;\n  -ms-animation-delay: 0.32s;\n  -o-animation-delay: 0.32s;\n}\n#followingBallsG_3 {\n  animation-delay: 0.64s;\n  -webkit-animation-delay: 0.64s;\n  -moz-animation-delay: 0.64s;\n  -ms-animation-delay: 0.64s;\n  -o-animation-delay: 0.64s;\n}\n#followingBallsG_4 {\n  animation-delay: 0.96s;\n  -webkit-animation-delay: 0.96s;\n  -moz-animation-delay: 0.96s;\n  -ms-animation-delay: 0.96s;\n  -o-animation-delay: 0.96s;\n}\n.login-wrapper {\n  position: absolute;\n  top: 50px;\n  width: 100%;\n  margin-left: 0;\n  animation: bounceInDownSmall 1s ease;\n  -webkit-animation: bounceInDownSmall 1s ease;\n  -moz-animation: bounceInDownSmall 1s ease;\n  -ms-animation: bounceInDownSmall 1s ease;\n  -o-animation: bounceInDownSmall 1s ease;\n}\n.login-wrapper.fadeOutUp {\n  animation: fadeOutUp 0.5s ease-out;\n  -webkit-animation: fadeOutUp 0.5s ease-out;\n  -moz-animation: fadeOutUp 0.5s ease-out;\n  -ms-animation: fadeOutUp 0.5s ease-out;\n  -o-animation: fadeOutUp 0.5s ease-out;\n  opacity: 0;\n}\n.login-wrapper .login-widget {\n  margin: 0 auto;\n  width: 400px;\n  margin-top: 20px;\n}\n@media (max-width: 480px) {\n  .login-wrapper .login-widget {\n    width: 100%;\n  }\n}\n.login-wrapper .login-widget .widget {\n  box-shadow: 0 1px 15px -4px #000000;\n  -moz-box-shadow: 0 1px 15px -4px #000000;\n  -webkit-box-shadow: 0 1px 15px -4px #000000;\n}\n.blog-container a:not(.btn) {\n  color: #999;\n  transition: all 0.2s linear;\n  -webkit-transition: all 0.2s linear;\n  -moz-transition: all 0.2s linear;\n  -ms-transition: all 0.2s linear;\n  -o-transition: all 0.2s linear;\n}\n.blog-container a:not(.btn):hover,\n.blog-container a:not(.btn):focus {\n  color: #777;\n  text-decoration: none;\n  transition: all 0.2s linear;\n  -webkit-transition: all 0.2s linear;\n  -moz-transition: all 0.2s linear;\n  -ms-transition: all 0.2s linear;\n  -o-transition: all 0.2s linear;\n}\n.blog-container .post-like {\n  float: right;\n  cursor: pointer;\n}\n.blog-container .post-like.liked {\n  color: #3c8dbc;\n}\n.blog-container .post-like.liked [class*=\"icon-\"]:before {\n  content: '\\f004';\n}\n.blog-container .post-like:hover {\n  text-decoration: none;\n  color: #3c8dbc;\n}\n.popular-post img {\n  width: 50px;\n  height: 50px;\n}\n.category {\n  padding: 0;\n  list-style: none;\n  margin-bottom: 30px;\n}\n.category li {\n  border-bottom: 1px solid #ccc;\n}\n.category li a {\n  display: block;\n  padding: 10px;\n  color: #777;\n  transition: all 0.4s ease;\n  -webkit-transition: all 0.4s ease;\n  -moz-transition: all 0.4s ease;\n  -ms-transition: all 0.4s ease;\n  -o-transition: all 0.4s ease;\n}\n.category li a:hover,\n.category li a:focus {\n  color: #3c8dbc;\n  text-decoration: none;\n  transition: all 0.4s ease;\n  -webkit-transition: all 0.4s ease;\n  -moz-transition: all 0.4s ease;\n  -ms-transition: all 0.4s ease;\n  -o-transition: all 0.4s ease;\n}\n.blog-tag {\n  display: inline-block;\n  padding: 5px;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  background-color: #fff;\n  color: #777;\n  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n  border-radius: 4px;\n  -moz-border-radius: 4px;\n  -webkit-border-radius: 4px;\n  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.25);\n  -moz-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.25);\n  -webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.25);\n  margin: 2px 2px;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.blog-tag:hover {\n  text-decoration: none;\n  color: #fff;\n  background-color: #3c8dbc;\n  text-shadow: none;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.photo-stream {\n  list-style: none;\n  padding: 0;\n  margin-bottom: 20px;\n}\n.photo-stream li {\n  display: inline-block;\n}\n.photo-stream li a {\n  display: inline-block;\n  border: 1px solid #3c8dbc;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.photo-stream li a:hover,\n.photo-stream li a:focus {\n  box-shadow: 0 0 0 10px #3c8dbc inset;\n  -moz-box-shadow: 0 0 0 10px #3c8dbc inset;\n  -webkit-box-shadow: 0 0 0 10px #3c8dbc inset;\n  opacity: 0.5;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.photo-stream li a img {\n  width: 60px;\n  height: 60px;\n  float: left;\n}\n@media (max-width: 480px) {\n  .share-blog {\n    text-align: center;\n  }\n  .share-blog .pull-left {\n    float: none !important;\n  }\n  .share-blog .pull-right {\n    float: none !important;\n  }\n}\n@media (max-width: 480px) {\n  .share-blog span {\n    display: block;\n  }\n}\n.comment-list li {\n  margin-bottom: 30px;\n}\n.comment-list li .media-heading {\n  border-bottom: 1px solid #eee;\n  padding-bottom: 5px;\n}\n.comment-list li .media-heading a {\n  color: #777;\n  font-weight: 500;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n@media (max-width: 480px) {\n  .comment-list li .media-heading a {\n    display: block;\n  }\n}\n.comment-list li .media-heading a:hover,\n.comment-list li .media-heading a:focus {\n  text-decoration: none;\n  color: #3c8dbc;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.comment-list li .media-heading small {\n  float: right;\n}\n@media (max-width: 480px) {\n  .comment-list li .media-heading small {\n    float: none;\n  }\n}\n.timeline-wrapper {\n  position: relative;\n  padding-left: 10px;\n  margin-bottom: 20px;\n}\n.timeline-wrapper:before {\n  content: '';\n  display: block;\n  position: absolute;\n  left: 40px;\n  top: 0px;\n  bottom: 0px;\n  border: solid #e2e3e7;\n  background-color: #e7eaef;\n  width: 4px;\n}\n.timeline-wrapper .timeline-start {\n  position: relative;\n  display: inline-block;\n}\n.timeline-wrapper .timeline-icon {\n  width: 40px;\n  height: 40px;\n  text-align: center;\n  border-radius: 50em;\n  -moz-border-radius: 50em;\n  -webkit-border-radius: 50em;\n  margin: 0 auto;\n  font-size: 20px;\n  line-height: 40px;\n}\n.timeline-wrapper .timeline-info {\n  position: relative;\n  float: left;\n  width: 65px;\n  text-align: center;\n}\n.timeline-wrapper .time {\n  margin-top: 10px;\n  background: #fff;\n  border: 1px solid #f1f5fc;\n  padding: 5px;\n  border-radius: 2px;\n  -moz-border-radius: 2px;\n  -webkit-border-radius: 2px;\n  color: #999;\n  box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.05);\n  -moz-box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.05);\n  -webkit-box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.05);\n}\n.timeline-wrapper .timeline-panel {\n  background: #fff;\n  margin-left: 75px;\n  border: 1px solid #f1f5fc;\n}\n.timeline-wrapper .timeline-panel img {\n  width: 200px;\n}\n.timeline-wrapper .timeline-date {\n  display: inline-block;\n  position: relative;\n  margin-top: 10px;\n  background: #3c8dbc;\n  border: 1px solid #3c8dbc;\n  padding: 5px;\n  border-radius: 2px;\n  -moz-border-radius: 2px;\n  -webkit-border-radius: 2px;\n  color: #fff;\n  box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.05);\n  -moz-box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.05);\n  -webkit-box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.05);\n  margin-bottom: 20px;\n  font-weight: bold;\n}\n.menu-grid .menu-header {\n  border-bottom: 1px solid #3c485a;\n  box-shadow: 0 1px 0 #48566c;\n  -moz-box-shadow: 0 1px 0 #48566c;\n  -webkit-box-shadow: 0 1px 0 #48566c;\n  padding: 10px 20px;\n  font-size: 18px;\n}\n.menu-grid .menu-header .btn {\n  color: #fff;\n}\n.menu-grid .navbar-toggle .icon-bar {\n  background: #fff;\n}\n.menu-grid .inbox-menu {\n  margin-bottom: 0;\n  transition: all 0.5s ease;\n  -webkit-transition: all 0.5s ease;\n  -moz-transition: all 0.5s ease;\n  -ms-transition: all 0.5s ease;\n  -o-transition: all 0.5s ease;\n}\n@media (min-width: 768px) {\n  .menu-grid .inbox-menu {\n    height: auto !important;\n  }\n}\n@media (max-width: 767px) {\n  .menu-grid .inbox-menu {\n    max-height: 0;\n  }\n  .menu-grid .inbox-menu.menu-display {\n    max-height: 350px;\n    height: auto;\n    transition: all 0.5s ease;\n    -webkit-transition: all 0.5s ease;\n    -moz-transition: all 0.5s ease;\n    -ms-transition: all 0.5s ease;\n    -o-transition: all 0.5s ease;\n  }\n}\n.menu-grid .inbox-menu > li {\n  border-bottom: 1px solid #3c485a;\n  box-shadow: 0 1px 0 #48566c;\n  -moz-box-shadow: 0 1px 0 #48566c;\n  -webkit-box-shadow: 0 1px 0 #48566c;\n}\n.menu-grid .inbox-menu > li.active > a {\n  background: #384354;\n}\n.menu-grid .inbox-menu > li.active > a:hover,\n.menu-grid .inbox-menu > li.active > a:focus {\n  background: #384354;\n}\n.menu-grid .inbox-menu > li > a {\n  display: block;\n  color: #fff;\n  padding: 10px 20px;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.menu-grid .inbox-menu > li > a:hover,\n.menu-grid .inbox-menu > li > a:focus {\n  background: #3c485a;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.menu-grid .inbox-menu > li .submenu > li {\n  border-bottom: 1px solid #445166;\n}\n.menu-grid .inbox-menu > li .submenu > li:last-child {\n  border-bottom: none;\n  box-shadow: none;\n  -moz-box-shadow: none;\n  -webkit-box-shadow: none;\n}\n.menu-grid .inbox-menu > li .submenu > li.active > a {\n  background: #343e4e;\n}\n.menu-grid .inbox-menu > li .submenu > li.active > a:hover,\n.menu-grid .inbox-menu > li .submenu > li.active > a:focus {\n  background: #343e4e;\n}\n.menu-grid .inbox-menu > li .submenu > li > a {\n  display: block;\n  color: #fff;\n  padding: 10px 20px;\n  background: #3e4a5d;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.menu-grid .inbox-menu > li .submenu > li > a:hover,\n.menu-grid .inbox-menu > li .submenu > li > a:focus {\n  background: #384354;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.inbox-panel {\n  margin-bottom: 0;\n  border-radius: 0;\n  -moz-border-radius: 0;\n  -webkit-border-radius: 0;\n}\n.inbox-panel .inbox-item {\n  cursor: pointer;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.inbox-panel .inbox-item:hover {\n  background: #f7f7f7;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.inbox-panel .inbox-item.selected {\n  color: #ccc;\n  background: #f1f5fc;\n  border: 1px solid #e4ecf9;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.inbox-panel .inbox-item.selected:hover {\n  background: #f1f5fc;\n  color: #ccc;\n}\n.inbox-panel .inbox-item .starred {\n  color: #f3ce85;\n}\n.inbox-panel .inbox-item .not-starred:hover {\n  color: #f3ce85;\n}\n.inbox-panel .inbox-item .from {\n  display: inline-block;\n  width: 100px;\n  text-overflow: ellipsis;\n  overflow: hidden;\n  vertical-align: middle;\n  white-space: nowrap;\n  font-weight: bold;\n  margin-left: 10px;\n  height: 19px;\n}\n.inbox-panel .inbox-item .detail {\n  display: inline-block;\n  overflow: hidden;\n  white-space: nowrap;\n  vertical-align: middle;\n  text-overflow: ellipsis;\n  width: 50%;\n  height: 19px;\n}\n@media (max-width: 480px) {\n  .inbox-panel .inbox-item .detail {\n    width: 65%;\n  }\n}\n.inbox-panel .inbox-item .attachment {\n  margin-right: 15px;\n}\n.inbox-panel .panel-footer .pagination {\n  margin: 2px 0 0;\n}\n.inbox-panel .panel-footer .pagination li a {\n  padding: 0 10px;\n  background: transparent;\n  border: none;\n}\n.inbox-panel .panel-footer .pagination li a .large {\n  font-size: 140%;\n}\n.inbox-action {\n  font-weight: bold;\n  background: #fff;\n  border-radius: 2px;\n  -moz-border-radius: 2px;\n  -webkit-border-radius: 2px;\n  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n  -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.inbox-action.active {\n  background: #65cea7;\n  color: #fff;\n}\n.inbox-action.active a {\n  color: #fff;\n}\n.inbox-action.active a:hover,\n.inbox-action.active a:focus {\n  background-color: #65cea7;\n}\n.inbox-action a {\n  display: block;\n  padding: 10px;\n  color: #777;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.inbox-action a:hover,\n.inbox-action a:focus {\n  text-decoration: none;\n  background-color: #f2f2f2;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.gallery-container .gallery-item {\n  display: inline-block;\n  width: 33.33333%;\n  float: left;\n  overflow: hidden;\n}\n@media (max-width: 1200px) {\n  .gallery-container .gallery-item {\n    width: 50%;\n  }\n}\n@media (max-width: 600px) {\n  .gallery-container .gallery-item {\n    width: 100%;\n  }\n}\n.gallery-container .gallery-item .image-wrapper {\n  width: 100%;\n  padding-top: 60%;\n}\n.gallery-container .gallery-item .image-wrapper img {\n  display: block;\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n}\n.pricing-widget {\n  position: relative;\n  border: 1px solid #f1f5fc;\n  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n  -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n  cursor: pointer;\n  margin: 20px 0;\n  border-radius: 6px;\n  -moz-border-radius: 6px;\n  -webkit-border-radius: 6px;\n  transition: all 0.4s ease;\n  -webkit-transition: all 0.4s ease;\n  -moz-transition: all 0.4s ease;\n  -ms-transition: all 0.4s ease;\n  -o-transition: all 0.4s ease;\n}\n.pricing-widget.active {\n  z-index: 2;\n}\n.pricing-widget:not(.pricing-title).active,\n.pricing-widget:not(.pricing-title):hover {\n  box-shadow: 0 3px 25px -4px rgba(0, 0, 0, 0.9);\n  -moz-box-shadow: 0 3px 25px -4px rgba(0, 0, 0, 0.9);\n  -webkit-box-shadow: 0 3px 25px -4px rgba(0, 0, 0, 0.9);\n  transition: all 0.4s ease;\n  -webkit-transition: all 0.4s ease;\n  -moz-transition: all 0.4s ease;\n  -ms-transition: all 0.4s ease;\n  -o-transition: all 0.4s ease;\n}\n.pricing-widget:not(.pricing-title).active .pricing-cost,\n.pricing-widget:not(.pricing-title):hover .pricing-cost {\n  color: #999;\n  transition: all 0.3s ease;\n  -webkit-transition: all 0.3s ease;\n  -moz-transition: all 0.3s ease;\n  -ms-transition: all 0.3s ease;\n  -o-transition: all 0.3s ease;\n}\n.pricing-widget .pricing-head {\n  background: #fff;\n  color: #777;\n  border-bottom: 1px solid #f1f5fc;\n  padding: 6px 20px;\n  font-weight: 600;\n  font-size: 13px;\n  min-height: 31px;\n}\n.pricing-widget .pricing-body {\n  background: #fff;\n  color: #626262;\n}\n.pricing-widget .pricing-cost {\n  background: #fff;\n  text-align: center;\n  padding: 20px;\n  border-bottom: 1px solid #f1f5fc;\n  color: #777777;\n  transition: all 0.3s ease;\n  -webkit-transition: all 0.3s ease;\n  -moz-transition: all 0.3s ease;\n  -ms-transition: all 0.3s ease;\n  -o-transition: all 0.3s ease;\n  font-size: 18px;\n  min-height: 125px;\n}\n.pricing-widget .pricing-cost strong {\n  font-size: 30px;\n}\n.pricing-widget .pricing-list {\n  list-style: none;\n  padding: 0;\n  margin: 0;\n}\n.pricing-widget .pricing-list [class*=\"icon-\"] {\n  margin-right: 30px;\n}\n.pricing-widget .pricing-list.text-center li {\n  text-align: center;\n}\n.pricing-widget .pricing-list li {\n  padding: 10px;\n  border-bottom: 1px solid #f1f5fc;\n}\n.pricing-widget .pricing-list li:last-child {\n  min-height: 84px;\n  padding-top: 40px;\n  box-shadow: none;\n  -moz-box-shadow: none;\n  -webkit-box-shadow: none;\n  border-bottom: none;\n}\n.pricing-widget .pricing-list li:last-child [class*=\"icon-\"] {\n  margin-right: 5px;\n}\n#wrapper .chat-wrapper {\n  position: relative;\n}\n#wrapper .chat-wrapper .chat-sidebar {\n  position: fixed;\n  width: 250px;\n  left: 194px;\n  top: 45px;\n  bottom: 0;\n  height: 100%;\n  overflow-y: auto;\n  padding-bottom: 50px;\n  border-bottom: 1px solid #eee;\n  transition: all 0.5s ease;\n  -webkit-transition: all 0.5s ease;\n  -moz-transition: all 0.5s ease;\n  -ms-transition: all 0.5s ease;\n  -o-transition: all 0.5s ease;\n}\n@media (max-width: 767px) {\n  #wrapper .chat-wrapper .chat-sidebar {\n    left: -250px;\n    transition: all 0.5s ease;\n    -webkit-transition: all 0.5s ease;\n    -moz-transition: all 0.5s ease;\n    -ms-transition: all 0.5s ease;\n    -o-transition: all 0.5s ease;\n  }\n}\n@media (max-width: 868px) and (min-width: 768px) {\n  #wrapper .chat-wrapper .chat-sidebar {\n    left: 90px !important;\n    transition: all 0.5s ease;\n    -webkit-transition: all 0.5s ease;\n    -moz-transition: all 0.5s ease;\n    -ms-transition: all 0.5s ease;\n    -o-transition: all 0.5s ease;\n  }\n}\n#wrapper .chat-wrapper .chat-sidebar .friend-list {\n  list-style: none;\n}\n#wrapper .chat-wrapper .chat-sidebar .friend-list li {\n  border-bottom: 1px solid #eee;\n}\n#wrapper .chat-wrapper .chat-sidebar .friend-list li.active a {\n  background-color: #f1f5fc;\n}\n#wrapper .chat-wrapper .chat-sidebar .friend-list li a {\n  position: relative;\n  display: block;\n  padding: 10px;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n#wrapper .chat-wrapper .chat-sidebar .friend-list li a img {\n  float: left;\n  width: 45px;\n  height: 45px;\n  margin-right: 10px;\n}\n#wrapper .chat-wrapper .chat-sidebar .friend-list li a .friend-name {\n  color: #777;\n}\n#wrapper .chat-wrapper .chat-sidebar .friend-list li a .friend-name:hover {\n  color: #777;\n}\n#wrapper .chat-wrapper .chat-sidebar .friend-list li a .last-message {\n  width: 65%;\n  white-space: nowrap;\n  text-overflow: ellipsis;\n  overflow: hidden;\n}\n#wrapper .chat-wrapper .chat-sidebar .friend-list li a .time {\n  position: absolute;\n  top: 10px;\n  right: 8px;\n}\n#wrapper .chat-wrapper .chat-sidebar .friend-list li a .chat-alert {\n  position: absolute;\n  right: 8px;\n  top: 27px;\n  font-size: 10px;\n  padding: 3px 5px;\n}\n#wrapper .chat-wrapper .chat-sidebar .friend-list li a:hover {\n  background-color: #eee;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n#wrapper .chat-wrapper .chat-inner {\n  position: fixed;\n  top: 40px;\n  right: 0;\n  left: 444px;\n  height: 100%;\n  overflow-y: auto;\n  transition: all 0.5s ease;\n  -webkit-transition: all 0.5s ease;\n  -moz-transition: all 0.5s ease;\n  -ms-transition: all 0.5s ease;\n  -o-transition: all 0.5s ease;\n}\n@media (max-width: 767px) {\n  #wrapper .chat-wrapper .chat-inner {\n    left: 0;\n    transition: all 0.5s ease;\n    -webkit-transition: all 0.5s ease;\n    -moz-transition: all 0.5s ease;\n    -ms-transition: all 0.5s ease;\n    -o-transition: all 0.5s ease;\n  }\n}\n@media (max-width: 868px) and (min-width: 768px) {\n  #wrapper .chat-wrapper .chat-inner {\n    left: 340px !important;\n    transition: all 0.5s ease;\n    -webkit-transition: all 0.5s ease;\n    -moz-transition: all 0.5s ease;\n    -ms-transition: all 0.5s ease;\n    -o-transition: all 0.5s ease;\n  }\n}\n#wrapper .chat-wrapper .chat-inner .chat-header {\n  position: fixed;\n  top: 45px;\n  left: 444px;\n  right: 0;\n  padding: 0 10px;\n  border-bottom: 1px solid #eee;\n  z-index: 10;\n  height: 40px;\n  transition: all 0.5s ease;\n  -webkit-transition: all 0.5s ease;\n  -moz-transition: all 0.5s ease;\n  -ms-transition: all 0.5s ease;\n  -o-transition: all 0.5s ease;\n}\n@media (max-width: 767px) {\n  #wrapper .chat-wrapper .chat-inner .chat-header {\n    left: 0;\n    transition: all 0.5s ease;\n    -webkit-transition: all 0.5s ease;\n    -moz-transition: all 0.5s ease;\n    -ms-transition: all 0.5s ease;\n    -o-transition: all 0.5s ease;\n  }\n}\n@media (max-width: 868px) and (min-width: 768px) {\n  #wrapper .chat-wrapper .chat-inner .chat-header {\n    left: 340px !important;\n    transition: all 0.5s ease;\n    -webkit-transition: all 0.5s ease;\n    -moz-transition: all 0.5s ease;\n    -ms-transition: all 0.5s ease;\n    -o-transition: all 0.5s ease;\n  }\n}\n#wrapper .chat-wrapper .chat-inner .chat-header .navbar-toggle {\n  float: left;\n  margin-top: 0;\n  color: #777;\n}\n#wrapper .chat-wrapper .chat-inner .chat-header .navbar-toggle .notification-label {\n  top: 4px;\n  right: 2px;\n}\n#wrapper .chat-wrapper .chat-inner .chat-header .btn {\n  margin-top: 8px;\n}\n#wrapper .chat-wrapper .chat-inner .chat-body {\n  padding-bottom: 20px;\n}\n#wrapper .chat-wrapper .chat-inner .chat-message {\n  padding: 60px 20px 115px;\n}\n#wrapper .chat-wrapper .chat-inner .chat-box {\n  position: fixed;\n  bottom: 0;\n  left: 444px;\n  right: 0;\n  padding: 15px;\n  border-top: 1px solid #eee;\n  transition: all 0.5s ease;\n  -webkit-transition: all 0.5s ease;\n  -moz-transition: all 0.5s ease;\n  -ms-transition: all 0.5s ease;\n  -o-transition: all 0.5s ease;\n}\n@media (max-width: 767px) {\n  #wrapper .chat-wrapper .chat-inner .chat-box {\n    left: 0;\n    transition: all 0.5s ease;\n    -webkit-transition: all 0.5s ease;\n    -moz-transition: all 0.5s ease;\n    -ms-transition: all 0.5s ease;\n    -o-transition: all 0.5s ease;\n  }\n}\n@media (max-width: 868px) and (min-width: 768px) {\n  #wrapper .chat-wrapper .chat-inner .chat-box {\n    left: 340px !important;\n    transition: all 0.5s ease;\n    -webkit-transition: all 0.5s ease;\n    -moz-transition: all 0.5s ease;\n    -ms-transition: all 0.5s ease;\n    -o-transition: all 0.5s ease;\n  }\n}\n@media (max-width: 767px) {\n  #wrapper .chat-wrapper.sidebar-display .chat-sidebar {\n    left: 0;\n    transition: all 0.5s ease;\n    -webkit-transition: all 0.5s ease;\n    -moz-transition: all 0.5s ease;\n    -ms-transition: all 0.5s ease;\n    -o-transition: all 0.5s ease;\n  }\n  #wrapper .chat-wrapper.sidebar-display .chat-inner {\n    left: 250px;\n    right: -250px;\n    transition: all 0.5s ease;\n    -webkit-transition: all 0.5s ease;\n    -moz-transition: all 0.5s ease;\n    -ms-transition: all 0.5s ease;\n    -o-transition: all 0.5s ease;\n  }\n  #wrapper .chat-wrapper.sidebar-display .chat-inner .chat-header,\n  #wrapper .chat-wrapper.sidebar-display .chat-inner .chat-box {\n    left: 250px;\n    right: -250px;\n    transition: all 0.5s ease;\n    -webkit-transition: all 0.5s ease;\n    -moz-transition: all 0.5s ease;\n    -ms-transition: all 0.5s ease;\n    -o-transition: all 0.5s ease;\n  }\n}\n@media (min-width: 768px) {\n  #wrapper.sidebar-mini .chat-wrapper .chat-sidebar {\n    left: 90px !important;\n  }\n  #wrapper.sidebar-mini .chat-wrapper .chat-inner {\n    left: 340px !important;\n  }\n  #wrapper.sidebar-mini .chat-wrapper .chat-inner .chat-header,\n  #wrapper.sidebar-mini .chat-wrapper .chat-inner .chat-box {\n    left: 340px !important;\n  }\n}\n@media (max-width: 767px) {\n  #wrapper.sidebar-display .chat-wrapper.sidebar-display .chat-sidebar {\n    left: 194px;\n  }\n  #wrapper.sidebar-display .chat-wrapper.sidebar-display .chat-inner {\n    left: 444px;\n    right: -444px;\n  }\n  #wrapper.sidebar-display .chat-wrapper.sidebar-display .chat-inner .chat-header,\n  #wrapper.sidebar-display .chat-wrapper.sidebar-display .chat-inner .chat-box {\n    left: 444px;\n    right: -444px;\n  }\n  #wrapper.sidebar-display .chat-wrapper .chat-inner {\n    left: 194px;\n    right: -194px;\n  }\n  #wrapper.sidebar-display .chat-wrapper .chat-inner .chat-header,\n  #wrapper.sidebar-display .chat-wrapper .chat-inner .chat-box {\n    left: 194px;\n    right: -194px;\n  }\n}\n.gallery-header {\n  padding: 10px;\n  background: #e6e6e6;\n}\n@media (max-width: 767px) {\n  #movieSlider {\n    margin-bottom: 20px;\n  }\n}\n#movieSlider .carousel-inner .item {\n  overflow: hidden;\n  opacity: 0;\n  transition: opacity 0.8s ease;\n  -webkit-transition: opacity 0.8s ease;\n  -moz-transition: opacity 0.8s ease;\n  -ms-transition: opacity 0.8s ease;\n  -o-transition: opacity 0.8s ease;\n}\n@media (max-width: 400px) {\n  #movieSlider .carousel-inner .item {\n    height: 200px;\n  }\n}\n@media (min-width: 401px) and (max-width: 480px) {\n  #movieSlider .carousel-inner .item {\n    height: 250px;\n  }\n  #movieSlider .carousel-inner .item h2 {\n    font-size: 17px;\n  }\n}\n@media (min-width: 481px) and (max-width: 979px) {\n  #movieSlider .carousel-inner .item {\n    height: 300px;\n  }\n}\n@media (min-width: 980px) {\n  #movieSlider .carousel-inner .item {\n    height: 350px;\n  }\n}\n#movieSlider .carousel-inner .item .slide-caption {\n  animation: none;\n  -webkit-animation: none;\n  -moz-animation: none;\n  -ms-animation: none;\n  -o-animation: none;\n}\n#movieSlider .carousel-inner .item.active {\n  opacity: 1;\n  transition: opacity 0.8s ease;\n  -webkit-transition: opacity 0.8s ease;\n  -moz-transition: opacity 0.8s ease;\n  -ms-transition: opacity 0.8s ease;\n  -o-transition: opacity 0.8s ease;\n}\n#movieSlider .carousel-inner .item.left.active {\n  left: 0;\n  opacity: 0;\n  z-index: 1;\n  transition: opacity 0.8s ease;\n  -webkit-transition: opacity 0.8s ease;\n  -moz-transition: opacity 0.8s ease;\n  -ms-transition: opacity 0.8s ease;\n  -o-transition: opacity 0.8s ease;\n}\n#movieSlider .carousel-inner .item.left.next {\n  opacity: 1;\n  transition: opacity 0.8s ease;\n  -webkit-transition: opacity 0.8s ease;\n  -moz-transition: opacity 0.8s ease;\n  -ms-transition: opacity 0.8s ease;\n  -o-transition: opacity 0.8s ease;\n}\n#movieSlider .carousel-inner .item.right.active {\n  left: 0;\n  opacity: 0;\n  z-index: 1;\n  transition: opacity 0.8s ease;\n  -webkit-transition: opacity 0.8s ease;\n  -moz-transition: opacity 0.8s ease;\n  -ms-transition: opacity 0.8s ease;\n  -o-transition: opacity 0.8s ease;\n}\n#movieSlider .carousel-inner .item.right.prev {\n  opacity: 1;\n  transition: opacity 0.8s ease;\n  -webkit-transition: opacity 0.8s ease;\n  -moz-transition: opacity 0.8s ease;\n  -ms-transition: opacity 0.8s ease;\n  -o-transition: opacity 0.8s ease;\n}\n#movieSlider .carousel-inner .item img {\n  position: absolute;\n  left: 0;\n  width: 100%;\n}\n@media (min-width: 1200px) {\n  #movieSlider .carousel-inner .item img {\n    top: -50px;\n  }\n}\n#movieSlider .carousel-control {\n  background-image: none;\n  z-index: 2;\n}\n#movieSlider .carousel-control:hover,\n#movieSlider .carousel-control:focus {\n  opacity: 1;\n}\n#movieSlider .carousel-control span {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  z-index: 5;\n  display: inline-block;\n}\n#featuredMovie {\n  height: 350px;\n}\n@media (max-width: 767px) {\n  #featuredMovie {\n    height: auto;\n  }\n}\n@media (min-width: 768px) and (max-width: 979px) {\n  #featuredMovie {\n    height: 300px;\n  }\n}\n@media (min-width: 980px) {\n  #featuredMovie {\n    height: 350px;\n  }\n}\n#featuredMovie .featured-name {\n  animation: text-color-animation 2s ease infinite;\n  -webkit-animation: text-color-animation 2s ease infinite;\n  -moz-animation: text-color-animation 2s ease infinite;\n  -ms-animation: text-color-animation 2s ease infinite;\n  -o-animation: text-color-animation 2s ease infinite;\n}\n.navbar-nav > li {\n  border-bottom: 2px solid transparent;\n  transition: border-color 0.4s ease;\n  -webkit-transition: border-color 0.4s ease;\n  -moz-transition: border-color 0.4s ease;\n  -ms-transition: border-color 0.4s ease;\n  -o-transition: border-color 0.4s ease;\n}\n.navbar-nav > li.active {\n  border-bottom: 2px solid #3c8dbc;\n}\n.navbar-nav > li:hover,\n.navbar-nav > li:focus {\n  border-bottom-color: #3c8dbc;\n  transition: border-color 0.4s ease;\n  -webkit-transition: border-color 0.4s ease;\n  -moz-transition: border-color 0.4s ease;\n  -ms-transition: border-color 0.4s ease;\n  -o-transition: border-color 0.4s ease;\n}\n.movie-news {\n  list-style: none;\n}\n.movie-news li {\n  display: block;\n  margin-bottom: 10px;\n  padding: 0 15px;\n  border-bottom: 1px solid #1a1a1a;\n}\n.movie-news li img {\n  float: left;\n  width: 130px;\n  margin-right: 15px;\n}\n.movie-news li .news-wrapper .news-header {\n  color: #3c8dbc;\n  font-weight: bold;\n  font-size: 14px;\n  margin-bottom: 3px;\n}\n.jcarousel-wrapper {\n  border: none;\n  box-shadow: none;\n  -moz-box-shadow: none;\n  -webkit-box-shadow: none;\n  margin-bottom: 0;\n}\n.jcarousel-wrapper .jcarousel {\n  position: relative;\n  overflow: hidden;\n  width: 100%;\n  height: auto;\n}\n.jcarousel-wrapper .jcarousel > ul > li {\n  position: relative;\n  float: left;\n  border-color: transparent;\n  border-radius: 4px;\n  -moz-border-radius: 4px;\n  -webkit-border-radius: 4px;\n}\n.jcarousel-wrapper .jcarousel > ul > li a {\n  display: block;\n  padding: 10px 15px;\n}\n.jcarousel-wrapper .jcarousel > ul > li ul {\n  width: auto;\n}\n.jcarousel-wrapper .jcarousel > ul > li ul > li {\n  float: none;\n  width: auto;\n  height: auto;\n}\n.movie-jcarousel > ul > li {\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.movie-jcarousel > ul > li:hover {\n  background: rgba(0, 0, 0, 0.15);\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.movie-list {\n  list-style: none;\n}\n.movie-list li {\n  display: block;\n  padding: 15px;\n  border-bottom: 1px solid #1a1a1a;\n}\n.movie-list li:last-child {\n  border-bottom: none;\n}\n.movie-list li img {\n  float: left;\n  width: 70px;\n  margin-right: 10px;\n}\n.jcarousel-control-next {\n  top: -40px;\n  right: 0;\n  background-color: #111;\n  width: 25px;\n  height: 25px;\n  color: #777;\n  line-height: 23px;\n  border-radius: 0;\n  -moz-border-radius: 0;\n  -webkit-border-radius: 0;\n  text-shadow: none;\n  box-shadow: none;\n  -moz-box-shadow: none;\n  -webkit-box-shadow: none;\n  transition: all 0.3s ease;\n  -webkit-transition: all 0.3s ease;\n  -moz-transition: all 0.3s ease;\n  -ms-transition: all 0.3s ease;\n  -o-transition: all 0.3s ease;\n}\n.jcarousel-control-next:hover {\n  background-color: #3c8dbc;\n  color: #fff;\n  transition: all 0.3s ease;\n  -webkit-transition: all 0.3s ease;\n  -moz-transition: all 0.3s ease;\n  -ms-transition: all 0.3s ease;\n  -o-transition: all 0.3s ease;\n}\n.jcarousel-control-prev {\n  top: -40px;\n  right: 32px;\n  left: auto;\n  width: 25px;\n  height: 25px;\n  background-color: #111;\n  color: #777;\n  line-height: 23px;\n  border-radius: 0;\n  -moz-border-radius: 0;\n  -webkit-border-radius: 0;\n  text-shadow: none;\n  box-shadow: none;\n  -moz-box-shadow: none;\n  -webkit-box-shadow: none;\n  transition: all 0.3s ease;\n  -webkit-transition: all 0.3s ease;\n  -moz-transition: all 0.3s ease;\n  -ms-transition: all 0.3s ease;\n  -o-transition: all 0.3s ease;\n}\n.jcarousel-control-prev:hover {\n  background-color: #3c8dbc;\n  color: #fff;\n  transition: all 0.3s ease;\n  -webkit-transition: all 0.3s ease;\n  -moz-transition: all 0.3s ease;\n  -ms-transition: all 0.3s ease;\n  -o-transition: all 0.3s ease;\n}\n#lockScreen {\n  display: table;\n  width: 100%;\n  height: 100%;\n  text-align: center;\n}\n#lockScreen.in .modal-dialog {\n  transform: translate(0, 0);\n  -webkit-transform: translate(0, 0);\n  -moz-transform: translate(0, 0);\n  -ms-transform: translate(0, 0);\n  -o-transform: translate(0, 0);\n  transition: all 0.5s ease-out;\n  -webkit-transition: all 0.5s ease-out;\n  -moz-transition: all 0.5s ease-out;\n  -ms-transition: all 0.5s ease-out;\n  -o-transition: all 0.5s ease-out;\n}\n#lockScreen .modal-dialog {\n  display: table-cell;\n  width: 270px !important;\n  vertical-align: middle;\n  transform: translate(0, -40px);\n  -webkit-transform: translate(0, -40px);\n  -moz-transform: translate(0, -40px);\n  -ms-transform: translate(0, -40px);\n  -o-transform: translate(0, -40px);\n}\n#lockScreen .modal-dialog .modal-content {\n  background-color: transparent;\n  box-shadow: none;\n  -moz-box-shadow: none;\n  -webkit-box-shadow: none;\n  border: none;\n}\n#lockScreen .modal-dialog .modal-content .input-group {\n  width: 270px;\n  margin: 0 auto;\n}\n#lockScreen .lock-screen-img {\n  text-align: center;\n}\n#lockScreen .lock-screen-img img {\n  border-radius: 50em;\n  -moz-border-radius: 50em;\n  -webkit-border-radius: 50em;\n  width: 70px;\n  height: 70px;\n}\n.fc-event {\n  background: #6bafbd;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n}\n.fc-header-title h2 {\n  font-size: 14px;\n  line-height: 37px;\n}\n.fc-header {\n  position: relative;\n}\n.fc-header td {\n  background: transparent;\n}\n.fc-header-right {\n  position: absolute;\n  width: 100%;\n  background: transparent;\n  top: -43px;\n  right: 0px;\n  text-align: right;\n}\n.fc-header-center {\n  position: absolute;\n  top: 0;\n  width: 80%;\n  left: 10%;\n  line-height: 37px;\n  text-align: center;\n}\n.fc-button {\n  position: relative;\n  cursor: pointer;\n  margin-top: -3px;\n  background: #fff;\n}\n.fc-button.fc-button-prev,\n.fc-button.fc-button-next {\n  border-radius: 50em;\n  -moz-border-radius: 50em;\n  -webkit-border-radius: 50em;\n  padding: 0 .3em;\n  width: 28px;\n  height: 25px;\n}\n.fc-button-today {\n  display: none;\n}\n.fc-header-left {\n  position: relative;\n  width: 100%;\n}\n.fc-header .fc-header-left .fc-corner-left {\n  float: left;\n}\n.fc-header .fc-header-left .fc-corner-right {\n  float: right;\n}\n.gritter-info .gritter-title {\n  color: #6bafbd;\n}\n.gritter-success .gritter-title {\n  color: #65cea7;\n}\n.gritter-warning .gritter-title {\n  color: #f3ce85;\n}\n.gritter-danger .gritter-title {\n  color: #fc8675;\n}\n@media (max-width: 480px) {\n  #gritter-notice-wrapper {\n    right: 0;\n  }\n}\n.custom-popup {\n  background-color: rgba(0, 0, 0, 0.9);\n  color: #777;\n  text-align: center !important;\n  padding: 15px;\n}\n.custom-popup.full-width {\n  width: 100%;\n}\n.custom-popup.light {\n  background-color: #f9f9f9;\n}\n.custom-popup {\n  -webkit-transform: scale(0.8);\n  -moz-transform: scale(0.8);\n  -ms-transform: scale(0.8);\n  transform: scale(0.8);\n}\n.popup_visible .custom-popup {\n  -webkit-transform: scale(1);\n  -moz-transform: scale(1);\n  -ms-transform: scale(1);\n  transform: scale(1);\n}\n.parsley-error-list {\n  list-style: none;\n}\n.parsley-error {\n  border-color: #f53535;\n  color: #b94a48;\n}\n.parsley-error:focus {\n  border-color: #f53535 !important;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 2px rgba(245, 53, 53, 0.6) !important;\n  -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 2px rgba(245, 53, 53, 0.6) !important;\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 2px rgba(245, 53, 53, 0.6) !important;\n}\n.dd {\n  position: relative;\n  display: block;\n  margin: 0;\n  padding: 0;\n  max-width: 600px;\n  list-style: none;\n  font-size: 13px;\n  line-height: 20px;\n}\n.dd-list {\n  display: block;\n  position: relative;\n  margin: 0;\n  padding: 0;\n  list-style: none;\n}\n.dd-list .dd-list {\n  padding-left: 30px;\n}\n.dd-collapsed .dd-list {\n  display: none;\n}\n.dd-item,\n.dd-empty,\n.dd-placeholder {\n  display: block;\n  position: relative;\n  margin: 0;\n  padding: 0;\n  min-height: 20px;\n  font-size: 13px;\n  line-height: 20px;\n}\n.dd-handle {\n  display: block;\n  height: 30px;\n  margin: 5px 0;\n  padding: 5px 10px;\n  color: #777;\n  text-decoration: none;\n  font-weight: bold;\n  border: 1px solid #eee;\n  background: #fff;\n  border-radius: 3px;\n  -moz-border-radius: 3px;\n  -webkit-border-radius: 3px;\n  box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  -webkit-box-sizing: border-box;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.dd-handle:hover {\n  background: #f7f7f7;\n  color: #777;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.dd-item > button {\n  display: block;\n  position: relative;\n  cursor: pointer;\n  float: left;\n  width: 25px;\n  height: 20px;\n  margin: 5px 0;\n  padding: 0;\n  text-indent: 100%;\n  white-space: nowrap;\n  overflow: hidden;\n  border: 0;\n  background: transparent;\n  font-size: 12px;\n  line-height: 1;\n  text-align: center;\n  font-weight: bold;\n}\n.dd-item > button:before {\n  content: '+';\n  display: block;\n  position: absolute;\n  width: 100%;\n  text-align: center;\n  text-indent: 0;\n}\n.dd-item > button[data-action=\"collapse\"]:before {\n  content: '-';\n}\n.dd-placeholder,\n.dd-empty {\n  margin: 5px 0;\n  padding: 0;\n  min-height: 30px;\n  background: #f2fbff;\n  border: 1px dashed #b6bcbf;\n  box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  -webkit-box-sizing: border-box;\n}\n.dd-empty {\n  border: 1px dashed #bbb;\n  min-height: 100px;\n  background-color: #e5e5e5;\n  background-image: -webkit-linear-gradient(45deg, #ffffff 25%, transparent 25%, transparent 75%, #ffffff 75%, #ffffff), -webkit-linear-gradient(45deg, #ffffff 25%, transparent 25%, transparent 75%, #ffffff 75%, #ffffff);\n  background-image: -moz-linear-gradient(45deg, #ffffff 25%, transparent 25%, transparent 75%, #ffffff 75%, #ffffff), -moz-linear-gradient(45deg, #ffffff 25%, transparent 25%, transparent 75%, #ffffff 75%, #ffffff);\n  background-image: linear-gradient(45deg, #ffffff 25%, transparent 25%, transparent 75%, #ffffff 75%, #ffffff), linear-gradient(45deg, #ffffff 25%, transparent 25%, transparent 75%, #ffffff 75%, #ffffff);\n  background-size: 60px 60px;\n  background-position: 0 0, 30px 30px;\n}\n.dd-dragel {\n  position: absolute;\n  pointer-events: none;\n  z-index: 9999;\n}\n.dd-dragel > .dd-item .dd-handle {\n  margin-top: 0;\n}\n.dd-dragel .dd-handle {\n  box-shadow: 2px 4px 6px 0 rgba(0, 0, 0, 0.1);\n  -moz-box-shadow: 2px 4px 6px 0 rgba(0, 0, 0, 0.1);\n  -webkit-box-shadow: 2px 4px 6px 0 rgba(0, 0, 0, 0.1);\n}\n.nestable-lists {\n  display: block;\n  clear: both;\n  padding: 30px 0;\n  width: 100%;\n  border: 0;\n  border-top: 2px solid #ddd;\n  border-bottom: 2px solid #ddd;\n}\n#nestable-menu {\n  padding: 0;\n  margin: 20px 0;\n}\n.dd-hover > .dd-handle {\n  background: #2ea8e5 !important;\n}\n.dd3-content {\n  display: block;\n  height: 30px;\n  margin: 5px 0;\n  padding: 5px 10px 5px 40px;\n  color: #777;\n  text-decoration: none;\n  font-weight: bold;\n  border: 1px solid #eee;\n  background: #fff;\n  border-radius: 3px;\n  -moz-border-radius: 3px;\n  -webkit-border-radius: 3px;\n  box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  -webkit-box-sizing: border-box;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.dd3-content:hover {\n  color: #777;\n  background: #f7f7f7;\n  transition: all 0.2s ease;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n}\n.dd-dragel > .dd3-item > .dd3-content {\n  margin: 0;\n}\n.dd3-item > button {\n  margin-left: 30px;\n}\n.dd3-handle {\n  position: absolute;\n  margin: 0;\n  left: 0;\n  top: 0;\n  cursor: pointer;\n  width: 30px;\n  text-indent: 100%;\n  white-space: nowrap;\n  overflow: hidden;\n  border: 1px solid #eee;\n  background: #fff;\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.dd3-handle:before {\n  content: '≡';\n  display: block;\n  position: absolute;\n  left: 0;\n  top: 3px;\n  width: 100%;\n  text-align: center;\n  text-indent: 0;\n  color: #777;\n  font-size: 20px;\n  font-weight: normal;\n}\n.dd3-handle:hover {\n  background: #eee;\n}\n.spinner .input-group-btn > .btn + .btn {\n  margin-left: 0;\n  height: 18px;\n  border-radius: 0 0 2px 0 !important;\n  -moz-border-radius: 0 0 2px 0 !important;\n  -webkit-border-radius: 0 0 2px 0 !important;\n}\n.spinner .input-group-btn .btn {\n  height: 17px;\n  line-height: 1px;\n  border-radius: 0 2px 0 0 !important;\n  -moz-border-radius: 0 2px 0 0 !important;\n  -webkit-border-radius: 0 2px 0 0 !important;\n}\n.chosen-container {\n  width: 100% !important;\n}\n.chosen-container-single .chosen-single,\n.chosen-container-multi .chosen-choices li.search-field input[type=text] {\n  height: 25px;\n}\n.tagsinput {\n  width: 100% !important;\n}\n.dropzone .dz-default.dz-message {\n  background-image: none;\n  width: 100%;\n  left: 0;\n  margin-left: auto;\n  text-align: center;\n}\n.dropzone .dz-default.dz-message span {\n  display: inline;\n  font-size: 30px;\n}\n.minicolors-theme-default .minicolors-input {\n  height: auto;\n}\n.minicolors-theme-default.minicolors-position-right .minicolors-input {\n  padding-left: 12px;\n}\n.seperator {\n  padding-top: 10px;\n}\n.block {\n  display: block !important;\n}\n.inline-block {\n  display: inline-block !important;\n}\n.inline {\n  display: inline !important;\n}\n.relative {\n  position: relative;\n}\n.ellipsis {\n  white-space: nowrap;\n  text-overflow: ellipsis;\n  overflow: hidden;\n}\n.scrollable {\n  overflow-y: auto;\n}\n.overflow-visible {\n  overflow: visible;\n}\n.overflow-hidden {\n  overflow: hidden;\n}\n.circle {\n  border-radius: 50em;\n  -moz-border-radius: 50em;\n  -webkit-border-radius: 50em;\n}\n.no-padding {\n  padding: 0 !important;\n}\n.p-top-xs {\n  padding-top: 5px;\n}\n.p-top-sm {\n  padding-top: 10px;\n}\n.p-top-md {\n  padding-top: 20px;\n}\n.padding-xs {\n  padding: 5px !important;\n}\n.padding-sm {\n  padding: 10px !important;\n}\n.padding-md {\n  padding: 20px !important;\n}\n.padding-lg {\n  padding: 40px !important;\n}\n.paddingLR-xs {\n  padding: 0 5px;\n}\n.paddingLR-sm {\n  padding: 0 10px;\n}\n.paddingLR-md {\n  padding: 0 20px;\n}\n.paddingLR-lg {\n  padding: 0 40px;\n}\n.paddingTB-xs {\n  padding: 5px 0;\n}\n.paddingTB-md {\n  padding: 10px 0;\n}\n.paddingTB-md {\n  padding: 20px 0;\n}\n.paddingTB-lg {\n  padding: 40px 0;\n}\n.no-margin {\n  margin: 0 !important;\n}\n.margin-xs {\n  margin: 5px !important;\n}\n.margin-sm {\n  margin: 10px !important;\n}\n.margin-md {\n  margin: 20px !important;\n}\n.margin-lg {\n  margin: 40px !important;\n}\n.m-top-none {\n  margin-top: 0;\n}\n.m-top-xs {\n  margin-top: 5px;\n}\n.m-top-sm {\n  margin-top: 10px;\n}\n.m-top-md {\n  margin-top: 20px;\n}\n.m-top-lg {\n  margin-top: 40px;\n}\n.m-left-xs {\n  margin-left: 5px;\n}\n.m-left-sm {\n  margin-left: 10px;\n}\n.m-left-md {\n  margin-left: 20px;\n}\n.m-left-lg {\n  margin-left: 40px;\n}\n.m-right-xs {\n  margin-right: 5px;\n}\n.m-right-sm {\n  margin-right: 10px;\n}\n.m-right-md {\n  margin-right: 20px;\n}\n.m-right-lg {\n  margin-right: 40px;\n}\n.m-bottom-xs {\n  margin-bottom: 5px;\n}\n.m-bottom-sm {\n  margin-bottom: 10px;\n}\n.m-bottom-md {\n  margin-bottom: 20px;\n}\n.m-bottom-lg {\n  margin-bottom: 40px;\n}\n.m-bottom-none {\n  margin-bottom: 0;\n}\n.no-shadow {\n  box-shadow: none !important;\n  -moz-box-shadow: none !important;\n  -webkit-box-shadow: none !important;\n}\n.middle {\n  vertical-align: middle;\n}\n.rounded {\n  border-radius: 6px;\n  -moz-border-radius: 6px;\n  -webkit-border-radius: 6px;\n}\n.no-rounded {\n  border-radius: 0;\n  -moz-border-radius: 0;\n  -webkit-border-radius: 0;\n}\n.no-border {\n  border: none !important;\n}\n.border {\n  border: 1px solid #eee;\n}\n.border-top {\n  border-top: 1px solid #eee;\n}\n.border-left {\n  border-left: 1px solid #eee;\n}\n.border-right {\n  border-right: 1px solid #eee;\n}\n.border-bottom {\n  border-bottom: 1px solid #eee;\n}\n.font-14 {\n  font-size: 14px !important;\n}\n.font-15 {\n  font-size: 15px !important;\n}\n.font-16 {\n  font-size: 16px !important;\n}\n.font-normal {\n  font-weight: normal !important;\n}\n.width-100 {\n  width: 100%;\n}\n.box-sizing {\n  box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  -webkit-box-sizing: border-box;\n}\n.primary-font {\n  color: #3c8dbc;\n}\n.text-white {\n  color: #fff;\n}\n.text-primary {\n  color: #424f63;\n}\n.text-info {\n  color: #6bafbd;\n}\n.text-success {\n  color: #65cea7;\n}\n.text-warning {\n  color: #f3ce85;\n}\n.text-danger {\n  color: #fc8675;\n}\n.font-normal {\n  font-weight: normal !important;\n}\n.text-shadow-white {\n  text-shadow: 0 1px 0 #fff;\n}\n.bg-white {\n  background-color: #fff;\n}\n.bg-light {\n  background-color: #f1f5fc;\n}\n.bg-dark {\n  background-color: #222222;\n}\n.bg-grey {\n  background-color: #eeeeee;\n  text-shadow: 0 1px #fff;\n}\n.bg-primary {\n  background-color: #424f63;\n  color: #BECFDF;\n}\n.bg-primary a {\n  color: #BECFDF;\n}\n.bg-primary a:hover,\n.bg-primary a:focus {\n  color: #fff;\n}\n.bg-warning {\n  background-color: #f3ce85;\n  color: #fff;\n}\n.bg-info {\n  background-color: #6bafbd;\n  color: #fff;\n}\n.bg-success {\n  background-color: #65cea7;\n  color: #fff;\n}\n.bg-danger {\n  background-color: #fc8675 !important;\n  color: #fff !important;\n}\n.shadow-pulse {\n  animation: shadow-pulse 1s linear infinite;\n  -webkit-animation: shadow-pulse 1s linear infinite;\n  -moz-animation: shadow-pulse 1s linear infinite;\n  -ms-animation: shadow-pulse 1s linear infinite;\n  -o-animation: shadow-pulse 1s linear infinite;\n}\n.no-animation * {\n  animation: none !important;\n  -webkit-animation: none !important;\n  -moz-animation: none !important;\n  -ms-animation: none !important;\n  -o-animation: none !important;\n  transform: none !important;\n  -webkit-transform: none !important;\n  -moz-transform: none !important;\n  -ms-transform: none !important;\n  -o-transform: none !important;\n}\n.preload * {\n  animation: none !important;\n  -webkit-animation: none !important;\n  -moz-animation: none !important;\n  -ms-animation: none !important;\n  -o-animation: none !important;\n}\n.transition-delay1 {\n  transition-delay: 0.5s !important;\n  -webkit-transition-delay: 0.5s !important;\n  -moz-transition-delay: 0.5s !important;\n  -ms-transition-delay: 0.5s !important;\n  -o-transition-delay: 0.5s !important;\n}\n.transition-delay2 {\n  transition-delay: 1s !important;\n  -webkit-transition-delay: 1s !important;\n  -moz-transition-delay: 1s !important;\n  -ms-transition-delay: 1s !important;\n  -o-transition-delay: 1s !important;\n}\n.transition-delay3 {\n  transition-delay: 1.5s !important;\n  -webkit-transition-delay: 1.5s !important;\n  -moz-transition-delay: 1.5s !important;\n  -ms-transition-delay: 1.5s !important;\n  -o-transition-delay: 1.5s !important;\n}\n.fadeInUp {\n  animation-name: fadeInUp;\n  -webkit-animation-name: fadeInUp;\n  -moz-animation-name: fadeInUp;\n  -ms-animation-name: fadeInUp;\n  -o-animation-name: fadeInUp;\n  animation-duration: 1s;\n  -webkit-animation-duration: 1s;\n  -moz-animation-duration: 1s;\n  -ms-animation-duration: 1s;\n  -o-animation-duration: 1s;\n}\n.fadeInDown {\n  animation-name: fadeInDown;\n  -webkit-animation-name: fadeInDown;\n  -moz-animation-name: fadeInDown;\n  -ms-animation-name: fadeInDown;\n  -o-animation-name: fadeInDown;\n  animation-duration: 1s;\n  -webkit-animation-duration: 1s;\n  -moz-animation-duration: 1s;\n  -ms-animation-duration: 1s;\n  -o-animation-duration: 1s;\n}\n.fadeInLeft {\n  animation-name: fadeInLeft;\n  -webkit-animation-name: fadeInLeft;\n  -moz-animation-name: fadeInLeft;\n  -ms-animation-name: fadeInLeft;\n  -o-animation-name: fadeInLeft;\n  animation-duration: 1s;\n  -webkit-animation-duration: 1s;\n  -moz-animation-duration: 1s;\n  -ms-animation-duration: 1s;\n  -o-animation-duration: 1s;\n}\n.fadeInRight {\n  animation-name: fadeInRight;\n  -webkit-animation-name: fadeInRight;\n  -moz-animation-name: fadeInRight;\n  -ms-animation-name: fadeInRight;\n  -o-animation-name: fadeInRight;\n  animation-duration: 1s;\n  -webkit-animation-duration: 1s;\n  -moz-animation-duration: 1s;\n  -ms-animation-duration: 1s;\n  -o-animation-duration: 1s;\n}\n.fadeInUpLarge {\n  animation-name: fadeInUpLarge;\n  -webkit-animation-name: fadeInUpLarge;\n  -moz-animation-name: fadeInUpLarge;\n  -ms-animation-name: fadeInUpLarge;\n  -o-animation-name: fadeInUpLarge;\n  animation-duration: 1s;\n  -webkit-animation-duration: 1s;\n  -moz-animation-duration: 1s;\n  -ms-animation-duration: 1s;\n  -o-animation-duration: 1s;\n}\n.fadeInDownLarge {\n  animation-name: fadeInDownLarge;\n  -webkit-animation-name: fadeInDownLarge;\n  -moz-animation-name: fadeInDownLarge;\n  -ms-animation-name: fadeInDownLarge;\n  -o-animation-name: fadeInDownLarge;\n  animation-duration: 1s;\n  -webkit-animation-duration: 1s;\n  -moz-animation-duration: 1s;\n  -ms-animation-duration: 1s;\n  -o-animation-duration: 1s;\n}\n.fadeInLeftLarge {\n  animation-name: fadeInLeftLarge;\n  -webkit-animation-name: fadeInLeftLarge;\n  -moz-animation-name: fadeInLeftLarge;\n  -ms-animation-name: fadeInLeftLarge;\n  -o-animation-name: fadeInLeftLarge;\n  animation-duration: 1s;\n  -webkit-animation-duration: 1s;\n  -moz-animation-duration: 1s;\n  -ms-animation-duration: 1s;\n  -o-animation-duration: 1s;\n}\n.fadeInRightLarge {\n  animation-name: fadeInRightLarge;\n  -webkit-animation-name: fadeInRightLarge;\n  -moz-animation-name: fadeInRightLarge;\n  -ms-animation-name: fadeInRightLarge;\n  -o-animation-name: fadeInRightLarge;\n  animation-duration: 1s;\n  -webkit-animation-duration: 1s;\n  -moz-animation-duration: 1s;\n  -ms-animation-duration: 1s;\n  -o-animation-duration: 1s;\n}\n.bounceInDown {\n  animation-name: bounceInDown;\n  -webkit-animation-name: bounceInDown;\n  -moz-animation-name: bounceInDown;\n  -ms-animation-name: bounceInDown;\n  -o-animation-name: bounceInDown;\n  animation-duration: 1s;\n  -webkit-animation-duration: 1s;\n  -moz-animation-duration: 1s;\n  -ms-animation-duration: 1s;\n  -o-animation-duration: 1s;\n}\n.bounceIn {\n  animation-name: bounceIn;\n  -webkit-animation-name: bounceIn;\n  -moz-animation-name: bounceIn;\n  -ms-animation-name: bounceIn;\n  -o-animation-name: bounceIn;\n  animation-duration: 1s;\n  -webkit-animation-duration: 1s;\n  -moz-animation-duration: 1s;\n  -ms-animation-duration: 1s;\n  -o-animation-duration: 1s;\n}\n.flipInH {\n  animation-name: flipInH;\n  -webkit-animation-name: flipInH;\n  -moz-animation-name: flipInH;\n  -ms-animation-name: flipInH;\n  -o-animation-name: flipInH;\n  animation-duration: 1s;\n  -webkit-animation-duration: 1s;\n  -moz-animation-duration: 1s;\n  -ms-animation-duration: 1s;\n  -o-animation-duration: 1s;\n}\n.flipInV {\n  animation-name: flipInV;\n  -webkit-animation-name: flipInV;\n  -moz-animation-name: flipInV;\n  -ms-animation-name: flipInV;\n  -o-animation-name: flipInV;\n  animation-duration: 1s;\n  -webkit-animation-duration: 1s;\n  -moz-animation-duration: 1s;\n  -ms-animation-duration: 1s;\n  -o-animation-duration: 1s;\n}\n.animation-delay1 {\n  animation-delay: 0.1s;\n  -webkit-animation-delay: 0.1s;\n  -moz-animation-delay: 0.1s;\n  -ms-animation-delay: 0.1s;\n  -o-animation-delay: 0.1s;\n  animation-timing-function: ease;\n  -webkit-animation-timing-function: ease;\n  -moz-animation-timing-function: ease;\n  -ms-animation-timing-function: ease;\n  -o-animation-timing-function: ease;\n  animation-fill-mode: both;\n  -webkit-animation-fill-mode: both;\n  -moz-animation-fill-mode: both;\n  -ms-animation-fill-mode: both;\n  -o-animation-fill-mode: both;\n}\n.animation-delay2 {\n  animation-delay: 0.3s;\n  -webkit-animation-delay: 0.3s;\n  -moz-animation-delay: 0.3s;\n  -ms-animation-delay: 0.3s;\n  -o-animation-delay: 0.3s;\n  animation-timing-function: ease;\n  -webkit-animation-timing-function: ease;\n  -moz-animation-timing-function: ease;\n  -ms-animation-timing-function: ease;\n  -o-animation-timing-function: ease;\n  animation-fill-mode: both;\n  -webkit-animation-fill-mode: both;\n  -moz-animation-fill-mode: both;\n  -ms-animation-fill-mode: both;\n  -o-animation-fill-mode: both;\n}\n.animation-delay3 {\n  animation-delay: 0.5s;\n  -webkit-animation-delay: 0.5s;\n  -moz-animation-delay: 0.5s;\n  -ms-animation-delay: 0.5s;\n  -o-animation-delay: 0.5s;\n  animation-timing-function: ease;\n  -webkit-animation-timing-function: ease;\n  -moz-animation-timing-function: ease;\n  -ms-animation-timing-function: ease;\n  -o-animation-timing-function: ease;\n  animation-fill-mode: both;\n  -webkit-animation-fill-mode: both;\n  -moz-animation-fill-mode: both;\n  -ms-animation-fill-mode: both;\n  -o-animation-fill-mode: both;\n}\n.animation-delay4 {\n  animation-delay: 0.7s;\n  -webkit-animation-delay: 0.7s;\n  -moz-animation-delay: 0.7s;\n  -ms-animation-delay: 0.7s;\n  -o-animation-delay: 0.7s;\n  animation-timing-function: ease;\n  -webkit-animation-timing-function: ease;\n  -moz-animation-timing-function: ease;\n  -ms-animation-timing-function: ease;\n  -o-animation-timing-function: ease;\n  animation-fill-mode: both;\n  -webkit-animation-fill-mode: both;\n  -moz-animation-fill-mode: both;\n  -ms-animation-fill-mode: both;\n  -o-animation-fill-mode: both;\n}\n.animation-delay5 {\n  animation-delay: 0.9s;\n  -webkit-animation-delay: 0.9s;\n  -moz-animation-delay: 0.9s;\n  -ms-animation-delay: 0.9s;\n  -o-animation-delay: 0.9s;\n  animation-timing-function: ease;\n  -webkit-animation-timing-function: ease;\n  -moz-animation-timing-function: ease;\n  -ms-animation-timing-function: ease;\n  -o-animation-timing-function: ease;\n  animation-fill-mode: both;\n  -webkit-animation-fill-mode: both;\n  -moz-animation-fill-mode: both;\n  -ms-animation-fill-mode: both;\n  -o-animation-fill-mode: both;\n}\n.animation-delay6 {\n  animation-delay: 1.1s;\n  -webkit-animation-delay: 1.1s;\n  -moz-animation-delay: 1.1s;\n  -ms-animation-delay: 1.1s;\n  -o-animation-delay: 1.1s;\n  animation-timing-function: ease;\n  -webkit-animation-timing-function: ease;\n  -moz-animation-timing-function: ease;\n  -ms-animation-timing-function: ease;\n  -o-animation-timing-function: ease;\n  animation-fill-mode: both;\n  -webkit-animation-fill-mode: both;\n  -moz-animation-fill-mode: both;\n  -ms-animation-fill-mode: both;\n  -o-animation-fill-mode: both;\n}\n.animation-delay7 {\n  animation-delay: 1.3s;\n  -webkit-animation-delay: 1.3s;\n  -moz-animation-delay: 1.3s;\n  -ms-animation-delay: 1.3s;\n  -o-animation-delay: 1.3s;\n  animation-timing-function: ease;\n  -webkit-animation-timing-function: ease;\n  -moz-animation-timing-function: ease;\n  -ms-animation-timing-function: ease;\n  -o-animation-timing-function: ease;\n  animation-fill-mode: both;\n  -webkit-animation-fill-mode: both;\n  -moz-animation-fill-mode: both;\n  -ms-animation-fill-mode: both;\n  -o-animation-fill-mode: both;\n}\n.animation-delay8 {\n  animation-delay: 1.5s;\n  -webkit-animation-delay: 1.5s;\n  -moz-animation-delay: 1.5s;\n  -ms-animation-delay: 1.5s;\n  -o-animation-delay: 1.5s;\n  animation-timing-function: ease;\n  -webkit-animation-timing-function: ease;\n  -moz-animation-timing-function: ease;\n  -ms-animation-timing-function: ease;\n  -o-animation-timing-function: ease;\n  animation-fill-mode: both;\n  -webkit-animation-fill-mode: both;\n  -moz-animation-fill-mode: both;\n  -ms-animation-fill-mode: both;\n  -o-animation-fill-mode: both;\n}\n.animation-delay9 {\n  animation-delay: 1.7s;\n  -webkit-animation-delay: 1.7s;\n  -moz-animation-delay: 1.7s;\n  -ms-animation-delay: 1.7s;\n  -o-animation-delay: 1.7s;\n  animation-timing-function: ease;\n  -webkit-animation-timing-function: ease;\n  -moz-animation-timing-function: ease;\n  -ms-animation-timing-function: ease;\n  -o-animation-timing-function: ease;\n  animation-fill-mode: both;\n  -webkit-animation-fill-mode: both;\n  -moz-animation-fill-mode: both;\n  -ms-animation-fill-mode: both;\n  -o-animation-fill-mode: both;\n}\n.animation-delay10 {\n  animation-delay: 1.9s;\n  -webkit-animation-delay: 1.9s;\n  -moz-animation-delay: 1.9s;\n  -ms-animation-delay: 1.9s;\n  -o-animation-delay: 1.9s;\n  animation-timing-function: ease;\n  -webkit-animation-timing-function: ease;\n  -moz-animation-timing-function: ease;\n  -ms-animation-timing-function: ease;\n  -o-animation-timing-function: ease;\n  animation-fill-mode: both;\n  -webkit-animation-fill-mode: both;\n  -moz-animation-fill-mode: both;\n  -ms-animation-fill-mode: both;\n  -o-animation-fill-mode: both;\n}\n@-moz-keyframes bounce_followingBallsG {\n  0% {\n    left: 0px;\n    background-color: #000;\n  }\n  50% {\n    left: 236px;\n    background-color: #fff;\n  }\n  100% {\n    left: 0px;\n    background-color: #000;\n  }\n}\n@-webkit-keyframes bounce_followingBallsG {\n  0% {\n    left: 0px;\n    background-color: #000;\n  }\n  50% {\n    left: 236px;\n    background-color: #fff;\n  }\n  100% {\n    left: 0px;\n    background-color: #000;\n  }\n}\n@-ms-keyframes bounce_followingBallsG {\n  0% {\n    left: 0px;\n    background-color: #000;\n  }\n  50% {\n    left: 236px;\n    background-color: #fff;\n  }\n  100% {\n    left: 0px;\n    background-color: #000;\n  }\n}\n@-o-keyframes bounce_followingBallsG {\n  0% {\n    left: 0px;\n    background-color: #000;\n  }\n  50% {\n    left: 236px;\n    background-color: #fff;\n  }\n  100% {\n    left: 0px;\n    background-color: #000;\n  }\n}\n@keyframes bounce_followingBallsG {\n  0% {\n    left: 0px;\n    background-color: #000;\n  }\n  50% {\n    left: 236px;\n    background-color: #fff;\n  }\n  100% {\n    left: 0px;\n    background-color: #000;\n  }\n}\n@keyframes fadeInUp {\n  0% {\n    opacity: 0;\n    transform: translateY(20px);\n  }\n  100% {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n@-webkit-keyframes fadeInUp {\n  0% {\n    opacity: 0;\n    -webkit-transform: translateY(20px);\n  }\n  100% {\n    opacity: 1;\n    -webkit-transform: translateY(0);\n  }\n}\n@-moz-keyframes fadeInUp {\n  0% {\n    opacity: 0;\n    -moz-transform: translateY(20px);\n  }\n  100% {\n    opacity: 1;\n    -moz-transform: translateY(0px);\n  }\n}\n@-ms-keyframes fadeInUp {\n  0% {\n    opacity: 0;\n    -ms-transform: translateY(20px);\n  }\n  100% {\n    opacity: 1;\n    -ms-transform: translateY(0);\n  }\n}\n@-o-keyframes fadeInUp {\n  0% {\n    opacity: 0;\n    -o-transform: translateY(20px);\n  }\n  100% {\n    opacity: 1;\n    -o-transform: translateY(0);\n  }\n}\n@keyframes fadeInDown {\n  0% {\n    opacity: 0;\n    transform: translateY(-20px);\n  }\n  100% {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n@-webkit-keyframes fadeInDown {\n  0% {\n    opacity: 0;\n    -webkit-transform: translateY(-20px);\n  }\n  100% {\n    opacity: 1;\n    -webkit-transform: translateY(0);\n  }\n}\n@-moz-keyframes fadeInDown {\n  0% {\n    opacity: 0;\n    -moz-transform: translateY(-20px);\n  }\n  100% {\n    opacity: 1;\n    -moz-transform: translateY(0px);\n  }\n}\n@-ms-keyframes fadeInDown {\n  0% {\n    opacity: 0;\n    -ms-transform: translateY(-20px);\n  }\n  100% {\n    opacity: 1;\n    -ms-transform: translateY(0);\n  }\n}\n@-o-keyframes fadeInDown {\n  0% {\n    opacity: 0;\n    -o-transform: translateY(-20px);\n  }\n  100% {\n    opacity: 1;\n    -o-transform: translateY(0);\n  }\n}\n@keyframes fadeInLeft {\n  0% {\n    opacity: 0;\n    transform: translateX(20px);\n  }\n  100% {\n    opacity: 1;\n    transform: translateX(0);\n  }\n}\n@-webkit-keyframes fadeInLeft {\n  0% {\n    opacity: 0;\n    -webkit-transform: translateX(20px);\n  }\n  100% {\n    opacity: 1;\n    -webkit-transform: translateX(0);\n  }\n}\n@-moz-keyframes fadeInLeft {\n  0% {\n    opacity: 0;\n    -moz-transform: translateX(20px);\n  }\n  100% {\n    opacity: 1;\n    -moz-transform: translateX(0px);\n  }\n}\n@-ms-keyframes fadeInLeft {\n  0% {\n    opacity: 0;\n    -ms-transform: translateX(20px);\n  }\n  100% {\n    opacity: 1;\n    -ms-transform: translateX(0);\n  }\n}\n@-o-keyframes fadeInLeft {\n  0% {\n    opacity: 0;\n    -o-transform: translateX(20px);\n  }\n  100% {\n    opacity: 1;\n    -o-transform: translateX(0);\n  }\n}\n@keyframes fadeInRight {\n  0% {\n    opacity: 0;\n    transform: translateX(-20px);\n  }\n  100% {\n    opacity: 1;\n    transform: translateX(0);\n  }\n}\n@-webkit-keyframes fadeInRight {\n  0% {\n    opacity: 0;\n    -webkit-transform: translateX(-20px);\n  }\n  100% {\n    opacity: 1;\n    -webkit-transform: translateX(0);\n  }\n}\n@-moz-keyframes fadeInRight {\n  0% {\n    opacity: 0;\n    -moz-transform: translateX(-20px);\n  }\n  100% {\n    opacity: 1;\n    -moz-transform: translateX(0px);\n  }\n}\n@-ms-keyframes fadeInRight {\n  0% {\n    opacity: 0;\n    -ms-transform: translateX(-20px);\n  }\n  100% {\n    opacity: 1;\n    -ms-transform: translateX(0);\n  }\n}\n@-o-keyframes fadeInRight {\n  0% {\n    opacity: 0;\n    -o-transform: translateX(-20px);\n  }\n  100% {\n    opacity: 1;\n    -o-transform: translateX(0);\n  }\n}\n@keyframes fadeInUpLarge {\n  0% {\n    opacity: 0;\n    transform: translateY(50px);\n  }\n  100% {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n@-webkit-keyframes fadeInUpLarge {\n  0% {\n    opacity: 0;\n    -webkit-transform: translateY(50px);\n  }\n  100% {\n    opacity: 1;\n    -webkit-transform: translateY(0);\n  }\n}\n@-moz-keyframes fadeInUpLarge {\n  0% {\n    opacity: 0;\n    -moz-transform: translateY(50px);\n  }\n  100% {\n    opacity: 1;\n    -moz-transform: translateY(0px);\n  }\n}\n@-ms-keyframes fadeInUpLarge {\n  0% {\n    opacity: 0;\n    -ms-transform: translateY(50px);\n  }\n  100% {\n    opacity: 1;\n    -ms-transform: translateY(0);\n  }\n}\n@-o-keyframes fadeInUpLarge {\n  0% {\n    opacity: 0;\n    -o-transform: translateY(50px);\n  }\n  100% {\n    opacity: 1;\n    -o-transform: translateY(0);\n  }\n}\n@keyframes fadeInDownLarge {\n  0% {\n    opacity: 0;\n    transform: translateY(-50px);\n  }\n  100% {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n@-webkit-keyframes fadeInDownLarge {\n  0% {\n    opacity: 0;\n    -webkit-transform: translateY(-50px);\n  }\n  100% {\n    opacity: 1;\n    -webkit-transform: translateY(0);\n  }\n}\n@-moz-keyframes fadeInDownLarge {\n  0% {\n    opacity: 0;\n    -moz-transform: translateY(-50px);\n  }\n  100% {\n    opacity: 1;\n    -moz-transform: translateY(0px);\n  }\n}\n@-ms-keyframes fadeInDownLarge {\n  0% {\n    opacity: 0;\n    -ms-transform: translateY(-50px);\n  }\n  100% {\n    opacity: 1;\n    -ms-transform: translateY(0);\n  }\n}\n@-o-keyframes fadeInDownLarge {\n  0% {\n    opacity: 0;\n    -o-transform: translateY(-50px);\n  }\n  100% {\n    opacity: 1;\n    -o-transform: translateY(0);\n  }\n}\n@keyframes fadeInLeftLarge {\n  0% {\n    opacity: 0;\n    transform: translateX(100px);\n  }\n  100% {\n    opacity: 1;\n    transform: translateX(0);\n  }\n}\n@-webkit-keyframes fadeInLeftLarge {\n  0% {\n    opacity: 0;\n    -webkit-transform: translateX(100px);\n  }\n  100% {\n    opacity: 1;\n    -webkit-transform: translateX(0);\n  }\n}\n@-moz-keyframes fadeInLeftLarge {\n  0% {\n    opacity: 0;\n    -moz-transform: translateX(100px);\n  }\n  100% {\n    opacity: 1;\n    -moz-transform: translateX(0px);\n  }\n}\n@-ms-keyframes fadeInLeftLarge {\n  0% {\n    opacity: 0;\n    -ms-transform: translateX(100px);\n  }\n  100% {\n    opacity: 1;\n    -ms-transform: translateX(0);\n  }\n}\n@-o-keyframes fadeInLeftLarge {\n  0% {\n    opacity: 0;\n    -o-transform: translateX(100px);\n  }\n  100% {\n    opacity: 1;\n    -o-transform: translateX(0);\n  }\n}\n@keyframes fadeInRightLarge {\n  0% {\n    opacity: 0;\n    transform: translateX(-100px);\n  }\n  100% {\n    opacity: 1;\n    transform: translateX(0);\n  }\n}\n@-webkit-keyframes fadeInRightLarge {\n  0% {\n    opacity: 0;\n    -webkit-transform: translateX(-100px);\n  }\n  100% {\n    opacity: 1;\n    -webkit-transform: translateX(0);\n  }\n}\n@-moz-keyframes fadeInRightLarge {\n  0% {\n    opacity: 0;\n    -moz-transform: translateX(-100px);\n  }\n  100% {\n    opacity: 1;\n    -moz-transform: translateX(0px);\n  }\n}\n@-ms-keyframes fadeInRightLarge {\n  0% {\n    opacity: 0;\n    -ms-transform: translateX(-100px);\n  }\n  100% {\n    opacity: 1;\n    -ms-transform: translateX(0);\n  }\n}\n@-o-keyframes fadeInRightLarge {\n  0% {\n    opacity: 0;\n    -o-transform: translateX(-100px);\n  }\n  100% {\n    opacity: 1;\n    -o-transform: translateX(0);\n  }\n}\n@-webkit-keyframes slidedown {\n  0% {\n    max-height: 0;\n  }\n  100% {\n    max-height: 500px;\n  }\n}\n@-moz-keyframes slidedown {\n  0% {\n    max-height: 0;\n  }\n  100% {\n    max-height: 500px;\n  }\n}\n@-ms-keyframes slidedown {\n  0% {\n    max-height: 0;\n  }\n  100% {\n    max-height: 500px;\n  }\n}\n@-o-keyframes slidedown {\n  0% {\n    max-height: 0;\n  }\n  100% {\n    max-height: 500px;\n  }\n}\n@keyframes slidedown {\n  0% {\n    max-height: 0;\n  }\n  100% {\n    max-height: 500px;\n  }\n}\n@-webkit-keyframes fadeIn {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n@-moz-keyframes fadeIn {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n@-ms-keyframes fadeIn {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n@-o-keyframes fadeIn {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n@keyframes fadeIn {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n@-webkit-keyframes fadeInRotate {\n  0% {\n    opacity: 0;\n    -webkit-transform: translateX(-20px) rotate(-60deg);\n  }\n  100% {\n    opacity: 1;\n  }\n}\n@-moz-keyframes fadeInRotate {\n  0% {\n    opacity: 0;\n    -moz-transform: translateX(-20px) rotate(-60deg);\n  }\n  100% {\n    opacity: 1;\n  }\n}\n@-ms-keyframes fadeInRotate {\n  0% {\n    opacity: 0;\n    -ms-transform: translateX(-20px) rotate(-60deg);\n  }\n  100% {\n    opacity: 1;\n  }\n}\n@-o-keyframes fadeInRotate {\n  0% {\n    opacity: 0;\n    -o-transform: translateX(-20px) rotate(-60deg);\n  }\n  100% {\n    opacity: 1;\n  }\n}\n@keyframes fadeInRotate {\n  0% {\n    opacity: 0;\n    transform: translateX(-20px) rotate(-60deg);\n  }\n  100% {\n    opacity: 1;\n  }\n}\n@-webkit-keyframes fadeInUp100 {\n  0% {\n    opacity: 0;\n    -webkit-transform: translateY(100px) scale(0.6);\n  }\n  100% {\n    opacity: 1;\n  }\n}\n@-moz-keyframes fadeInUp100 {\n  0% {\n    opacity: 0;\n    -moz-transform: translateY(100px) scale(0.6);\n  }\n  100% {\n    opacity: 1;\n  }\n}\n@-ms-keyframes fadeInUp100 {\n  0% {\n    opacity: 0;\n    -ms-transform: translateY(100px) scale(0.6);\n  }\n  100% {\n    opacity: 1;\n  }\n}\n@-o-keyframes fadeInUp100 {\n  0% {\n    opacity: 0;\n    -o-transform: translateY(100px) scale(0.6);\n  }\n  100% {\n    opacity: 1;\n  }\n}\n@keyframes fadeInUp100 {\n  0% {\n    opacity: 0;\n    transform: translateY(100px) scale(0.6);\n  }\n  100% {\n    opacity: 1;\n  }\n}\n@-webkit-keyframes shadow-pulse {\n  0% {\n    box-shadow: 0 0 3px rgba(50, 50, 50, 0.5);\n    -moz-box-shadow: 0 0 3px rgba(50, 50, 50, 0.5);\n    -webkit-box-shadow: 0 0 3px rgba(50, 50, 50, 0.5);\n  }\n  50% {\n    box-shadow: 0 0 6px #323232;\n    -moz-box-shadow: 0 0 6px #323232;\n    -webkit-box-shadow: 0 0 6px #323232;\n  }\n  100% {\n    box-shadow: 0 0 3px rgba(50, 50, 50, 0.5);\n    -moz-box-shadow: 0 0 3px rgba(50, 50, 50, 0.5);\n    -webkit-box-shadow: 0 0 3px rgba(50, 50, 50, 0.5);\n  }\n}\n@-moz-keyframes shadow-pulse {\n  0% {\n    box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n    -moz-box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n    -webkit-box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n  }\n  50% {\n    box-shadow: 0 0 6px #323232;\n    -moz-box-shadow: 0 0 6px #323232;\n    -webkit-box-shadow: 0 0 6px #323232;\n  }\n  100% {\n    box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n    -moz-box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n    -webkit-box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n  }\n}\n@-ms-keyframes shadow-pulse {\n  0% {\n    box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n    -moz-box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n    -webkit-box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n  }\n  50% {\n    box-shadow: 0 0 6px #323232;\n    -moz-box-shadow: 0 0 6px #323232;\n    -webkit-box-shadow: 0 0 6px #323232;\n  }\n  100% {\n    box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n    -moz-box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n    -webkit-box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n  }\n}\n@-o-keyframes shadow-pulse {\n  0% {\n    box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n    -moz-box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n    -webkit-box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n  }\n  50% {\n    box-shadow: 0 0 6px #323232;\n    -moz-box-shadow: 0 0 6px #323232;\n    -webkit-box-shadow: 0 0 6px #323232;\n  }\n  100% {\n    box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n    -moz-box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n    -webkit-box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n  }\n}\n@keyframes shadow-pulse {\n  0% {\n    box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n    -moz-box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n    -webkit-box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n  }\n  50% {\n    box-shadow: 0 0 6px #323232;\n    -moz-box-shadow: 0 0 6px #323232;\n    -webkit-box-shadow: 0 0 6px #323232;\n  }\n  100% {\n    box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n    -moz-box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n    -webkit-box-shadow: 0 0 3px rgba(50, 50, 50, 0);\n  }\n}\n@keyframes text-moving {\n  0% {\n    left: 110%;\n  }\n  40% {\n    left: 0%;\n  }\n  50% {\n    left: 0%;\n  }\n  60% {\n    left: 0%;\n  }\n  70% {\n    left: 0%;\n  }\n  100% {\n    left: -150%;\n  }\n}\n@-webkit-keyframes text-moving {\n  0% {\n    left: 110%;\n  }\n  40% {\n    left: 0%;\n  }\n  50% {\n    left: 0%;\n  }\n  60% {\n    left: 0%;\n  }\n  70% {\n    left: 0%;\n  }\n  100% {\n    left: -150%;\n  }\n}\n@-moz-keyframes text-moving {\n  0% {\n    left: 110%;\n  }\n  40% {\n    left: 0%;\n  }\n  50% {\n    left: 0%;\n  }\n  60% {\n    left: 0%;\n  }\n  70% {\n    left: 0%;\n  }\n  100% {\n    left: -150%;\n  }\n}\n@-ms-keyframes text-moving {\n  0% {\n    left: 110%;\n  }\n  40% {\n    left: 0%;\n  }\n  50% {\n    left: 0%;\n  }\n  60% {\n    left: 0%;\n  }\n  70% {\n    left: 0%;\n  }\n  100% {\n    left: -150%;\n  }\n}\n@-o-keyframes text-moving {\n  0% {\n    left: 110%;\n  }\n  40% {\n    left: 0%;\n  }\n  50% {\n    left: 0%;\n  }\n  60% {\n    left: 0%;\n  }\n  70% {\n    left: 0%;\n  }\n  100% {\n    left: -150%;\n  }\n}\n@-webkit-keyframes bounceIn {\n  0% {\n    opacity: 0;\n    -webkit-transform: scale(0.7);\n  }\n  50% {\n    opacity: 1;\n    -webkit-transform: scale(1.05);\n  }\n  100% {\n    -webkit-transform: scale(1);\n  }\n}\n@-moz-keyframes bounceIn {\n  0% {\n    opacity: 0;\n    -moz-transform: scale(0.7);\n  }\n  50% {\n    opacity: 1;\n    -moz-transform: scale(1.05);\n  }\n  100% {\n    -moz-transform: scale(1);\n  }\n}\n@-ms-keyframes bounceIn {\n  0% {\n    opacity: 0;\n    -ms-transform: scale(0.7);\n  }\n  50% {\n    opacity: 1;\n    -ms-transform: scale(1.1);\n  }\n  100% {\n    -ms-transform: scale(1);\n  }\n}\n@-o-keyframes bounceIn {\n  0% {\n    opacity: 0;\n    -o-transform: scale(0.7);\n  }\n  50% {\n    opacity: 1;\n    -o-transform: scale(1.1);\n  }\n  100% {\n    -o-transform: scale(1);\n  }\n}\n@keyframes bounceIn {\n  0% {\n    opacity: 0;\n    transform: scale(0.7);\n  }\n  50% {\n    opacity: 1;\n    transform: scale(1.1);\n  }\n  100% {\n    transform: scale(1);\n  }\n}\n@-webkit-keyframes bounceInDown {\n  0% {\n    opacity: 0;\n    -webkit-transform: translateY(-1000px);\n  }\n  60% {\n    opacity: 1;\n    -webkit-transform: translateY(30px);\n  }\n  80% {\n    -webkit-transform: translateY(-20px);\n  }\n  100% {\n    -webkit-transform: translateY(0);\n  }\n}\n@-moz-keyframes bounceInDown {\n  0% {\n    opacity: 0;\n    -moz-transform: translateY(-1000px);\n  }\n  60% {\n    opacity: 1;\n    -moz-transform: translateY(30px);\n  }\n  80% {\n    -moz-transform: translateY(-20%);\n  }\n  100% {\n    -moz-transform: translateY(0);\n  }\n}\n@-ms-keyframes bounceInDown {\n  0% {\n    opacity: 0;\n    -ms-transform: translateY(-1000px);\n  }\n  60% {\n    opacity: 1;\n    -ms-transform: translateY(30px);\n  }\n  80% {\n    -ms-transform: translateY(-20px);\n  }\n  100% {\n    -ms-transform: translateY(0);\n  }\n}\n@-o-keyframes bounceInDown {\n  0% {\n    opacity: 0;\n    -o-transform: translateY(-1000px);\n  }\n  60% {\n    opacity: 1;\n    -o-transform: translateY(30px);\n  }\n  80% {\n    -o-transform: translateY(-20%);\n  }\n  100% {\n    -o-transform: translateY(0);\n  }\n}\n@keyframes bounceInDown {\n  0% {\n    opacity: 0;\n    transform: translateY(-1000px);\n  }\n  60% {\n    opacity: 1;\n    transform: translateY(30px);\n  }\n  80% {\n    transform: translateY(-20px);\n  }\n  100% {\n    transform: translateY(0);\n  }\n}\n@-webkit-keyframes bounceInDownSmall {\n  0% {\n    opacity: 0;\n    -webkit-transform: translateY(-100px);\n  }\n  60% {\n    opacity: 1;\n    -webkit-transform: translateY(20px);\n  }\n  100% {\n    -webkit-transform: translateY(0);\n  }\n}\n@-moz-keyframes bounceInDownSmall {\n  0% {\n    opacity: 0;\n    -moz-transform: translateY(-100px);\n  }\n  60% {\n    opacity: 1;\n    -moz-transform: translateY(20px);\n  }\n  100% {\n    -moz-transform: translateY(0);\n  }\n}\n@-ms-keyframes bounceInDownSmall {\n  0% {\n    opacity: 0;\n    -ms-transform: translateY(-100px);\n  }\n  60% {\n    opacity: 1;\n    -ms-transform: translateY(20px);\n  }\n  100% {\n    -ms-transform: translateY(0);\n  }\n}\n@-o-keyframes bounceInDownSmall {\n  0% {\n    opacity: 0;\n    -o-transform: translateY(-100px);\n  }\n  60% {\n    opacity: 1;\n    -o-transform: translateY(20px);\n  }\n  100% {\n    -o-transform: translateY(0);\n  }\n}\n@keyframes bounceInDownSmall {\n  0% {\n    opacity: 0;\n    transform: translateY(-100px);\n  }\n  60% {\n    opacity: 1;\n    transform: translateY(20px);\n  }\n  100% {\n    transform: translateY(0);\n  }\n}\n@-webkit-keyframes fadeOutUp {\n  0% {\n    opacity: 1;\n    -webkit-transform: translateY(0);\n  }\n  50% {\n    -webkit-transform: translateY(-40px);\n  }\n  100% {\n    opacity: 0;\n    -webkit-transform: translateY(-50px);\n  }\n}\n@-moz-keyframes fadeOutUp {\n  0% {\n    opacity: 1;\n    -moz-transform: translateY(0);\n  }\n  50% {\n    -moz-transform: translateY(-40px);\n  }\n  100% {\n    opacity: 0;\n    -moz-transform: translateY(-50px);\n  }\n}\n@-ms-keyframes fadeOutUp {\n  0% {\n    opacity: 1;\n    -ms-transform: translateY(0);\n  }\n  50% {\n    -ms-transform: translateY(-40px);\n  }\n  100% {\n    opacity: 0;\n    -ms-transform: translateY(-50px);\n  }\n}\n@-o-keyframes fadeOutUp {\n  0% {\n    opacity: 1;\n    -o-transform: translateY(0);\n  }\n  50% {\n    -o-transform: translateY(-40px);\n  }\n  100% {\n    opacity: 0;\n    -o-transform: translateY(-50px);\n  }\n}\n@keyframes fadeOutUp {\n  0% {\n    opacity: 1;\n    transform: translateY(0);\n  }\n  50% {\n    transform: translateY(-40px);\n  }\n  100% {\n    opacity: 0;\n    transform: translateY(-50px);\n  }\n}\n@-webkit-keyframes progress-start {\n  0% {\n    width: 0;\n  }\n}\n@-moz-keyframes progress-start {\n  0% {\n    width: 0;\n  }\n}\n@-ms-keyframes progress-start {\n  0% {\n    width: 0;\n  }\n}\n@-o-keyframes progress-start {\n  0% {\n    width: 0;\n  }\n}\n@keyframes progress-start {\n  0% {\n    width: 0;\n  }\n}\n@-webkit-keyframes flipInH {\n  0% {\n    -webkit-transform: perspective(1000px) rotateY(90deg);\n    opacity: 0;\n  }\n  33% {\n    -webkit-transform: perspective(1000px) rotateY(-10deg);\n  }\n  66% {\n    -webkit-transform: perspective(1000px) rotateY(10deg);\n  }\n  100% {\n    -webkit-transform: perspective(1000px) rotateY(0deg);\n    opacity: 1;\n  }\n}\n@-moz-keyframes flipInH {\n  0% {\n    -moz-transform: perspective(1000px) rotateY(90deg);\n    opacity: 0;\n  }\n  33% {\n    -moz-transform: perspective(1000px) rotateY(-10deg);\n  }\n  66% {\n    -moz-transform: perspective(1000px) rotateY(10deg);\n  }\n  100% {\n    -moz-transform: perspective(1000px) rotateY(0deg);\n    opacity: 1;\n  }\n}\n@-ms-keyframes flipInH {\n  0% {\n    -ms-transform: perspective(1000px) rotateY(90deg);\n    opacity: 0;\n  }\n  33% {\n    -ms-transform: perspective(1000px) rotateY(-10deg);\n  }\n  66% {\n    -ms-transform: perspective(1000px) rotateY(10deg);\n  }\n  100% {\n    -ms-transform: perspective(1000px) rotateY(0deg);\n    opacity: 1;\n  }\n}\n@-o-keyframes flipInH {\n  0% {\n    -o-transform: perspective(1000px) rotateY(90deg);\n    opacity: 0;\n  }\n  33% {\n    -o-transform: perspective(1000px) rotateY(-10deg);\n  }\n  66% {\n    -o-transform: perspective(1000px) rotateY(10deg);\n  }\n  100% {\n    -o-transform: perspective(1000px) rotateY(0deg);\n    opacity: 1;\n  }\n}\n@keyframes flipInH {\n  0% {\n    transform: perspective(1000px) rotateY(90deg);\n    opacity: 0;\n  }\n  33% {\n    transform: perspective(1000px) rotateY(-10deg);\n  }\n  66% {\n    transform: perspective(1000px) rotateY(10deg);\n  }\n  100% {\n    transform: perspective(1000px) rotateY(0deg);\n    opacity: 1;\n  }\n}\n@-webkit-keyframes flipInV {\n  0% {\n    -webkit-transform: perspective(1000px) rotateX(90deg);\n    opacity: 0;\n  }\n  33% {\n    -webkit-transform: perspective(1000px) rotateX(-10deg);\n  }\n  66% {\n    -webkit-transform: perspective(1000px) rotateX(10deg);\n  }\n  100% {\n    -webkit-transform: perspective(1000px) rotateX(0deg);\n    opacity: 1;\n  }\n}\n@-moz-keyframes flipInV {\n  0% {\n    -moz-transform: perspective(1000px) rotateX(90deg);\n    opacity: 0;\n  }\n  33% {\n    -moz-transform: perspective(1000px) rotateX(-10deg);\n  }\n  66% {\n    -moz-transform: perspective(1000px) rotateX(10deg);\n  }\n  100% {\n    -moz-transform: perspective(1000px) rotateX(0deg);\n    opacity: 1;\n  }\n}\n@-ms-keyframes flipInV {\n  0% {\n    -ms-transform: perspective(1000px) rotateX(90deg);\n    opacity: 0;\n  }\n  33% {\n    -ms-transform: perspective(1000px) rotateX(-10deg);\n  }\n  66% {\n    -ms-transform: perspective(1000px) rotateX(10deg);\n  }\n  100% {\n    -ms-transform: perspective(1000px) rotateX(0deg);\n    opacity: 1;\n  }\n}\n@-o-keyframes flipInV {\n  0% {\n    -o-transform: perspective(1000px) rotateX(90deg);\n    opacity: 0;\n  }\n  33% {\n    -o-transform: perspective(1000px) rotateX(-10deg);\n  }\n  66% {\n    -o-transform: perspective(1000px) rotateX(10deg);\n  }\n  100% {\n    -o-transform: perspective(1000px) rotateX(0deg);\n    opacity: 1;\n  }\n}\n@keyframes flipInV {\n  0% {\n    transform: perspective(1000px) rotateX(90deg);\n    opacity: 0;\n  }\n  33% {\n    transform: perspective(1000px) rotateX(-10deg);\n  }\n  66% {\n    transform: perspective(1000px) rotateX(10deg);\n  }\n  100% {\n    transform: perspective(1000px) rotateX(0deg);\n    opacity: 1;\n  }\n}\n@-webkit-keyframes text-color-animation {\n  50% {\n    color: #fff;\n  }\n}\n@-moz-keyframes text-color-animation {\n  50% {\n    color: #fff;\n  }\n}\n@-ms-keyframes text-color-animation {\n  50% {\n    color: #fff;\n  }\n}\n@-o-keyframes text-color-animation {\n  50% {\n    color: #fff;\n  }\n}\n@keyframes text-color-animation {\n  50% {\n    color: #fff;\n  }\n}\n"
  },
  {
    "path": "static/template/css/fullcalendar.css",
    "content": "/*!\n * FullCalendar v1.6.0 Stylesheet\n * Docs & License: http://arshaw.com/fullcalendar/\n * (c) 2013 Adam Shaw\n */\n\n\n.fc {\n\tdirection: ltr;\n\ttext-align: left;\n\t}\n\t\n.fc table {\n\tborder-collapse: collapse;\n\tborder-spacing: 0;\n\t}\n\t\nhtml .fc,\n.fc table {\n\tfont-size: 1em;\n\t}\n\t\n.fc td,\n.fc th {\n\tpadding: 0;\n\tvertical-align: top;\n\t}\n\n\n\n/* Header\n------------------------------------------------------------------------*/\n\n.fc-header td {\n\twhite-space: nowrap;\n\t}\n\n.fc-header-left {\n\twidth: 25%;\n\ttext-align: left;\n\t}\n\t\n.fc-header-center {\n\ttext-align: center;\n\t}\n\t\n.fc-header-right {\n\twidth: 25%;\n\ttext-align: right;\n\t}\n\t\n.fc-header-title {\n\tdisplay: inline-block;\n\tvertical-align: top;\n\t}\n\t\n.fc-header-title h2 {\n\tmargin-top: 0;\n\twhite-space: nowrap;\n\t}\n\t\n.fc .fc-header-space {\n\tpadding-left: 10px;\n\t}\n\t\n.fc-header .fc-button {\n\tmargin-bottom: 1em;\n\tvertical-align: top;\n\t}\n\t\n/* buttons edges butting together */\n\n.fc-header .fc-button {\n\tmargin-right: -1px;\n\t}\n\t\n.fc-header .fc-corner-right,  /* non-theme */\n.fc-header .ui-corner-right { /* theme */\n\tmargin-right: 0; /* back to normal */\n\t}\n\t\n/* button layering (for border precedence) */\n\t\n.fc-header .fc-state-hover,\n.fc-header .ui-state-hover {\n\tz-index: 2;\n\t}\n\t\n.fc-header .fc-state-down {\n\tz-index: 3;\n\t}\n\n.fc-header .fc-state-active,\n.fc-header .ui-state-active {\n\tz-index: 4;\n\t}\n\t\n\t\n\t\n/* Content\n------------------------------------------------------------------------*/\n\t\n.fc-content {\n\tclear: both;\n\t}\n\t\n.fc-view {\n\twidth: 100%; /* needed for view switching (when view is absolute) */\n\toverflow: hidden;\n\t}\n\t\n\t\n\n/* Cell Styles\n------------------------------------------------------------------------*/\n\n.fc-widget-header,    /* <th>, usually */\n.fc-widget-content {  /* <td>, usually */\n\tborder: 1px solid #ddd;\n\t}\n\t\n.fc-state-highlight { /* <td> today cell */ /* TODO: add .fc-today to <th> */\n\tbackground: #F2F5A9;\n\t}\n\t\n.fc-cell-overlay { /* semi-transparent rectangle while dragging */\n\tbackground: #bce8f1;\n\topacity: .3;\n\tfilter: alpha(opacity=30); /* for IE */\n\t}\n\t\n\n\n/* Buttons\n------------------------------------------------------------------------*/\n\n.fc-button {\n\tposition: relative;\n\tdisplay: inline-block;\n\tpadding: 0 .6em;\n\toverflow: hidden;\n\theight: 1.9em;\n\tline-height: 1.9em;\n\twhite-space: nowrap;\n\tcursor: pointer;\n\t}\n\t\n.fc-state-default { /* non-theme */\n\tborder: 1px solid;\n\t}\n\n.fc-state-default.fc-corner-left { /* non-theme */\n\tborder-top-left-radius: 4px;\n\tborder-bottom-left-radius: 4px;\n\t}\n\n.fc-state-default.fc-corner-right { /* non-theme */\n\tborder-top-right-radius: 4px;\n\tborder-bottom-right-radius: 4px;\n\t}\n\n/*\n\tOur default prev/next buttons use HTML entities like &lsaquo; &rsaquo; &laquo; &raquo;\n\tand we'll try to make them look good cross-browser.\n*/\n\n.fc-text-arrow {\n\tmargin: 0 .1em;\n\tfont-size: 2em;\n\tfont-family: \"Courier New\", Courier, monospace;\n\tvertical-align: baseline; /* for IE7 */\n\t}\n\n.fc-button-prev .fc-text-arrow,\n.fc-button-next .fc-text-arrow { /* for &lsaquo; &rsaquo; */\n\tfont-weight: bold;\n\t}\n\t\n/* icon (for jquery ui) */\n\t\n.fc-button .fc-icon-wrap {\n\tposition: relative;\n\tfloat: left;\n\ttop: 50%;\n\t}\n\t\n.fc-button .ui-icon {\n\tposition: relative;\n\tfloat: left;\n\tmargin-top: -50%;\n\t*margin-top: 0;\n\t*top: -50%;\n\t}\n\t\n/*\n  button states\n  borrowed from twitter bootstrap (http://twitter.github.com/bootstrap/)\n*/\n\n.fc-state-default {\n\tbackground-color: #f5f5f5;\n\tbackground-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);\n\tbackground-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));\n\tbackground-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);\n\tbackground-image: -o-linear-gradient(top, #ffffff, #e6e6e6);\n\tbackground-image: linear-gradient(to bottom, #ffffff, #e6e6e6);\n\tbackground-repeat: repeat-x;\n\tborder-color: #e6e6e6 #e6e6e6 #bfbfbf;\n\tborder-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n\tcolor: #333;\n\ttext-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);\n\tbox-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);\n\t}\n\n.fc-state-hover,\n.fc-state-down,\n.fc-state-active,\n.fc-state-disabled {\n\tcolor: #333333;\n\tbackground-color: #e6e6e6;\n\t}\n\n.fc-state-hover {\n\tcolor: #333333;\n\ttext-decoration: none;\n\tbackground-position: 0 -15px;\n\t-webkit-transition: background-position 0.1s linear;\n\t   -moz-transition: background-position 0.1s linear;\n\t     -o-transition: background-position 0.1s linear;\n\t        transition: background-position 0.1s linear;\n\t}\n\n.fc-state-down,\n.fc-state-active {\n\tbackground-color: #cccccc;\n\tbackground-image: none;\n\toutline: 0;\n\tbox-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);\n\t}\n\n.fc-state-disabled {\n\tcursor: default;\n\tbackground-image: none;\n\topacity: 0.65;\n\tfilter: alpha(opacity=65);\n\tbox-shadow: none;\n\t}\n\n\t\n\n/* Global Event Styles\n------------------------------------------------------------------------*/\n\t \n.fc-event {\n\tborder: 1px solid #81DAF5; /* default BORDER color */\n\tbackground-color: #81DAF5; /* default BACKGROUND color */\n\tcolor: #fff;               /* default TEXT color */\n\ttext-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n\tfont-size: .85em;\n\tcursor: default;\n\t}\n\na.fc-event {\n\ttext-decoration: none;\n\t}\n\t\na.fc-event,\n.fc-event-draggable {\n\tcursor: pointer;\n\t}\n\t\n.fc-rtl .fc-event {\n\ttext-align: right;\n\t}\n\n.fc-event-inner {\n\twidth: 100%;\n\toverflow: hidden;\n\t}\n\t\n.fc-event-time,\n.fc-event-title {\n\tpadding: 0 1px;\n\t}\n\t\n.fc .ui-resizable-handle {\n\tdisplay: block;\n\tposition: absolute;\n\tz-index: 99999;\n\toverflow: hidden; /* hacky spaces (IE6/7) */\n\tfont-size: 300%;  /* */\n\tline-height: 50%; /* */\n\t}\n\t\n\t\n\t\n/* Horizontal Events\n------------------------------------------------------------------------*/\n\n.fc-event-hori {\n\tborder-width: 1px 0;\n\tmargin-bottom: 1px;\n\t}\n\n.fc-ltr .fc-event-hori.fc-event-start,\n.fc-rtl .fc-event-hori.fc-event-end {\n\tborder-left-width: 1px;\n\tborder-top-left-radius: 3px;\n\tborder-bottom-left-radius: 3px;\n\t}\n\n.fc-ltr .fc-event-hori.fc-event-end,\n.fc-rtl .fc-event-hori.fc-event-start {\n\tborder-right-width: 1px;\n\tborder-top-right-radius: 3px;\n\tborder-bottom-right-radius: 3px;\n\t}\n\t\n/* resizable */\n\t\n.fc-event-hori .ui-resizable-e {\n\ttop: 0           !important; /* importants override pre jquery ui 1.7 styles */\n\tright: -3px      !important;\n\twidth: 7px       !important;\n\theight: 100%     !important;\n\tcursor: e-resize;\n\t}\n\t\n.fc-event-hori .ui-resizable-w {\n\ttop: 0           !important;\n\tleft: -3px       !important;\n\twidth: 7px       !important;\n\theight: 100%     !important;\n\tcursor: w-resize;\n\t}\n\t\n.fc-event-hori .ui-resizable-handle {\n\t_padding-bottom: 14px; /* IE6 had 0 height */\n\t}\n\t\n\t\n\t\n/* Reusable Separate-border Table\n------------------------------------------------------------*/\n\ntable.fc-border-separate {\n\tborder-collapse: separate;\n\t}\n\t\n.fc-border-separate th,\n.fc-border-separate td {\n\tborder-width: 1px 0 0 1px;\n\t}\n\t\n.fc-border-separate th.fc-last,\n.fc-border-separate td.fc-last {\n\tborder-right-width: 1px;\n\t}\n\t\n.fc-border-separate tr.fc-last th,\n.fc-border-separate tr.fc-last td {\n\tborder-bottom-width: 1px;\n\t}\n\t\n.fc-border-separate tbody tr.fc-first td,\n.fc-border-separate tbody tr.fc-first th {\n\tborder-top-width: 0;\n\t}\n\t\n\t\n\n/* Month View, Basic Week View, Basic Day View\n------------------------------------------------------------------------*/\n\n.fc-grid th {\n\ttext-align: center;\n\t}\n\n.fc .fc-week-number {\n\twidth: 22px;\n\ttext-align: center;\n\t}\n\n.fc .fc-week-number div {\n\tpadding: 0 2px;\n\t}\n\t\n.fc-grid .fc-day-number {\n\tfloat: right;\n\tpadding: 0 2px;\n\t}\n\t\n.fc-grid .fc-other-month .fc-day-number {\n\topacity: 0.3;\n\tfilter: alpha(opacity=30); /* for IE */\n\t/* opacity with small font can sometimes look too faded\n\t   might want to set the 'color' property instead\n\t   making day-numbers bold also fixes the problem */\n\t}\n\t\n.fc-grid .fc-day-content {\n\tclear: both;\n\tpadding: 2px 2px 1px; /* distance between events and day edges */\n\t}\n\t\n/* event styles */\n\t\n.fc-grid .fc-event-time {\n\tfont-weight: bold;\n\t}\n\t\n/* right-to-left */\n\t\n.fc-rtl .fc-grid .fc-day-number {\n\tfloat: left;\n\t}\n\t\n.fc-rtl .fc-grid .fc-event-time {\n\tfloat: right;\n\t}\n\t\n\t\n\n/* Agenda Week View, Agenda Day View\n------------------------------------------------------------------------*/\n\n.fc-agenda table {\n\tborder-collapse: separate;\n\t}\n\t\n.fc-agenda-days th {\n\ttext-align: center;\n\t}\n\t\n.fc-agenda .fc-agenda-axis {\n\twidth: 50px;\n\tpadding: 0 4px;\n\tvertical-align: middle;\n\ttext-align: right;\n\twhite-space: nowrap;\n\tfont-weight: normal;\n\t}\n\n.fc-agenda .fc-week-number {\n\tfont-weight: bold;\n\t}\n\t\n.fc-agenda .fc-day-content {\n\tpadding: 2px 2px 1px;\n\t}\n\t\n/* make axis border take precedence */\n\t\n.fc-agenda-days .fc-agenda-axis {\n\tborder-right-width: 1px;\n\t}\n\t\n.fc-agenda-days .fc-col0 {\n\tborder-left-width: 0;\n\t}\n\t\n/* all-day area */\n\t\n.fc-agenda-allday th {\n\tborder-width: 0 1px;\n\t}\n\t\n.fc-agenda-allday .fc-day-content {\n\tmin-height: 34px; /* TODO: doesnt work well in quirksmode */\n\t_height: 34px;\n\t}\n\t\n/* divider (between all-day and slots) */\n\t\n.fc-agenda-divider-inner {\n\theight: 2px;\n\toverflow: hidden;\n\t}\n\t\n.fc-widget-header .fc-agenda-divider-inner {\n\tbackground: #eee;\n\t}\n\t\n/* slot rows */\n\t\n.fc-agenda-slots th {\n\tborder-width: 1px 1px 0;\n\t}\n\t\n.fc-agenda-slots td {\n\tborder-width: 1px 0 0;\n\tbackground: none;\n\t}\n\t\n.fc-agenda-slots td div {\n\theight: 20px;\n\t}\n\t\n.fc-agenda-slots tr.fc-slot0 th,\n.fc-agenda-slots tr.fc-slot0 td {\n\tborder-top-width: 0;\n\t}\n\n.fc-agenda-slots tr.fc-minor th,\n.fc-agenda-slots tr.fc-minor td {\n\tborder-top-style: dotted;\n\t}\n\t\n.fc-agenda-slots tr.fc-minor th.ui-widget-header {\n\t*border-top-style: solid; /* doesn't work with background in IE6/7 */\n\t}\n\t\n\n\n/* Vertical Events\n------------------------------------------------------------------------*/\n\n.fc-event-vert {\n\tborder-width: 0 1px;\n\t}\n\n.fc-event-vert.fc-event-start {\n\tborder-top-width: 1px;\n\tborder-top-left-radius: 3px;\n\tborder-top-right-radius: 3px;\n\t}\n\n.fc-event-vert.fc-event-end {\n\tborder-bottom-width: 1px;\n\tborder-bottom-left-radius: 3px;\n\tborder-bottom-right-radius: 3px;\n\t}\n\t\n.fc-event-vert .fc-event-time {\n\twhite-space: nowrap;\n\tfont-size: 10px;\n\t}\n\n.fc-event-vert .fc-event-inner {\n\tposition: relative;\n\tz-index: 2;\n\t}\n\t\n.fc-event-vert .fc-event-bg { /* makes the event lighter w/ a semi-transparent overlay  */\n\tposition: absolute;\n\tz-index: 1;\n\ttop: 0;\n\tleft: 0;\n\twidth: 100%;\n\theight: 100%;\n\tbackground: #fff;\n\topacity: .3;\n\tfilter: alpha(opacity=30);\n\t}\n\t\n.fc .ui-draggable-dragging .fc-event-bg, /* TODO: something nicer like .fc-opacity */\n.fc-select-helper .fc-event-bg {\n\tdisplay: none\\9; /* for IE6/7/8. nested opacity filters while dragging don't work */\n\t}\n\t\n/* resizable */\n\t\n.fc-event-vert .ui-resizable-s {\n\tbottom: 0        !important; /* importants override pre jquery ui 1.7 styles */\n\twidth: 100%      !important;\n\theight: 8px      !important;\n\toverflow: hidden !important;\n\tline-height: 8px !important;\n\tfont-size: 11px  !important;\n\tfont-family: monospace;\n\ttext-align: center;\n\tcursor: s-resize;\n\t}\n\t\n.fc-agenda .ui-resizable-resizing { /* TODO: better selector */\n\t_overflow: hidden;\n\t}\n\t\n\t\n"
  },
  {
    "path": "static/template/css/gritter/jquery.gritter.css",
    "content": "/* the norm */\n#gritter-notice-wrapper {\n\tposition:fixed;\n\ttop:20px;\n\tright:20px;\n\twidth:301px;\n\tz-index:9999;\n}\n#gritter-notice-wrapper.top-left {\n    left: 20px;\n    right: auto;\n}\n#gritter-notice-wrapper.bottom-right {\n    top: auto;\n    left: auto;\n    bottom: 20px;\n    right: 20px;\n}\n#gritter-notice-wrapper.bottom-left {\n    top: auto;\n    right: auto;\n    bottom: 20px;\n    left: 20px;\n}\n.gritter-item-wrapper {\n\tposition:relative;\n\tmargin:0 0 10px 0;\n\tbackground:url('images/ie-spacer.gif'); /* ie7/8 fix */ \n}\n.gritter-top {\n\tbackground:url(images/gritter.png) no-repeat left -30px;\n\theight:10px;\n}\n.hover .gritter-top {\n\tbackground-position:right -30px;\n}\n.gritter-bottom {\n\tbackground:url(images/gritter.png) no-repeat left bottom;\n\theight:8px;\n\tmargin:0;\n}\n.hover .gritter-bottom {\n\tbackground-position: bottom right;\n}\n.gritter-item {\n\tdisplay:block;\n\tbackground:url(images/gritter.png) no-repeat left -40px;\n\tcolor:#eee;\n\tpadding:2px 11px 8px 11px;\n\tfont-size: 11px;\n\tfont-family:verdana;\n}\n.hover .gritter-item {\n\tbackground-position:right -40px;\n}\n.gritter-item p {\n\tpadding:0;\n\tmargin:0;\n\tword-wrap:break-word;\n}\n.gritter-close {\n\tdisplay:none;\n\tposition:absolute;\n\ttop:5px;\n\tleft:3px;\n\tbackground:url(images/gritter.png) no-repeat left top;\n\tcursor:pointer;\n\twidth:30px;\n\theight:30px;\n}\n.gritter-title {\n\tfont-size:14px;\n\tfont-weight:bold;\n\tpadding:0 0 7px 0;\n\tdisplay:block;\n\ttext-shadow:1px 1px 0 #000; /* Not supported by IE :( */\n}\n.gritter-image {\n\twidth:48px;\n\theight:48px;\n\tfloat:left;\n}\n.gritter-with-image,\n.gritter-without-image {\n\tpadding:0;\n}\n.gritter-with-image {\n\twidth:220px;\n\tfloat:right;\n}\n/* for the light (white) version of the gritter notice */\n.gritter-light .gritter-item,\n.gritter-light .gritter-bottom,\n.gritter-light .gritter-top,\n.gritter-light .gritter-close {\n    background-image: url(images/gritter-light.png);\n    color: #222;\n}\n.gritter-light .gritter-title {\n    text-shadow: none;\n}\n"
  },
  {
    "path": "static/template/css/jcarousel.responsive.css",
    "content": ".jcarousel-wrapper {\n    margin: 20px auto;\n    position: relative;\n    border: 10px solid #fff;\n    -webkit-border-radius: 5px;\n    -moz-border-radius: 5px;\n    border-radius: 5px;\n    -webkit-box-shadow: 0 0 2px #999;\n    -moz-box-shadow: 0 0 2px #999;\n    box-shadow: 0 0 2px #999;\n}\n\n/** Carousel **/\n\n.jcarousel {\n    position: relative;\n    overflow: hidden;\n    width: 100%;\n}\n\n.jcarousel ul {\n    width: 20000em;\n    position: relative;\n    list-style: none;\n    margin: 0;\n    padding: 0;\n}\n\n.jcarousel li {\n    width: 200px;\n    float: left;\n    border: 1px solid #fff;\n    -moz-box-sizing: border-box;\n    -webkit-box-sizing: border-box;\n    box-sizing: border-box;\n}\n\n.jcarousel img {\n    display: block;\n    max-width: 100%;\n    height: auto !important;\n}\n\n/** Carousel Controls **/\n\n.jcarousel-control-prev,\n.jcarousel-control-next {\n    position: absolute;\n    top: 50%;\n    margin-top: -15px;\n    width: 30px;\n    height: 30px;\n    text-align: center;\n    background: #4E443C;\n    color: #fff;\n    text-decoration: none;\n    text-shadow: 0 0 1px #000;\n    font: 24px/27px Arial, sans-serif;\n    -webkit-border-radius: 30px;\n    -moz-border-radius: 30px;\n    border-radius: 30px;\n    -webkit-box-shadow: 0 0 4px #F0EFE7;\n    -moz-box-shadow: 0 0 4px #F0EFE7;\n    box-shadow: 0 0 4px #F0EFE7;\n}\n\n.jcarousel-control-prev {\n    left: 15px;\n}\n\n.jcarousel-control-next {\n    right: 15px;\n}\n\n/** Carousel Pagination **/\n\n.jcarousel-pagination {\n    position: absolute;\n    bottom: -40px;\n    left: 50%;\n    -webkit-transform: translate(-50%, 0);\n    -ms-transform: translate(-50%, 0);\n    transform: translate(-50%, 0);\n    margin: 0;\n}\n\n.jcarousel-pagination a {\n    text-decoration: none;\n    display: inline-block;\n\n    font-size: 11px;\n    height: 10px;\n    width: 10px;\n    line-height: 10px;\n\n    background: #fff;\n    color: #4E443C;\n    border-radius: 10px;\n    text-indent: -9999px;\n\n    margin-right: 7px;\n\n\n    -webkit-box-shadow: 0 0 2px #4E443C;\n    -moz-box-shadow: 0 0 2px #4E443C;\n    box-shadow: 0 0 2px #4E443C;\n}\n\n.jcarousel-pagination a.active {\n    background: #4E443C;\n    color: #fff;\n    opacity: 1;\n\n    -webkit-box-shadow: 0 0 2px #F0EFE7;\n    -moz-box-shadow: 0 0 2px #F0EFE7;\n    box-shadow: 0 0 2px #F0EFE7;\n}\n"
  },
  {
    "path": "static/template/css/jquery.dataTables_themeroller.css",
    "content": "\n\n/*\n * Table\n */\ntable.dataTable {\n\tmargin: 0 auto;\n\tclear: both;\n\twidth: 100%;\n\tborder-collapse: collapse;\n}\n\ntable.dataTable thead th {\n\tpadding: 3px 0px 3px 10px;\n\tcursor: pointer;\n\t*cursor: hand;\n}\n\ntable.dataTable tfoot th {\n\tpadding: 3px 10px;\n}\n\ntable.dataTable td {\n\tpadding: 3px 10px;\n}\n\ntable.dataTable td.center,\ntable.dataTable td.dataTables_empty {\n\ttext-align: center;\n}\n\ntable.dataTable tr.odd { background-color: #E2E4FF; }\ntable.dataTable tr.even { background-color: white; }\n\ntable.dataTable tr.odd td.sorting_1 { background-color: #D3D6FF; }\ntable.dataTable tr.odd td.sorting_2 { background-color: #DADCFF; }\ntable.dataTable tr.odd td.sorting_3 { background-color: #E0E2FF; }\ntable.dataTable tr.even td.sorting_1 { background-color: #EAEBFF; }\ntable.dataTable tr.even td.sorting_2 { background-color: #F2F3FF; }\ntable.dataTable tr.even td.sorting_3 { background-color: #F9F9FF; }\n\n\n/*\n * Table wrapper\n */\n.dataTables_wrapper {\n\tposition: relative;\n\tclear: both;\n\t*zoom: 1;\n}\n.dataTables_wrapper .ui-widget-header {\n\tfont-weight: normal;\n}\n.dataTables_wrapper .ui-toolbar {\n\tpadding: 5px;\n}\n\n\n/*\n * Page length menu\n */\n.dataTables_length {\n\tfloat: left;\n}\n\n\n/*\n * Filter\n */\n.dataTables_filter {\n\tfloat: right;\n\ttext-align: right;\n}\n\n\n/*\n * Table information\n */\n.dataTables_info {\n\tpadding-top: 3px;\n\tclear: both;\n\tfloat: left;\n}\n\n\n/*\n * Pagination\n */\n.dataTables_paginate {\n\tfloat: right;\n\ttext-align: right;\n}\n\n.dataTables_paginate .ui-button {\n\tmargin-right: -0.1em !important;\n}\n\n.paging_two_button .ui-button {\n\tfloat: left;\n\tcursor: pointer;\n\t* cursor: hand;\n}\n\n.paging_full_numbers .ui-button {\n\tpadding: 2px 6px;\n\tmargin: 0;\n\tcursor: pointer;\n\t* cursor: hand;\n\tcolor: #333 !important;\n}\n\n/* Two button pagination - previous / next */\n.paginate_disabled_previous,\n.paginate_enabled_previous,\n.paginate_disabled_next,\n.paginate_enabled_next {\n\theight: 19px;\n\tfloat: left;\n\tcursor: pointer;\n\t*cursor: hand;\n\tcolor: #111 !important;\n}\n.paginate_disabled_previous:hover,\n.paginate_enabled_previous:hover,\n.paginate_disabled_next:hover,\n.paginate_enabled_next:hover {\n\ttext-decoration: none !important;\n}\n.paginate_disabled_previous:active,\n.paginate_enabled_previous:active,\n.paginate_disabled_next:active,\n.paginate_enabled_next:active {\n\toutline: none;\n}\n\n.paginate_disabled_previous,\n.paginate_disabled_next {\n\tcolor: #666 !important;\n}\n.paginate_disabled_previous,\n.paginate_enabled_previous {\n\tpadding-left: 23px;\n}\n.paginate_disabled_next,\n.paginate_enabled_next {\n\tpadding-right: 23px;\n\tmargin-left: 10px;\n}\n\n.paginate_enabled_previous { background: url('../images/back_enabled.png') no-repeat top left; }\n.paginate_enabled_previous:hover { background: url('../images/back_enabled_hover.png') no-repeat top left; }\n.paginate_disabled_previous { background: url('../images/back_disabled.png') no-repeat top left; }\n\n.paginate_enabled_next { background: url('../images/forward_enabled.png') no-repeat top right; }\n.paginate_enabled_next:hover { background: url('../images/forward_enabled_hover.png') no-repeat top right; }\n.paginate_disabled_next { background: url('../images/forward_disabled.png') no-repeat top right; }\n\n/* Full number pagination */\n.paging_full_numbers a:active {\n\toutline: none\n}\n.paging_full_numbers a:hover {\n\ttext-decoration: none;\n}\n\n.paging_full_numbers a.paginate_button,\n.paging_full_numbers a.paginate_active {\n\tborder: 1px solid #aaa;\n\t-webkit-border-radius: 5px;\n\t-moz-border-radius: 5px;\n\tborder-radius: 5px;\n\tpadding: 2px 5px;\n\tmargin: 0 3px;\n\tcursor: pointer;\n\t*cursor: hand;\n\tcolor: #333 !important;\n}\n\n.paging_full_numbers a.paginate_button {\n\tbackground-color: #ddd;\n}\n\n.paging_full_numbers a.paginate_button:hover {\n\tbackground-color: #ccc;\n\ttext-decoration: none !important;\n}\n\n.paging_full_numbers a.paginate_active {\n\tbackground-color: #99B3FF;\n}\n\n\n/*\n * Processing indicator\n */\n.dataTables_processing {\n\tposition: absolute;\n\ttop: 50%;\n\tleft: 50%;\n\twidth: 250px;\n\theight: 30px;\n\tmargin-left: -125px;\n\tmargin-top: -15px;\n\tpadding: 14px 0 2px 0;\n\tborder: 1px solid #ddd;\n\ttext-align: center;\n\tcolor: #999;\n\tfont-size: 14px;\n\tbackground-color: white;\n}\n\n\n/*\n * Sorting\n */\ntable.dataTable thead th div.DataTables_sort_wrapper {\n\tposition: relative;\n\tpadding-right: 20px;\n}\n\ntable.dataTable thead th div.DataTables_sort_wrapper span {\n\tposition: absolute;\n\ttop: 50%;\n\tmargin-top: -8px;\n\tright: 0;\n}\n\ntable.dataTable th:active {\n\toutline: none;\n}\n\n\n/*\n * Scrolling\n */\n.dataTables_scroll {\n\tclear: both;\n}\n\n.dataTables_scrollBody {\n\t*margin-top: -1px;\n\t-webkit-overflow-scrolling: touch;\n}\n\n"
  },
  {
    "path": "static/template/css/jquery.tagsinput.css",
    "content": "div.tagsinput { border:1px solid #CCC; background: #FFF; padding:5px; width:300px; height:100px; overflow-y: auto;}\ndiv.tagsinput span.tag { border: 1px solid #a5d24a; -moz-border-radius:2px; -webkit-border-radius:2px; display: block; float: left; padding: 5px; text-decoration:none; background: #cde69c; color: #638421; margin-right: 5px; margin-bottom:5px;font-family: helvetica;  font-size:13px;}\ndiv.tagsinput span.tag a { font-weight: bold; color: #82ad2b; text-decoration:none; font-size: 11px;  } \ndiv.tagsinput input { width:80px; margin:0px; font-family: helvetica; font-size: 13px; border:1px solid transparent; padding:5px; background: transparent; color: #000; outline:0px;  margin-right:5px; margin-bottom:5px; }\ndiv.tagsinput div { display:block; float: left; } \n.tags_clear { clear: both; width: 100%; height: 0px; }\n.not_valid {background: #FBD8DB !important; color: #90111A !important;}\n"
  },
  {
    "path": "static/template/css/morris.css",
    "content": ".morris-hover{position:absolute;z-index:1000;}.morris-hover.morris-default-style{border-radius:10px;padding:6px;color:#666;background:rgba(255, 255, 255, 0.8);border:solid 2px rgba(230, 230, 230, 0.8);font-family:sans-serif;font-size:12px;text-align:center;}.morris-hover.morris-default-style .morris-hover-row-label{font-weight:bold;margin:0.25em 0;}\n.morris-hover.morris-default-style .morris-hover-point{white-space:nowrap;margin:0.1em 0;}\n"
  },
  {
    "path": "static/template/css/pace.css",
    "content": "/* This is a compiled file, you should be editing the file in the templates directory */\n.pace {\n  -webkit-pointer-events: none;\n  pointer-events: none;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  user-select: none;\n}\n\n.pace-inactive {\n  display: none;\n}\n\n.pace .pace-progress {\n  background: #29d;\n  position: fixed;\n  z-index: 2000;\n  top: 0;\n  left: 0;\n  height: 2px;\n\n  -webkit-transition: width 1s;\n  -moz-transition: width 1s;\n  -o-transition: width 1s;\n  transition: width 1s;\n}\n\n.pace .pace-progress-inner {\n  display: block;\n  position: absolute;\n  right: 0px;\n  width: 100px;\n  height: 100%;\n  box-shadow: 0 0 10px #29d, 0 0 5px #29d;\n  opacity: 1.0;\n  -webkit-transform: rotate(3deg) translate(0px, -4px);\n  -moz-transform: rotate(3deg) translate(0px, -4px);\n  -ms-transform: rotate(3deg) translate(0px, -4px);\n  -o-transform: rotate(3deg) translate(0px, -4px);\n  transform: rotate(3deg) translate(0px, -4px);\n}\n\n.pace .pace-activity {\n  display: block;\n  position: fixed;\n  z-index: 2000;\n  top: 15px;\n  right: 15px;\n  width: 14px;\n  height: 14px;\n  border: solid 2px transparent;\n  border-top-color: #29d;\n  border-left-color: #29d;\n  border-radius: 10px;\n  -webkit-animation: pace-spinner 400ms linear infinite;\n  -moz-animation: pace-spinner 400ms linear infinite;\n  -ms-animation: pace-spinner 400ms linear infinite;\n  -o-animation: pace-spinner 400ms linear infinite;\n  animation: pace-spinner 400ms linear infinite;\n}\n\n@-webkit-keyframes pace-spinner {\n  0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); }\n  100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); }\n}\n@-moz-keyframes pace-spinner {\n  0% { -moz-transform: rotate(0deg); transform: rotate(0deg); }\n  100% { -moz-transform: rotate(360deg); transform: rotate(360deg); }\n}\n@-o-keyframes pace-spinner {\n  0% { -o-transform: rotate(0deg); transform: rotate(0deg); }\n  100% { -o-transform: rotate(360deg); transform: rotate(360deg); }\n}\n@-ms-keyframes pace-spinner {\n  0% { -ms-transform: rotate(0deg); transform: rotate(0deg); }\n  100% { -ms-transform: rotate(360deg); transform: rotate(360deg); }\n}\n@keyframes pace-spinner {\n  0% { transform: rotate(0deg); transform: rotate(0deg); }\n  100% { transform: rotate(360deg); transform: rotate(360deg); }\n}\n"
  },
  {
    "path": "static/template/css/prettify.css",
    "content": "/* Pretty printing styles. Used with prettify.js. */\n\n/* SPAN elements with the classes below are added by prettyprint. */\n.pln { color: #000 }  /* plain text */\n\n@media screen {\n  .str { color: #080 }  /* string content */\n  .kwd { color: #008 }  /* a keyword */\n  .com { color: #800 }  /* a comment */\n  .typ { color: #606 }  /* a type name */\n  .lit { color: #066 }  /* a literal value */\n  /* punctuation, lisp open bracket, lisp close bracket */\n  .pun, .opn, .clo { color: #660 }\n  .tag { color: #008 }  /* a markup tag name */\n  .atn { color: #606 }  /* a markup attribute name */\n  .atv { color: #080 }  /* a markup attribute value */\n  .dec, .var { color: #606 }  /* a declaration; a variable name */\n  .fun { color: red }  /* a function name */\n}\n\n/* Use higher contrast and text-weight for printable form. */\n@media print, projection {\n  .str { color: #060 }\n  .kwd { color: #006; font-weight: bold }\n  .com { color: #600; font-style: italic }\n  .typ { color: #404; font-weight: bold }\n  .lit { color: #044 }\n  .pun, .opn, .clo { color: #440 }\n  .tag { color: #006; font-weight: bold }\n  .atn { color: #404 }\n  .atv { color: #060 }\n}\n\n/* Put a border around prettyprinted code snippets. */\npre.prettyprint { padding: 2px; border: 1px solid #888 }\n\n/* Specify class=linenums on a pre to get line numbering */\nol.linenums { margin-top: 0; margin-bottom: 0 } /* IE indents via margin-left */\nli.L0,\nli.L1,\nli.L2,\nli.L3,\nli.L5,\nli.L6,\nli.L7,\nli.L8 { list-style-type: none }\n/* Alternate shading for lines */\nli.L1,\nli.L3,\nli.L5,\nli.L7,\nli.L9 { background: #eee }\n"
  },
  {
    "path": "static/template/css/slider.css",
    "content": "/*!\n * Slider for Bootstrap\n *\n * Copyright 2012 Stefan Petre\n * Licensed under the Apache License v2.0\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n */\n.slider {\n  display: inline-block;\n  vertical-align: middle;\n  position: relative;\n}\n.slider.slider-horizontal {\n  width: 210px;\n  height: 20px;\n}\n.slider.slider-horizontal .slider-track {\n  height: 10px;\n  width: 100%;\n  margin-top: -5px;\n  top: 50%;\n  left: 0;\n}\n.slider.slider-horizontal .slider-selection {\n  height: 100%;\n  top: 0;\n  bottom: 0;\n}\n.slider.slider-horizontal .slider-handle {\n  margin-left: -10px;\n  margin-top: -5px;\n}\n.slider.slider-horizontal .slider-handle.triangle {\n  border-width: 0 10px 10px 10px;\n  width: 0;\n  height: 0;\n  border-bottom-color: #0480be;\n  margin-top: 0;\n}\n.slider.slider-vertical {\n  height: 210px;\n  width: 20px;\n}\n.slider.slider-vertical .slider-track {\n  width: 10px;\n  height: 100%;\n  margin-left: -5px;\n  left: 50%;\n  top: 0;\n}\n.slider.slider-vertical .slider-selection {\n  width: 100%;\n  left: 0;\n  top: 0;\n  bottom: 0;\n}\n.slider.slider-vertical .slider-handle {\n  margin-left: -5px;\n  margin-top: -10px;\n}\n.slider.slider-vertical .slider-handle.triangle {\n  border-width: 10px 0 10px 10px;\n  width: 1px;\n  height: 1px;\n  border-left-color: #0480be;\n  margin-left: 0;\n}\n.slider input {\n  display: none;\n}\n.slider .tooltip-inner {\n  white-space: nowrap;\n}\n.slider-track {\n  position: absolute;\n  cursor: pointer;\n  background-color: #f7f7f7;\n  background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));\n  background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9);\n  background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9);\n  background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0);\n  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n  -moz-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  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n}\n.slider-selection {\n  position: absolute;\n  background-color: #f7f7f7;\n  background-image: -moz-linear-gradient(top, #f9f9f9, #f5f5f5);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f9f9f9), to(#f5f5f5));\n  background-image: -webkit-linear-gradient(top, #f9f9f9, #f5f5f5);\n  background-image: -o-linear-gradient(top, #f9f9f9, #f5f5f5);\n  background-image: linear-gradient(to bottom, #f9f9f9, #f5f5f5);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9f9f9', endColorstr='#fff5f5f5', GradientType=0);\n  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n  -moz-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-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n}\n.slider-handle {\n  position: absolute;\n  width: 20px;\n  height: 20px;\n  background-color: #0e90d2;\n  background-image: -moz-linear-gradient(top, #149bdf, #0480be);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));\n  background-image: -webkit-linear-gradient(top, #149bdf, #0480be);\n  background-image: -o-linear-gradient(top, #149bdf, #0480be);\n  background-image: linear-gradient(to bottom, #149bdf, #0480be);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0);\n  -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);\n  -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);\n  box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);\n  opacity: 0.8;\n  border: 0px solid transparent;\n}\n.slider-handle.round {\n  -webkit-border-radius: 20px;\n  -moz-border-radius: 20px;\n  border-radius: 20px;\n}\n.slider-handle.triangle {\n  background: transparent none;\n}"
  },
  {
    "path": "static/template/js/bootstrap-datepicker.js",
    "content": "/*!\n * Datepicker for Bootstrap v1.7.0-dev (https://github.com/uxsolutions/bootstrap-datepicker)\n *\n * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)\n */\n\n(function(factory){\n    if (typeof define === \"function\" && define.amd) {\n        define([\"jquery\"], factory);\n    } else if (typeof exports === 'object') {\n        factory(require('jquery'));\n    } else {\n        factory(jQuery);\n    }\n}(function($, undefined){\n\n\tfunction UTCDate(){\n\t\treturn new Date(Date.UTC.apply(Date, arguments));\n\t}\n\tfunction UTCToday(){\n\t\tvar today = new Date();\n\t\treturn UTCDate(today.getFullYear(), today.getMonth(), today.getDate());\n\t}\n\tfunction isUTCEquals(date1, date2) {\n\t\treturn (\n\t\t\tdate1.getUTCFullYear() === date2.getUTCFullYear() &&\n\t\t\tdate1.getUTCMonth() === date2.getUTCMonth() &&\n\t\t\tdate1.getUTCDate() === date2.getUTCDate()\n\t\t);\n\t}\n\tfunction alias(method){\n\t\treturn function(){\n\t\t\treturn this[method].apply(this, arguments);\n\t\t};\n\t}\n\tfunction isValidDate(d) {\n\t\treturn d && !isNaN(d.getTime());\n\t}\n\n\tvar DateArray = (function(){\n\t\tvar extras = {\n\t\t\tget: function(i){\n\t\t\t\treturn this.slice(i)[0];\n\t\t\t},\n\t\t\tcontains: function(d){\n\t\t\t\t// Array.indexOf is not cross-browser;\n\t\t\t\t// $.inArray doesn't work with Dates\n\t\t\t\tvar val = d && d.valueOf();\n\t\t\t\tfor (var i=0, l=this.length; i < l; i++)\n          // Use date arithmetic to allow dates with different times to match\n          if (0 <= this[i].valueOf() - val && this[i].valueOf() - val < 1000*60*60*24)\n\t\t\t\t\t\treturn i;\n\t\t\t\treturn -1;\n\t\t\t},\n\t\t\tremove: function(i){\n\t\t\t\tthis.splice(i,1);\n\t\t\t},\n\t\t\treplace: function(new_array){\n\t\t\t\tif (!new_array)\n\t\t\t\t\treturn;\n\t\t\t\tif (!$.isArray(new_array))\n\t\t\t\t\tnew_array = [new_array];\n\t\t\t\tthis.clear();\n\t\t\t\tthis.push.apply(this, new_array);\n\t\t\t},\n\t\t\tclear: function(){\n\t\t\t\tthis.length = 0;\n\t\t\t},\n\t\t\tcopy: function(){\n\t\t\t\tvar a = new DateArray();\n\t\t\t\ta.replace(this);\n\t\t\t\treturn a;\n\t\t\t}\n\t\t};\n\n\t\treturn function(){\n\t\t\tvar a = [];\n\t\t\ta.push.apply(a, arguments);\n\t\t\t$.extend(a, extras);\n\t\t\treturn a;\n\t\t};\n\t})();\n\n\n\t// Picker object\n\n\tvar Datepicker = function(element, options){\n\t\t$.data(element, 'datepicker', this);\n\t\tthis._process_options(options);\n\n\t\tthis.dates = new DateArray();\n\t\tthis.viewDate = this.o.defaultViewDate;\n\t\tthis.focusDate = null;\n\n\t\tthis.element = $(element);\n\t\tthis.isInput = this.element.is('input');\n\t\tthis.inputField = this.isInput ? this.element : this.element.find('input');\n\t\tthis.component = this.element.hasClass('date') ? this.element.find('.add-on, .input-group-addon, .btn') : false;\n\t\tif (this.component && this.component.length === 0)\n\t\t\tthis.component = false;\n\t\tthis.isInline = !this.component && this.element.is('div');\n\n\t\tthis.picker = $(DPGlobal.template);\n\n\t\t// Checking templates and inserting\n\t\tif (this._check_template(this.o.templates.leftArrow)) {\n\t\t\tthis.picker.find('.prev').html(this.o.templates.leftArrow);\n\t\t}\n\n\t\tif (this._check_template(this.o.templates.rightArrow)) {\n\t\t\tthis.picker.find('.next').html(this.o.templates.rightArrow);\n\t\t}\n\n\t\tthis._buildEvents();\n\t\tthis._attachEvents();\n\n\t\tif (this.isInline){\n\t\t\tthis.picker.addClass('datepicker-inline').appendTo(this.element);\n\t\t}\n\t\telse {\n\t\t\tthis.picker.addClass('datepicker-dropdown dropdown-menu');\n\t\t}\n\n\t\tif (this.o.rtl){\n\t\t\tthis.picker.addClass('datepicker-rtl');\n\t\t}\n\n\t\tif (this.o.calendarWeeks) {\n\t\t\tthis.picker.find('.datepicker-days .datepicker-switch, thead .datepicker-title, tfoot .today, tfoot .clear')\n\t\t\t\t.attr('colspan', function(i, val){\n\t\t\t\t\treturn Number(val) + 1;\n\t\t\t\t});\n\t\t}\n\n\t\tthis._allow_update = false;\n\n\t\tthis.setStartDate(this._o.startDate);\n\t\tthis.setEndDate(this._o.endDate);\n\t\tthis.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled);\n\t\tthis.setDaysOfWeekHighlighted(this.o.daysOfWeekHighlighted);\n\t\tthis.setDatesDisabled(this.o.datesDisabled);\n\n\t\tthis.setViewMode(this.o.startView);\n\t\tthis.fillDow();\n\t\tthis.fillMonths();\n\n\t\tthis._allow_update = true;\n\n\t\tthis.update();\n\n\t\tif (this.isInline){\n\t\t\tthis.show();\n\t\t}\n\t};\n\n\tDatepicker.prototype = {\n\t\tconstructor: Datepicker,\n\n\t\t_resolveViewName: function(view){\n\t\t\t$.each(DPGlobal.viewModes, function(i, viewMode){\n\t\t\t\tif (view === i || $.inArray(view, viewMode.names) !== -1){\n\t\t\t\t\tview = i;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn view;\n\t\t},\n\n\t\t_resolveDaysOfWeek: function(daysOfWeek){\n\t\t\tif (!$.isArray(daysOfWeek))\n\t\t\t\tdaysOfWeek = daysOfWeek.split(/[,\\s]*/);\n\t\t\treturn $.map(daysOfWeek, Number);\n\t\t},\n\n\t\t_check_template: function(tmp){\n\t\t\ttry {\n\t\t\t\t// If empty\n\t\t\t\tif (tmp === undefined || tmp === \"\") {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t// If no html, everything ok\n\t\t\t\tif ((tmp.match(/[<>]/g) || []).length <= 0) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\t// Checking if html is fine\n\t\t\t\tvar jDom = $(tmp);\n\t\t\t\treturn jDom.length > 0;\n\t\t\t}\n\t\t\tcatch (ex) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\n\t\t_process_options: function(opts){\n\t\t\t// Store raw options for reference\n\t\t\tthis._o = $.extend({}, this._o, opts);\n\t\t\t// Processed options\n\t\t\tvar o = this.o = $.extend({}, this._o);\n\n\t\t\t// Check if \"de-DE\" style date is available, if not language should\n\t\t\t// fallback to 2 letter code eg \"de\"\n\t\t\tvar lang = o.language;\n\t\t\tif (!dates[lang]){\n\t\t\t\tlang = lang.split('-')[0];\n\t\t\t\tif (!dates[lang])\n\t\t\t\t\tlang = defaults.language;\n\t\t\t}\n\t\t\to.language = lang;\n\n\t\t\t// Retrieve view index from any aliases\n\t\t\to.startView = this._resolveViewName(o.startView);\n\t\t\to.minViewMode = this._resolveViewName(o.minViewMode);\n\t\t\to.maxViewMode = this._resolveViewName(o.maxViewMode);\n\n\t\t\t// Check view is between min and max\n\t\t\to.startView = Math.max(this.o.minViewMode, Math.min(this.o.maxViewMode, o.startView));\n\n\t\t\t// true, false, or Number > 0\n\t\t\tif (o.multidate !== true){\n\t\t\t\to.multidate = Number(o.multidate) || false;\n\t\t\t\tif (o.multidate !== false)\n\t\t\t\t\to.multidate = Math.max(0, o.multidate);\n\t\t\t}\n\t\t\to.multidateSeparator = String(o.multidateSeparator);\n\n\t\t\to.weekStart %= 7;\n\t\t\to.weekEnd = (o.weekStart + 6) % 7;\n\n\t\t\tvar format = DPGlobal.parseFormat(o.format);\n\t\t\tif (o.startDate !== -Infinity){\n\t\t\t\tif (!!o.startDate){\n\t\t\t\t\tif (o.startDate instanceof Date)\n\t\t\t\t\t\to.startDate = this._local_to_utc(this._zero_time(o.startDate));\n\t\t\t\t\telse\n\t\t\t\t\t\to.startDate = DPGlobal.parseDate(o.startDate, format, o.language, o.assumeNearbyYear);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\to.startDate = -Infinity;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (o.endDate !== Infinity){\n\t\t\t\tif (!!o.endDate){\n\t\t\t\t\tif (o.endDate instanceof Date)\n\t\t\t\t\t\to.endDate = this._local_to_utc(this._zero_time(o.endDate));\n\t\t\t\t\telse\n\t\t\t\t\t\to.endDate = DPGlobal.parseDate(o.endDate, format, o.language, o.assumeNearbyYear);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\to.endDate = Infinity;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\to.daysOfWeekDisabled = this._resolveDaysOfWeek(o.daysOfWeekDisabled||[]);\n\t\t\to.daysOfWeekHighlighted = this._resolveDaysOfWeek(o.daysOfWeekHighlighted||[]);\n\n\t\t\to.datesDisabled = o.datesDisabled||[];\n\t\t\tif (!$.isArray(o.datesDisabled)) {\n\t\t\t\to.datesDisabled = o.datesDisabled.split(',');\n\t\t\t}\n\t\t\to.datesDisabled = $.map(o.datesDisabled, function(d){\n\t\t\t\treturn DPGlobal.parseDate(d, format, o.language, o.assumeNearbyYear);\n\t\t\t});\n\n\t\t\tvar plc = String(o.orientation).toLowerCase().split(/\\s+/g),\n\t\t\t\t_plc = o.orientation.toLowerCase();\n\t\t\tplc = $.grep(plc, function(word){\n\t\t\t\treturn /^auto|left|right|top|bottom$/.test(word);\n\t\t\t});\n\t\t\to.orientation = {x: 'auto', y: 'auto'};\n\t\t\tif (!_plc || _plc === 'auto')\n\t\t\t\t; // no action\n\t\t\telse if (plc.length === 1){\n\t\t\t\tswitch (plc[0]){\n\t\t\t\t\tcase 'top':\n\t\t\t\t\tcase 'bottom':\n\t\t\t\t\t\to.orientation.y = plc[0];\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'left':\n\t\t\t\t\tcase 'right':\n\t\t\t\t\t\to.orientation.x = plc[0];\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\t_plc = $.grep(plc, function(word){\n\t\t\t\t\treturn /^left|right$/.test(word);\n\t\t\t\t});\n\t\t\t\to.orientation.x = _plc[0] || 'auto';\n\n\t\t\t\t_plc = $.grep(plc, function(word){\n\t\t\t\t\treturn /^top|bottom$/.test(word);\n\t\t\t\t});\n\t\t\t\to.orientation.y = _plc[0] || 'auto';\n\t\t\t}\n\t\t\tif (o.defaultViewDate) {\n\t\t\t\tvar year = o.defaultViewDate.year || new Date().getFullYear();\n\t\t\t\tvar month = o.defaultViewDate.month || 0;\n\t\t\t\tvar day = o.defaultViewDate.day || 1;\n\t\t\t\to.defaultViewDate = UTCDate(year, month, day);\n\t\t\t} else {\n\t\t\t\to.defaultViewDate = UTCToday();\n\t\t\t}\n\t\t},\n\t\t_events: [],\n\t\t_secondaryEvents: [],\n\t\t_applyEvents: function(evs){\n\t\t\tfor (var i=0, el, ch, ev; i < evs.length; i++){\n\t\t\t\tel = evs[i][0];\n\t\t\t\tif (evs[i].length === 2){\n\t\t\t\t\tch = undefined;\n\t\t\t\t\tev = evs[i][1];\n\t\t\t\t} else if (evs[i].length === 3){\n\t\t\t\t\tch = evs[i][1];\n\t\t\t\t\tev = evs[i][2];\n\t\t\t\t}\n\t\t\t\tel.on(ev, ch);\n\t\t\t}\n\t\t},\n\t\t_unapplyEvents: function(evs){\n\t\t\tfor (var i=0, el, ev, ch; i < evs.length; i++){\n\t\t\t\tel = evs[i][0];\n\t\t\t\tif (evs[i].length === 2){\n\t\t\t\t\tch = undefined;\n\t\t\t\t\tev = evs[i][1];\n\t\t\t\t} else if (evs[i].length === 3){\n\t\t\t\t\tch = evs[i][1];\n\t\t\t\t\tev = evs[i][2];\n\t\t\t\t}\n\t\t\t\tel.off(ev, ch);\n\t\t\t}\n\t\t},\n\t\t_buildEvents: function(){\n            var events = {\n                keyup: $.proxy(function(e){\n                    if ($.inArray(e.keyCode, [27, 37, 39, 38, 40, 32, 13, 9]) === -1)\n                        this.update();\n                }, this),\n                keydown: $.proxy(this.keydown, this),\n                paste: $.proxy(this.paste, this)\n            };\n\n            if (this.o.showOnFocus === true) {\n                events.focus = $.proxy(this.show, this);\n            }\n\n            if (this.isInput) { // single input\n                this._events = [\n                    [this.element, events]\n                ];\n            }\n            // component: input + button\n            else if (this.component && this.inputField.length) {\n                this._events = [\n                    // For components that are not readonly, allow keyboard nav\n                    [this.inputField, events],\n                    [this.component, {\n                        click: $.proxy(this.show, this)\n                    }]\n                ];\n            }\n\t\t\telse {\n\t\t\t\tthis._events = [\n\t\t\t\t\t[this.element, {\n\t\t\t\t\t\tclick: $.proxy(this.show, this),\n\t\t\t\t\t\tkeydown: $.proxy(this.keydown, this)\n\t\t\t\t\t}]\n\t\t\t\t];\n\t\t\t}\n\t\t\tthis._events.push(\n\t\t\t\t// Component: listen for blur on element descendants\n\t\t\t\t[this.element, '*', {\n\t\t\t\t\tblur: $.proxy(function(e){\n\t\t\t\t\t\tthis._focused_from = e.target;\n\t\t\t\t\t}, this)\n\t\t\t\t}],\n\t\t\t\t// Input: listen for blur on element\n\t\t\t\t[this.element, {\n\t\t\t\t\tblur: $.proxy(function(e){\n\t\t\t\t\t\tthis._focused_from = e.target;\n\t\t\t\t\t}, this)\n\t\t\t\t}]\n\t\t\t);\n\n\t\t\tif (this.o.immediateUpdates) {\n\t\t\t\t// Trigger input updates immediately on changed year/month\n\t\t\t\tthis._events.push([this.element, {\n\t\t\t\t\t'changeYear changeMonth': $.proxy(function(e){\n\t\t\t\t\t\tthis.update(e.date);\n\t\t\t\t\t}, this)\n\t\t\t\t}]);\n\t\t\t}\n\n\t\t\tthis._secondaryEvents = [\n\t\t\t\t[this.picker, {\n\t\t\t\t\tclick: $.proxy(this.click, this)\n\t\t\t\t}],\n\t\t\t\t[this.picker, '.prev, .next', {\n\t\t\t\t\tclick: $.proxy(this.navArrowsClick, this)\n\t\t\t\t}],\n\t\t\t\t[$(window), {\n\t\t\t\t\tresize: $.proxy(this.place, this)\n\t\t\t\t}],\n\t\t\t\t[$(document), {\n\t\t\t\t\t'mousedown touchstart': $.proxy(function(e){\n\t\t\t\t\t\t// Clicked outside the datepicker, hide it\n\t\t\t\t\t\tif (!(\n\t\t\t\t\t\t\tthis.element.is(e.target) ||\n\t\t\t\t\t\t\tthis.element.find(e.target).length ||\n\t\t\t\t\t\t\tthis.picker.is(e.target) ||\n\t\t\t\t\t\t\tthis.picker.find(e.target).length ||\n\t\t\t\t\t\t\tthis.isInline\n\t\t\t\t\t\t)){\n\t\t\t\t\t\t\tthis.hide();\n\t\t\t\t\t\t}\n\t\t\t\t\t}, this)\n\t\t\t\t}]\n\t\t\t];\n\t\t},\n\t\t_attachEvents: function(){\n\t\t\tthis._detachEvents();\n\t\t\tthis._applyEvents(this._events);\n\t\t},\n\t\t_detachEvents: function(){\n\t\t\tthis._unapplyEvents(this._events);\n\t\t},\n\t\t_attachSecondaryEvents: function(){\n\t\t\tthis._detachSecondaryEvents();\n\t\t\tthis._applyEvents(this._secondaryEvents);\n\t\t},\n\t\t_detachSecondaryEvents: function(){\n\t\t\tthis._unapplyEvents(this._secondaryEvents);\n\t\t},\n\t\t_trigger: function(event, altdate){\n\t\t\tvar date = altdate || this.dates.get(-1),\n\t\t\t\tlocal_date = this._utc_to_local(date);\n\n\t\t\tthis.element.trigger({\n\t\t\t\ttype: event,\n\t\t\t\tdate: local_date,\n\t\t\t\tviewMode: this.viewMode,\n\t\t\t\tdates: $.map(this.dates, this._utc_to_local),\n\t\t\t\tformat: $.proxy(function(ix, format){\n\t\t\t\t\tif (arguments.length === 0){\n\t\t\t\t\t\tix = this.dates.length - 1;\n\t\t\t\t\t\tformat = this.o.format;\n\t\t\t\t\t} else if (typeof ix === 'string'){\n\t\t\t\t\t\tformat = ix;\n\t\t\t\t\t\tix = this.dates.length - 1;\n\t\t\t\t\t}\n\t\t\t\t\tformat = format || this.o.format;\n\t\t\t\t\tvar date = this.dates.get(ix);\n\t\t\t\t\treturn DPGlobal.formatDate(date, format, this.o.language);\n\t\t\t\t}, this)\n\t\t\t});\n\t\t},\n\n\t\tshow: function(){\n\t\t\tif (this.inputField.prop('disabled') || (this.inputField.prop('readonly') && this.o.enableOnReadonly === false))\n\t\t\t\treturn;\n\t\t\tif (!this.isInline)\n\t\t\t\tthis.picker.appendTo(this.o.container);\n\t\t\tthis.place();\n\t\t\tthis.picker.show();\n\t\t\tthis._attachSecondaryEvents();\n\t\t\tthis._trigger('show');\n\t\t\tif ((window.navigator.msMaxTouchPoints || 'ontouchstart' in document) && this.o.disableTouchKeyboard) {\n\t\t\t\t$(this.element).blur();\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\n\t\thide: function(){\n\t\t\tif (this.isInline || !this.picker.is(':visible'))\n\t\t\t\treturn this;\n\t\t\tthis.focusDate = null;\n\t\t\tthis.picker.hide().detach();\n\t\t\tthis._detachSecondaryEvents();\n\t\t\tthis.setViewMode(this.o.startView);\n\n\t\t\tif (this.o.forceParse && this.inputField.val())\n\t\t\t\tthis.setValue();\n\t\t\tthis._trigger('hide');\n\t\t\treturn this;\n\t\t},\n\n\t\tdestroy: function(){\n\t\t\tthis.hide();\n\t\t\tthis._detachEvents();\n\t\t\tthis._detachSecondaryEvents();\n\t\t\tthis.picker.remove();\n\t\t\tdelete this.element.data().datepicker;\n\t\t\tif (!this.isInput){\n\t\t\t\tdelete this.element.data().date;\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\n\t\tpaste: function(e){\n\t\t\tvar dateString;\n\t\t\tif (e.originalEvent.clipboardData && e.originalEvent.clipboardData.types\n\t\t\t\t&& $.inArray('text/plain', e.originalEvent.clipboardData.types) !== -1) {\n\t\t\t\tdateString = e.originalEvent.clipboardData.getData('text/plain');\n\t\t\t} else if (window.clipboardData) {\n\t\t\t\tdateString = window.clipboardData.getData('Text');\n\t\t\t} else {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.setDate(dateString);\n\t\t\tthis.update();\n\t\t\te.preventDefault();\n\t\t},\n\n\t\t_utc_to_local: function(utc){\n\t\t\tif (!utc) {\n\t\t\t\treturn utc;\n\t\t\t}\n\n\t\t\tvar local = new Date(utc.getTime() + (utc.getTimezoneOffset() * 60000));\n\n\t\t\tif (local.getTimezoneOffset() !== utc.getTimezoneOffset()) {\n\t\t\t\tlocal = new Date(utc.getTime() + (local.getTimezoneOffset() * 60000));\n\t\t\t}\n\n\t\t\treturn local;\n\t\t},\n\t\t_local_to_utc: function(local){\n\t\t\treturn local && new Date(local.getTime() - (local.getTimezoneOffset()*60000));\n\t\t},\n\t\t_zero_time: function(local){\n\t\t\treturn local && new Date(local.getFullYear(), local.getMonth(), local.getDate());\n\t\t},\n\t\t_zero_utc_time: function(utc){\n\t\t\treturn utc && UTCDate(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate());\n\t\t},\n\n\t\tgetDates: function(){\n\t\t\treturn $.map(this.dates, this._utc_to_local);\n\t\t},\n\n\t\tgetUTCDates: function(){\n\t\t\treturn $.map(this.dates, function(d){\n\t\t\t\treturn new Date(d);\n\t\t\t});\n\t\t},\n\n\t\tgetDate: function(){\n\t\t\treturn this._utc_to_local(this.getUTCDate());\n\t\t},\n\n\t\tgetUTCDate: function(){\n\t\t\tvar selected_date = this.dates.get(-1);\n\t\t\tif (selected_date !== undefined) {\n\t\t\t\treturn new Date(selected_date);\n\t\t\t} else {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\n\t\tclearDates: function(){\n\t\t\tthis.inputField.val('');\n\t\t\tthis.update();\n\t\t\tthis._trigger('changeDate');\n\n\t\t\tif (this.o.autoclose) {\n\t\t\t\tthis.hide();\n\t\t\t}\n\t\t},\n\n\t\tsetDates: function(){\n\t\t\tvar args = $.isArray(arguments[0]) ? arguments[0] : arguments;\n\t\t\tthis.update.apply(this, args);\n\t\t\tthis._trigger('changeDate');\n\t\t\tthis.setValue();\n\t\t\treturn this;\n\t\t},\n\n\t\tsetUTCDates: function(){\n\t\t\tvar args = $.isArray(arguments[0]) ? arguments[0] : arguments;\n\t\t\tthis.setDates.apply(this, $.map(args, this._utc_to_local));\n\t\t\treturn this;\n\t\t},\n\n\t\tsetDate: alias('setDates'),\n\t\tsetUTCDate: alias('setUTCDates'),\n\t\tremove: alias('destroy'),\n\n\t\tsetValue: function(){\n\t\t\tvar formatted = this.getFormattedDate();\n\t\t\tthis.inputField.val(formatted);\n\t\t\treturn this;\n\t\t},\n\n\t\tgetFormattedDate: function(format){\n\t\t\tif (format === undefined)\n\t\t\t\tformat = this.o.format;\n\n\t\t\tvar lang = this.o.language;\n\t\t\treturn $.map(this.dates, function(d){\n\t\t\t\treturn DPGlobal.formatDate(d, format, lang);\n\t\t\t}).join(this.o.multidateSeparator);\n\t\t},\n\n\t\tgetStartDate: function(){\n\t\t\treturn this.o.startDate;\n\t\t},\n\n\t\tsetStartDate: function(startDate){\n\t\t\tthis._process_options({startDate: startDate});\n\t\t\tthis.update();\n\t\t\tthis.updateNavArrows();\n\t\t\treturn this;\n\t\t},\n\n\t\tgetEndDate: function(){\n\t\t\treturn this.o.endDate;\n\t\t},\n\n\t\tsetEndDate: function(endDate){\n\t\t\tthis._process_options({endDate: endDate});\n\t\t\tthis.update();\n\t\t\tthis.updateNavArrows();\n\t\t\treturn this;\n\t\t},\n\n\t\tsetDaysOfWeekDisabled: function(daysOfWeekDisabled){\n\t\t\tthis._process_options({daysOfWeekDisabled: daysOfWeekDisabled});\n\t\t\tthis.update();\n\t\t\treturn this;\n\t\t},\n\n\t\tsetDaysOfWeekHighlighted: function(daysOfWeekHighlighted){\n\t\t\tthis._process_options({daysOfWeekHighlighted: daysOfWeekHighlighted});\n\t\t\tthis.update();\n\t\t\treturn this;\n\t\t},\n\n\t\tsetDatesDisabled: function(datesDisabled){\n\t\t\tthis._process_options({datesDisabled: datesDisabled});\n\t\t\tthis.update();\n\t\t\treturn this;\n\t\t},\n\n\t\tplace: function(){\n\t\t\tif (this.isInline)\n\t\t\t\treturn this;\n\t\t\tvar calendarWidth = this.picker.outerWidth(),\n\t\t\t\tcalendarHeight = this.picker.outerHeight(),\n\t\t\t\tvisualPadding = 10,\n\t\t\t\tcontainer = $(this.o.container),\n\t\t\t\twindowWidth = container.width(),\n\t\t\t\tscrollTop = this.o.container === 'body' ? $(document).scrollTop() : container.scrollTop(),\n\t\t\t\tappendOffset = container.offset();\n\n\t\t\tvar parentsZindex = [];\n\t\t\tthis.element.parents().each(function(){\n\t\t\t\tvar itemZIndex = $(this).css('z-index');\n\t\t\t\tif (itemZIndex !== 'auto' && itemZIndex !== 0) parentsZindex.push(parseInt(itemZIndex));\n\t\t\t});\n\t\t\tvar zIndex = Math.max.apply(Math, parentsZindex) + this.o.zIndexOffset;\n\t\t\tvar offset = this.component ? this.component.parent().offset() : this.element.offset();\n\t\t\tvar height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false);\n\t\t\tvar width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false);\n\t\t\tvar left = offset.left - appendOffset.left,\n\t\t\t\ttop = offset.top - appendOffset.top;\n\n\t\t\tif (this.o.container !== 'body') {\n\t\t\t\ttop += scrollTop;\n\t\t\t}\n\n\t\t\tthis.picker.removeClass(\n\t\t\t\t'datepicker-orient-top datepicker-orient-bottom '+\n\t\t\t\t'datepicker-orient-right datepicker-orient-left'\n\t\t\t);\n\n\t\t\tif (this.o.orientation.x !== 'auto'){\n\t\t\t\tthis.picker.addClass('datepicker-orient-' + this.o.orientation.x);\n\t\t\t\tif (this.o.orientation.x === 'right')\n\t\t\t\t\tleft -= calendarWidth - width;\n\t\t\t}\n\t\t\t// auto x orientation is best-placement: if it crosses a window\n\t\t\t// edge, fudge it sideways\n\t\t\telse {\n\t\t\t\tif (offset.left < 0) {\n\t\t\t\t\t// component is outside the window on the left side. Move it into visible range\n\t\t\t\t\tthis.picker.addClass('datepicker-orient-left');\n\t\t\t\t\tleft -= offset.left - visualPadding;\n\t\t\t\t} else if (left + calendarWidth > windowWidth) {\n\t\t\t\t\t// the calendar passes the widow right edge. Align it to component right side\n\t\t\t\t\tthis.picker.addClass('datepicker-orient-right');\n\t\t\t\t\tleft += width - calendarWidth;\n\t\t\t\t} else {\n\t\t\t\t\tif (this.o.rtl) {\n\t\t\t\t\t\t// Default to right\n\t\t\t\t\t\tthis.picker.addClass('datepicker-orient-right');\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Default to left\n\t\t\t\t\t\tthis.picker.addClass('datepicker-orient-left');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// auto y orientation is best-situation: top or bottom, no fudging,\n\t\t\t// decision based on which shows more of the calendar\n\t\t\tvar yorient = this.o.orientation.y,\n\t\t\t\ttop_overflow;\n\t\t\tif (yorient === 'auto'){\n\t\t\t\ttop_overflow = -scrollTop + top - calendarHeight;\n\t\t\t\tyorient = top_overflow < 0 ? 'bottom' : 'top';\n\t\t\t}\n\n\t\t\tthis.picker.addClass('datepicker-orient-' + yorient);\n\t\t\tif (yorient === 'top')\n\t\t\t\ttop -= calendarHeight + parseInt(this.picker.css('padding-top'));\n\t\t\telse\n\t\t\t\ttop += height;\n\n\t\t\tif (this.o.rtl) {\n\t\t\t\tvar right = windowWidth - (left + width);\n\t\t\t\tthis.picker.css({\n\t\t\t\t\ttop: top,\n\t\t\t\t\tright: right,\n\t\t\t\t\tzIndex: zIndex\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.picker.css({\n\t\t\t\t\ttop: top,\n\t\t\t\t\tleft: left,\n\t\t\t\t\tzIndex: zIndex\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\n\t\t_allow_update: true,\n\t\tupdate: function(){\n\t\t\tif (!this._allow_update)\n\t\t\t\treturn this;\n\n\t\t\tvar oldDates = this.dates.copy(),\n\t\t\t\tdates = [],\n\t\t\t\tfromArgs = false;\n\t\t\tif (arguments.length){\n\t\t\t\t$.each(arguments, $.proxy(function(i, date){\n\t\t\t\t\tif (date instanceof Date)\n\t\t\t\t\t\tdate = this._local_to_utc(date);\n\t\t\t\t\tdates.push(date);\n\t\t\t\t}, this));\n\t\t\t\tfromArgs = true;\n\t\t\t} else {\n\t\t\t\tdates = this.isInput\n\t\t\t\t\t\t? this.element.val()\n\t\t\t\t\t\t: this.element.data('date') || this.inputField.val();\n\t\t\t\tif (dates && this.o.multidate)\n\t\t\t\t\tdates = dates.split(this.o.multidateSeparator);\n\t\t\t\telse\n\t\t\t\t\tdates = [dates];\n\t\t\t\tdelete this.element.data().date;\n\t\t\t}\n\n\t\t\tdates = $.map(dates, $.proxy(function(date){\n\t\t\t\treturn DPGlobal.parseDate(date, this.o.format, this.o.language, this.o.assumeNearbyYear);\n\t\t\t}, this));\n\t\t\tdates = $.grep(dates, $.proxy(function(date){\n\t\t\t\treturn (\n\t\t\t\t\t!this.dateWithinRange(date) ||\n\t\t\t\t\t!date\n\t\t\t\t);\n\t\t\t}, this), true);\n\t\t\tthis.dates.replace(dates);\n\n\t\t\tif (this.o.updateViewDate) {\n\t\t\t\tif (this.dates.length)\n\t\t\t\t\tthis.viewDate = new Date(this.dates.get(-1));\n\t\t\t\telse if (this.viewDate < this.o.startDate)\n\t\t\t\t\tthis.viewDate = new Date(this.o.startDate);\n\t\t\t\telse if (this.viewDate > this.o.endDate)\n\t\t\t\t\tthis.viewDate = new Date(this.o.endDate);\n\t\t\t\telse\n\t\t\t\t\tthis.viewDate = this.o.defaultViewDate;\n\t\t\t}\n\n\t\t\tif (fromArgs){\n\t\t\t\t// setting date by clicking\n\t\t\t\tthis.setValue();\n\t\t\t\tthis.element.change();\n\t\t\t}\n\t\t\telse if (this.dates.length){\n\t\t\t\t// setting date by typing\n\t\t\t\tif (String(oldDates) !== String(this.dates) && fromArgs) {\n\t\t\t\t\tthis._trigger('changeDate');\n\t\t\t\t\tthis.element.change();\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!this.dates.length && oldDates.length) {\n\t\t\t\tthis._trigger('clearDate');\n\t\t\t\tthis.element.change();\n\t\t\t}\n\n\t\t\tthis.fill();\n\t\t\treturn this;\n\t\t},\n\n\t\tfillDow: function(){\n\t\t\tvar dowCnt = this.o.weekStart,\n\t\t\t\thtml = '<tr>';\n\t\t\tif (this.o.calendarWeeks){\n\t\t\t\thtml += '<th class=\"cw\">&#160;</th>';\n\t\t\t}\n\t\t\twhile (dowCnt < this.o.weekStart + 7){\n\t\t\t\thtml += '<th class=\"dow';\n        if ($.inArray(dowCnt, this.o.daysOfWeekDisabled) !== -1)\n          html += ' disabled';\n        html += '\">'+dates[this.o.language].daysMin[(dowCnt++)%7]+'</th>';\n\t\t\t}\n\t\t\thtml += '</tr>';\n\t\t\tthis.picker.find('.datepicker-days thead').append(html);\n\t\t},\n\n\t\tfillMonths: function(){\n      var localDate = this._utc_to_local(this.viewDate);\n\t\t\tvar html = '',\n\t\t\ti = 0;\n\t\t\twhile (i < 12){\n        var focused = localDate && localDate.getMonth() === i ? ' focused' : '';\n\t\t\t\thtml += '<span class=\"month' + focused + '\">' + dates[this.o.language].monthsShort[i++]+'</span>';\n\t\t\t}\n\t\t\tthis.picker.find('.datepicker-months td').html(html);\n\t\t},\n\n\t\tsetRange: function(range){\n\t\t\tif (!range || !range.length)\n\t\t\t\tdelete this.range;\n\t\t\telse\n\t\t\t\tthis.range = $.map(range, function(d){\n\t\t\t\t\treturn d.valueOf();\n\t\t\t\t});\n\t\t\tthis.fill();\n\t\t},\n\n\t\tgetClassNames: function(date){\n\t\t\tvar cls = [],\n\t\t\t\tyear = this.viewDate.getUTCFullYear(),\n\t\t\t\tmonth = this.viewDate.getUTCMonth(),\n\t\t\t\ttoday = UTCToday();\n\t\t\tif (date.getUTCFullYear() < year || (date.getUTCFullYear() === year && date.getUTCMonth() < month)){\n\t\t\t\tcls.push('old');\n\t\t\t} else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){\n\t\t\t\tcls.push('new');\n\t\t\t}\n\t\t\tif (this.focusDate && date.valueOf() === this.focusDate.valueOf())\n\t\t\t\tcls.push('focused');\n\t\t\t// Compare internal UTC date with UTC today, not local today\n\t\t\tif (this.o.todayHighlight && isUTCEquals(date, today)) {\n\t\t\t\tcls.push('today');\n\t\t\t}\n\t\t\tif (this.dates.contains(date) !== -1)\n\t\t\t\tcls.push('active');\n\t\t\tif (!this.dateWithinRange(date)){\n\t\t\t\tcls.push('disabled');\n\t\t\t}\n\t\t\tif (this.dateIsDisabled(date)){\n\t\t\t\tcls.push('disabled', 'disabled-date');\n\t\t\t}\n\t\t\tif ($.inArray(date.getUTCDay(), this.o.daysOfWeekHighlighted) !== -1){\n\t\t\t\tcls.push('highlighted');\n\t\t\t}\n\n\t\t\tif (this.range){\n\t\t\t\tif (date > this.range[0] && date < this.range[this.range.length-1]){\n\t\t\t\t\tcls.push('range');\n\t\t\t\t}\n\t\t\t\tif ($.inArray(date.valueOf(), this.range) !== -1){\n\t\t\t\t\tcls.push('selected');\n\t\t\t\t}\n\t\t\t\tif (date.valueOf() === this.range[0]){\n          cls.push('range-start');\n        }\n        if (date.valueOf() === this.range[this.range.length-1]){\n          cls.push('range-end');\n        }\n\t\t\t}\n\t\t\treturn cls;\n\t\t},\n\n\t\t_fill_yearsView: function(selector, cssClass, factor, step, currentYear, startYear, endYear, callback){\n\t\t\tvar html, view, year, steps, startStep, endStep, thisYear, i, classes, tooltip, before;\n\n\t\t\thtml      = '';\n\t\t\tview      = this.picker.find(selector);\n\t\t\tyear      = parseInt(currentYear / factor, 10) * factor;\n\t\t\tstartStep = parseInt(startYear / step, 10) * step;\n\t\t\tendStep   = parseInt(endYear / step, 10) * step;\n\t\t\tsteps     = $.map(this.dates, function(d){\n\t\t\t\treturn parseInt(d.getUTCFullYear() / step, 10) * step;\n\t\t\t});\n\n\t\t\tview.find('.datepicker-switch').text(year + '-' + (year + step * 9));\n\n\t\t\tthisYear = year - step;\n\t\t\tfor (i = -1; i < 11; i += 1) {\n\t\t\t\tclasses = [cssClass];\n\t\t\t\ttooltip = null;\n\n\t\t\t\tif (i === -1) {\n\t\t\t\t\tclasses.push('old');\n\t\t\t\t} else if (i === 10) {\n\t\t\t\t\tclasses.push('new');\n\t\t\t\t}\n\t\t\t\tif ($.inArray(thisYear, steps) !== -1) {\n\t\t\t\t\tclasses.push('active');\n\t\t\t\t}\n\t\t\t\tif (thisYear < startStep || thisYear > endStep) {\n\t\t\t\t\tclasses.push('disabled');\n\t\t\t\t}\n        if (thisYear === this.viewDate.getFullYear()) {\n\t\t\t\t  classes.push('focused');\n        }\n\n\t\t\t\tif (callback !== $.noop) {\n\t\t\t\t\tbefore = callback(new Date(thisYear, 0, 1));\n\t\t\t\t\tif (before === undefined) {\n\t\t\t\t\t\tbefore = {};\n\t\t\t\t\t} else if (typeof before === 'boolean') {\n\t\t\t\t\t\tbefore = {enabled: before};\n\t\t\t\t\t} else if (typeof before === 'string') {\n\t\t\t\t\t\tbefore = {classes: before};\n\t\t\t\t\t}\n\t\t\t\t\tif (before.enabled === false) {\n\t\t\t\t\t\tclasses.push('disabled');\n\t\t\t\t\t}\n\t\t\t\t\tif (before.classes) {\n\t\t\t\t\t\tclasses = classes.concat(before.classes.split(/\\s+/));\n\t\t\t\t\t}\n\t\t\t\t\tif (before.tooltip) {\n\t\t\t\t\t\ttooltip = before.tooltip;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\thtml += '<span class=\"' + classes.join(' ') + '\"' + (tooltip ? ' title=\"' + tooltip + '\"' : '') + '>' + thisYear + '</span>';\n\t\t\t\tthisYear += step;\n\t\t\t}\n\t\t\tview.find('td').html(html);\n\t\t},\n\n\t\tfill: function(){\n\t\t\tvar d = new Date(this.viewDate),\n\t\t\t\tyear = d.getUTCFullYear(),\n\t\t\t\tmonth = d.getUTCMonth(),\n\t\t\t\tstartYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity,\n\t\t\t\tstartMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity,\n\t\t\t\tendYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity,\n\t\t\t\tendMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity,\n\t\t\t\ttodaytxt = dates[this.o.language].today || dates['en'].today || '',\n\t\t\t\tcleartxt = dates[this.o.language].clear || dates['en'].clear || '',\n\t\t\t\ttitleFormat = dates[this.o.language].titleFormat || dates['en'].titleFormat,\n\t\t\t\ttooltip,\n\t\t\t\tbefore;\n\t\t\tif (isNaN(year) || isNaN(month))\n\t\t\t\treturn;\n\t\t\tthis.picker.find('.datepicker-days .datepicker-switch')\n\t\t\t\t\t\t.text(DPGlobal.formatDate(d, titleFormat, this.o.language));\n\t\t\tthis.picker.find('tfoot .today')\n\t\t\t\t\t\t.text(todaytxt)\n\t\t\t\t\t\t.toggle(this.o.todayBtn !== false);\n\t\t\tthis.picker.find('tfoot .clear')\n\t\t\t\t\t\t.text(cleartxt)\n\t\t\t\t\t\t.toggle(this.o.clearBtn !== false);\n\t\t\tthis.picker.find('thead .datepicker-title')\n\t\t\t\t\t\t.text(this.o.title)\n\t\t\t\t\t\t.toggle(this.o.title !== '');\n\t\t\tthis.updateNavArrows();\n\t\t\tthis.fillMonths();\n\t\t\tvar prevMonth = UTCDate(year, month, 0),\n\t\t\t\tday = prevMonth.getUTCDate();\n\t\t\tprevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7);\n\t\t\tvar nextMonth = new Date(prevMonth);\n\t\t\tif (prevMonth.getUTCFullYear() < 100){\n        nextMonth.setUTCFullYear(prevMonth.getUTCFullYear());\n      }\n\t\t\tnextMonth.setUTCDate(nextMonth.getUTCDate() + 42);\n\t\t\tnextMonth = nextMonth.valueOf();\n\t\t\tvar html = [];\n\t\t\tvar weekDay, clsName;\n\t\t\twhile (prevMonth.valueOf() < nextMonth){\n\t\t\t\tweekDay = prevMonth.getUTCDay();\n\t\t\t\tif (weekDay === this.o.weekStart){\n\t\t\t\t\thtml.push('<tr>');\n\t\t\t\t\tif (this.o.calendarWeeks){\n\t\t\t\t\t\t// ISO 8601: First week contains first thursday.\n\t\t\t\t\t\t// ISO also states week starts on Monday, but we can be more abstract here.\n\t\t\t\t\t\tvar\n\t\t\t\t\t\t\t// Start of current week: based on weekstart/current date\n\t\t\t\t\t\t\tws = new Date(+prevMonth + (this.o.weekStart - weekDay - 7) % 7 * 864e5),\n\t\t\t\t\t\t\t// Thursday of this week\n\t\t\t\t\t\t\tth = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),\n\t\t\t\t\t\t\t// First Thursday of year, year from thursday\n\t\t\t\t\t\t\tyth = new Date(Number(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay()) % 7 * 864e5),\n\t\t\t\t\t\t\t// Calendar week: ms between thursdays, div ms per day, div 7 days\n\t\t\t\t\t\t\tcalWeek = (th - yth) / 864e5 / 7 + 1;\n\t\t\t\t\t\thtml.push('<td class=\"cw\">'+ calWeek +'</td>');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tclsName = this.getClassNames(prevMonth);\n\t\t\t\tclsName.push('day');\n\n\t\t\t\tif (this.o.beforeShowDay !== $.noop){\n\t\t\t\t\tbefore = this.o.beforeShowDay(this._utc_to_local(prevMonth));\n\t\t\t\t\tif (before === undefined)\n\t\t\t\t\t\tbefore = {};\n\t\t\t\t\telse if (typeof before === 'boolean')\n\t\t\t\t\t\tbefore = {enabled: before};\n\t\t\t\t\telse if (typeof before === 'string')\n\t\t\t\t\t\tbefore = {classes: before};\n\t\t\t\t\tif (before.enabled === false)\n\t\t\t\t\t\tclsName.push('disabled');\n\t\t\t\t\tif (before.classes)\n\t\t\t\t\t\tclsName = clsName.concat(before.classes.split(/\\s+/));\n\t\t\t\t\tif (before.tooltip)\n\t\t\t\t\t\ttooltip = before.tooltip;\n\t\t\t\t}\n\n\t\t\t\t//Check if uniqueSort exists (supported by jquery >=1.12 and >=2.2)\n\t\t\t\t//Fallback to unique function for older jquery versions\n\t\t\t\tif ($.isFunction($.uniqueSort)) {\n\t\t\t\t\tclsName = $.uniqueSort(clsName);\n\t\t\t\t} else {\n\t\t\t\t\tclsName = $.unique(clsName);\n\t\t\t\t}\n\n\t\t\t\thtml.push('<td class=\"'+clsName.join(' ')+'\"' + (tooltip ? ' title=\"'+tooltip+'\"' : '') + (this.o.dateCells ? ' data-date=\"'+(prevMonth.getTime().toString())+'\"' : '') + '>'+prevMonth.getUTCDate() + '</td>');\n\t\t\t\ttooltip = null;\n\t\t\t\tif (weekDay === this.o.weekEnd){\n\t\t\t\t\thtml.push('</tr>');\n\t\t\t\t}\n\t\t\t\tprevMonth.setUTCDate(prevMonth.getUTCDate() + 1);\n\t\t\t}\n\t\t\tthis.picker.find('.datepicker-days tbody').html(html.join(''));\n\n\t\t\tvar monthsTitle = dates[this.o.language].monthsTitle || dates['en'].monthsTitle || 'Months';\n\t\t\tvar months = this.picker.find('.datepicker-months')\n\t\t\t\t\t\t.find('.datepicker-switch')\n\t\t\t\t\t\t\t.text(this.o.maxViewMode < 2 ? monthsTitle : year)\n\t\t\t\t\t\t\t.end()\n\t\t\t\t\t\t.find('tbody span').removeClass('active');\n\n\t\t\t$.each(this.dates, function(i, d){\n\t\t\t\tif (d.getUTCFullYear() === year)\n\t\t\t\t\tmonths.eq(d.getUTCMonth()).addClass('active');\n\t\t\t});\n\n\t\t\tif (year < startYear || year > endYear){\n\t\t\t\tmonths.addClass('disabled');\n\t\t\t}\n\t\t\tif (year === startYear){\n\t\t\t\tmonths.slice(0, startMonth).addClass('disabled');\n\t\t\t}\n\t\t\tif (year === endYear){\n\t\t\t\tmonths.slice(endMonth+1).addClass('disabled');\n\t\t\t}\n\n\t\t\tif (this.o.beforeShowMonth !== $.noop){\n\t\t\t\tvar that = this;\n\t\t\t\t$.each(months, function(i, month){\n          var moDate = new Date(year, i, 1);\n          var before = that.o.beforeShowMonth(moDate);\n\t\t\t\t\tif (before === undefined)\n\t\t\t\t\t\tbefore = {};\n\t\t\t\t\telse if (typeof before === 'boolean')\n\t\t\t\t\t\tbefore = {enabled: before};\n\t\t\t\t\telse if (typeof before === 'string')\n\t\t\t\t\t\tbefore = {classes: before};\n\t\t\t\t\tif (before.enabled === false && !$(month).hasClass('disabled'))\n\t\t\t\t\t    $(month).addClass('disabled');\n\t\t\t\t\tif (before.classes)\n\t\t\t\t\t    $(month).addClass(before.classes);\n\t\t\t\t\tif (before.tooltip)\n\t\t\t\t\t    $(month).prop('title', before.tooltip);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Generating decade/years picker\n\t\t\tthis._fill_yearsView(\n\t\t\t\t'.datepicker-years',\n\t\t\t\t'year',\n\t\t\t\t10,\n\t\t\t\t1,\n\t\t\t\tyear,\n\t\t\t\tstartYear,\n\t\t\t\tendYear,\n\t\t\t\tthis.o.beforeShowYear\n\t\t\t);\n\n\t\t\t// Generating century/decades picker\n\t\t\tthis._fill_yearsView(\n\t\t\t\t'.datepicker-decades',\n\t\t\t\t'decade',\n\t\t\t\t100,\n\t\t\t\t10,\n\t\t\t\tyear,\n\t\t\t\tstartYear,\n\t\t\t\tendYear,\n\t\t\t\tthis.o.beforeShowDecade\n\t\t\t);\n\n\t\t\t// Generating millennium/centuries picker\n\t\t\tthis._fill_yearsView(\n\t\t\t\t'.datepicker-centuries',\n\t\t\t\t'century',\n\t\t\t\t1000,\n\t\t\t\t100,\n\t\t\t\tyear,\n\t\t\t\tstartYear,\n\t\t\t\tendYear,\n\t\t\t\tthis.o.beforeShowCentury\n\t\t\t);\n\t\t},\n\n\t\tupdateNavArrows: function(){\n\t\t\tif (!this._allow_update)\n\t\t\t\treturn;\n\n\t\t\tvar d = new Date(this.viewDate),\n\t\t\t\tyear = d.getUTCFullYear(),\n\t\t\t\tmonth = d.getUTCMonth(),\n\t\t\t\tprevState,\n\t\t\t\tnextState;\n\t\t\tswitch (this.viewMode){\n\t\t\t\tcase 0:\n\t\t\t\t\tprevState = (\n\t\t\t\t\t\tthis.o.startDate !== -Infinity &&\n\t\t\t\t\t\tyear <= this.o.startDate.getUTCFullYear() &&\n\t\t\t\t\t\tmonth <= this.o.startDate.getUTCMonth()\n\t\t\t\t\t);\n\n\t\t\t\t\tnextState = (\n\t\t\t\t\t\tthis.o.endDate !== Infinity &&\n\t\t\t\t\t\tyear >= this.o.endDate.getUTCFullYear() &&\n\t\t\t\t\t\tmonth >= this.o.endDate.getUTCMonth()\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\tcase 2:\n\t\t\t\tcase 3:\n\t\t\t\tcase 4:\n\t\t\t\t\tprevState = (\n\t\t\t\t\t\tthis.o.startDate !== -Infinity &&\n\t\t\t\t\t\tyear <= this.o.startDate.getUTCFullYear()\n\t\t\t\t\t);\n\n\t\t\t\t\tnextState = (\n\t\t\t\t\t\tthis.o.endDate !== Infinity &&\n\t\t\t\t\t\tyear >= this.o.endDate.getUTCFullYear()\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tthis.picker.find('.prev').toggleClass('disabled', prevState);\n\t\t\tthis.picker.find('.next').toggleClass('disabled', nextState);\n\t\t},\n\n\t\tclick: function(e){\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\n\t\t\tvar target, dir, day, year, month;\n\t\t\ttarget = $(e.target);\n\n\t\t\t// Clicked on the switch\n\t\t\tif (target.hasClass('datepicker-switch') && this.viewMode !== this.o.maxViewMode){\n\t\t\t\tthis.setViewMode(this.viewMode + 1);\n\t\t\t}\n\n\t\t\t// Clicked on today button\n\t\t\tif (target.hasClass('today') && !target.hasClass('day')){\n\t\t\t\tthis.setViewMode(0);\n\t\t\t\tthis._setDate(UTCToday(), this.o.todayBtn === 'linked' ? null : 'view');\n\t\t\t}\n\n\t\t\t// Clicked on clear button\n\t\t\tif (target.hasClass('clear')){\n\t\t\t\tthis.clearDates();\n\t\t\t}\n\n\t\t\tif (!target.hasClass('disabled')){\n\t\t\t\t// Clicked on a day\n\t\t\t\tif (target.hasClass('day')){\n\t\t\t\t\tday = Number(target.text());\n\t\t\t\t\tyear = this.viewDate.getUTCFullYear();\n\t\t\t\t\tmonth = this.viewDate.getUTCMonth();\n\n\t\t\t\t\tif (target.hasClass('old') || target.hasClass('new')){\n\t\t\t\t\t\tdir = target.hasClass('old') ? -1 : 1;\n\t\t\t\t\t\tmonth = (month + dir + 12) % 12;\n\t\t\t\t\t\tif ((dir === -1 && month === 11) || (dir === 1 && month === 0)) {\n\t\t\t\t\t\t\tyear += dir;\n\t\t\t\t\t\t\tif (this.o.updateViewDate) {\n\t\t\t\t\t\t\t\tthis._trigger('changeYear', this.viewDate);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (this.o.updateViewDate) {\n\t\t\t\t\t\t\tthis._trigger('changeMonth', this.viewDate);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis._setDate(UTCDate(year, month, day));\n\t\t\t\t}\n\n\t\t\t\t// Clicked on a month, year, decade, century\n\t\t\t\tif (target.hasClass('month')\n\t\t\t\t\t\t|| target.hasClass('year')\n\t\t\t\t\t\t|| target.hasClass('decade')\n\t\t\t\t\t\t|| target.hasClass('century')) {\n\t\t\t\t\tthis.viewDate.setUTCDate(1);\n\n\t\t\t\t\tday = 1;\n\t\t\t\t\tif (this.viewMode === 1){\n\t\t\t\t\t\tmonth = target.parent().find('span').index(target);\n\t\t\t\t\t\tyear = this.viewDate.getUTCFullYear();\n\t\t\t\t\t\tthis.viewDate.setUTCMonth(month);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tmonth = 0;\n\t\t\t\t\t\tyear = Number(target.text());\n\t\t\t\t\t\tthis.viewDate.setUTCFullYear(year);\n\t\t\t\t\t}\n\n\t\t\t\t\tthis._trigger(DPGlobal.viewModes[this.viewMode - 1].e, this.viewDate);\n\n\t\t\t\t\tif (this.viewMode === this.o.minViewMode){\n\t\t\t\t\t\tthis._setDate(UTCDate(year, month, day));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.setViewMode(this.viewMode - 1);\n\t\t\t\t\t\tthis.fill();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.picker.is(':visible') && this._focused_from){\n\t\t\t\tthis._focused_from.focus();\n\t\t\t}\n\t\t\tdelete this._focused_from;\n\t\t},\n\n\t\t// Clicked on prev or next\n\t\tnavArrowsClick: function(e){\n\t\t\tvar target = $(e.target);\n\t\t\tvar dir = target.hasClass('prev') ? -1 : 1;\n\t\t\tif (this.viewMode !== 0){\n\t\t\t\tdir *= DPGlobal.viewModes[this.viewMode].navStep * 12;\n\t\t\t}\n\t\t\tthis.viewDate = this.moveMonth(this.viewDate, dir);\n\t\t\tthis._trigger(DPGlobal.viewModes[this.viewMode].e, this.viewDate);\n\t\t\tthis.fill();\n\t\t},\n\n\t\t_toggle_multidate: function(date){\n\t\t\tvar ix = this.dates.contains(date);\n\t\t\tif (!date){\n\t\t\t\tthis.dates.clear();\n\t\t\t}\n\n\t\t\tif (ix !== -1){\n\t\t\t\tif (this.o.multidate === true || this.o.multidate > 1 || this.o.toggleActive){\n\t\t\t\t\tthis.dates.remove(ix);\n\t\t\t\t}\n\t\t\t} else if (this.o.multidate === false) {\n\t\t\t\tthis.dates.clear();\n\t\t\t\tthis.dates.push(date);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.dates.push(date);\n\t\t\t}\n\n\t\t\tif (typeof this.o.multidate === 'number')\n\t\t\t\twhile (this.dates.length > this.o.multidate)\n\t\t\t\t\tthis.dates.remove(0);\n\t\t},\n\n\t\t_setDate: function(date, which){\n\t\t\tif (!which || which === 'date')\n\t\t\t\tthis._toggle_multidate(date && new Date(date));\n\t\t\tif ((!which && this.o.updateViewDate) || which === 'view')\n\t\t\t\tthis.viewDate = date && new Date(date);\n\n\t\t\tthis.fill();\n\t\t\tthis.setValue();\n\t\t\tif (!which || which !== 'view') {\n\t\t\t\tthis._trigger('changeDate');\n\t\t\t}\n\t\t\tthis.inputField.trigger('change');\n\t\t\tif (this.o.autoclose && (!which || which === 'date')){\n\t\t\t\tthis.hide();\n\t\t\t}\n\t\t},\n\n\t\tmoveDay: function(date, dir){\n\t\t\tvar newDate = new Date(date);\n\t\t\tnewDate.setUTCDate(date.getUTCDate() + dir);\n\n\t\t\treturn newDate;\n\t\t},\n\n\t\tmoveWeek: function(date, dir){\n\t\t\treturn this.moveDay(date, dir * 7);\n\t\t},\n\n\t\tmoveMonth: function(date, dir){\n\t\t\tif (!isValidDate(date))\n\t\t\t\treturn this.o.defaultViewDate;\n\t\t\tif (!dir)\n\t\t\t\treturn date;\n\t\t\tvar new_date = new Date(date.valueOf()),\n\t\t\t\tday = new_date.getUTCDate(),\n\t\t\t\tmonth = new_date.getUTCMonth(),\n\t\t\t\tmag = Math.abs(dir),\n\t\t\t\tnew_month, test;\n\t\t\tdir = dir > 0 ? 1 : -1;\n\t\t\tif (mag === 1){\n\t\t\t\ttest = dir === -1\n\t\t\t\t\t// If going back one month, make sure month is not current month\n\t\t\t\t\t// (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02)\n\t\t\t\t\t? function(){\n\t\t\t\t\t\treturn new_date.getUTCMonth() === month;\n\t\t\t\t\t}\n\t\t\t\t\t// If going forward one month, make sure month is as expected\n\t\t\t\t\t// (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02)\n\t\t\t\t\t: function(){\n\t\t\t\t\t\treturn new_date.getUTCMonth() !== new_month;\n\t\t\t\t\t};\n\t\t\t\tnew_month = month + dir;\n\t\t\t\tnew_date.setUTCMonth(new_month);\n\t\t\t\t// Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11\n\t\t\t\tnew_month = (new_month + 12) % 12;\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// For magnitudes >1, move one month at a time...\n\t\t\t\tfor (var i=0; i < mag; i++)\n\t\t\t\t\t// ...which might decrease the day (eg, Jan 31 to Feb 28, etc)...\n\t\t\t\t\tnew_date = this.moveMonth(new_date, dir);\n\t\t\t\t// ...then reset the day, keeping it in the new month\n\t\t\t\tnew_month = new_date.getUTCMonth();\n\t\t\t\tnew_date.setUTCDate(day);\n\t\t\t\ttest = function(){\n\t\t\t\t\treturn new_month !== new_date.getUTCMonth();\n\t\t\t\t};\n\t\t\t}\n\t\t\t// Common date-resetting loop -- if date is beyond end of month, make it\n\t\t\t// end of month\n\t\t\twhile (test()){\n\t\t\t\tnew_date.setUTCDate(--day);\n\t\t\t\tnew_date.setUTCMonth(new_month);\n\t\t\t}\n\t\t\treturn new_date;\n\t\t},\n\n\t\tmoveYear: function(date, dir){\n\t\t\treturn this.moveMonth(date, dir*12);\n\t\t},\n\n\t\tmoveAvailableDate: function(date, dir, fn){\n\t\t\tdo {\n\t\t\t\tdate = this[fn](date, dir);\n\n\t\t\t\tif (!this.dateWithinRange(date))\n\t\t\t\t\treturn false;\n\n\t\t\t\tfn = 'moveDay';\n\t\t\t}\n\t\t\twhile (this.dateIsDisabled(date));\n\n\t\t\treturn date;\n\t\t},\n\n\t\tweekOfDateIsDisabled: function(date){\n\t\t\treturn $.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1;\n\t\t},\n\n\t\tdateIsDisabled: function(date){\n\t\t\treturn (\n\t\t\t\tthis.weekOfDateIsDisabled(date) ||\n\t\t\t\t$.grep(this.o.datesDisabled, function(d){\n\t\t\t\t\treturn isUTCEquals(date, d);\n\t\t\t\t}).length > 0\n\t\t\t);\n\t\t},\n\n\t\tdateWithinRange: function(date){\n\t\t\treturn date >= this.o.startDate && date <= this.o.endDate;\n\t\t},\n\n\t\tkeydown: function(e){\n\t\t\tif (!this.picker.is(':visible')){\n\t\t\t\tif (e.keyCode === 40 || e.keyCode === 27) { // allow down to re-show picker\n\t\t\t\t\tthis.show();\n\t\t\t\t\te.stopPropagation();\n        }\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar dateChanged = false,\n\t\t\t\tdir, newViewDate,\n\t\t\t\tfocusDate = this.focusDate || this.viewDate;\n\t\t\tswitch (e.keyCode){\n\t\t\t\tcase 27: // escape\n\t\t\t\t\tif (this.focusDate){\n\t\t\t\t\t\tthis.focusDate = null;\n\t\t\t\t\t\tthis.viewDate = this.dates.get(-1) || this.viewDate;\n\t\t\t\t\t\tthis.fill();\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tthis.hide();\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\te.stopPropagation();\n\t\t\t\t\tbreak;\n\t\t\t\tcase 37: // left\n\t\t\t\tcase 38: // up\n\t\t\t\tcase 39: // right\n\t\t\t\tcase 40: // down\n\t\t\t\t\tif (!this.o.keyboardNavigation || this.o.daysOfWeekDisabled.length === 7)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdir = e.keyCode === 37 || e.keyCode === 38 ? -1 : 1;\n          if (this.viewMode === 0) {\n  \t\t\t\t\tif (e.ctrlKey){\n  \t\t\t\t\t\tnewViewDate = this.moveAvailableDate(focusDate, dir, 'moveYear');\n\n  \t\t\t\t\t\tif (newViewDate)\n  \t\t\t\t\t\t\tthis._trigger('changeYear', this.viewDate);\n  \t\t\t\t\t} else if (e.shiftKey){\n  \t\t\t\t\t\tnewViewDate = this.moveAvailableDate(focusDate, dir, 'moveMonth');\n\n  \t\t\t\t\t\tif (newViewDate)\n  \t\t\t\t\t\t\tthis._trigger('changeMonth', this.viewDate);\n  \t\t\t\t\t} else if (e.keyCode === 37 || e.keyCode === 39){\n  \t\t\t\t\t\tnewViewDate = this.moveAvailableDate(focusDate, dir, 'moveDay');\n  \t\t\t\t\t} else if (!this.weekOfDateIsDisabled(focusDate)){\n  \t\t\t\t\t\tnewViewDate = this.moveAvailableDate(focusDate, dir, 'moveWeek');\n  \t\t\t\t\t}\n          } else if (this.viewMode === 1) {\n            if (e.keyCode === 38 || e.keyCode === 40) {\n              dir = dir * 4;\n            }\n            newViewDate = this.moveAvailableDate(focusDate, dir, 'moveMonth');\n          } else if (this.viewMode === 2) {\n            if (e.keyCode === 38 || e.keyCode === 40) {\n              dir = dir * 4;\n            }\n            newViewDate = this.moveAvailableDate(focusDate, dir, 'moveYear');\n          }\n\t\t\t\t\tif (newViewDate){\n\t\t\t\t\t\tthis.focusDate = this.viewDate = newViewDate;\n\t\t\t\t\t\tthis.setValue();\n\t\t\t\t\t\tthis.fill();\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 13: // enter\n\t\t\t\t\tif (!this.o.forceParse)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tfocusDate = this.focusDate || this.dates.get(-1) || this.viewDate;\n\t\t\t\t\tif (this.o.keyboardNavigation) {\n\t\t\t\t\t\tthis._toggle_multidate(focusDate);\n\t\t\t\t\t\tdateChanged = true;\n\t\t\t\t\t}\n\t\t\t\t\tthis.focusDate = null;\n\t\t\t\t\tthis.viewDate = this.dates.get(-1) || this.viewDate;\n\t\t\t\t\tthis.setValue();\n\t\t\t\t\tthis.fill();\n\t\t\t\t\tif (this.picker.is(':visible')){\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\tif (this.o.autoclose)\n\t\t\t\t\t\t\tthis.hide();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 9: // tab\n\t\t\t\t\tthis.focusDate = null;\n\t\t\t\t\tthis.viewDate = this.dates.get(-1) || this.viewDate;\n\t\t\t\t\tthis.fill();\n\t\t\t\t\tthis.hide();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (dateChanged){\n\t\t\t\tif (this.dates.length)\n\t\t\t\t\tthis._trigger('changeDate');\n\t\t\t\telse\n\t\t\t\t\tthis._trigger('clearDate');\n\t\t\t\tthis.inputField.trigger('change');\n\t\t\t}\n\t\t},\n\n\t\tsetViewMode: function(viewMode){\n\t\t\tthis.viewMode = viewMode;\n\t\t\tthis.picker\n\t\t\t\t.children('div')\n\t\t\t\t.hide()\n\t\t\t\t.filter('.datepicker-' + DPGlobal.viewModes[this.viewMode].clsName)\n\t\t\t\t\t.show();\n\t\t\tthis.updateNavArrows();\n      this._trigger('changeViewMode', new Date(this.viewDate));\n\t\t}\n\t};\n\n\tvar DateRangePicker = function(element, options){\n\t\t$.data(element, 'datepicker', this);\n\t\tthis.element = $(element);\n\t\tthis.inputs = $.map(options.inputs, function(i){\n\t\t\treturn i.jquery ? i[0] : i;\n\t\t});\n\t\tdelete options.inputs;\n\n\t\tthis.keepEmptyValues = options.keepEmptyValues;\n\t\tdelete options.keepEmptyValues;\n\n\t\tdatepickerPlugin.call($(this.inputs), options)\n\t\t\t.on('changeDate', $.proxy(this.dateUpdated, this));\n\n\t\tthis.pickers = $.map(this.inputs, function(i){\n\t\t\treturn $.data(i, 'datepicker');\n\t\t});\n\t\tthis.updateDates();\n\t};\n\tDateRangePicker.prototype = {\n\t\tupdateDates: function(){\n\t\t\tthis.dates = $.map(this.pickers, function(i){\n\t\t\t\treturn i.getUTCDate();\n\t\t\t});\n\t\t\tthis.updateRanges();\n\t\t},\n\t\tupdateRanges: function(){\n\t\t\tvar range = $.map(this.dates, function(d){\n\t\t\t\treturn d.valueOf();\n\t\t\t});\n\t\t\t$.each(this.pickers, function(i, p){\n\t\t\t\tp.setRange(range);\n\t\t\t});\n\t\t},\n\t\tdateUpdated: function(e){\n\t\t\t// `this.updating` is a workaround for preventing infinite recursion\n\t\t\t// between `changeDate` triggering and `setUTCDate` calling.  Until\n\t\t\t// there is a better mechanism.\n\t\t\tif (this.updating)\n\t\t\t\treturn;\n\t\t\tthis.updating = true;\n\n\t\t\tvar dp = $.data(e.target, 'datepicker');\n\n\t\t\tif (dp === undefined) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar new_date = dp.getUTCDate(),\n\t\t\t\tkeep_empty_values = this.keepEmptyValues,\n\t\t\t\ti = $.inArray(e.target, this.inputs),\n\t\t\t\tj = i - 1,\n\t\t\t\tk = i + 1,\n\t\t\t\tl = this.inputs.length;\n\t\t\tif (i === -1)\n\t\t\t\treturn;\n\n\t\t\t$.each(this.pickers, function(i, p){\n\t\t\t\tif (!p.getUTCDate() && (p === dp || !keep_empty_values))\n\t\t\t\t\tp.setUTCDate(new_date);\n\t\t\t});\n\n\t\t\tif (new_date < this.dates[j]){\n\t\t\t\t// Date being moved earlier/left\n\t\t\t\twhile (j >= 0 && new_date < this.dates[j]){\n\t\t\t\t\tthis.pickers[j--].setUTCDate(new_date);\n\t\t\t\t}\n\t\t\t} else if (new_date > this.dates[k]){\n\t\t\t\t// Date being moved later/right\n\t\t\t\twhile (k < l && new_date > this.dates[k]){\n\t\t\t\t\tthis.pickers[k++].setUTCDate(new_date);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.updateDates();\n\n\t\t\tdelete this.updating;\n\t\t},\n\t\tdestroy: function(){\n\t\t\t$.map(this.pickers, function(p){ p.destroy(); });\n\t\t\t$(this.inputs).off('changeDate', this.dateUpdated);\n\t\t\tdelete this.element.data().datepicker;\n\t\t},\n\t\tremove: alias('destroy')\n\t};\n\n\tfunction opts_from_el(el, prefix){\n\t\t// Derive options from element data-attrs\n\t\tvar data = $(el).data(),\n\t\t\tout = {}, inkey,\n\t\t\treplace = new RegExp('^' + prefix.toLowerCase() + '([A-Z])');\n\t\tprefix = new RegExp('^' + prefix.toLowerCase());\n\t\tfunction re_lower(_,a){\n\t\t\treturn a.toLowerCase();\n\t\t}\n\t\tfor (var key in data)\n\t\t\tif (prefix.test(key)){\n\t\t\t\tinkey = key.replace(replace, re_lower);\n\t\t\t\tout[inkey] = data[key];\n\t\t\t}\n\t\treturn out;\n\t}\n\n\tfunction opts_from_locale(lang){\n\t\t// Derive options from locale plugins\n\t\tvar out = {};\n\t\t// Check if \"de-DE\" style date is available, if not language should\n\t\t// fallback to 2 letter code eg \"de\"\n\t\tif (!dates[lang]){\n\t\t\tlang = lang.split('-')[0];\n\t\t\tif (!dates[lang])\n\t\t\t\treturn;\n\t\t}\n\t\tvar d = dates[lang];\n\t\t$.each(locale_opts, function(i,k){\n\t\t\tif (k in d)\n\t\t\t\tout[k] = d[k];\n\t\t});\n\t\treturn out;\n\t}\n\n\tvar old = $.fn.datepicker;\n\tvar datepickerPlugin = function(option){\n\t\tvar args = Array.apply(null, arguments);\n\t\targs.shift();\n\t\tvar internal_return;\n\t\tthis.each(function(){\n\t\t\tvar $this = $(this),\n\t\t\t\tdata = $this.data('datepicker'),\n\t\t\t\toptions = typeof option === 'object' && option;\n\t\t\tif (!data){\n\t\t\t\tvar elopts = opts_from_el(this, 'date'),\n\t\t\t\t\t// Preliminary otions\n\t\t\t\t\txopts = $.extend({}, defaults, elopts, options),\n\t\t\t\t\tlocopts = opts_from_locale(xopts.language),\n\t\t\t\t\t// Options priority: js args, data-attrs, locales, defaults\n\t\t\t\t\topts = $.extend({}, defaults, locopts, elopts, options);\n\t\t\t\tif ($this.hasClass('input-daterange') || opts.inputs){\n\t\t\t\t\t$.extend(opts, {\n\t\t\t\t\t\tinputs: opts.inputs || $this.find('input').toArray()\n\t\t\t\t\t});\n\t\t\t\t\tdata = new DateRangePicker(this, opts);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tdata = new Datepicker(this, opts);\n\t\t\t\t}\n\t\t\t\t$this.data('datepicker', data);\n\t\t\t}\n\t\t\tif (typeof option === 'string' && typeof data[option] === 'function'){\n\t\t\t\tinternal_return = data[option].apply(data, args);\n\t\t\t}\n\t\t});\n\n\t\tif (\n\t\t\tinternal_return === undefined ||\n\t\t\tinternal_return instanceof Datepicker ||\n\t\t\tinternal_return instanceof DateRangePicker\n\t\t)\n\t\t\treturn this;\n\n\t\tif (this.length > 1)\n\t\t\tthrow new Error('Using only allowed for the collection of a single element (' + option + ' function)');\n\t\telse\n\t\t\treturn internal_return;\n\t};\n\t$.fn.datepicker = datepickerPlugin;\n\n\tvar defaults = $.fn.datepicker.defaults = {\n\t\tassumeNearbyYear: false,\n\t\tautoclose: false,\n\t\tbeforeShowDay: $.noop,\n\t\tbeforeShowMonth: $.noop,\n\t\tbeforeShowYear: $.noop,\n\t\tbeforeShowDecade: $.noop,\n\t\tbeforeShowCentury: $.noop,\n\t\tcalendarWeeks: false,\n\t\tclearBtn: false,\n\t\ttoggleActive: false,\n\t\tdaysOfWeekDisabled: [],\n\t\tdaysOfWeekHighlighted: [],\n\t\tdatesDisabled: [],\n\t\tendDate: Infinity,\n\t\tforceParse: true,\n\t\tformat: 'mm/dd/yyyy',\n\t\tkeepEmptyValues: false,\n\t\tkeyboardNavigation: true,\n\t\tlanguage: 'en',\n\t\tminViewMode: 0,\n\t\tmaxViewMode: 4,\n\t\tmultidate: false,\n\t\tmultidateSeparator: ',',\n\t\torientation: \"auto\",\n\t\trtl: false,\n\t\tstartDate: -Infinity,\n\t\tstartView: 0,\n\t\ttodayBtn: false,\n\t\ttodayHighlight: false,\n\t\tupdateViewDate: true,\n\t\tweekStart: 0,\n\t\tdisableTouchKeyboard: false,\n\t\tenableOnReadonly: true,\n\t\tshowOnFocus: true,\n\t\tzIndexOffset: 10,\n\t\tcontainer: 'body',\n\t\timmediateUpdates: false,\n\t\tdateCells:false,\n\t\ttitle: '',\n\t\ttemplates: {\n\t\t\tleftArrow: '&#x00AB;',\n\t\t\trightArrow: '&#x00BB;'\n\t\t}\n\t};\n\tvar locale_opts = $.fn.datepicker.locale_opts = [\n\t\t'format',\n\t\t'rtl',\n\t\t'weekStart'\n\t];\n\t$.fn.datepicker.Constructor = Datepicker;\n\tvar dates = $.fn.datepicker.dates = {\n\t\ten: {\n\t\t\tdays: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"],\n\t\t\tdaysShort: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n\t\t\tdaysMin: [\"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\"],\n\t\t\tmonths: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"],\n\t\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"],\n\t\t\ttoday: \"Today\",\n\t\t\tclear: \"Clear\",\n\t\t\ttitleFormat: \"MM yyyy\"\n\t\t}\n\t};\n\n\tvar DPGlobal = {\n\t\tviewModes: [\n\t\t\t{\n\t\t\t\tnames: ['days', 'month'],\n\t\t\t\tclsName: 'days',\n\t\t\t\te: 'changeMonth'\n\t\t\t},\n\t\t\t{\n\t\t\t\tnames: ['months', 'year'],\n\t\t\t\tclsName: 'months',\n\t\t\t\te: 'changeYear',\n\t\t\t\tnavStep: 1\n\t\t\t},\n\t\t\t{\n\t\t\t\tnames: ['years', 'decade'],\n\t\t\t\tclsName: 'years',\n\t\t\t\te: 'changeDecade',\n\t\t\t\tnavStep: 10\n\t\t\t},\n\t\t\t{\n\t\t\t\tnames: ['decades', 'century'],\n\t\t\t\tclsName: 'decades',\n\t\t\t\te: 'changeCentury',\n\t\t\t\tnavStep: 100\n\t\t\t},\n\t\t\t{\n\t\t\t\tnames: ['centuries', 'millennium'],\n\t\t\t\tclsName: 'centuries',\n\t\t\t\te: 'changeMillennium',\n\t\t\t\tnavStep: 1000\n\t\t\t}\n\t\t],\n\t\tvalidParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g,\n\t\tnonpunctuation: /[^ -\\/:-@\\u5e74\\u6708\\u65e5\\[-`{-~\\t\\n\\r]+/g,\n\t\tparseFormat: function(format){\n\t\t\tif (typeof format.toValue === 'function' && typeof format.toDisplay === 'function')\n                return format;\n            // IE treats \\0 as a string end in inputs (truncating the value),\n\t\t\t// so it's a bad format delimiter, anyway\n\t\t\tvar separators = format.replace(this.validParts, '\\0').split('\\0'),\n\t\t\t\tparts = format.match(this.validParts);\n\t\t\tif (!separators || !separators.length || !parts || parts.length === 0){\n\t\t\t\tthrow new Error(\"Invalid date format.\");\n\t\t\t}\n\t\t\treturn {separators: separators, parts: parts};\n\t\t},\n\t\tparseDate: function(date, format, language, assumeNearby){\n\t\t\tif (!date)\n\t\t\t\treturn undefined;\n\t\t\tif (date instanceof Date)\n\t\t\t\treturn date;\n\t\t\tif (typeof format === 'string')\n\t\t\t\tformat = DPGlobal.parseFormat(format);\n\t\t\tif (format.toValue)\n\t\t\t\treturn format.toValue(date, format, language);\n\t\t\tvar fn_map = {\n\t\t\t\t\td: 'moveDay',\n\t\t\t\t\tm: 'moveMonth',\n\t\t\t\t\tw: 'moveWeek',\n\t\t\t\t\ty: 'moveYear'\n\t\t\t\t},\n\t\t\t\tdateAliases = {\n\t\t\t\t\tyesterday: '-1d',\n\t\t\t\t\ttoday: '+0d',\n\t\t\t\t\ttomorrow: '+1d'\n\t\t\t\t},\n\t\t\t\tparts, part, dir, i, fn;\n\t\t\tif (date in dateAliases){\n\t\t\t\tdate = dateAliases[date];\n\t\t\t}\n\t\t\tif (/^[\\-+]\\d+[dmwy]([\\s,]+[\\-+]\\d+[dmwy])*$/i.test(date)){\n\t\t\t\tparts = date.match(/([\\-+]\\d+)([dmwy])/gi);\n\t\t\t\tdate = new Date();\n\t\t\t\tfor (i=0; i < parts.length; i++){\n\t\t\t\t\tpart = parts[i].match(/([\\-+]\\d+)([dmwy])/i);\n\t\t\t\t\tdir = Number(part[1]);\n\t\t\t\t\tfn = fn_map[part[2].toLowerCase()];\n\t\t\t\t\tdate = Datepicker.prototype[fn](date, dir);\n\t\t\t\t}\n\t\t\t\treturn UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());\n\t\t\t}\n\n\t\t\tparts = date && date.match(this.nonpunctuation) || [];\n\t\t\tdate = new Date();\n\n\t\t\tfunction applyNearbyYear(year, threshold){\n\t\t\t\tif (threshold === true)\n\t\t\t\t\tthreshold = 10;\n\n\t\t\t\t// if year is 2 digits or less, than the user most likely is trying to get a recent century\n\t\t\t\tif (year < 100){\n\t\t\t\t\tyear += 2000;\n\t\t\t\t\t// if the new year is more than threshold years in advance, use last century\n\t\t\t\t\tif (year > ((new Date()).getFullYear()+threshold)){\n\t\t\t\t\t\tyear -= 100;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn year;\n\t\t\t}\n\n\t\t\tvar parsed = {},\n\t\t\t\tsetters_order = ['yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'],\n\t\t\t\tsetters_map = {\n\t\t\t\t\tyyyy: function(d,v){\n\t\t\t\t\t\treturn d.setUTCFullYear(assumeNearby ? applyNearbyYear(v, assumeNearby) : v);\n\t\t\t\t\t},\n\t\t\t\t\tm: function(d,v){\n\t\t\t\t\t\tif (isNaN(d))\n\t\t\t\t\t\t\treturn d;\n\t\t\t\t\t\tv -= 1;\n\t\t\t\t\t\twhile (v < 0) v += 12;\n\t\t\t\t\t\tv %= 12;\n\t\t\t\t\t\td.setUTCMonth(v);\n\t\t\t\t\t\twhile (d.getUTCMonth() !== v)\n\t\t\t\t\t\t\td.setUTCDate(d.getUTCDate()-1);\n\t\t\t\t\t\treturn d;\n\t\t\t\t\t},\n\t\t\t\t\td: function(d,v){\n\t\t\t\t\t\treturn d.setUTCDate(v);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tval, filtered;\n\t\t\tsetters_map['yy'] = setters_map['yyyy'];\n\t\t\tsetters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];\n\t\t\tsetters_map['dd'] = setters_map['d'];\n\t\t\tdate = UTCToday();\n\t\t\tvar fparts = format.parts.slice();\n\t\t\t// Remove noop parts\n\t\t\tif (parts.length !== fparts.length){\n\t\t\t\tfparts = $(fparts).filter(function(i,p){\n\t\t\t\t\treturn $.inArray(p, setters_order) !== -1;\n\t\t\t\t}).toArray();\n\t\t\t}\n\t\t\t// Process remainder\n\t\t\tfunction match_part(){\n\t\t\t\tvar m = this.slice(0, parts[i].length),\n\t\t\t\t\tp = parts[i].slice(0, m.length);\n\t\t\t\treturn m.toLowerCase() === p.toLowerCase();\n\t\t\t}\n\t\t\tif (parts.length === fparts.length){\n\t\t\t\tvar cnt;\n\t\t\t\tfor (i=0, cnt = fparts.length; i < cnt; i++){\n\t\t\t\t\tval = parseInt(parts[i], 10);\n\t\t\t\t\tpart = fparts[i];\n\t\t\t\t\tif (isNaN(val)){\n\t\t\t\t\t\tswitch (part){\n\t\t\t\t\t\t\tcase 'MM':\n\t\t\t\t\t\t\t\tfiltered = $(dates[language].months).filter(match_part);\n\t\t\t\t\t\t\t\tval = $.inArray(filtered[0], dates[language].months) + 1;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'M':\n\t\t\t\t\t\t\t\tfiltered = $(dates[language].monthsShort).filter(match_part);\n\t\t\t\t\t\t\t\tval = $.inArray(filtered[0], dates[language].monthsShort) + 1;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tparsed[part] = val;\n\t\t\t\t}\n\t\t\t\tvar _date, s;\n\t\t\t\tfor (i=0; i < setters_order.length; i++){\n\t\t\t\t\ts = setters_order[i];\n\t\t\t\t\tif (s in parsed && !isNaN(parsed[s])){\n\t\t\t\t\t\t_date = new Date(date);\n\t\t\t\t\t\tsetters_map[s](_date, parsed[s]);\n\t\t\t\t\t\tif (!isNaN(_date))\n\t\t\t\t\t\t\tdate = _date;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn date;\n\t\t},\n\t\tformatDate: function(date, format, language){\n\t\t\tif (!date)\n\t\t\t\treturn '';\n\t\t\tif (typeof format === 'string')\n\t\t\t\tformat = DPGlobal.parseFormat(format);\n\t\t\tif (format.toDisplay)\n                return format.toDisplay(date, format, language);\n            var val = {\n\t\t\t\td: date.getUTCDate(),\n\t\t\t\tD: dates[language].daysShort[date.getUTCDay()],\n\t\t\t\tDD: dates[language].days[date.getUTCDay()],\n\t\t\t\tm: date.getUTCMonth() + 1,\n\t\t\t\tM: dates[language].monthsShort[date.getUTCMonth()],\n\t\t\t\tMM: dates[language].months[date.getUTCMonth()],\n\t\t\t\tyy: date.getUTCFullYear().toString().substring(2),\n\t\t\t\tyyyy: date.getUTCFullYear()\n\t\t\t};\n\t\t\tval.dd = (val.d < 10 ? '0' : '') + val.d;\n\t\t\tval.mm = (val.m < 10 ? '0' : '') + val.m;\n\t\t\tdate = [];\n\t\t\tvar seps = $.extend([], format.separators);\n\t\t\tfor (var i=0, cnt = format.parts.length; i <= cnt; i++){\n\t\t\t\tif (seps.length)\n\t\t\t\t\tdate.push(seps.shift());\n\t\t\t\tdate.push(val[format.parts[i]]);\n\t\t\t}\n\t\t\treturn date.join('');\n\t\t},\n\t\theadTemplate: '<thead>'+\n\t\t\t              '<tr>'+\n\t\t\t                '<th colspan=\"7\" class=\"datepicker-title\"></th>'+\n\t\t\t              '</tr>'+\n\t\t\t\t\t\t\t'<tr>'+\n\t\t\t\t\t\t\t\t'<th class=\"prev\">&laquo;</th>'+\n\t\t\t\t\t\t\t\t'<th colspan=\"5\" class=\"datepicker-switch\"></th>'+\n\t\t\t\t\t\t\t\t'<th class=\"next\">&raquo;</th>'+\n\t\t\t\t\t\t\t'</tr>'+\n\t\t\t\t\t\t'</thead>',\n\t\tcontTemplate: '<tbody><tr><td colspan=\"7\"></td></tr></tbody>',\n\t\tfootTemplate: '<tfoot>'+\n\t\t\t\t\t\t\t'<tr>'+\n\t\t\t\t\t\t\t\t'<th colspan=\"7\" class=\"today\"></th>'+\n\t\t\t\t\t\t\t'</tr>'+\n\t\t\t\t\t\t\t'<tr>'+\n\t\t\t\t\t\t\t\t'<th colspan=\"7\" class=\"clear\"></th>'+\n\t\t\t\t\t\t\t'</tr>'+\n\t\t\t\t\t\t'</tfoot>'\n\t};\n\tDPGlobal.template = '<div class=\"datepicker\">'+\n\t\t\t\t\t\t\t'<div class=\"datepicker-days\">'+\n\t\t\t\t\t\t\t\t'<table class=\"table-condensed\">'+\n\t\t\t\t\t\t\t\t\tDPGlobal.headTemplate+\n\t\t\t\t\t\t\t\t\t'<tbody></tbody>'+\n\t\t\t\t\t\t\t\t\tDPGlobal.footTemplate+\n\t\t\t\t\t\t\t\t'</table>'+\n\t\t\t\t\t\t\t'</div>'+\n\t\t\t\t\t\t\t'<div class=\"datepicker-months\">'+\n\t\t\t\t\t\t\t\t'<table class=\"table-condensed\">'+\n\t\t\t\t\t\t\t\t\tDPGlobal.headTemplate+\n\t\t\t\t\t\t\t\t\tDPGlobal.contTemplate+\n\t\t\t\t\t\t\t\t\tDPGlobal.footTemplate+\n\t\t\t\t\t\t\t\t'</table>'+\n\t\t\t\t\t\t\t'</div>'+\n\t\t\t\t\t\t\t'<div class=\"datepicker-years\">'+\n\t\t\t\t\t\t\t\t'<table class=\"table-condensed\">'+\n\t\t\t\t\t\t\t\t\tDPGlobal.headTemplate+\n\t\t\t\t\t\t\t\t\tDPGlobal.contTemplate+\n\t\t\t\t\t\t\t\t\tDPGlobal.footTemplate+\n\t\t\t\t\t\t\t\t'</table>'+\n\t\t\t\t\t\t\t'</div>'+\n\t\t\t\t\t\t\t'<div class=\"datepicker-decades\">'+\n\t\t\t\t\t\t\t\t'<table class=\"table-condensed\">'+\n\t\t\t\t\t\t\t\t\tDPGlobal.headTemplate+\n\t\t\t\t\t\t\t\t\tDPGlobal.contTemplate+\n\t\t\t\t\t\t\t\t\tDPGlobal.footTemplate+\n\t\t\t\t\t\t\t\t'</table>'+\n\t\t\t\t\t\t\t'</div>'+\n\t\t\t\t\t\t\t'<div class=\"datepicker-centuries\">'+\n\t\t\t\t\t\t\t\t'<table class=\"table-condensed\">'+\n\t\t\t\t\t\t\t\t\tDPGlobal.headTemplate+\n\t\t\t\t\t\t\t\t\tDPGlobal.contTemplate+\n\t\t\t\t\t\t\t\t\tDPGlobal.footTemplate+\n\t\t\t\t\t\t\t\t'</table>'+\n\t\t\t\t\t\t\t'</div>'+\n\t\t\t\t\t\t'</div>';\n\n\t$.fn.datepicker.DPGlobal = DPGlobal;\n\n\n\t/* DATEPICKER NO CONFLICT\n\t* =================== */\n\n\t$.fn.datepicker.noConflict = function(){\n\t\t$.fn.datepicker = old;\n\t\treturn this;\n\t};\n\n\t/* DATEPICKER VERSION\n\t * =================== */\n\t$.fn.datepicker.version = '1.7.0-dev';\n\n\t/* DATEPICKER DATA-API\n\t* ================== */\n\n\t$(document).on(\n\t\t'focus.datepicker.data-api click.datepicker.data-api',\n\t\t'[data-provide=\"datepicker\"]',\n\t\tfunction(e){\n\t\t\tvar $this = $(this);\n\t\t\tif ($this.data('datepicker'))\n\t\t\t\treturn;\n\t\t\te.preventDefault();\n\t\t\t// component click requires us to explicitly show it\n\t\t\tdatepickerPlugin.call($this, 'show');\n\t\t}\n\t);\n\t$(function(){\n\t\tdatepickerPlugin.call($('[data-provide=\"datepicker-inline\"]'));\n\t});\n\n}));\n"
  },
  {
    "path": "static/template/js/endless/endless.js",
    "content": "\n$(function\t()\t{\n\n\t// Cookie validation\n\tif(jQuery.type($.cookie('skin_color')) != 'undefined')\t{\n\t\n\t\t$('aside').removeClass('skin-1');\n\t\t$('aside').removeClass('skin-2');\n\t\t$('aside').removeClass('skin-3');\n\t\t$('aside').removeClass('skin-4');\n\t\t$('aside').removeClass('skin-5');\n\t\t$('aside').removeClass('skin-6');\n\t\t$('#top-nav').removeClass('skin-1');\n\t\t$('#top-nav').removeClass('skin-2');\n\t\t$('#top-nav').removeClass('skin-3');\n\t\t$('#top-nav').removeClass('skin-4');\n\t\t$('#top-nav').removeClass('skin-5');\n\t\t$('#top-nav').removeClass('skin-6');\n\t\t\n\t\t$('aside').addClass($.cookie('skin_color'));\n\t\t$('#top-nav').addClass($.cookie('skin_color'));\n\t}\n\t\n\t//Skin color\n\t$('.theme-color').click(function()\t{\n\t\t//Cookies for storing theme color\n\t\t$.cookie('skin_color', $(this).attr('id'));\n\t\t\n\t\t$('aside').removeClass('skin-1');\n\t\t$('aside').removeClass('skin-2');\n\t\t$('aside').removeClass('skin-3');\n\t\t$('aside').removeClass('skin-4');\n\t\t$('aside').removeClass('skin-5');\n\t\t$('aside').removeClass('skin-6');\n\t\t$('#top-nav').removeClass('skin-1');\n\t\t$('#top-nav').removeClass('skin-2');\n\t\t$('#top-nav').removeClass('skin-3');\n\t\t$('#top-nav').removeClass('skin-4');\n\t\t$('#top-nav').removeClass('skin-5');\n\t\t$('#top-nav').removeClass('skin-6');\n\t\t\n\t\t$('aside').addClass($(this).attr('id'));\n\t\t$('#top-nav').addClass($(this).attr('id'));\n\t});\n\t\n\t// Delete values stored in cookies \n\t// uncomment code to activate\n\t//\t$.removeCookie('skin_color');\n\t//\n\t\n\t//Preloading\n\tpaceOptions = {\n\t\tstartOnPageLoad: true,\n\t\tajax: false, // disabled\n\t\tdocument: false, // disabled\n\t\teventLag: false, // disabled\n\t\telements: false\n\t};\n\t\n\t//\n\t$('.login-link').click(function(e) {\n\t\te.preventDefault();\n\t\thref = $(this).attr('href');\n\t\t\n\t\t$('.login-wrapper').addClass('fadeOutUp');\n\n\t\tsetTimeout(function() {\n\t\t\twindow.location = href;\n\t\t}, 900);\n\t\t\t\n\t\treturn false;\t\n\t});\n\t\n\t//Logout Confirmation\n\t$('#logoutConfirm').popup({\n\t\tpagecontainer: '.container',\n\t\t transition: 'all 0.3s'\n\t});\n\t\n\t//scroll to top of the page\n\t$(\"#scroll-to-top\").click(function()\t{\n\t\t$(\"html, body\").animate({ scrollTop: 0 }, 600);\n\t\t return false;\n\t});\n\t\n\t//scrollable sidebar\n\t$('.scrollable-sidebar').slimScroll({\n\t\theight: '100%',\n\t\tsize: '0px'\n\t});\n\t\n\t//Sidebar menu dropdown\n\t$('aside li').hover(\n       function(){ $(this).addClass('open') },\n       function(){ $(this).removeClass('open') }\n\t)\n\t\n\t//Collapsible Sidebar Menu\n\t$('.openable > a').click(function()\t{\t\n\t\tif(!$('#wrapper').hasClass('sidebar-mini'))\t{\n\t\t\tif( $(this).parent().children('.submenu').is(':hidden') ) {\n\t\t\t\t$(this).parent().siblings().removeClass('open').children('.submenu').slideUp();\n\t\t\t\t$(this).parent().addClass('open').children('.submenu').slideDown();\n\t\t\t}\n\t\t\telse\t{\n\t\t\t\t$(this).parent().removeClass('open').children('.submenu').slideUp();\n\t\t\t}\n\t\t}\n\t\t\n\t\treturn false;\n\t});\n\t\t\n\t//Toggle Menu\n\t$('#sidebarToggle').click(function()\t{\n\t\t$('#wrapper').toggleClass('sidebar-display');\n\t\t$('.main-menu').find('.openable').removeClass('open');\n\t\t$('.main-menu').find('.submenu').removeAttr('style');\n\t});\n\t\n\t$('#sizeToggle').click(function()\t{\n\t\n\t\t$('#wrapper').off(\"resize\");\n\t\n\t\t$('#wrapper').toggleClass('sidebar-mini');\n\t\t$('.main-menu').find('.openable').removeClass('open');\n\t\t$('.main-menu').find('.submenu').removeAttr('style');\n\t});\n\t\n\tif(!$('#wrapper').hasClass('sidebar-mini'))\t{ \n\t\tif (Modernizr.mq('(min-width: 768px)') && Modernizr.mq('(max-width: 868px)')) {\n\t\t\t$('#wrapper').addClass('sidebar-mini');\n\t\t}\n\t\telse if (Modernizr.mq('(min-width: 869px)'))\t{\n\t\t\tif(!$('#wrapper').hasClass('sidebar-mini'))\t{\n\t\t\t}\n\t\t}\n\t}\n\n\t//show/hide menu\n\t$('#menuToggle').click(function()\t{\n\t\t$('#wrapper').toggleClass('sidebar-hide');\n\t\t$('.main-menu').find('.openable').removeClass('open');\n\t\t$('.main-menu').find('.submenu').removeAttr('style');\n\t});\n\t\n\t$(window).resize(function() {\n\t\tif (Modernizr.mq('(min-width: 768px)') && Modernizr.mq('(max-width: 868px)')) {\n\t\t\t$('#wrapper').addClass('sidebar-mini').addClass('window-resize');\n\t\t\t$('.main-menu').find('.openable').removeClass('open');\n\t\t\t$('.main-menu').find('.submenu').removeAttr('style');\n\t\t}\n\t\telse if (Modernizr.mq('(min-width: 869px)'))\t{\n\t\t\tif($('#wrapper').hasClass('window-resize'))\t{\n\t\t\t\t$('#wrapper').removeClass('sidebar-mini window-resize');\n\t\t\t\t$('.main-menu').find('.openable').removeClass('open');\n\t\t\t\t$('.main-menu').find('.submenu').removeAttr('style');\n\t\t\t}\n\t\t}\n\t\telse\t{\n\t\t\t$('#wrapper').removeClass('sidebar-mini window-resize');\n\t\t\t$('.main-menu').find('.openable').removeClass('open');\n\t\t\t$('.main-menu').find('.submenu').removeAttr('style');\n\t\t}\n\t});\n\t\n\t//fixed Sidebar\n\t$('#fixedSidebar').click(function()\t{\n\t\tif($(this).prop('checked'))\t{\n\t\t\t$('aside').addClass('fixed');\n\t\t}\t\n\t\telse\t{\n\t\t\t$('aside').removeClass('fixed');\n\t\t}\n\t});\n\t\n\t//Inbox sidebar (inbox.html)\n\t$('#inboxMenuToggle').click(function()\t{\n\t\t$('#inboxMenu').toggleClass('menu-display');\n\t});\n\t\n\t//Collapse panel\n\t$('.collapse-toggle').click(function()\t{\n\t\n\t\t$(this).parent().toggleClass('active');\n\t\n\t\tvar parentElm = $(this).parent().parent().parent().parent();\n\t\t\n\t\tvar targetElm = parentElm.find('.panel-body');\n\t\t\n\t\ttargetElm.toggleClass('collapse');\n\t});\n\t\n\t//Number Animation\n\tvar currentVisitor = $('#currentVisitor').text();\n\t\n\t$({numberValue: 0}).animate({numberValue: currentVisitor}, {\n\t\tduration: 2500,\n\t\teasing: 'linear',\n\t\tstep: function() { \n\t\t\t$('#currentVisitor').text(Math.ceil(this.numberValue)); \n\t\t}\n\t});\n\t\t\t\n\tvar currentBalance = $('#currentBalance').text();\n\t\n\t$({numberValue: 0}).animate({numberValue: currentBalance}, {\n\t\tduration: 2500,\n\t\teasing: 'linear',\n\t\tstep: function() { \n\t\t\t$('#currentBalance').text(Math.ceil(this.numberValue)); \n\t\t}\n\t});\n\t\n\t//Refresh Widget\n\t$('.refresh-widget').click(function() {\n\t\tvar _overlayDiv = $(this).parent().parent().parent().parent().find('.loading-overlay');\n\t\t_overlayDiv.addClass('active');\n\t\t\n\t\tsetTimeout(function() {\n\t\t\t_overlayDiv.removeClass('active');\n\t\t}, 2000);\n\t\t\n\t\treturn false;\n\t});\n\t\t\n\t//Check all\tcheckboxes\n\t$('#chk-all').click(function()\t{\n\t\tif($(this).is(':checked'))\t{\n\t\t\t$('.inbox-panel').find('.chk-item').each(function()\t{\n\t\t\t\t$(this).prop('checked', true);\n\t\t\t\t$(this).parent().parent().addClass('selected');\n\t\t\t});\n\t\t}\n\t\telse\t{\n\t\t\t$('.inbox-panel').find('.chk-item').each(function()\t{\n\t\t\t\t$(this).prop('checked' , false);\n\t\t\t\t$(this).parent().parent().removeClass('selected');\n\t\t\t});\n\t\t}\n\t});\n\t\n\t$('.chk-item').click(function()\t{\n\t\tif($(this).is(':checked'))\t{\n\t\t\t$(this).parent().parent().addClass('selected');\t\t\n\t\t}\n\t\telse\t{\n\t\t\t$(this).parent().parent().removeClass('selected');\n\t\t}\n\t});\n\t\n\t$('.chk-row').click(function()\t{\n\t\tif($(this).is(':checked'))\t{\n\t\t\t$(this).parent().parent().parent().addClass('selected');\t\t\n\t\t}\n\t\telse\t{\n\t\t\t$(this).parent().parent().parent().removeClass('selected');\n\t\t}\n\t});\n\t\n\t//Hover effect on touch device\n\t$('.image-wrapper').bind('touchstart', function(e) {\n\t\t$('.image-wrapper').removeClass('active');\n\t\t$(this).addClass('active');\n    });\n\t\n\t//Dropdown menu with hover\n\t$('.hover-dropdown').hover(\n       function(){ $(this).addClass('open') },\n       function(){ $(this).removeClass('open') }\n\t)\n\n\t//upload file\n\t$('.upload-demo').change(function()\t{\n\t\tvar filename = $(this).val().split('\\\\').pop();\n\t\t$(this).parent().find('span').attr('data-title',filename);\n\t\t$(this).parent().find('label').attr('data-title','Change file');\n\t\t$(this).parent().find('label').addClass('selected');\n\t});\n\n\t$('.remove-file').click(function()\t{\n\t\t$(this).parent().find('span').attr('data-title','No file...');\n\t\t$(this).parent().find('label').attr('data-title','Select file');\n\t\t$(this).parent().find('label').removeClass('selected');\n\n\t\treturn false;\n\t});\t\n\n\t//theme setting\n\t$(\"#theme-setting-icon\").click(function()\t{ \n\t\tif($('#theme-setting').hasClass('open'))\t{\n\t\t\t$('#theme-setting').removeClass('open');\n\t\t\t$('#theme-setting-icon').removeClass('open');\n\t\t}\n\t\telse\t{\n\t\t\t$('#theme-setting').addClass('open');\n\t\t\t$('#theme-setting-icon').addClass('open');\n\t\t}\n\n\t\treturn false;\n\t});\n\t\n\t//to do list\n\t$('.task-finish').click(function()\t{\n\t\tif($(this).is(':checked'))\t{\n\t\t\t$(this).parent().parent().addClass('selected');\t\t\t\t\t\n\t\t}\n\t\telse\t{\n\t\t\t$(this).parent().parent().removeClass('selected');\n\t\t}\n\t});\n\n\t//Delete to do list\n\t$('.task-del').click(function()\t{\t\t\t\n\t\tvar activeList = $(this).parent().parent();\n\n\t\tactiveList.addClass('removed');\n\t\t\t\t\n\t\tsetTimeout(function() {\n\t\t\tactiveList.remove();\n\t\t}, 1000);\n\t\t\t\n\t\treturn false;\n\t});\n\t\n\t// Popover\n    $(\"[data-toggle=popover]\").popover();\n\t\n\t// Tooltip\n    $(\"[data-toggle=tooltip]\").tooltip();\n\t\n});\n\n$(window).load(function() {\n\t//Stop preloading animation\n\tPace.stop();\n\t\n\t// Fade out the overlay div\n\t$('#overlay').fadeOut(800);\n\t\n\t$('body').removeAttr('class');\n\t\n\t//Enable animation\n\t$('#wrapper').removeClass('preload');\n\t\t\n\t//Collapsible Active Menu\n\tif(!$('#wrapper').hasClass('sidebar-mini'))\t{\n\t\t$('aside').find('.active.openable').children('.submenu').slideDown();\n\t}\n});\n\n$(window).scroll(function(){\n\t\t\n\t var position = $(window).scrollTop();\n\t\n\t //Display a scroll to top button\n\t if(position >= 200)\t{\n\t\t$('#scroll-to-top').attr('style','bottom:8px;');\t\n\t }\n\t else\t{\n\t\t$('#scroll-to-top').removeAttr('style');\n\t }\n});\n"
  },
  {
    "path": "static/template/js/endless/endless_dashboard.js",
    "content": "$(function\t()\t{\n\n\t//Flot Chart\n\t//Website traffic chart\n\tvar init = { data: [[0, 5], [1, 8], [2, 5], [3, 8], [4, 7], [5,9], [6, 8], [7, 8], [8, 10], [9, 12], [10, 10]],\n\t\t\t label: \"Visitor\"\n\t\t},\n\t\toptions = {\n\t\t\tseries: {\n\t\t\t\tlines: {\n\t\t\t\t\tshow: true,\n\t\t\t\t\tfill: true,\n\t\t\t\t\tfillColor: 'rgba(121,206,167,0.2)'\n\t\t\t\t},\n\t\t\t\tpoints: {\n\t\t\t\t\tshow: true,\n\t\t\t\t\tradius: '4.5'\n\t\t\t\t}\n\t\t\t},\n\t\t\tgrid: {\n\t\t\t\thoverable: true,\n\t\t\t\tclickable: true\n\t\t\t},\n\t\t\tcolors: [\"#37b494\"]\n\t\t},\n\t\tplot;\n\n\tplot = $.plot($('#placeholder'), [init], options);\n\n\t$(\"<div id='tooltip'></div>\").css({\n\t\tposition: \"absolute\",\n\t\tdisplay: \"none\",\n\t\tborder: \"1px solid #222\",\n\t\tpadding: \"4px\",\n\t\tcolor: \"#fff\",\n\t\t\"border-radius\": \"4px\",\n\t\t\"background-color\": \"rgb(0,0,0)\",\n\t\topacity: 0.90\n\t}).appendTo(\"body\");\n\n\t$(\"#placeholder\").bind(\"plothover\", function (event, pos, item) {\n\n\t\tvar str = \"(\" + pos.x.toFixed(2) + \", \" + pos.y.toFixed(2) + \")\";\n\t\t$(\"#hoverdata\").text(str);\n\n\t\tif (item) {\n\t\t\tvar x = item.datapoint[0],\n\t\t\t\ty = item.datapoint[1];\n\n\t\t\t\t$(\"#tooltip\").html(\"Visitor : \" + y)\n\t\t\t\t.css({top: item.pageY+5, left: item.pageX+5})\n\t\t\t\t.fadeIn(200);\n\t\t} else {\n\t\t\t$(\"#tooltip\").hide();\n\t\t}\n\t});\n\n\t$(\"#placeholder\").bind(\"plotclick\", function (event, pos, item) {\n\t\tif (item) {\n\t\t\t$(\"#clickdata\").text(\" - click point \" + item.dataIndex + \" in \" + item.series.label);\n\t\t\tplot.highlight(item.series, item.datapoint);\n\t\t}\n\t});\n\n\tvar animate = function () {\n\t   $('#placeholder').animate( {tabIndex: 0}, {\n\t\t   duration: 3000,\n\t\t   step: function ( now, fx ) {\n\n\t\t\t\t var r = $.map( init.data, function ( o ) {\n\t\t\t\t\t  return [[ o[0], o[1] * fx.pos ]];\n\t\t\t\t});\n\n\t\t\t\t plot.setData( [{ data: r }] );\n\t\t\t plot.draw();\n\t\t\t}\n\t\t});\n\t}\n\n\tanimate();\n\n\t//Morris Chart\n\tvar donutChart = Morris.Donut({\n\t  element: 'donutChart',\n\t  data: [\n\t\t{label: \"Download Sales\", value: 1236},\n\t\t{label: \"In-Store Sales\", value: 3091},\n\t\t{label: \"Mail-Order Sales\", value: 2781}\n\t  ],\n\t  colors: ['#f3ce85','#65CEA7' ,'#FC8675']\n\t});\n\n\tvar lineChart = Morris.Line({\n\t\telement: 'lineChart',\n\t\tdata: [\n\t\t\t{ y: '2006', a: 30,  b: 20 },\n\t\t\t{ y: '2007', a: 45,  b: 35 },\n\t\t\t{ y: '2008', a: 60,  b: 60 },\n\t\t\t{ y: '2009', a: 75,  b: 65 },\n\t\t\t{ y: '2010', a: 50,  b: 70 },\n\t\t\t{ y: '2011', a: 80,  b: 85 },\n\t\t\t{ y: '2012', a: 100, b: 90 }\n\t\t],\n\t\txkey: 'y',\n\t\tgrid: false,\n\t\tykeys: ['a', 'b'],\n\t\tlabels: ['Item A', 'Item B'],\n\t\tlineColors: ['#8CB4BC', '#538792'],\n\t\tgridTextColor : '#fff'\n\t});\n\n\tvar barChart = Morris.Bar({\n\t  element: 'barChart',\n\t  data: [\n\t\t{ y: '2006', a: 100, b: 90 },\n\t\t{ y: '2007', a: 75,  b: 65 },\n\t\t{ y: '2008', a: 50,  b: 40 },\n\t\t{ y: '2009', a: 75,  b: 65 },\n\t\t{ y: '2010', a: 50,  b: 40 },\n\t\t{ y: '2011', a: 75,  b: 65 },\n\t\t{ y: '2012', a: 100, b: 90 }\n\t  ],\n\t  xkey: 'y',\n\t  ykeys: ['a', 'b'],\n\t  grid: false,\n\t  labels: ['Item C', 'Item D'],\n\t  barColors: ['#5EE1B1', '#3BC894'],\n\t  gridTextColor : '#fff'\n\t});\n\n\t//Sparkline\n\t$('#visits').sparkline([15,19,20,22,33,27,31,27,19,30,21,10,15,18,25,9], {\n\t\ttype: 'bar',\n\t\tbarColor: '#FC8675',\n\t\theight:'35px',\n\t\tweight:'96px'\n\t});\n\t$('#balances').sparkline([220,160,189,156,201,220,104,242,221,111,164,242,183,165], {\n\t\ttype: 'bar',\n\t\tbarColor: '#65CEA7',\n\t\theight:'35px',\n\t\tweight:'96px'\n\t});\n\n\t//Timeline color box\n\t$('.timeline-img').colorbox({\n\t\trel:'group1',\n\t\twidth:\"90%\",\n\t\tmaxWidth:'800px'\n\t});\n\n\t//Resize graph when toggle side menu\n\t$('.navbar-toggle').click(function()\t{\n\t\tsetTimeout(function() {\n\t\t\tdonutChart.redraw();\n\t\t\tlineChart.redraw();\n\t\t\tbarChart.redraw();\n\n\t\t\t$.plot($('#placeholder'), [init], options);\n\t\t},500);\n\t});\n\n\t$('.size-toggle').click(function()\t{\n\t\t//resize morris chart\n\t\tsetTimeout(function() {\n\t\t\tdonutChart.redraw();\n\t\t\tlineChart.redraw();\n\t\t\tbarChart.redraw();\n\n\t\t\t$.plot($('#placeholder'), [init], options);\n\t\t},500);\n\t});\n\n\t//Refresh statistic widget\n\t$('.refresh-button').click(function() {\n\t\tvar _overlayDiv = $(this).parent().children('.loading-overlay');\n\t\t_overlayDiv.addClass('active');\n\n\t\tsetTimeout(function() {\n\t\t\t_overlayDiv.removeClass('active');\n\t\t}, 2000);\n\n\t\treturn false;\n\t});\n\n\t$(window).resize(function(e)\t{\n\n\t\t//Sparkline\n\t\t$('#visits').sparkline([15,19,20,22,33,27,31,27,19,30,21,10,15,18,25,9], {\n\t\t\ttype: 'bar',\n\t\t\tbarColor: '#fa4c38',\n\t\t\theight:'35px',\n\t\t\tweight:'96px'\n\t\t});\n\t\t$('#balances').sparkline([220,160,189,156,201,220,104,242,221,111,164,242,183,165], {\n\t\t\ttype: 'bar',\n\t\t\tbarColor: '#92cf5c',\n\t\t\theight:'35px',\n\t\t\tweight:'96px'\n\t\t});\n\n\t\t//resize morris chart\n\t\tsetTimeout(function() {\n\t\t\tdonutChart.redraw();\n\t\t\tlineChart.redraw();\n\t\t\tbarChart.redraw();\n\n\t\t\t$.plot($('#placeholder'), [init], options);\n\t\t},500);\n\t});\n\n\t$(window).load(function(e)\t{\n\n\t\t//Number Animation\n/*\t\tvar currentUser = $('#userCount').text();\n\t\t$({numberValue: 0}).animate({numberValue: currentUser}, {\n\t\t\tduration: 2500,\n\t\t\teasing: 'linear',\n\t\t\tstep: function() {\n\t\t\t\t$('#userCount').text(Math.ceil(this.numberValue));\n\t\t\t}\n\t\t});*/\n\n/*\t\tvar currentServerload = $('#serverloadCount').text();\n\t\t$({numberValue: 0}).animate({numberValue: currentServerload}, {\n\t\t\tduration: 2500,\n\t\t\teasing: 'linear',\n\t\t\tstep: function() {\n\t\t\t\t$('#serverloadCount').text(Math.ceil(this.numberValue));\n\t\t\t}\n\t\t});*/\n\n\t\tvar currentOrder = $('#orderCount').text();\n\t\t$({numberValue: 0}).animate({numberValue: currentOrder}, {\n\t\t\tduration: 2500,\n\t\t\teasing: 'linear',\n\t\t\tstep: function() {\n\t\t\t\t$('#orderCount').text(Math.ceil(this.numberValue));\n\t\t\t}\n\t\t});\n\n\t\tvar currentVisitor = $('#visitorCount').text();\n\t\t$({numberValue: 0}).animate({numberValue: currentVisitor}, {\n\t\t\tduration: 2500,\n\t\t\teasing: 'linear',\n\t\t\tstep: function() {\n\t\t\t\t$('#visitorCount').text(Math.ceil(this.numberValue));\n\t\t\t}\n\t\t});\n\n/*\t\tsetInterval(function() {\n\t\t\tvar currentNumber = $('#userCount').text();\n\t\t\tvar randomNumber = Math.floor(Math.random()*20) + 1;\n\t\t\tvar newNumber = parseInt(currentNumber, 10) + parseInt(randomNumber, 10);\n\n\t\t\t$({numberValue: currentNumber}).animate({numberValue: newNumber}, {\n\t\t\t\tduration: 500,\n\t\t\t\teasing: 'linear',\n\t\t\t\tstep: function() {\n\t\t\t\t\t$('#userCount').text(Math.ceil(this.numberValue));\n\t\t\t\t}\n\t\t\t});\n\t\t}, 3000);*/\n\n\t\tsetInterval(function() {\n\t\t\tvar currentNumber = $('#visitorCount').text();\n\t\t\tvar randomNumber = Math.floor(Math.random()*50) + 1;\n\t\t\tvar newNumber = parseInt(currentNumber, 10) + parseInt(randomNumber, 10);\n\n\t\t\t$({numberValue: currentNumber}).animate({numberValue: newNumber}, {\n\t\t\t\tduration: 500,\n\t\t\t\teasing: 'linear',\n\t\t\t\tstep: function() {\n\t\t\t\t\t$('#visitorCount').text(Math.ceil(this.numberValue));\n\t\t\t\t}\n\t\t\t});\n\t\t}, 5000);\n\t});\n});\n\n\n\n\n"
  },
  {
    "path": "static/template/js/endless/endless_form.js",
    "content": "$(function()\t{\n\t// Chosen \n\t$(\".chzn-select\").chosen();\n\t\n\t// Datepicker\n\t$('.datepicker').datepicker();\n\n\t// Timepicker\n\t$('.timepicker').timepicker();\n\t\t\t\n\t// Slider\t\t\n\t$('#sl1').slider();\n\t$('#sl2').slider();\n\t$('#sl3').slider();\n\t$('#sl4').slider();\n\t$('#sl5').slider();\n\t\t\t\n\t// Tags input\n\t$('.tag-demo1').tagsInput({\n\t\t'height':'auto',\n\t\t'width':'90%'\n\t});\n\n\t// Masked input\n\t$(\".date\").mask(\"99/99/9999\");\t\t\n\t$(\".phone\").mask(\"(999) 999-9999\");\n\t$(\".ssn\").mask(\"999-99-9999\");\n\t$(\".eyescript\").mask(\"~9.99 ~9.99 999\");\n\t$(\".product-key\").mask(\"a*-999-a999\");\n\n\t// Wysihtml5\n\t$('#wysihtml5-textarea').wysihtml5();\n\n\t// Toggle border of control group\n\t$('#toggleLine').click(function()\t{\t\t\t\n\t\tif($(this).is(':checked'))\t{\n\t\t\t$('#formToggleLine').addClass('form-border');\n\t\t}\n\t\telse\t{\n\t\t\t$('#formToggleLine').removeClass('form-border');\n\t\t}\n\t});\n\n\t// Draggable Multiselect\n\t$('#btnSelect').click(function()\t{\n\t\t\t\t\n\t\t$('#selectedBox1 option:selected').appendTo('#selectedBox2');  \n\t\treturn false;\n\t});\n\n\t$('#btnRemove').click(function()\t{\n\t\t$('#selectedBox2 option:selected').appendTo('#selectedBox1'); \n\t\treturn false;\n\t});\n\n\t$('#btnSelectAll').click(function()\t{\n\t\t\t\n\t\t$('#selectedBox1 option').each(function() {               \n           $(this).appendTo('#selectedBox2');                   \n        });\n\n\t\treturn false;\n\t});\n\n\t$('#btnRemoveAll').click(function()\t{\n\t\t\t\n\t\t$('#selectedBox2 option').each(function() {                  \n\t\t\t$(this).appendTo('#selectedBox1');            \n        });\n\n\t\treturn false;\n\t});\n});"
  },
  {
    "path": "static/template/js/endless/endless_wizard.js",
    "content": "$(function\t()\t{\n\n\t//Form Wizard 1\n\tvar currentStep_1 = 1;\n\t\n\t//Form Wizard 2\n\tvar currentStep_2 = 1; \n\t\n\t$('.wizard-demo li a').click(function()\t{\n\t\talert('You must enter your information')\n\t\treturn false;\n\t});\n\t \n\t//Form Validation\n\t$('#basic-constraint').parsley( { listeners: {\n        onFormSubmit: function ( isFormValid, event ) {\n            if(isFormValid)\t{\n\t\t\t\treturn false;\n\t\t\t}\n        }\n    }}); \n\t\n\t$('#type-constraint').parsley( { listeners: {\n        onFormSubmit: function ( isFormValid, event ) {\n            if(isFormValid)\t{\n\t\t\t\treturn false;\n\t\t\t}\n        }\n    }}); \n\t \n\t$('#formValidate1').parsley( { listeners: {\n        onFormSubmit: function ( isFormValid, event ) {\n            if(isFormValid)\t{\n\t\t\t\talert('Registration Complete');\n\t\t\t\treturn false;\n\t\t\t}\n        }\n    }}); \n\t\n\t$('#formValidate2').parsley( { listeners: {\n        onFormSubmit: function ( isFormValid, event ) {\n            if(isFormValid)\t{\n\t\t\t\talert('Your message has been sent');\n\t\t\t\treturn false;\n\t\t\t}\n        }\n    }}); \n\t \n\t$('#formWizard1').parsley( { listeners: {\n\t\tonFieldValidate: function ( elem ) {\n\t\t\t// if field is not visible, do not apply Parsley validation!\n\t\t\tif ( !$( elem ).is( ':visible' ) ) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t},\n        onFormSubmit: function ( isFormValid, event ) {\n            if(isFormValid)\t{\n\t\t\t\t\t\n\t\t\t\tcurrentStep_1++;\n\t\t\t\t\n\t\t\t\tif(currentStep_1 == 2)\t{\n\t\t\t\t\t$('#wizardDemo1 li:eq(1) a').tab('show');\n\t\t\t\t\t$('#wizardProgress').css(\"width\",\"66%\");\n\t\t\t\t\t\n\t\t\t\t\t$('#prevStep1').attr('disabled',false);\n\t\t\t\t\t$('#prevStep1').removeClass('disabled');\n\t\t\t\t}\n\t\t\t\telse if(currentStep_1 == 3)\t{\n\t\t\t\t\t$('#wizardDemo1 li:eq(2) a').tab('show');\n\t\t\t\t\t$('#wizardProgress').css(\"width\",\"100%\");\n\t\t\t\t\t\n\t\t\t\t\t$('#nextStep1').attr('disabled',true);\n\t\t\t\t\t$('#nextStep1').addClass('disabled');\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\treturn false;\n\t\t\t}\n        }\n    }});\n\t\n\t$('#formWizard2').parsley( { listeners: {\n\t\tonFieldValidate: function ( elem ) {\n\t\t\t// if field is not visible, do not apply Parsley validation!\n\t\t\tif ( !$( elem ).is( ':visible' ) ) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t},\n        onFormSubmit: function ( isFormValid, event ) {\n            if(isFormValid)\t{\n\t\t\t\t\t\n\t\t\t\tcurrentStep_2++;\n\t\t\t\t\n\t\t\t\tif(currentStep_2 == 2)\t{\n\t\t\t\t\t$('#wizardDemo2 li:eq(1) a').tab('show');\n\t\t\t\t\t\n\t\t\t\t\t$('#prevStep2').attr('disabled',false);\n\t\t\t\t\t$('#prevStep2').removeClass('disabled');\n\t\t\t\t}\n\t\t\t\telse if(currentStep_2 == 3)\t{\n\t\t\t\t\t$('#wizardDemo2 li:eq(2) a').tab('show');\n\t\t\t\t}\n\t\t\t\telse if(currentStep_2 == 4)\t{\n\t\t\t\t\t$('#wizardDemo2 li:eq(3) a').tab('show');\n\t\t\t\t\t\n\t\t\t\t\t$('#nextStep2').attr('disabled',true);\n\t\t\t\t\t$('#nextStep2').addClass('disabled');\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\treturn false;\n\t\t\t}\n        }\n    }});\n\t\n\t$('#prevStep1').click(function()\t{\n\t\t\n\t\tcurrentStep_1--;\n\t\t\n\t\tif(currentStep_1 == 1)\t{\n\t\t\n\t\t\t$('#wizardDemo1 li:eq(0) a').tab('show');\n\t\t\t$('#wizardProgress').css(\"width\",\"66%\");\n\t\t\t\t\n\t\t\t$('#prevStep1').attr('disabled',true);\n\t\t\t$('#prevStep1').addClass('disabled');\n\t\t\t\n\t\t\t$('#wizardProgress').css(\"width\",\"33%\");\n\t\t}\n\t\telse if(currentStep_1 == 2)\t{\n\t\t\n\t\t\t$('#wizardDemo1 li:eq(1) a').tab('show');\n\t\t\t$('#wizardProgress').css(\"width\",\"66%\");\n\t\t\t\t\t\n\t\t\t$('#nextStep1').attr('disabled',false);\n\t\t\t$('#nextStep1').removeClass('disabled');\n\t\t\t\n\t\t\t$('#wizardProgress').css(\"width\",\"66%\");\n\t\t}\n\t\t\n\t\treturn false;\n\t});\n\t\n\t$('#prevStep2').click(function()\t{\n\t\t\n\t\tcurrentStep_2--;\n\t\t\n\t\tif(currentStep_2 == 1)\t{\n\t\t\n\t\t\t$('#wizardDemo2 li:eq(0) a').tab('show');\n\t\t\t\t\n\t\t\t$('#prevStep2').attr('disabled',true);\n\t\t\t$('#prevStep2').addClass('disabled');\n\t\t\t\n\t\t}\n\t\telse if(currentStep_2 == 2)\t{\n\t\t\t$('#wizardDemo2 li:eq(1) a').tab('show');\n\t\t}\n\t\t\n\t\telse if(currentStep_2 == 3)\t{\n\t\t\n\t\t\t$('#wizardDemo2 li:eq(2) a').tab('show');\n\t\t\t\t\t\n\t\t\t$('#nextStep2').attr('disabled',false);\n\t\t\t$('#nextStep2').removeClass('disabled');\n\t\t\t\n\t\t}\n\t\t\n\t\treturn false;\n\t});\n});"
  },
  {
    "path": "static/template/js/jquery-ui.js",
    "content": "/*! jQuery UI - v1.10.3 - 2013-05-03\n* http://jqueryui.com\n* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js\n* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */\n(function( $, undefined ) {\n\nvar uuid = 0,\n\truniqueId = /^ui-id-\\d+$/;\n\n// $.ui might exist from components with no dependencies, e.g., $.ui.position\n$.ui = $.ui || {};\n\n$.extend( $.ui, {\n\tversion: \"1.10.3\",\n\n\tkeyCode: {\n\t\tBACKSPACE: 8,\n\t\tCOMMA: 188,\n\t\tDELETE: 46,\n\t\tDOWN: 40,\n\t\tEND: 35,\n\t\tENTER: 13,\n\t\tESCAPE: 27,\n\t\tHOME: 36,\n\t\tLEFT: 37,\n\t\tNUMPAD_ADD: 107,\n\t\tNUMPAD_DECIMAL: 110,\n\t\tNUMPAD_DIVIDE: 111,\n\t\tNUMPAD_ENTER: 108,\n\t\tNUMPAD_MULTIPLY: 106,\n\t\tNUMPAD_SUBTRACT: 109,\n\t\tPAGE_DOWN: 34,\n\t\tPAGE_UP: 33,\n\t\tPERIOD: 190,\n\t\tRIGHT: 39,\n\t\tSPACE: 32,\n\t\tTAB: 9,\n\t\tUP: 38\n\t}\n});\n\n// plugins\n$.fn.extend({\n\tfocus: (function( orig ) {\n\t\treturn function( delay, fn ) {\n\t\t\treturn typeof delay === \"number\" ?\n\t\t\t\tthis.each(function() {\n\t\t\t\t\tvar elem = this;\n\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\t$( elem ).focus();\n\t\t\t\t\t\tif ( fn ) {\n\t\t\t\t\t\t\tfn.call( elem );\n\t\t\t\t\t\t}\n\t\t\t\t\t}, delay );\n\t\t\t\t}) :\n\t\t\t\torig.apply( this, arguments );\n\t\t};\n\t})( $.fn.focus ),\n\n\tscrollParent: function() {\n\t\tvar scrollParent;\n\t\tif (($.ui.ie && (/(static|relative)/).test(this.css(\"position\"))) || (/absolute/).test(this.css(\"position\"))) {\n\t\t\tscrollParent = this.parents().filter(function() {\n\t\t\t\treturn (/(relative|absolute|fixed)/).test($.css(this,\"position\")) && (/(auto|scroll)/).test($.css(this,\"overflow\")+$.css(this,\"overflow-y\")+$.css(this,\"overflow-x\"));\n\t\t\t}).eq(0);\n\t\t} else {\n\t\t\tscrollParent = this.parents().filter(function() {\n\t\t\t\treturn (/(auto|scroll)/).test($.css(this,\"overflow\")+$.css(this,\"overflow-y\")+$.css(this,\"overflow-x\"));\n\t\t\t}).eq(0);\n\t\t}\n\n\t\treturn (/fixed/).test(this.css(\"position\")) || !scrollParent.length ? $(document) : scrollParent;\n\t},\n\n\tzIndex: function( zIndex ) {\n\t\tif ( zIndex !== undefined ) {\n\t\t\treturn this.css( \"zIndex\", zIndex );\n\t\t}\n\n\t\tif ( this.length ) {\n\t\t\tvar elem = $( this[ 0 ] ), position, value;\n\t\t\twhile ( elem.length && elem[ 0 ] !== document ) {\n\t\t\t\t// Ignore z-index if position is set to a value where z-index is ignored by the browser\n\t\t\t\t// This makes behavior of this function consistent across browsers\n\t\t\t\t// WebKit always returns auto if the element is positioned\n\t\t\t\tposition = elem.css( \"position\" );\n\t\t\t\tif ( position === \"absolute\" || position === \"relative\" || position === \"fixed\" ) {\n\t\t\t\t\t// IE returns 0 when zIndex is not specified\n\t\t\t\t\t// other browsers return a string\n\t\t\t\t\t// we ignore the case of nested elements with an explicit value of 0\n\t\t\t\t\t// <div style=\"z-index: -10;\"><div style=\"z-index: 0;\"></div></div>\n\t\t\t\t\tvalue = parseInt( elem.css( \"zIndex\" ), 10 );\n\t\t\t\t\tif ( !isNaN( value ) && value !== 0 ) {\n\t\t\t\t\t\treturn value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telem = elem.parent();\n\t\t\t}\n\t\t}\n\n\t\treturn 0;\n\t},\n\n\tuniqueId: function() {\n\t\treturn this.each(function() {\n\t\t\tif ( !this.id ) {\n\t\t\t\tthis.id = \"ui-id-\" + (++uuid);\n\t\t\t}\n\t\t});\n\t},\n\n\tremoveUniqueId: function() {\n\t\treturn this.each(function() {\n\t\t\tif ( runiqueId.test( this.id ) ) {\n\t\t\t\t$( this ).removeAttr( \"id\" );\n\t\t\t}\n\t\t});\n\t}\n});\n\n// selectors\nfunction focusable( element, isTabIndexNotNaN ) {\n\tvar map, mapName, img,\n\t\tnodeName = element.nodeName.toLowerCase();\n\tif ( \"area\" === nodeName ) {\n\t\tmap = element.parentNode;\n\t\tmapName = map.name;\n\t\tif ( !element.href || !mapName || map.nodeName.toLowerCase() !== \"map\" ) {\n\t\t\treturn false;\n\t\t}\n\t\timg = $( \"img[usemap=#\" + mapName + \"]\" )[0];\n\t\treturn !!img && visible( img );\n\t}\n\treturn ( /input|select|textarea|button|object/.test( nodeName ) ?\n\t\t!element.disabled :\n\t\t\"a\" === nodeName ?\n\t\t\telement.href || isTabIndexNotNaN :\n\t\t\tisTabIndexNotNaN) &&\n\t\t// the element and all of its ancestors must be visible\n\t\tvisible( element );\n}\n\nfunction visible( element ) {\n\treturn $.expr.filters.visible( element ) &&\n\t\t!$( element ).parents().addBack().filter(function() {\n\t\t\treturn $.css( this, \"visibility\" ) === \"hidden\";\n\t\t}).length;\n}\n\n$.extend( $.expr[ \":\" ], {\n\tdata: $.expr.createPseudo ?\n\t\t$.expr.createPseudo(function( dataName ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn !!$.data( elem, dataName );\n\t\t\t};\n\t\t}) :\n\t\t// support: jQuery <1.8\n\t\tfunction( elem, i, match ) {\n\t\t\treturn !!$.data( elem, match[ 3 ] );\n\t\t},\n\n\tfocusable: function( element ) {\n\t\treturn focusable( element, !isNaN( $.attr( element, \"tabindex\" ) ) );\n\t},\n\n\ttabbable: function( element ) {\n\t\tvar tabIndex = $.attr( element, \"tabindex\" ),\n\t\t\tisTabIndexNaN = isNaN( tabIndex );\n\t\treturn ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );\n\t}\n});\n\n// support: jQuery <1.8\nif ( !$( \"<a>\" ).outerWidth( 1 ).jquery ) {\n\t$.each( [ \"Width\", \"Height\" ], function( i, name ) {\n\t\tvar side = name === \"Width\" ? [ \"Left\", \"Right\" ] : [ \"Top\", \"Bottom\" ],\n\t\t\ttype = name.toLowerCase(),\n\t\t\torig = {\n\t\t\t\tinnerWidth: $.fn.innerWidth,\n\t\t\t\tinnerHeight: $.fn.innerHeight,\n\t\t\t\touterWidth: $.fn.outerWidth,\n\t\t\t\touterHeight: $.fn.outerHeight\n\t\t\t};\n\n\t\tfunction reduce( elem, size, border, margin ) {\n\t\t\t$.each( side, function() {\n\t\t\t\tsize -= parseFloat( $.css( elem, \"padding\" + this ) ) || 0;\n\t\t\t\tif ( border ) {\n\t\t\t\t\tsize -= parseFloat( $.css( elem, \"border\" + this + \"Width\" ) ) || 0;\n\t\t\t\t}\n\t\t\t\tif ( margin ) {\n\t\t\t\t\tsize -= parseFloat( $.css( elem, \"margin\" + this ) ) || 0;\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn size;\n\t\t}\n\n\t\t$.fn[ \"inner\" + name ] = function( size ) {\n\t\t\tif ( size === undefined ) {\n\t\t\t\treturn orig[ \"inner\" + name ].call( this );\n\t\t\t}\n\n\t\t\treturn this.each(function() {\n\t\t\t\t$( this ).css( type, reduce( this, size ) + \"px\" );\n\t\t\t});\n\t\t};\n\n\t\t$.fn[ \"outer\" + name] = function( size, margin ) {\n\t\t\tif ( typeof size !== \"number\" ) {\n\t\t\t\treturn orig[ \"outer\" + name ].call( this, size );\n\t\t\t}\n\n\t\t\treturn this.each(function() {\n\t\t\t\t$( this).css( type, reduce( this, size, true, margin ) + \"px\" );\n\t\t\t});\n\t\t};\n\t});\n}\n\n// support: jQuery <1.8\nif ( !$.fn.addBack ) {\n\t$.fn.addBack = function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t};\n}\n\n// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)\nif ( $( \"<a>\" ).data( \"a-b\", \"a\" ).removeData( \"a-b\" ).data( \"a-b\" ) ) {\n\t$.fn.removeData = (function( removeData ) {\n\t\treturn function( key ) {\n\t\t\tif ( arguments.length ) {\n\t\t\t\treturn removeData.call( this, $.camelCase( key ) );\n\t\t\t} else {\n\t\t\t\treturn removeData.call( this );\n\t\t\t}\n\t\t};\n\t})( $.fn.removeData );\n}\n\n\n\n\n\n// deprecated\n$.ui.ie = !!/msie [\\w.]+/.exec( navigator.userAgent.toLowerCase() );\n\n$.support.selectstart = \"onselectstart\" in document.createElement( \"div\" );\n$.fn.extend({\n\tdisableSelection: function() {\n\t\treturn this.bind( ( $.support.selectstart ? \"selectstart\" : \"mousedown\" ) +\n\t\t\t\".ui-disableSelection\", function( event ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t});\n\t},\n\n\tenableSelection: function() {\n\t\treturn this.unbind( \".ui-disableSelection\" );\n\t}\n});\n\n$.extend( $.ui, {\n\t// $.ui.plugin is deprecated. Use $.widget() extensions instead.\n\tplugin: {\n\t\tadd: function( module, option, set ) {\n\t\t\tvar i,\n\t\t\t\tproto = $.ui[ module ].prototype;\n\t\t\tfor ( i in set ) {\n\t\t\t\tproto.plugins[ i ] = proto.plugins[ i ] || [];\n\t\t\t\tproto.plugins[ i ].push( [ option, set[ i ] ] );\n\t\t\t}\n\t\t},\n\t\tcall: function( instance, name, args ) {\n\t\t\tvar i,\n\t\t\t\tset = instance.plugins[ name ];\n\t\t\tif ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfor ( i = 0; i < set.length; i++ ) {\n\t\t\t\tif ( instance.options[ set[ i ][ 0 ] ] ) {\n\t\t\t\t\tset[ i ][ 1 ].apply( instance.element, args );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// only used by resizable\n\thasScroll: function( el, a ) {\n\n\t\t//If overflow is hidden, the element might have extra content, but the user wants to hide it\n\t\tif ( $( el ).css( \"overflow\" ) === \"hidden\") {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar scroll = ( a && a === \"left\" ) ? \"scrollLeft\" : \"scrollTop\",\n\t\t\thas = false;\n\n\t\tif ( el[ scroll ] > 0 ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// TODO: determine which cases actually cause this to happen\n\t\t// if the element doesn't have the scroll set, see if it's possible to\n\t\t// set the scroll\n\t\tel[ scroll ] = 1;\n\t\thas = ( el[ scroll ] > 0 );\n\t\tel[ scroll ] = 0;\n\t\treturn has;\n\t}\n});\n\n})( jQuery );\n\n(function( $, undefined ) {\n\nvar uuid = 0,\n\tslice = Array.prototype.slice,\n\t_cleanData = $.cleanData;\n$.cleanData = function( elems ) {\n\tfor ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {\n\t\ttry {\n\t\t\t$( elem ).triggerHandler( \"remove\" );\n\t\t// http://bugs.jquery.com/ticket/8235\n\t\t} catch( e ) {}\n\t}\n\t_cleanData( elems );\n};\n\n$.widget = function( name, base, prototype ) {\n\tvar fullName, existingConstructor, constructor, basePrototype,\n\t\t// proxiedPrototype allows the provided prototype to remain unmodified\n\t\t// so that it can be used as a mixin for multiple widgets (#8876)\n\t\tproxiedPrototype = {},\n\t\tnamespace = name.split( \".\" )[ 0 ];\n\n\tname = name.split( \".\" )[ 1 ];\n\tfullName = namespace + \"-\" + name;\n\n\tif ( !prototype ) {\n\t\tprototype = base;\n\t\tbase = $.Widget;\n\t}\n\n\t// create selector for plugin\n\t$.expr[ \":\" ][ fullName.toLowerCase() ] = function( elem ) {\n\t\treturn !!$.data( elem, fullName );\n\t};\n\n\t$[ namespace ] = $[ namespace ] || {};\n\texistingConstructor = $[ namespace ][ name ];\n\tconstructor = $[ namespace ][ name ] = function( options, element ) {\n\t\t// allow instantiation without \"new\" keyword\n\t\tif ( !this._createWidget ) {\n\t\t\treturn new constructor( options, element );\n\t\t}\n\n\t\t// allow instantiation without initializing for simple inheritance\n\t\t// must use \"new\" keyword (the code above always passes args)\n\t\tif ( arguments.length ) {\n\t\t\tthis._createWidget( options, element );\n\t\t}\n\t};\n\t// extend with the existing constructor to carry over any static properties\n\t$.extend( constructor, existingConstructor, {\n\t\tversion: prototype.version,\n\t\t// copy the object used to create the prototype in case we need to\n\t\t// redefine the widget later\n\t\t_proto: $.extend( {}, prototype ),\n\t\t// track widgets that inherit from this widget in case this widget is\n\t\t// redefined after a widget inherits from it\n\t\t_childConstructors: []\n\t});\n\n\tbasePrototype = new base();\n\t// we need to make the options hash a property directly on the new instance\n\t// otherwise we'll modify the options hash on the prototype that we're\n\t// inheriting from\n\tbasePrototype.options = $.widget.extend( {}, basePrototype.options );\n\t$.each( prototype, function( prop, value ) {\n\t\tif ( !$.isFunction( value ) ) {\n\t\t\tproxiedPrototype[ prop ] = value;\n\t\t\treturn;\n\t\t}\n\t\tproxiedPrototype[ prop ] = (function() {\n\t\t\tvar _super = function() {\n\t\t\t\t\treturn base.prototype[ prop ].apply( this, arguments );\n\t\t\t\t},\n\t\t\t\t_superApply = function( args ) {\n\t\t\t\t\treturn base.prototype[ prop ].apply( this, args );\n\t\t\t\t};\n\t\t\treturn function() {\n\t\t\t\tvar __super = this._super,\n\t\t\t\t\t__superApply = this._superApply,\n\t\t\t\t\treturnValue;\n\n\t\t\t\tthis._super = _super;\n\t\t\t\tthis._superApply = _superApply;\n\n\t\t\t\treturnValue = value.apply( this, arguments );\n\n\t\t\t\tthis._super = __super;\n\t\t\t\tthis._superApply = __superApply;\n\n\t\t\t\treturn returnValue;\n\t\t\t};\n\t\t})();\n\t});\n\tconstructor.prototype = $.widget.extend( basePrototype, {\n\t\t// TODO: remove support for widgetEventPrefix\n\t\t// always use the name + a colon as the prefix, e.g., draggable:start\n\t\t// don't prefix for widgets that aren't DOM-based\n\t\twidgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name\n\t}, proxiedPrototype, {\n\t\tconstructor: constructor,\n\t\tnamespace: namespace,\n\t\twidgetName: name,\n\t\twidgetFullName: fullName\n\t});\n\n\t// If this widget is being redefined then we need to find all widgets that\n\t// are inheriting from it and redefine all of them so that they inherit from\n\t// the new version of this widget. We're essentially trying to replace one\n\t// level in the prototype chain.\n\tif ( existingConstructor ) {\n\t\t$.each( existingConstructor._childConstructors, function( i, child ) {\n\t\t\tvar childPrototype = child.prototype;\n\n\t\t\t// redefine the child widget using the same prototype that was\n\t\t\t// originally used, but inherit from the new version of the base\n\t\t\t$.widget( childPrototype.namespace + \".\" + childPrototype.widgetName, constructor, child._proto );\n\t\t});\n\t\t// remove the list of existing child constructors from the old constructor\n\t\t// so the old child constructors can be garbage collected\n\t\tdelete existingConstructor._childConstructors;\n\t} else {\n\t\tbase._childConstructors.push( constructor );\n\t}\n\n\t$.widget.bridge( name, constructor );\n};\n\n$.widget.extend = function( target ) {\n\tvar input = slice.call( arguments, 1 ),\n\t\tinputIndex = 0,\n\t\tinputLength = input.length,\n\t\tkey,\n\t\tvalue;\n\tfor ( ; inputIndex < inputLength; inputIndex++ ) {\n\t\tfor ( key in input[ inputIndex ] ) {\n\t\t\tvalue = input[ inputIndex ][ key ];\n\t\t\tif ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {\n\t\t\t\t// Clone objects\n\t\t\t\tif ( $.isPlainObject( value ) ) {\n\t\t\t\t\ttarget[ key ] = $.isPlainObject( target[ key ] ) ?\n\t\t\t\t\t\t$.widget.extend( {}, target[ key ], value ) :\n\t\t\t\t\t\t// Don't extend strings, arrays, etc. with objects\n\t\t\t\t\t\t$.widget.extend( {}, value );\n\t\t\t\t// Copy everything else by reference\n\t\t\t\t} else {\n\t\t\t\t\ttarget[ key ] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn target;\n};\n\n$.widget.bridge = function( name, object ) {\n\tvar fullName = object.prototype.widgetFullName || name;\n\t$.fn[ name ] = function( options ) {\n\t\tvar isMethodCall = typeof options === \"string\",\n\t\t\targs = slice.call( arguments, 1 ),\n\t\t\treturnValue = this;\n\n\t\t// allow multiple hashes to be passed on init\n\t\toptions = !isMethodCall && args.length ?\n\t\t\t$.widget.extend.apply( null, [ options ].concat(args) ) :\n\t\t\toptions;\n\n\t\tif ( isMethodCall ) {\n\t\t\tthis.each(function() {\n\t\t\t\tvar methodValue,\n\t\t\t\t\tinstance = $.data( this, fullName );\n\t\t\t\tif ( !instance ) {\n\t\t\t\t\treturn $.error( \"cannot call methods on \" + name + \" prior to initialization; \" +\n\t\t\t\t\t\t\"attempted to call method '\" + options + \"'\" );\n\t\t\t\t}\n\t\t\t\tif ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === \"_\" ) {\n\t\t\t\t\treturn $.error( \"no such method '\" + options + \"' for \" + name + \" widget instance\" );\n\t\t\t\t}\n\t\t\t\tmethodValue = instance[ options ].apply( instance, args );\n\t\t\t\tif ( methodValue !== instance && methodValue !== undefined ) {\n\t\t\t\t\treturnValue = methodValue && methodValue.jquery ?\n\t\t\t\t\t\treturnValue.pushStack( methodValue.get() ) :\n\t\t\t\t\t\tmethodValue;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tthis.each(function() {\n\t\t\t\tvar instance = $.data( this, fullName );\n\t\t\t\tif ( instance ) {\n\t\t\t\t\tinstance.option( options || {} )._init();\n\t\t\t\t} else {\n\t\t\t\t\t$.data( this, fullName, new object( options, this ) );\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn returnValue;\n\t};\n};\n\n$.Widget = function( /* options, element */ ) {};\n$.Widget._childConstructors = [];\n\n$.Widget.prototype = {\n\twidgetName: \"widget\",\n\twidgetEventPrefix: \"\",\n\tdefaultElement: \"<div>\",\n\toptions: {\n\t\tdisabled: false,\n\n\t\t// callbacks\n\t\tcreate: null\n\t},\n\t_createWidget: function( options, element ) {\n\t\telement = $( element || this.defaultElement || this )[ 0 ];\n\t\tthis.element = $( element );\n\t\tthis.uuid = uuid++;\n\t\tthis.eventNamespace = \".\" + this.widgetName + this.uuid;\n\t\tthis.options = $.widget.extend( {},\n\t\t\tthis.options,\n\t\t\tthis._getCreateOptions(),\n\t\t\toptions );\n\n\t\tthis.bindings = $();\n\t\tthis.hoverable = $();\n\t\tthis.focusable = $();\n\n\t\tif ( element !== this ) {\n\t\t\t$.data( element, this.widgetFullName, this );\n\t\t\tthis._on( true, this.element, {\n\t\t\t\tremove: function( event ) {\n\t\t\t\t\tif ( event.target === element ) {\n\t\t\t\t\t\tthis.destroy();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.document = $( element.style ?\n\t\t\t\t// element within the document\n\t\t\t\telement.ownerDocument :\n\t\t\t\t// element is window or document\n\t\t\t\telement.document || element );\n\t\t\tthis.window = $( this.document[0].defaultView || this.document[0].parentWindow );\n\t\t}\n\n\t\tthis._create();\n\t\tthis._trigger( \"create\", null, this._getCreateEventData() );\n\t\tthis._init();\n\t},\n\t_getCreateOptions: $.noop,\n\t_getCreateEventData: $.noop,\n\t_create: $.noop,\n\t_init: $.noop,\n\n\tdestroy: function() {\n\t\tthis._destroy();\n\t\t// we can probably remove the unbind calls in 2.0\n\t\t// all event bindings should go through this._on()\n\t\tthis.element\n\t\t\t.unbind( this.eventNamespace )\n\t\t\t// 1.9 BC for #7810\n\t\t\t// TODO remove dual storage\n\t\t\t.removeData( this.widgetName )\n\t\t\t.removeData( this.widgetFullName )\n\t\t\t// support: jquery <1.6.3\n\t\t\t// http://bugs.jquery.com/ticket/9413\n\t\t\t.removeData( $.camelCase( this.widgetFullName ) );\n\t\tthis.widget()\n\t\t\t.unbind( this.eventNamespace )\n\t\t\t.removeAttr( \"aria-disabled\" )\n\t\t\t.removeClass(\n\t\t\t\tthis.widgetFullName + \"-disabled \" +\n\t\t\t\t\"ui-state-disabled\" );\n\n\t\t// clean up events and states\n\t\tthis.bindings.unbind( this.eventNamespace );\n\t\tthis.hoverable.removeClass( \"ui-state-hover\" );\n\t\tthis.focusable.removeClass( \"ui-state-focus\" );\n\t},\n\t_destroy: $.noop,\n\n\twidget: function() {\n\t\treturn this.element;\n\t},\n\n\toption: function( key, value ) {\n\t\tvar options = key,\n\t\t\tparts,\n\t\t\tcurOption,\n\t\t\ti;\n\n\t\tif ( arguments.length === 0 ) {\n\t\t\t// don't return a reference to the internal hash\n\t\t\treturn $.widget.extend( {}, this.options );\n\t\t}\n\n\t\tif ( typeof key === \"string\" ) {\n\t\t\t// handle nested keys, e.g., \"foo.bar\" => { foo: { bar: ___ } }\n\t\t\toptions = {};\n\t\t\tparts = key.split( \".\" );\n\t\t\tkey = parts.shift();\n\t\t\tif ( parts.length ) {\n\t\t\t\tcurOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );\n\t\t\t\tfor ( i = 0; i < parts.length - 1; i++ ) {\n\t\t\t\t\tcurOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};\n\t\t\t\t\tcurOption = curOption[ parts[ i ] ];\n\t\t\t\t}\n\t\t\t\tkey = parts.pop();\n\t\t\t\tif ( value === undefined ) {\n\t\t\t\t\treturn curOption[ key ] === undefined ? null : curOption[ key ];\n\t\t\t\t}\n\t\t\t\tcurOption[ key ] = value;\n\t\t\t} else {\n\t\t\t\tif ( value === undefined ) {\n\t\t\t\t\treturn this.options[ key ] === undefined ? null : this.options[ key ];\n\t\t\t\t}\n\t\t\t\toptions[ key ] = value;\n\t\t\t}\n\t\t}\n\n\t\tthis._setOptions( options );\n\n\t\treturn this;\n\t},\n\t_setOptions: function( options ) {\n\t\tvar key;\n\n\t\tfor ( key in options ) {\n\t\t\tthis._setOption( key, options[ key ] );\n\t\t}\n\n\t\treturn this;\n\t},\n\t_setOption: function( key, value ) {\n\t\tthis.options[ key ] = value;\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.widget()\n\t\t\t\t.toggleClass( this.widgetFullName + \"-disabled ui-state-disabled\", !!value )\n\t\t\t\t.attr( \"aria-disabled\", value );\n\t\t\tthis.hoverable.removeClass( \"ui-state-hover\" );\n\t\t\tthis.focusable.removeClass( \"ui-state-focus\" );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tenable: function() {\n\t\treturn this._setOption( \"disabled\", false );\n\t},\n\tdisable: function() {\n\t\treturn this._setOption( \"disabled\", true );\n\t},\n\n\t_on: function( suppressDisabledCheck, element, handlers ) {\n\t\tvar delegateElement,\n\t\t\tinstance = this;\n\n\t\t// no suppressDisabledCheck flag, shuffle arguments\n\t\tif ( typeof suppressDisabledCheck !== \"boolean\" ) {\n\t\t\thandlers = element;\n\t\t\telement = suppressDisabledCheck;\n\t\t\tsuppressDisabledCheck = false;\n\t\t}\n\n\t\t// no element argument, shuffle and use this.element\n\t\tif ( !handlers ) {\n\t\t\thandlers = element;\n\t\t\telement = this.element;\n\t\t\tdelegateElement = this.widget();\n\t\t} else {\n\t\t\t// accept selectors, DOM elements\n\t\t\telement = delegateElement = $( element );\n\t\t\tthis.bindings = this.bindings.add( element );\n\t\t}\n\n\t\t$.each( handlers, function( event, handler ) {\n\t\t\tfunction handlerProxy() {\n\t\t\t\t// allow widgets to customize the disabled handling\n\t\t\t\t// - disabled as an array instead of boolean\n\t\t\t\t// - disabled class as method for disabling individual parts\n\t\t\t\tif ( !suppressDisabledCheck &&\n\t\t\t\t\t\t( instance.options.disabled === true ||\n\t\t\t\t\t\t\t$( this ).hasClass( \"ui-state-disabled\" ) ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\treturn ( typeof handler === \"string\" ? instance[ handler ] : handler )\n\t\t\t\t\t.apply( instance, arguments );\n\t\t\t}\n\n\t\t\t// copy the guid so direct unbinding works\n\t\t\tif ( typeof handler !== \"string\" ) {\n\t\t\t\thandlerProxy.guid = handler.guid =\n\t\t\t\t\thandler.guid || handlerProxy.guid || $.guid++;\n\t\t\t}\n\n\t\t\tvar match = event.match( /^(\\w+)\\s*(.*)$/ ),\n\t\t\t\teventName = match[1] + instance.eventNamespace,\n\t\t\t\tselector = match[2];\n\t\t\tif ( selector ) {\n\t\t\t\tdelegateElement.delegate( selector, eventName, handlerProxy );\n\t\t\t} else {\n\t\t\t\telement.bind( eventName, handlerProxy );\n\t\t\t}\n\t\t});\n\t},\n\n\t_off: function( element, eventName ) {\n\t\teventName = (eventName || \"\").split( \" \" ).join( this.eventNamespace + \" \" ) + this.eventNamespace;\n\t\telement.unbind( eventName ).undelegate( eventName );\n\t},\n\n\t_delay: function( handler, delay ) {\n\t\tfunction handlerProxy() {\n\t\t\treturn ( typeof handler === \"string\" ? instance[ handler ] : handler )\n\t\t\t\t.apply( instance, arguments );\n\t\t}\n\t\tvar instance = this;\n\t\treturn setTimeout( handlerProxy, delay || 0 );\n\t},\n\n\t_hoverable: function( element ) {\n\t\tthis.hoverable = this.hoverable.add( element );\n\t\tthis._on( element, {\n\t\t\tmouseenter: function( event ) {\n\t\t\t\t$( event.currentTarget ).addClass( \"ui-state-hover\" );\n\t\t\t},\n\t\t\tmouseleave: function( event ) {\n\t\t\t\t$( event.currentTarget ).removeClass( \"ui-state-hover\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_focusable: function( element ) {\n\t\tthis.focusable = this.focusable.add( element );\n\t\tthis._on( element, {\n\t\t\tfocusin: function( event ) {\n\t\t\t\t$( event.currentTarget ).addClass( \"ui-state-focus\" );\n\t\t\t},\n\t\t\tfocusout: function( event ) {\n\t\t\t\t$( event.currentTarget ).removeClass( \"ui-state-focus\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_trigger: function( type, event, data ) {\n\t\tvar prop, orig,\n\t\t\tcallback = this.options[ type ];\n\n\t\tdata = data || {};\n\t\tevent = $.Event( event );\n\t\tevent.type = ( type === this.widgetEventPrefix ?\n\t\t\ttype :\n\t\t\tthis.widgetEventPrefix + type ).toLowerCase();\n\t\t// the original event may come from any element\n\t\t// so we need to reset the target on the new event\n\t\tevent.target = this.element[ 0 ];\n\n\t\t// copy original event properties over to the new event\n\t\torig = event.originalEvent;\n\t\tif ( orig ) {\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tif ( !( prop in event ) ) {\n\t\t\t\t\tevent[ prop ] = orig[ prop ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.element.trigger( event, data );\n\t\treturn !( $.isFunction( callback ) &&\n\t\t\tcallback.apply( this.element[0], [ event ].concat( data ) ) === false ||\n\t\t\tevent.isDefaultPrevented() );\n\t}\n};\n\n$.each( { show: \"fadeIn\", hide: \"fadeOut\" }, function( method, defaultEffect ) {\n\t$.Widget.prototype[ \"_\" + method ] = function( element, options, callback ) {\n\t\tif ( typeof options === \"string\" ) {\n\t\t\toptions = { effect: options };\n\t\t}\n\t\tvar hasOptions,\n\t\t\teffectName = !options ?\n\t\t\t\tmethod :\n\t\t\t\toptions === true || typeof options === \"number\" ?\n\t\t\t\t\tdefaultEffect :\n\t\t\t\t\toptions.effect || defaultEffect;\n\t\toptions = options || {};\n\t\tif ( typeof options === \"number\" ) {\n\t\t\toptions = { duration: options };\n\t\t}\n\t\thasOptions = !$.isEmptyObject( options );\n\t\toptions.complete = callback;\n\t\tif ( options.delay ) {\n\t\t\telement.delay( options.delay );\n\t\t}\n\t\tif ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {\n\t\t\telement[ method ]( options );\n\t\t} else if ( effectName !== method && element[ effectName ] ) {\n\t\t\telement[ effectName ]( options.duration, options.easing, callback );\n\t\t} else {\n\t\t\telement.queue(function( next ) {\n\t\t\t\t$( this )[ method ]();\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback.call( element[ 0 ] );\n\t\t\t\t}\n\t\t\t\tnext();\n\t\t\t});\n\t\t}\n\t};\n});\n\n})( jQuery );\n\n(function( $, undefined ) {\n\nvar mouseHandled = false;\n$( document ).mouseup( function() {\n\tmouseHandled = false;\n});\n\n$.widget(\"ui.mouse\", {\n\tversion: \"1.10.3\",\n\toptions: {\n\t\tcancel: \"input,textarea,button,select,option\",\n\t\tdistance: 1,\n\t\tdelay: 0\n\t},\n\t_mouseInit: function() {\n\t\tvar that = this;\n\n\t\tthis.element\n\t\t\t.bind(\"mousedown.\"+this.widgetName, function(event) {\n\t\t\t\treturn that._mouseDown(event);\n\t\t\t})\n\t\t\t.bind(\"click.\"+this.widgetName, function(event) {\n\t\t\t\tif (true === $.data(event.target, that.widgetName + \".preventClickEvent\")) {\n\t\t\t\t\t$.removeData(event.target, that.widgetName + \".preventClickEvent\");\n\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\n\t\tthis.started = false;\n\t},\n\n\t// TODO: make sure destroying one instance of mouse doesn't mess with\n\t// other instances of mouse\n\t_mouseDestroy: function() {\n\t\tthis.element.unbind(\".\"+this.widgetName);\n\t\tif ( this._mouseMoveDelegate ) {\n\t\t\t$(document)\n\t\t\t\t.unbind(\"mousemove.\"+this.widgetName, this._mouseMoveDelegate)\n\t\t\t\t.unbind(\"mouseup.\"+this.widgetName, this._mouseUpDelegate);\n\t\t}\n\t},\n\n\t_mouseDown: function(event) {\n\t\t// don't let more than one widget handle mouseStart\n\t\tif( mouseHandled ) { return; }\n\n\t\t// we may have missed mouseup (out of window)\n\t\t(this._mouseStarted && this._mouseUp(event));\n\n\t\tthis._mouseDownEvent = event;\n\n\t\tvar that = this,\n\t\t\tbtnIsLeft = (event.which === 1),\n\t\t\t// event.target.nodeName works around a bug in IE 8 with\n\t\t\t// disabled inputs (#7620)\n\t\t\telIsCancel = (typeof this.options.cancel === \"string\" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);\n\t\tif (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {\n\t\t\treturn true;\n\t\t}\n\n\t\tthis.mouseDelayMet = !this.options.delay;\n\t\tif (!this.mouseDelayMet) {\n\t\t\tthis._mouseDelayTimer = setTimeout(function() {\n\t\t\t\tthat.mouseDelayMet = true;\n\t\t\t}, this.options.delay);\n\t\t}\n\n\t\tif (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {\n\t\t\tthis._mouseStarted = (this._mouseStart(event) !== false);\n\t\t\tif (!this._mouseStarted) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\t// Click event may never have fired (Gecko & Opera)\n\t\tif (true === $.data(event.target, this.widgetName + \".preventClickEvent\")) {\n\t\t\t$.removeData(event.target, this.widgetName + \".preventClickEvent\");\n\t\t}\n\n\t\t// these delegates are required to keep context\n\t\tthis._mouseMoveDelegate = function(event) {\n\t\t\treturn that._mouseMove(event);\n\t\t};\n\t\tthis._mouseUpDelegate = function(event) {\n\t\t\treturn that._mouseUp(event);\n\t\t};\n\t\t$(document)\n\t\t\t.bind(\"mousemove.\"+this.widgetName, this._mouseMoveDelegate)\n\t\t\t.bind(\"mouseup.\"+this.widgetName, this._mouseUpDelegate);\n\n\t\tevent.preventDefault();\n\n\t\tmouseHandled = true;\n\t\treturn true;\n\t},\n\n\t_mouseMove: function(event) {\n\t\t// IE mouseup check - mouseup happened when mouse was out of window\n\t\tif ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {\n\t\t\treturn this._mouseUp(event);\n\t\t}\n\n\t\tif (this._mouseStarted) {\n\t\t\tthis._mouseDrag(event);\n\t\t\treturn event.preventDefault();\n\t\t}\n\n\t\tif (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {\n\t\t\tthis._mouseStarted =\n\t\t\t\t(this._mouseStart(this._mouseDownEvent, event) !== false);\n\t\t\t(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));\n\t\t}\n\n\t\treturn !this._mouseStarted;\n\t},\n\n\t_mouseUp: function(event) {\n\t\t$(document)\n\t\t\t.unbind(\"mousemove.\"+this.widgetName, this._mouseMoveDelegate)\n\t\t\t.unbind(\"mouseup.\"+this.widgetName, this._mouseUpDelegate);\n\n\t\tif (this._mouseStarted) {\n\t\t\tthis._mouseStarted = false;\n\n\t\t\tif (event.target === this._mouseDownEvent.target) {\n\t\t\t\t$.data(event.target, this.widgetName + \".preventClickEvent\", true);\n\t\t\t}\n\n\t\t\tthis._mouseStop(event);\n\t\t}\n\n\t\treturn false;\n\t},\n\n\t_mouseDistanceMet: function(event) {\n\t\treturn (Math.max(\n\t\t\t\tMath.abs(this._mouseDownEvent.pageX - event.pageX),\n\t\t\t\tMath.abs(this._mouseDownEvent.pageY - event.pageY)\n\t\t\t) >= this.options.distance\n\t\t);\n\t},\n\n\t_mouseDelayMet: function(/* event */) {\n\t\treturn this.mouseDelayMet;\n\t},\n\n\t// These are placeholder methods, to be overriden by extending plugin\n\t_mouseStart: function(/* event */) {},\n\t_mouseDrag: function(/* event */) {},\n\t_mouseStop: function(/* event */) {},\n\t_mouseCapture: function(/* event */) { return true; }\n});\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.widget(\"ui.draggable\", $.ui.mouse, {\n\tversion: \"1.10.3\",\n\twidgetEventPrefix: \"drag\",\n\toptions: {\n\t\taddClasses: true,\n\t\tappendTo: \"parent\",\n\t\taxis: false,\n\t\tconnectToSortable: false,\n\t\tcontainment: false,\n\t\tcursor: \"auto\",\n\t\tcursorAt: false,\n\t\tgrid: false,\n\t\thandle: false,\n\t\thelper: \"original\",\n\t\tiframeFix: false,\n\t\topacity: false,\n\t\trefreshPositions: false,\n\t\trevert: false,\n\t\trevertDuration: 500,\n\t\tscope: \"default\",\n\t\tscroll: true,\n\t\tscrollSensitivity: 20,\n\t\tscrollSpeed: 20,\n\t\tsnap: false,\n\t\tsnapMode: \"both\",\n\t\tsnapTolerance: 20,\n\t\tstack: false,\n\t\tzIndex: false,\n\n\t\t// callbacks\n\t\tdrag: null,\n\t\tstart: null,\n\t\tstop: null\n\t},\n\t_create: function() {\n\n\t\tif (this.options.helper === \"original\" && !(/^(?:r|a|f)/).test(this.element.css(\"position\"))) {\n\t\t\tthis.element[0].style.position = \"relative\";\n\t\t}\n\t\tif (this.options.addClasses){\n\t\t\tthis.element.addClass(\"ui-draggable\");\n\t\t}\n\t\tif (this.options.disabled){\n\t\t\tthis.element.addClass(\"ui-draggable-disabled\");\n\t\t}\n\n\t\tthis._mouseInit();\n\n\t},\n\n\t_destroy: function() {\n\t\tthis.element.removeClass( \"ui-draggable ui-draggable-dragging ui-draggable-disabled\" );\n\t\tthis._mouseDestroy();\n\t},\n\n\t_mouseCapture: function(event) {\n\n\t\tvar o = this.options;\n\n\t\t// among others, prevent a drag on a resizable-handle\n\t\tif (this.helper || o.disabled || $(event.target).closest(\".ui-resizable-handle\").length > 0) {\n\t\t\treturn false;\n\t\t}\n\n\t\t//Quit if we're not on a valid handle\n\t\tthis.handle = this._getHandle(event);\n\t\tif (!this.handle) {\n\t\t\treturn false;\n\t\t}\n\n\t\t$(o.iframeFix === true ? \"iframe\" : o.iframeFix).each(function() {\n\t\t\t$(\"<div class='ui-draggable-iframeFix' style='background: #fff;'></div>\")\n\t\t\t.css({\n\t\t\t\twidth: this.offsetWidth+\"px\", height: this.offsetHeight+\"px\",\n\t\t\t\tposition: \"absolute\", opacity: \"0.001\", zIndex: 1000\n\t\t\t})\n\t\t\t.css($(this).offset())\n\t\t\t.appendTo(\"body\");\n\t\t});\n\n\t\treturn true;\n\n\t},\n\n\t_mouseStart: function(event) {\n\n\t\tvar o = this.options;\n\n\t\t//Create and append the visible helper\n\t\tthis.helper = this._createHelper(event);\n\n\t\tthis.helper.addClass(\"ui-draggable-dragging\");\n\n\t\t//Cache the helper size\n\t\tthis._cacheHelperProportions();\n\n\t\t//If ddmanager is used for droppables, set the global draggable\n\t\tif($.ui.ddmanager) {\n\t\t\t$.ui.ddmanager.current = this;\n\t\t}\n\n\t\t/*\n\t\t * - Position generation -\n\t\t * This block generates everything position related - it's the core of draggables.\n\t\t */\n\n\t\t//Cache the margins of the original element\n\t\tthis._cacheMargins();\n\n\t\t//Store the helper's css position\n\t\tthis.cssPosition = this.helper.css( \"position\" );\n\t\tthis.scrollParent = this.helper.scrollParent();\n\t\tthis.offsetParent = this.helper.offsetParent();\n\t\tthis.offsetParentCssPosition = this.offsetParent.css( \"position\" );\n\n\t\t//The element's absolute position on the page minus margins\n\t\tthis.offset = this.positionAbs = this.element.offset();\n\t\tthis.offset = {\n\t\t\ttop: this.offset.top - this.margins.top,\n\t\t\tleft: this.offset.left - this.margins.left\n\t\t};\n\n\t\t//Reset scroll cache\n\t\tthis.offset.scroll = false;\n\n\t\t$.extend(this.offset, {\n\t\t\tclick: { //Where the click happened, relative to the element\n\t\t\t\tleft: event.pageX - this.offset.left,\n\t\t\t\ttop: event.pageY - this.offset.top\n\t\t\t},\n\t\t\tparent: this._getParentOffset(),\n\t\t\trelative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper\n\t\t});\n\n\t\t//Generate the original position\n\t\tthis.originalPosition = this.position = this._generatePosition(event);\n\t\tthis.originalPageX = event.pageX;\n\t\tthis.originalPageY = event.pageY;\n\n\t\t//Adjust the mouse offset relative to the helper if \"cursorAt\" is supplied\n\t\t(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));\n\n\t\t//Set a containment if given in the options\n\t\tthis._setContainment();\n\n\t\t//Trigger event + callbacks\n\t\tif(this._trigger(\"start\", event) === false) {\n\t\t\tthis._clear();\n\t\t\treturn false;\n\t\t}\n\n\t\t//Recache the helper size\n\t\tthis._cacheHelperProportions();\n\n\t\t//Prepare the droppable offsets\n\t\tif ($.ui.ddmanager && !o.dropBehaviour) {\n\t\t\t$.ui.ddmanager.prepareOffsets(this, event);\n\t\t}\n\n\n\t\tthis._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position\n\n\t\t//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)\n\t\tif ( $.ui.ddmanager ) {\n\t\t\t$.ui.ddmanager.dragStart(this, event);\n\t\t}\n\n\t\treturn true;\n\t},\n\n\t_mouseDrag: function(event, noPropagation) {\n\t\t// reset any necessary cached properties (see #5009)\n\t\tif ( this.offsetParentCssPosition === \"fixed\" ) {\n\t\t\tthis.offset.parent = this._getParentOffset();\n\t\t}\n\n\t\t//Compute the helpers position\n\t\tthis.position = this._generatePosition(event);\n\t\tthis.positionAbs = this._convertPositionTo(\"absolute\");\n\n\t\t//Call plugins and callbacks and use the resulting position if something is returned\n\t\tif (!noPropagation) {\n\t\t\tvar ui = this._uiHash();\n\t\t\tif(this._trigger(\"drag\", event, ui) === false) {\n\t\t\t\tthis._mouseUp({});\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis.position = ui.position;\n\t\t}\n\n\t\tif(!this.options.axis || this.options.axis !== \"y\") {\n\t\t\tthis.helper[0].style.left = this.position.left+\"px\";\n\t\t}\n\t\tif(!this.options.axis || this.options.axis !== \"x\") {\n\t\t\tthis.helper[0].style.top = this.position.top+\"px\";\n\t\t}\n\t\tif($.ui.ddmanager) {\n\t\t\t$.ui.ddmanager.drag(this, event);\n\t\t}\n\n\t\treturn false;\n\t},\n\n\t_mouseStop: function(event) {\n\n\t\t//If we are using droppables, inform the manager about the drop\n\t\tvar that = this,\n\t\t\tdropped = false;\n\t\tif ($.ui.ddmanager && !this.options.dropBehaviour) {\n\t\t\tdropped = $.ui.ddmanager.drop(this, event);\n\t\t}\n\n\t\t//if a drop comes from outside (a sortable)\n\t\tif(this.dropped) {\n\t\t\tdropped = this.dropped;\n\t\t\tthis.dropped = false;\n\t\t}\n\n\t\t//if the original element is no longer in the DOM don't bother to continue (see #8269)\n\t\tif ( this.options.helper === \"original\" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif((this.options.revert === \"invalid\" && !dropped) || (this.options.revert === \"valid\" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {\n\t\t\t$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {\n\t\t\t\tif(that._trigger(\"stop\", event) !== false) {\n\t\t\t\t\tthat._clear();\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tif(this._trigger(\"stop\", event) !== false) {\n\t\t\t\tthis._clear();\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t},\n\n\t_mouseUp: function(event) {\n\t\t//Remove frame helpers\n\t\t$(\"div.ui-draggable-iframeFix\").each(function() {\n\t\t\tthis.parentNode.removeChild(this);\n\t\t});\n\n\t\t//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)\n\t\tif( $.ui.ddmanager ) {\n\t\t\t$.ui.ddmanager.dragStop(this, event);\n\t\t}\n\n\t\treturn $.ui.mouse.prototype._mouseUp.call(this, event);\n\t},\n\n\tcancel: function() {\n\n\t\tif(this.helper.is(\".ui-draggable-dragging\")) {\n\t\t\tthis._mouseUp({});\n\t\t} else {\n\t\t\tthis._clear();\n\t\t}\n\n\t\treturn this;\n\n\t},\n\n\t_getHandle: function(event) {\n\t\treturn this.options.handle ?\n\t\t\t!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :\n\t\t\ttrue;\n\t},\n\n\t_createHelper: function(event) {\n\n\t\tvar o = this.options,\n\t\t\thelper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === \"clone\" ? this.element.clone().removeAttr(\"id\") : this.element);\n\n\t\tif(!helper.parents(\"body\").length) {\n\t\t\thelper.appendTo((o.appendTo === \"parent\" ? this.element[0].parentNode : o.appendTo));\n\t\t}\n\n\t\tif(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css(\"position\"))) {\n\t\t\thelper.css(\"position\", \"absolute\");\n\t\t}\n\n\t\treturn helper;\n\n\t},\n\n\t_adjustOffsetFromHelper: function(obj) {\n\t\tif (typeof obj === \"string\") {\n\t\t\tobj = obj.split(\" \");\n\t\t}\n\t\tif ($.isArray(obj)) {\n\t\t\tobj = {left: +obj[0], top: +obj[1] || 0};\n\t\t}\n\t\tif (\"left\" in obj) {\n\t\t\tthis.offset.click.left = obj.left + this.margins.left;\n\t\t}\n\t\tif (\"right\" in obj) {\n\t\t\tthis.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;\n\t\t}\n\t\tif (\"top\" in obj) {\n\t\t\tthis.offset.click.top = obj.top + this.margins.top;\n\t\t}\n\t\tif (\"bottom\" in obj) {\n\t\t\tthis.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;\n\t\t}\n\t},\n\n\t_getParentOffset: function() {\n\n\t\t//Get the offsetParent and cache its position\n\t\tvar po = this.offsetParent.offset();\n\n\t\t// This is a special case where we need to modify a offset calculated on start, since the following happened:\n\t\t// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent\n\t\t// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that\n\t\t//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag\n\t\tif(this.cssPosition === \"absolute\" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {\n\t\t\tpo.left += this.scrollParent.scrollLeft();\n\t\t\tpo.top += this.scrollParent.scrollTop();\n\t\t}\n\n\t\t//This needs to be actually done for all browsers, since pageX/pageY includes this information\n\t\t//Ugly IE fix\n\t\tif((this.offsetParent[0] === document.body) ||\n\t\t\t(this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === \"html\" && $.ui.ie)) {\n\t\t\tpo = { top: 0, left: 0 };\n\t\t}\n\n\t\treturn {\n\t\t\ttop: po.top + (parseInt(this.offsetParent.css(\"borderTopWidth\"),10) || 0),\n\t\t\tleft: po.left + (parseInt(this.offsetParent.css(\"borderLeftWidth\"),10) || 0)\n\t\t};\n\n\t},\n\n\t_getRelativeOffset: function() {\n\n\t\tif(this.cssPosition === \"relative\") {\n\t\t\tvar p = this.element.position();\n\t\t\treturn {\n\t\t\t\ttop: p.top - (parseInt(this.helper.css(\"top\"),10) || 0) + this.scrollParent.scrollTop(),\n\t\t\t\tleft: p.left - (parseInt(this.helper.css(\"left\"),10) || 0) + this.scrollParent.scrollLeft()\n\t\t\t};\n\t\t} else {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t},\n\n\t_cacheMargins: function() {\n\t\tthis.margins = {\n\t\t\tleft: (parseInt(this.element.css(\"marginLeft\"),10) || 0),\n\t\t\ttop: (parseInt(this.element.css(\"marginTop\"),10) || 0),\n\t\t\tright: (parseInt(this.element.css(\"marginRight\"),10) || 0),\n\t\t\tbottom: (parseInt(this.element.css(\"marginBottom\"),10) || 0)\n\t\t};\n\t},\n\n\t_cacheHelperProportions: function() {\n\t\tthis.helperProportions = {\n\t\t\twidth: this.helper.outerWidth(),\n\t\t\theight: this.helper.outerHeight()\n\t\t};\n\t},\n\n\t_setContainment: function() {\n\n\t\tvar over, c, ce,\n\t\t\to = this.options;\n\n\t\tif ( !o.containment ) {\n\t\t\tthis.containment = null;\n\t\t\treturn;\n\t\t}\n\n\t\tif ( o.containment === \"window\" ) {\n\t\t\tthis.containment = [\n\t\t\t\t$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,\n\t\t\t\t$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,\n\t\t\t\t$( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,\n\t\t\t\t$( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top\n\t\t\t];\n\t\t\treturn;\n\t\t}\n\n\t\tif ( o.containment === \"document\") {\n\t\t\tthis.containment = [\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\t$( document ).width() - this.helperProportions.width - this.margins.left,\n\t\t\t\t( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top\n\t\t\t];\n\t\t\treturn;\n\t\t}\n\n\t\tif ( o.containment.constructor === Array ) {\n\t\t\tthis.containment = o.containment;\n\t\t\treturn;\n\t\t}\n\n\t\tif ( o.containment === \"parent\" ) {\n\t\t\to.containment = this.helper[ 0 ].parentNode;\n\t\t}\n\n\t\tc = $( o.containment );\n\t\tce = c[ 0 ];\n\n\t\tif( !ce ) {\n\t\t\treturn;\n\t\t}\n\n\t\tover = c.css( \"overflow\" ) !== \"hidden\";\n\n\t\tthis.containment = [\n\t\t\t( parseInt( c.css( \"borderLeftWidth\" ), 10 ) || 0 ) + ( parseInt( c.css( \"paddingLeft\" ), 10 ) || 0 ),\n\t\t\t( parseInt( c.css( \"borderTopWidth\" ), 10 ) || 0 ) + ( parseInt( c.css( \"paddingTop\" ), 10 ) || 0 ) ,\n\t\t\t( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( c.css( \"borderRightWidth\" ), 10 ) || 0 ) - ( parseInt( c.css( \"paddingRight\" ), 10 ) || 0 ) - this.helperProportions.width - this.margins.left - this.margins.right,\n\t\t\t( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - ( parseInt( c.css( \"borderBottomWidth\" ), 10 ) || 0 ) - ( parseInt( c.css( \"paddingBottom\" ), 10 ) || 0 ) - this.helperProportions.height - this.margins.top  - this.margins.bottom\n\t\t];\n\t\tthis.relative_container = c;\n\t},\n\n\t_convertPositionTo: function(d, pos) {\n\n\t\tif(!pos) {\n\t\t\tpos = this.position;\n\t\t}\n\n\t\tvar mod = d === \"absolute\" ? 1 : -1,\n\t\t\tscroll = this.cssPosition === \"absolute\" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent;\n\n\t\t//Cache the scroll\n\t\tif (!this.offset.scroll) {\n\t\t\tthis.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};\n\t\t}\n\n\t\treturn {\n\t\t\ttop: (\n\t\t\t\tpos.top\t+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.relative.top * mod +\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.top * mod -\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod )\n\t\t\t),\n\t\t\tleft: (\n\t\t\t\tpos.left +\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.relative.left * mod +\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.left * mod\t-\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod )\n\t\t\t)\n\t\t};\n\n\t},\n\n\t_generatePosition: function(event) {\n\n\t\tvar containment, co, top, left,\n\t\t\to = this.options,\n\t\t\tscroll = this.cssPosition === \"absolute\" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent,\n\t\t\tpageX = event.pageX,\n\t\t\tpageY = event.pageY;\n\n\t\t//Cache the scroll\n\t\tif (!this.offset.scroll) {\n\t\t\tthis.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};\n\t\t}\n\n\t\t/*\n\t\t * - Position constraining -\n\t\t * Constrain the position to a mix of grid, containment.\n\t\t */\n\n\t\t// If we are not dragging yet, we won't check for options\n\t\tif ( this.originalPosition ) {\n\t\t\tif ( this.containment ) {\n\t\t\t\tif ( this.relative_container ){\n\t\t\t\t\tco = this.relative_container.offset();\n\t\t\t\t\tcontainment = [\n\t\t\t\t\t\tthis.containment[ 0 ] + co.left,\n\t\t\t\t\t\tthis.containment[ 1 ] + co.top,\n\t\t\t\t\t\tthis.containment[ 2 ] + co.left,\n\t\t\t\t\t\tthis.containment[ 3 ] + co.top\n\t\t\t\t\t];\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tcontainment = this.containment;\n\t\t\t\t}\n\n\t\t\t\tif(event.pageX - this.offset.click.left < containment[0]) {\n\t\t\t\t\tpageX = containment[0] + this.offset.click.left;\n\t\t\t\t}\n\t\t\t\tif(event.pageY - this.offset.click.top < containment[1]) {\n\t\t\t\t\tpageY = containment[1] + this.offset.click.top;\n\t\t\t\t}\n\t\t\t\tif(event.pageX - this.offset.click.left > containment[2]) {\n\t\t\t\t\tpageX = containment[2] + this.offset.click.left;\n\t\t\t\t}\n\t\t\t\tif(event.pageY - this.offset.click.top > containment[3]) {\n\t\t\t\t\tpageY = containment[3] + this.offset.click.top;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(o.grid) {\n\t\t\t\t//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)\n\t\t\t\ttop = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;\n\t\t\t\tpageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;\n\n\t\t\t\tleft = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;\n\t\t\t\tpageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\t\t\ttop: (\n\t\t\t\tpageY -\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.click.top\t-\t\t\t\t\t\t\t\t\t\t\t\t// Click offset (relative to the element)\n\t\t\t\tthis.offset.relative.top -\t\t\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.top +\t\t\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollTop() : this.offset.scroll.top )\n\t\t\t),\n\t\t\tleft: (\n\t\t\t\tpageX -\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.click.left -\t\t\t\t\t\t\t\t\t\t\t\t// Click offset (relative to the element)\n\t\t\t\tthis.offset.relative.left -\t\t\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.left +\t\t\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left )\n\t\t\t)\n\t\t};\n\n\t},\n\n\t_clear: function() {\n\t\tthis.helper.removeClass(\"ui-draggable-dragging\");\n\t\tif(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {\n\t\t\tthis.helper.remove();\n\t\t}\n\t\tthis.helper = null;\n\t\tthis.cancelHelperRemoval = false;\n\t},\n\n\t// From now on bulk stuff - mainly helpers\n\n\t_trigger: function(type, event, ui) {\n\t\tui = ui || this._uiHash();\n\t\t$.ui.plugin.call(this, type, [event, ui]);\n\t\t//The absolute position has to be recalculated after plugins\n\t\tif(type === \"drag\") {\n\t\t\tthis.positionAbs = this._convertPositionTo(\"absolute\");\n\t\t}\n\t\treturn $.Widget.prototype._trigger.call(this, type, event, ui);\n\t},\n\n\tplugins: {},\n\n\t_uiHash: function() {\n\t\treturn {\n\t\t\thelper: this.helper,\n\t\t\tposition: this.position,\n\t\t\toriginalPosition: this.originalPosition,\n\t\t\toffset: this.positionAbs\n\t\t};\n\t}\n\n});\n\n$.ui.plugin.add(\"draggable\", \"connectToSortable\", {\n\tstart: function(event, ui) {\n\n\t\tvar inst = $(this).data(\"ui-draggable\"), o = inst.options,\n\t\t\tuiSortable = $.extend({}, ui, { item: inst.element });\n\t\tinst.sortables = [];\n\t\t$(o.connectToSortable).each(function() {\n\t\t\tvar sortable = $.data(this, \"ui-sortable\");\n\t\t\tif (sortable && !sortable.options.disabled) {\n\t\t\t\tinst.sortables.push({\n\t\t\t\t\tinstance: sortable,\n\t\t\t\t\tshouldRevert: sortable.options.revert\n\t\t\t\t});\n\t\t\t\tsortable.refreshPositions();\t// Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).\n\t\t\t\tsortable._trigger(\"activate\", event, uiSortable);\n\t\t\t}\n\t\t});\n\n\t},\n\tstop: function(event, ui) {\n\n\t\t//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper\n\t\tvar inst = $(this).data(\"ui-draggable\"),\n\t\t\tuiSortable = $.extend({}, ui, { item: inst.element });\n\n\t\t$.each(inst.sortables, function() {\n\t\t\tif(this.instance.isOver) {\n\n\t\t\t\tthis.instance.isOver = 0;\n\n\t\t\t\tinst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance\n\t\t\t\tthis.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)\n\n\t\t\t\t//The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: \"valid/invalid\"\n\t\t\t\tif(this.shouldRevert) {\n\t\t\t\t\tthis.instance.options.revert = this.shouldRevert;\n\t\t\t\t}\n\n\t\t\t\t//Trigger the stop of the sortable\n\t\t\t\tthis.instance._mouseStop(event);\n\n\t\t\t\tthis.instance.options.helper = this.instance.options._helper;\n\n\t\t\t\t//If the helper has been the original item, restore properties in the sortable\n\t\t\t\tif(inst.options.helper === \"original\") {\n\t\t\t\t\tthis.instance.currentItem.css({ top: \"auto\", left: \"auto\" });\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\tthis.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance\n\t\t\t\tthis.instance._trigger(\"deactivate\", event, uiSortable);\n\t\t\t}\n\n\t\t});\n\n\t},\n\tdrag: function(event, ui) {\n\n\t\tvar inst = $(this).data(\"ui-draggable\"), that = this;\n\n\t\t$.each(inst.sortables, function() {\n\n\t\t\tvar innermostIntersecting = false,\n\t\t\t\tthisSortable = this;\n\n\t\t\t//Copy over some variables to allow calling the sortable's native _intersectsWith\n\t\t\tthis.instance.positionAbs = inst.positionAbs;\n\t\t\tthis.instance.helperProportions = inst.helperProportions;\n\t\t\tthis.instance.offset.click = inst.offset.click;\n\n\t\t\tif(this.instance._intersectsWith(this.instance.containerCache)) {\n\t\t\t\tinnermostIntersecting = true;\n\t\t\t\t$.each(inst.sortables, function () {\n\t\t\t\t\tthis.instance.positionAbs = inst.positionAbs;\n\t\t\t\t\tthis.instance.helperProportions = inst.helperProportions;\n\t\t\t\t\tthis.instance.offset.click = inst.offset.click;\n\t\t\t\t\tif (this !== thisSortable &&\n\t\t\t\t\t\tthis.instance._intersectsWith(this.instance.containerCache) &&\n\t\t\t\t\t\t$.contains(thisSortable.instance.element[0], this.instance.element[0])\n\t\t\t\t\t) {\n\t\t\t\t\t\tinnermostIntersecting = false;\n\t\t\t\t\t}\n\t\t\t\t\treturn innermostIntersecting;\n\t\t\t\t});\n\t\t\t}\n\n\n\t\t\tif(innermostIntersecting) {\n\t\t\t\t//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once\n\t\t\t\tif(!this.instance.isOver) {\n\n\t\t\t\t\tthis.instance.isOver = 1;\n\t\t\t\t\t//Now we fake the start of dragging for the sortable instance,\n\t\t\t\t\t//by cloning the list group item, appending it to the sortable and using it as inst.currentItem\n\t\t\t\t\t//We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)\n\t\t\t\t\tthis.instance.currentItem = $(that).clone().removeAttr(\"id\").appendTo(this.instance.element).data(\"ui-sortable-item\", true);\n\t\t\t\t\tthis.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it\n\t\t\t\t\tthis.instance.options.helper = function() { return ui.helper[0]; };\n\n\t\t\t\t\tevent.target = this.instance.currentItem[0];\n\t\t\t\t\tthis.instance._mouseCapture(event, true);\n\t\t\t\t\tthis.instance._mouseStart(event, true, true);\n\n\t\t\t\t\t//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes\n\t\t\t\t\tthis.instance.offset.click.top = inst.offset.click.top;\n\t\t\t\t\tthis.instance.offset.click.left = inst.offset.click.left;\n\t\t\t\t\tthis.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;\n\t\t\t\t\tthis.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;\n\n\t\t\t\t\tinst._trigger(\"toSortable\", event);\n\t\t\t\t\tinst.dropped = this.instance.element; //draggable revert needs that\n\t\t\t\t\t//hack so receive/update callbacks work (mostly)\n\t\t\t\t\tinst.currentItem = inst.element;\n\t\t\t\t\tthis.instance.fromOutside = inst;\n\n\t\t\t\t}\n\n\t\t\t\t//Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable\n\t\t\t\tif(this.instance.currentItem) {\n\t\t\t\t\tthis.instance._mouseDrag(event);\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t//If it doesn't intersect with the sortable, and it intersected before,\n\t\t\t\t//we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval\n\t\t\t\tif(this.instance.isOver) {\n\n\t\t\t\t\tthis.instance.isOver = 0;\n\t\t\t\t\tthis.instance.cancelHelperRemoval = true;\n\n\t\t\t\t\t//Prevent reverting on this forced stop\n\t\t\t\t\tthis.instance.options.revert = false;\n\n\t\t\t\t\t// The out event needs to be triggered independently\n\t\t\t\t\tthis.instance._trigger(\"out\", event, this.instance._uiHash(this.instance));\n\n\t\t\t\t\tthis.instance._mouseStop(event, true);\n\t\t\t\t\tthis.instance.options.helper = this.instance.options._helper;\n\n\t\t\t\t\t//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size\n\t\t\t\t\tthis.instance.currentItem.remove();\n\t\t\t\t\tif(this.instance.placeholder) {\n\t\t\t\t\t\tthis.instance.placeholder.remove();\n\t\t\t\t\t}\n\n\t\t\t\t\tinst._trigger(\"fromSortable\", event);\n\t\t\t\t\tinst.dropped = false; //draggable revert needs that\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t});\n\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"cursor\", {\n\tstart: function() {\n\t\tvar t = $(\"body\"), o = $(this).data(\"ui-draggable\").options;\n\t\tif (t.css(\"cursor\")) {\n\t\t\to._cursor = t.css(\"cursor\");\n\t\t}\n\t\tt.css(\"cursor\", o.cursor);\n\t},\n\tstop: function() {\n\t\tvar o = $(this).data(\"ui-draggable\").options;\n\t\tif (o._cursor) {\n\t\t\t$(\"body\").css(\"cursor\", o._cursor);\n\t\t}\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"opacity\", {\n\tstart: function(event, ui) {\n\t\tvar t = $(ui.helper), o = $(this).data(\"ui-draggable\").options;\n\t\tif(t.css(\"opacity\")) {\n\t\t\to._opacity = t.css(\"opacity\");\n\t\t}\n\t\tt.css(\"opacity\", o.opacity);\n\t},\n\tstop: function(event, ui) {\n\t\tvar o = $(this).data(\"ui-draggable\").options;\n\t\tif(o._opacity) {\n\t\t\t$(ui.helper).css(\"opacity\", o._opacity);\n\t\t}\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"scroll\", {\n\tstart: function() {\n\t\tvar i = $(this).data(\"ui-draggable\");\n\t\tif(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== \"HTML\") {\n\t\t\ti.overflowOffset = i.scrollParent.offset();\n\t\t}\n\t},\n\tdrag: function( event ) {\n\n\t\tvar i = $(this).data(\"ui-draggable\"), o = i.options, scrolled = false;\n\n\t\tif(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== \"HTML\") {\n\n\t\t\tif(!o.axis || o.axis !== \"x\") {\n\t\t\t\tif((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {\n\t\t\t\t\ti.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;\n\t\t\t\t} else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) {\n\t\t\t\t\ti.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(!o.axis || o.axis !== \"y\") {\n\t\t\t\tif((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {\n\t\t\t\t\ti.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;\n\t\t\t\t} else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) {\n\t\t\t\t\ti.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tif(!o.axis || o.axis !== \"x\") {\n\t\t\t\tif(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);\n\t\t\t\t} else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(!o.axis || o.axis !== \"y\") {\n\t\t\t\tif(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);\n\t\t\t\t} else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\tif(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {\n\t\t\t$.ui.ddmanager.prepareOffsets(i, event);\n\t\t}\n\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"snap\", {\n\tstart: function() {\n\n\t\tvar i = $(this).data(\"ui-draggable\"),\n\t\t\to = i.options;\n\n\t\ti.snapElements = [];\n\n\t\t$(o.snap.constructor !== String ? ( o.snap.items || \":data(ui-draggable)\" ) : o.snap).each(function() {\n\t\t\tvar $t = $(this),\n\t\t\t\t$o = $t.offset();\n\t\t\tif(this !== i.element[0]) {\n\t\t\t\ti.snapElements.push({\n\t\t\t\t\titem: this,\n\t\t\t\t\twidth: $t.outerWidth(), height: $t.outerHeight(),\n\t\t\t\t\ttop: $o.top, left: $o.left\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t},\n\tdrag: function(event, ui) {\n\n\t\tvar ts, bs, ls, rs, l, r, t, b, i, first,\n\t\t\tinst = $(this).data(\"ui-draggable\"),\n\t\t\to = inst.options,\n\t\t\td = o.snapTolerance,\n\t\t\tx1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,\n\t\t\ty1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;\n\n\t\tfor (i = inst.snapElements.length - 1; i >= 0; i--){\n\n\t\t\tl = inst.snapElements[i].left;\n\t\t\tr = l + inst.snapElements[i].width;\n\t\t\tt = inst.snapElements[i].top;\n\t\t\tb = t + inst.snapElements[i].height;\n\n\t\t\tif ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {\n\t\t\t\tif(inst.snapElements[i].snapping) {\n\t\t\t\t\t(inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));\n\t\t\t\t}\n\t\t\t\tinst.snapElements[i].snapping = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif(o.snapMode !== \"inner\") {\n\t\t\t\tts = Math.abs(t - y2) <= d;\n\t\t\t\tbs = Math.abs(b - y1) <= d;\n\t\t\t\tls = Math.abs(l - x2) <= d;\n\t\t\t\trs = Math.abs(r - x1) <= d;\n\t\t\t\tif(ts) {\n\t\t\t\t\tui.position.top = inst._convertPositionTo(\"relative\", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;\n\t\t\t\t}\n\t\t\t\tif(bs) {\n\t\t\t\t\tui.position.top = inst._convertPositionTo(\"relative\", { top: b, left: 0 }).top - inst.margins.top;\n\t\t\t\t}\n\t\t\t\tif(ls) {\n\t\t\t\t\tui.position.left = inst._convertPositionTo(\"relative\", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;\n\t\t\t\t}\n\t\t\t\tif(rs) {\n\t\t\t\t\tui.position.left = inst._convertPositionTo(\"relative\", { top: 0, left: r }).left - inst.margins.left;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfirst = (ts || bs || ls || rs);\n\n\t\t\tif(o.snapMode !== \"outer\") {\n\t\t\t\tts = Math.abs(t - y1) <= d;\n\t\t\t\tbs = Math.abs(b - y2) <= d;\n\t\t\t\tls = Math.abs(l - x1) <= d;\n\t\t\t\trs = Math.abs(r - x2) <= d;\n\t\t\t\tif(ts) {\n\t\t\t\t\tui.position.top = inst._convertPositionTo(\"relative\", { top: t, left: 0 }).top - inst.margins.top;\n\t\t\t\t}\n\t\t\t\tif(bs) {\n\t\t\t\t\tui.position.top = inst._convertPositionTo(\"relative\", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;\n\t\t\t\t}\n\t\t\t\tif(ls) {\n\t\t\t\t\tui.position.left = inst._convertPositionTo(\"relative\", { top: 0, left: l }).left - inst.margins.left;\n\t\t\t\t}\n\t\t\t\tif(rs) {\n\t\t\t\t\tui.position.left = inst._convertPositionTo(\"relative\", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {\n\t\t\t\t(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));\n\t\t\t}\n\t\t\tinst.snapElements[i].snapping = (ts || bs || ls || rs || first);\n\n\t\t}\n\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"stack\", {\n\tstart: function() {\n\t\tvar min,\n\t\t\to = this.data(\"ui-draggable\").options,\n\t\t\tgroup = $.makeArray($(o.stack)).sort(function(a,b) {\n\t\t\t\treturn (parseInt($(a).css(\"zIndex\"),10) || 0) - (parseInt($(b).css(\"zIndex\"),10) || 0);\n\t\t\t});\n\n\t\tif (!group.length) { return; }\n\n\t\tmin = parseInt($(group[0]).css(\"zIndex\"), 10) || 0;\n\t\t$(group).each(function(i) {\n\t\t\t$(this).css(\"zIndex\", min + i);\n\t\t});\n\t\tthis.css(\"zIndex\", (min + group.length));\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"zIndex\", {\n\tstart: function(event, ui) {\n\t\tvar t = $(ui.helper), o = $(this).data(\"ui-draggable\").options;\n\t\tif(t.css(\"zIndex\")) {\n\t\t\to._zIndex = t.css(\"zIndex\");\n\t\t}\n\t\tt.css(\"zIndex\", o.zIndex);\n\t},\n\tstop: function(event, ui) {\n\t\tvar o = $(this).data(\"ui-draggable\").options;\n\t\tif(o._zIndex) {\n\t\t\t$(ui.helper).css(\"zIndex\", o._zIndex);\n\t\t}\n\t}\n});\n\n})(jQuery);\n\n(function( $, undefined ) {\n\nfunction isOverAxis( x, reference, size ) {\n\treturn ( x > reference ) && ( x < ( reference + size ) );\n}\n\n$.widget(\"ui.droppable\", {\n\tversion: \"1.10.3\",\n\twidgetEventPrefix: \"drop\",\n\toptions: {\n\t\taccept: \"*\",\n\t\tactiveClass: false,\n\t\taddClasses: true,\n\t\tgreedy: false,\n\t\thoverClass: false,\n\t\tscope: \"default\",\n\t\ttolerance: \"intersect\",\n\n\t\t// callbacks\n\t\tactivate: null,\n\t\tdeactivate: null,\n\t\tdrop: null,\n\t\tout: null,\n\t\tover: null\n\t},\n\t_create: function() {\n\n\t\tvar o = this.options,\n\t\t\taccept = o.accept;\n\n\t\tthis.isover = false;\n\t\tthis.isout = true;\n\n\t\tthis.accept = $.isFunction(accept) ? accept : function(d) {\n\t\t\treturn d.is(accept);\n\t\t};\n\n\t\t//Store the droppable's proportions\n\t\tthis.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };\n\n\t\t// Add the reference and positions to the manager\n\t\t$.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];\n\t\t$.ui.ddmanager.droppables[o.scope].push(this);\n\n\t\t(o.addClasses && this.element.addClass(\"ui-droppable\"));\n\n\t},\n\n\t_destroy: function() {\n\t\tvar i = 0,\n\t\t\tdrop = $.ui.ddmanager.droppables[this.options.scope];\n\n\t\tfor ( ; i < drop.length; i++ ) {\n\t\t\tif ( drop[i] === this ) {\n\t\t\t\tdrop.splice(i, 1);\n\t\t\t}\n\t\t}\n\n\t\tthis.element.removeClass(\"ui-droppable ui-droppable-disabled\");\n\t},\n\n\t_setOption: function(key, value) {\n\n\t\tif(key === \"accept\") {\n\t\t\tthis.accept = $.isFunction(value) ? value : function(d) {\n\t\t\t\treturn d.is(value);\n\t\t\t};\n\t\t}\n\t\t$.Widget.prototype._setOption.apply(this, arguments);\n\t},\n\n\t_activate: function(event) {\n\t\tvar draggable = $.ui.ddmanager.current;\n\t\tif(this.options.activeClass) {\n\t\t\tthis.element.addClass(this.options.activeClass);\n\t\t}\n\t\tif(draggable){\n\t\t\tthis._trigger(\"activate\", event, this.ui(draggable));\n\t\t}\n\t},\n\n\t_deactivate: function(event) {\n\t\tvar draggable = $.ui.ddmanager.current;\n\t\tif(this.options.activeClass) {\n\t\t\tthis.element.removeClass(this.options.activeClass);\n\t\t}\n\t\tif(draggable){\n\t\t\tthis._trigger(\"deactivate\", event, this.ui(draggable));\n\t\t}\n\t},\n\n\t_over: function(event) {\n\n\t\tvar draggable = $.ui.ddmanager.current;\n\n\t\t// Bail if draggable and droppable are same element\n\t\tif (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {\n\t\t\tif(this.options.hoverClass) {\n\t\t\t\tthis.element.addClass(this.options.hoverClass);\n\t\t\t}\n\t\t\tthis._trigger(\"over\", event, this.ui(draggable));\n\t\t}\n\n\t},\n\n\t_out: function(event) {\n\n\t\tvar draggable = $.ui.ddmanager.current;\n\n\t\t// Bail if draggable and droppable are same element\n\t\tif (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {\n\t\t\tif(this.options.hoverClass) {\n\t\t\t\tthis.element.removeClass(this.options.hoverClass);\n\t\t\t}\n\t\t\tthis._trigger(\"out\", event, this.ui(draggable));\n\t\t}\n\n\t},\n\n\t_drop: function(event,custom) {\n\n\t\tvar draggable = custom || $.ui.ddmanager.current,\n\t\t\tchildrenIntersection = false;\n\n\t\t// Bail if draggable and droppable are same element\n\t\tif (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.element.find(\":data(ui-droppable)\").not(\".ui-draggable-dragging\").each(function() {\n\t\t\tvar inst = $.data(this, \"ui-droppable\");\n\t\t\tif(\n\t\t\t\tinst.options.greedy &&\n\t\t\t\t!inst.options.disabled &&\n\t\t\t\tinst.options.scope === draggable.options.scope &&\n\t\t\t\tinst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) &&\n\t\t\t\t$.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)\n\t\t\t) { childrenIntersection = true; return false; }\n\t\t});\n\t\tif(childrenIntersection) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {\n\t\t\tif(this.options.activeClass) {\n\t\t\t\tthis.element.removeClass(this.options.activeClass);\n\t\t\t}\n\t\t\tif(this.options.hoverClass) {\n\t\t\t\tthis.element.removeClass(this.options.hoverClass);\n\t\t\t}\n\t\t\tthis._trigger(\"drop\", event, this.ui(draggable));\n\t\t\treturn this.element;\n\t\t}\n\n\t\treturn false;\n\n\t},\n\n\tui: function(c) {\n\t\treturn {\n\t\t\tdraggable: (c.currentItem || c.element),\n\t\t\thelper: c.helper,\n\t\t\tposition: c.position,\n\t\t\toffset: c.positionAbs\n\t\t};\n\t}\n\n});\n\n$.ui.intersect = function(draggable, droppable, toleranceMode) {\n\n\tif (!droppable.offset) {\n\t\treturn false;\n\t}\n\n\tvar draggableLeft, draggableTop,\n\t\tx1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,\n\t\ty1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height,\n\t\tl = droppable.offset.left, r = l + droppable.proportions.width,\n\t\tt = droppable.offset.top, b = t + droppable.proportions.height;\n\n\tswitch (toleranceMode) {\n\t\tcase \"fit\":\n\t\t\treturn (l <= x1 && x2 <= r && t <= y1 && y2 <= b);\n\t\tcase \"intersect\":\n\t\t\treturn (l < x1 + (draggable.helperProportions.width / 2) && // Right Half\n\t\t\t\tx2 - (draggable.helperProportions.width / 2) < r && // Left Half\n\t\t\t\tt < y1 + (draggable.helperProportions.height / 2) && // Bottom Half\n\t\t\t\ty2 - (draggable.helperProportions.height / 2) < b ); // Top Half\n\t\tcase \"pointer\":\n\t\t\tdraggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);\n\t\t\tdraggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);\n\t\t\treturn isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width );\n\t\tcase \"touch\":\n\t\t\treturn (\n\t\t\t\t(y1 >= t && y1 <= b) ||\t// Top edge touching\n\t\t\t\t(y2 >= t && y2 <= b) ||\t// Bottom edge touching\n\t\t\t\t(y1 < t && y2 > b)\t\t// Surrounded vertically\n\t\t\t) && (\n\t\t\t\t(x1 >= l && x1 <= r) ||\t// Left edge touching\n\t\t\t\t(x2 >= l && x2 <= r) ||\t// Right edge touching\n\t\t\t\t(x1 < l && x2 > r)\t\t// Surrounded horizontally\n\t\t\t);\n\t\tdefault:\n\t\t\treturn false;\n\t\t}\n\n};\n\n/*\n\tThis manager tracks offsets of draggables and droppables\n*/\n$.ui.ddmanager = {\n\tcurrent: null,\n\tdroppables: { \"default\": [] },\n\tprepareOffsets: function(t, event) {\n\n\t\tvar i, j,\n\t\t\tm = $.ui.ddmanager.droppables[t.options.scope] || [],\n\t\t\ttype = event ? event.type : null, // workaround for #2317\n\t\t\tlist = (t.currentItem || t.element).find(\":data(ui-droppable)\").addBack();\n\n\t\tdroppablesLoop: for (i = 0; i < m.length; i++) {\n\n\t\t\t//No disabled and non-accepted\n\t\t\tif(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Filter out elements in the current dragged item\n\t\t\tfor (j=0; j < list.length; j++) {\n\t\t\t\tif(list[j] === m[i].element[0]) {\n\t\t\t\t\tm[i].proportions.height = 0;\n\t\t\t\t\tcontinue droppablesLoop;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tm[i].visible = m[i].element.css(\"display\") !== \"none\";\n\t\t\tif(!m[i].visible) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t//Activate the droppable if used directly from draggables\n\t\t\tif(type === \"mousedown\") {\n\t\t\t\tm[i]._activate.call(m[i], event);\n\t\t\t}\n\n\t\t\tm[i].offset = m[i].element.offset();\n\t\t\tm[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };\n\n\t\t}\n\n\t},\n\tdrop: function(draggable, event) {\n\n\t\tvar dropped = false;\n\t\t// Create a copy of the droppables in case the list changes during the drop (#9116)\n\t\t$.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() {\n\n\t\t\tif(!this.options) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {\n\t\t\t\tdropped = this._drop.call(this, event) || dropped;\n\t\t\t}\n\n\t\t\tif (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {\n\t\t\t\tthis.isout = true;\n\t\t\t\tthis.isover = false;\n\t\t\t\tthis._deactivate.call(this, event);\n\t\t\t}\n\n\t\t});\n\t\treturn dropped;\n\n\t},\n\tdragStart: function( draggable, event ) {\n\t\t//Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)\n\t\tdraggable.element.parentsUntil( \"body\" ).bind( \"scroll.droppable\", function() {\n\t\t\tif( !draggable.options.refreshPositions ) {\n\t\t\t\t$.ui.ddmanager.prepareOffsets( draggable, event );\n\t\t\t}\n\t\t});\n\t},\n\tdrag: function(draggable, event) {\n\n\t\t//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.\n\t\tif(draggable.options.refreshPositions) {\n\t\t\t$.ui.ddmanager.prepareOffsets(draggable, event);\n\t\t}\n\n\t\t//Run through all droppables and check their positions based on specific tolerance options\n\t\t$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {\n\n\t\t\tif(this.options.disabled || this.greedyChild || !this.visible) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar parentInstance, scope, parent,\n\t\t\t\tintersects = $.ui.intersect(draggable, this, this.options.tolerance),\n\t\t\t\tc = !intersects && this.isover ? \"isout\" : (intersects && !this.isover ? \"isover\" : null);\n\t\t\tif(!c) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.options.greedy) {\n\t\t\t\t// find droppable parents with same scope\n\t\t\t\tscope = this.options.scope;\n\t\t\t\tparent = this.element.parents(\":data(ui-droppable)\").filter(function () {\n\t\t\t\t\treturn $.data(this, \"ui-droppable\").options.scope === scope;\n\t\t\t\t});\n\n\t\t\t\tif (parent.length) {\n\t\t\t\t\tparentInstance = $.data(parent[0], \"ui-droppable\");\n\t\t\t\t\tparentInstance.greedyChild = (c === \"isover\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// we just moved into a greedy child\n\t\t\tif (parentInstance && c === \"isover\") {\n\t\t\t\tparentInstance.isover = false;\n\t\t\t\tparentInstance.isout = true;\n\t\t\t\tparentInstance._out.call(parentInstance, event);\n\t\t\t}\n\n\t\t\tthis[c] = true;\n\t\t\tthis[c === \"isout\" ? \"isover\" : \"isout\"] = false;\n\t\t\tthis[c === \"isover\" ? \"_over\" : \"_out\"].call(this, event);\n\n\t\t\t// we just moved out of a greedy child\n\t\t\tif (parentInstance && c === \"isout\") {\n\t\t\t\tparentInstance.isout = false;\n\t\t\t\tparentInstance.isover = true;\n\t\t\t\tparentInstance._over.call(parentInstance, event);\n\t\t\t}\n\t\t});\n\n\t},\n\tdragStop: function( draggable, event ) {\n\t\tdraggable.element.parentsUntil( \"body\" ).unbind( \"scroll.droppable\" );\n\t\t//Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)\n\t\tif( !draggable.options.refreshPositions ) {\n\t\t\t$.ui.ddmanager.prepareOffsets( draggable, event );\n\t\t}\n\t}\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\nfunction num(v) {\n\treturn parseInt(v, 10) || 0;\n}\n\nfunction isNumber(value) {\n\treturn !isNaN(parseInt(value, 10));\n}\n\n$.widget(\"ui.resizable\", $.ui.mouse, {\n\tversion: \"1.10.3\",\n\twidgetEventPrefix: \"resize\",\n\toptions: {\n\t\talsoResize: false,\n\t\tanimate: false,\n\t\tanimateDuration: \"slow\",\n\t\tanimateEasing: \"swing\",\n\t\taspectRatio: false,\n\t\tautoHide: false,\n\t\tcontainment: false,\n\t\tghost: false,\n\t\tgrid: false,\n\t\thandles: \"e,s,se\",\n\t\thelper: false,\n\t\tmaxHeight: null,\n\t\tmaxWidth: null,\n\t\tminHeight: 10,\n\t\tminWidth: 10,\n\t\t// See #7960\n\t\tzIndex: 90,\n\n\t\t// callbacks\n\t\tresize: null,\n\t\tstart: null,\n\t\tstop: null\n\t},\n\t_create: function() {\n\n\t\tvar n, i, handle, axis, hname,\n\t\t\tthat = this,\n\t\t\to = this.options;\n\t\tthis.element.addClass(\"ui-resizable\");\n\n\t\t$.extend(this, {\n\t\t\t_aspectRatio: !!(o.aspectRatio),\n\t\t\taspectRatio: o.aspectRatio,\n\t\t\toriginalElement: this.element,\n\t\t\t_proportionallyResizeElements: [],\n\t\t\t_helper: o.helper || o.ghost || o.animate ? o.helper || \"ui-resizable-helper\" : null\n\t\t});\n\n\t\t//Wrap the element if it cannot hold child nodes\n\t\tif(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {\n\n\t\t\t//Create a wrapper element and set the wrapper to the new current internal element\n\t\t\tthis.element.wrap(\n\t\t\t\t$(\"<div class='ui-wrapper' style='overflow: hidden;'></div>\").css({\n\t\t\t\t\tposition: this.element.css(\"position\"),\n\t\t\t\t\twidth: this.element.outerWidth(),\n\t\t\t\t\theight: this.element.outerHeight(),\n\t\t\t\t\ttop: this.element.css(\"top\"),\n\t\t\t\t\tleft: this.element.css(\"left\")\n\t\t\t\t})\n\t\t\t);\n\n\t\t\t//Overwrite the original this.element\n\t\t\tthis.element = this.element.parent().data(\n\t\t\t\t\"ui-resizable\", this.element.data(\"ui-resizable\")\n\t\t\t);\n\n\t\t\tthis.elementIsWrapper = true;\n\n\t\t\t//Move margins to the wrapper\n\t\t\tthis.element.css({ marginLeft: this.originalElement.css(\"marginLeft\"), marginTop: this.originalElement.css(\"marginTop\"), marginRight: this.originalElement.css(\"marginRight\"), marginBottom: this.originalElement.css(\"marginBottom\") });\n\t\t\tthis.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});\n\n\t\t\t//Prevent Safari textarea resize\n\t\t\tthis.originalResizeStyle = this.originalElement.css(\"resize\");\n\t\t\tthis.originalElement.css(\"resize\", \"none\");\n\n\t\t\t//Push the actual element to our proportionallyResize internal array\n\t\t\tthis._proportionallyResizeElements.push(this.originalElement.css({ position: \"static\", zoom: 1, display: \"block\" }));\n\n\t\t\t// avoid IE jump (hard set the margin)\n\t\t\tthis.originalElement.css({ margin: this.originalElement.css(\"margin\") });\n\n\t\t\t// fix handlers offset\n\t\t\tthis._proportionallyResize();\n\n\t\t}\n\n\t\tthis.handles = o.handles || (!$(\".ui-resizable-handle\", this.element).length ? \"e,s,se\" : { n: \".ui-resizable-n\", e: \".ui-resizable-e\", s: \".ui-resizable-s\", w: \".ui-resizable-w\", se: \".ui-resizable-se\", sw: \".ui-resizable-sw\", ne: \".ui-resizable-ne\", nw: \".ui-resizable-nw\" });\n\t\tif(this.handles.constructor === String) {\n\n\t\t\tif ( this.handles === \"all\") {\n\t\t\t\tthis.handles = \"n,e,s,w,se,sw,ne,nw\";\n\t\t\t}\n\n\t\t\tn = this.handles.split(\",\");\n\t\t\tthis.handles = {};\n\n\t\t\tfor(i = 0; i < n.length; i++) {\n\n\t\t\t\thandle = $.trim(n[i]);\n\t\t\t\thname = \"ui-resizable-\"+handle;\n\t\t\t\taxis = $(\"<div class='ui-resizable-handle \" + hname + \"'></div>\");\n\n\t\t\t\t// Apply zIndex to all handles - see #7960\n\t\t\t\taxis.css({ zIndex: o.zIndex });\n\n\t\t\t\t//TODO : What's going on here?\n\t\t\t\tif (\"se\" === handle) {\n\t\t\t\t\taxis.addClass(\"ui-icon ui-icon-gripsmall-diagonal-se\");\n\t\t\t\t}\n\n\t\t\t\t//Insert into internal handles object and append to element\n\t\t\t\tthis.handles[handle] = \".ui-resizable-\"+handle;\n\t\t\t\tthis.element.append(axis);\n\t\t\t}\n\n\t\t}\n\n\t\tthis._renderAxis = function(target) {\n\n\t\t\tvar i, axis, padPos, padWrapper;\n\n\t\t\ttarget = target || this.element;\n\n\t\t\tfor(i in this.handles) {\n\n\t\t\t\tif(this.handles[i].constructor === String) {\n\t\t\t\t\tthis.handles[i] = $(this.handles[i], this.element).show();\n\t\t\t\t}\n\n\t\t\t\t//Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)\n\t\t\t\tif (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {\n\n\t\t\t\t\taxis = $(this.handles[i], this.element);\n\n\t\t\t\t\t//Checking the correct pad and border\n\t\t\t\t\tpadWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();\n\n\t\t\t\t\t//The padding type i have to apply...\n\t\t\t\t\tpadPos = [ \"padding\",\n\t\t\t\t\t\t/ne|nw|n/.test(i) ? \"Top\" :\n\t\t\t\t\t\t/se|sw|s/.test(i) ? \"Bottom\" :\n\t\t\t\t\t\t/^e$/.test(i) ? \"Right\" : \"Left\" ].join(\"\");\n\n\t\t\t\t\ttarget.css(padPos, padWrapper);\n\n\t\t\t\t\tthis._proportionallyResize();\n\n\t\t\t\t}\n\n\t\t\t\t//TODO: What's that good for? There's not anything to be executed left\n\t\t\t\tif(!$(this.handles[i]).length) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t//TODO: make renderAxis a prototype function\n\t\tthis._renderAxis(this.element);\n\n\t\tthis._handles = $(\".ui-resizable-handle\", this.element)\n\t\t\t.disableSelection();\n\n\t\t//Matching axis name\n\t\tthis._handles.mouseover(function() {\n\t\t\tif (!that.resizing) {\n\t\t\t\tif (this.className) {\n\t\t\t\t\taxis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);\n\t\t\t\t}\n\t\t\t\t//Axis, default = se\n\t\t\t\tthat.axis = axis && axis[1] ? axis[1] : \"se\";\n\t\t\t}\n\t\t});\n\n\t\t//If we want to auto hide the elements\n\t\tif (o.autoHide) {\n\t\t\tthis._handles.hide();\n\t\t\t$(this.element)\n\t\t\t\t.addClass(\"ui-resizable-autohide\")\n\t\t\t\t.mouseenter(function() {\n\t\t\t\t\tif (o.disabled) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t$(this).removeClass(\"ui-resizable-autohide\");\n\t\t\t\t\tthat._handles.show();\n\t\t\t\t})\n\t\t\t\t.mouseleave(function(){\n\t\t\t\t\tif (o.disabled) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (!that.resizing) {\n\t\t\t\t\t\t$(this).addClass(\"ui-resizable-autohide\");\n\t\t\t\t\t\tthat._handles.hide();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t}\n\n\t\t//Initialize the mouse interaction\n\t\tthis._mouseInit();\n\n\t},\n\n\t_destroy: function() {\n\n\t\tthis._mouseDestroy();\n\n\t\tvar wrapper,\n\t\t\t_destroy = function(exp) {\n\t\t\t\t$(exp).removeClass(\"ui-resizable ui-resizable-disabled ui-resizable-resizing\")\n\t\t\t\t\t.removeData(\"resizable\").removeData(\"ui-resizable\").unbind(\".resizable\").find(\".ui-resizable-handle\").remove();\n\t\t\t};\n\n\t\t//TODO: Unwrap at same DOM position\n\t\tif (this.elementIsWrapper) {\n\t\t\t_destroy(this.element);\n\t\t\twrapper = this.element;\n\t\t\tthis.originalElement.css({\n\t\t\t\tposition: wrapper.css(\"position\"),\n\t\t\t\twidth: wrapper.outerWidth(),\n\t\t\t\theight: wrapper.outerHeight(),\n\t\t\t\ttop: wrapper.css(\"top\"),\n\t\t\t\tleft: wrapper.css(\"left\")\n\t\t\t}).insertAfter( wrapper );\n\t\t\twrapper.remove();\n\t\t}\n\n\t\tthis.originalElement.css(\"resize\", this.originalResizeStyle);\n\t\t_destroy(this.originalElement);\n\n\t\treturn this;\n\t},\n\n\t_mouseCapture: function(event) {\n\t\tvar i, handle,\n\t\t\tcapture = false;\n\n\t\tfor (i in this.handles) {\n\t\t\thandle = $(this.handles[i])[0];\n\t\t\tif (handle === event.target || $.contains(handle, event.target)) {\n\t\t\t\tcapture = true;\n\t\t\t}\n\t\t}\n\n\t\treturn !this.options.disabled && capture;\n\t},\n\n\t_mouseStart: function(event) {\n\n\t\tvar curleft, curtop, cursor,\n\t\t\to = this.options,\n\t\t\tiniPos = this.element.position(),\n\t\t\tel = this.element;\n\n\t\tthis.resizing = true;\n\n\t\t// bugfix for http://dev.jquery.com/ticket/1749\n\t\tif ( (/absolute/).test( el.css(\"position\") ) ) {\n\t\t\tel.css({ position: \"absolute\", top: el.css(\"top\"), left: el.css(\"left\") });\n\t\t} else if (el.is(\".ui-draggable\")) {\n\t\t\tel.css({ position: \"absolute\", top: iniPos.top, left: iniPos.left });\n\t\t}\n\n\t\tthis._renderProxy();\n\n\t\tcurleft = num(this.helper.css(\"left\"));\n\t\tcurtop = num(this.helper.css(\"top\"));\n\n\t\tif (o.containment) {\n\t\t\tcurleft += $(o.containment).scrollLeft() || 0;\n\t\t\tcurtop += $(o.containment).scrollTop() || 0;\n\t\t}\n\n\t\t//Store needed variables\n\t\tthis.offset = this.helper.offset();\n\t\tthis.position = { left: curleft, top: curtop };\n\t\tthis.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };\n\t\tthis.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };\n\t\tthis.originalPosition = { left: curleft, top: curtop };\n\t\tthis.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };\n\t\tthis.originalMousePosition = { left: event.pageX, top: event.pageY };\n\n\t\t//Aspect Ratio\n\t\tthis.aspectRatio = (typeof o.aspectRatio === \"number\") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);\n\n\t\tcursor = $(\".ui-resizable-\" + this.axis).css(\"cursor\");\n\t\t$(\"body\").css(\"cursor\", cursor === \"auto\" ? this.axis + \"-resize\" : cursor);\n\n\t\tel.addClass(\"ui-resizable-resizing\");\n\t\tthis._propagate(\"start\", event);\n\t\treturn true;\n\t},\n\n\t_mouseDrag: function(event) {\n\n\t\t//Increase performance, avoid regex\n\t\tvar data,\n\t\t\tel = this.helper, props = {},\n\t\t\tsmp = this.originalMousePosition,\n\t\t\ta = this.axis,\n\t\t\tprevTop = this.position.top,\n\t\t\tprevLeft = this.position.left,\n\t\t\tprevWidth = this.size.width,\n\t\t\tprevHeight = this.size.height,\n\t\t\tdx = (event.pageX-smp.left)||0,\n\t\t\tdy = (event.pageY-smp.top)||0,\n\t\t\ttrigger = this._change[a];\n\n\t\tif (!trigger) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Calculate the attrs that will be change\n\t\tdata = trigger.apply(this, [event, dx, dy]);\n\n\t\t// Put this in the mouseDrag handler since the user can start pressing shift while resizing\n\t\tthis._updateVirtualBoundaries(event.shiftKey);\n\t\tif (this._aspectRatio || event.shiftKey) {\n\t\t\tdata = this._updateRatio(data, event);\n\t\t}\n\n\t\tdata = this._respectSize(data, event);\n\n\t\tthis._updateCache(data);\n\n\t\t// plugins callbacks need to be called first\n\t\tthis._propagate(\"resize\", event);\n\n\t\tif (this.position.top !== prevTop) {\n\t\t\tprops.top = this.position.top + \"px\";\n\t\t}\n\t\tif (this.position.left !== prevLeft) {\n\t\t\tprops.left = this.position.left + \"px\";\n\t\t}\n\t\tif (this.size.width !== prevWidth) {\n\t\t\tprops.width = this.size.width + \"px\";\n\t\t}\n\t\tif (this.size.height !== prevHeight) {\n\t\t\tprops.height = this.size.height + \"px\";\n\t\t}\n\t\tel.css(props);\n\n\t\tif (!this._helper && this._proportionallyResizeElements.length) {\n\t\t\tthis._proportionallyResize();\n\t\t}\n\n\t\t// Call the user callback if the element was resized\n\t\tif ( ! $.isEmptyObject(props) ) {\n\t\t\tthis._trigger(\"resize\", event, this.ui());\n\t\t}\n\n\t\treturn false;\n\t},\n\n\t_mouseStop: function(event) {\n\n\t\tthis.resizing = false;\n\t\tvar pr, ista, soffseth, soffsetw, s, left, top,\n\t\t\to = this.options, that = this;\n\n\t\tif(this._helper) {\n\n\t\t\tpr = this._proportionallyResizeElements;\n\t\t\tista = pr.length && (/textarea/i).test(pr[0].nodeName);\n\t\t\tsoffseth = ista && $.ui.hasScroll(pr[0], \"left\") /* TODO - jump height */ ? 0 : that.sizeDiff.height;\n\t\t\tsoffsetw = ista ? 0 : that.sizeDiff.width;\n\n\t\t\ts = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) };\n\t\t\tleft = (parseInt(that.element.css(\"left\"), 10) + (that.position.left - that.originalPosition.left)) || null;\n\t\t\ttop = (parseInt(that.element.css(\"top\"), 10) + (that.position.top - that.originalPosition.top)) || null;\n\n\t\t\tif (!o.animate) {\n\t\t\t\tthis.element.css($.extend(s, { top: top, left: left }));\n\t\t\t}\n\n\t\t\tthat.helper.height(that.size.height);\n\t\t\tthat.helper.width(that.size.width);\n\n\t\t\tif (this._helper && !o.animate) {\n\t\t\t\tthis._proportionallyResize();\n\t\t\t}\n\t\t}\n\n\t\t$(\"body\").css(\"cursor\", \"auto\");\n\n\t\tthis.element.removeClass(\"ui-resizable-resizing\");\n\n\t\tthis._propagate(\"stop\", event);\n\n\t\tif (this._helper) {\n\t\t\tthis.helper.remove();\n\t\t}\n\n\t\treturn false;\n\n\t},\n\n\t_updateVirtualBoundaries: function(forceAspectRatio) {\n\t\tvar pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,\n\t\t\to = this.options;\n\n\t\tb = {\n\t\t\tminWidth: isNumber(o.minWidth) ? o.minWidth : 0,\n\t\t\tmaxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,\n\t\t\tminHeight: isNumber(o.minHeight) ? o.minHeight : 0,\n\t\t\tmaxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity\n\t\t};\n\n\t\tif(this._aspectRatio || forceAspectRatio) {\n\t\t\t// We want to create an enclosing box whose aspect ration is the requested one\n\t\t\t// First, compute the \"projected\" size for each dimension based on the aspect ratio and other dimension\n\t\t\tpMinWidth = b.minHeight * this.aspectRatio;\n\t\t\tpMinHeight = b.minWidth / this.aspectRatio;\n\t\t\tpMaxWidth = b.maxHeight * this.aspectRatio;\n\t\t\tpMaxHeight = b.maxWidth / this.aspectRatio;\n\n\t\t\tif(pMinWidth > b.minWidth) {\n\t\t\t\tb.minWidth = pMinWidth;\n\t\t\t}\n\t\t\tif(pMinHeight > b.minHeight) {\n\t\t\t\tb.minHeight = pMinHeight;\n\t\t\t}\n\t\t\tif(pMaxWidth < b.maxWidth) {\n\t\t\t\tb.maxWidth = pMaxWidth;\n\t\t\t}\n\t\t\tif(pMaxHeight < b.maxHeight) {\n\t\t\t\tb.maxHeight = pMaxHeight;\n\t\t\t}\n\t\t}\n\t\tthis._vBoundaries = b;\n\t},\n\n\t_updateCache: function(data) {\n\t\tthis.offset = this.helper.offset();\n\t\tif (isNumber(data.left)) {\n\t\t\tthis.position.left = data.left;\n\t\t}\n\t\tif (isNumber(data.top)) {\n\t\t\tthis.position.top = data.top;\n\t\t}\n\t\tif (isNumber(data.height)) {\n\t\t\tthis.size.height = data.height;\n\t\t}\n\t\tif (isNumber(data.width)) {\n\t\t\tthis.size.width = data.width;\n\t\t}\n\t},\n\n\t_updateRatio: function( data ) {\n\n\t\tvar cpos = this.position,\n\t\t\tcsize = this.size,\n\t\t\ta = this.axis;\n\n\t\tif (isNumber(data.height)) {\n\t\t\tdata.width = (data.height * this.aspectRatio);\n\t\t} else if (isNumber(data.width)) {\n\t\t\tdata.height = (data.width / this.aspectRatio);\n\t\t}\n\n\t\tif (a === \"sw\") {\n\t\t\tdata.left = cpos.left + (csize.width - data.width);\n\t\t\tdata.top = null;\n\t\t}\n\t\tif (a === \"nw\") {\n\t\t\tdata.top = cpos.top + (csize.height - data.height);\n\t\t\tdata.left = cpos.left + (csize.width - data.width);\n\t\t}\n\n\t\treturn data;\n\t},\n\n\t_respectSize: function( data ) {\n\n\t\tvar o = this._vBoundaries,\n\t\t\ta = this.axis,\n\t\t\tismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),\n\t\t\tisminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height),\n\t\t\tdw = this.originalPosition.left + this.originalSize.width,\n\t\t\tdh = this.position.top + this.size.height,\n\t\t\tcw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);\n\t\tif (isminw) {\n\t\t\tdata.width = o.minWidth;\n\t\t}\n\t\tif (isminh) {\n\t\t\tdata.height = o.minHeight;\n\t\t}\n\t\tif (ismaxw) {\n\t\t\tdata.width = o.maxWidth;\n\t\t}\n\t\tif (ismaxh) {\n\t\t\tdata.height = o.maxHeight;\n\t\t}\n\n\t\tif (isminw && cw) {\n\t\t\tdata.left = dw - o.minWidth;\n\t\t}\n\t\tif (ismaxw && cw) {\n\t\t\tdata.left = dw - o.maxWidth;\n\t\t}\n\t\tif (isminh && ch) {\n\t\t\tdata.top = dh - o.minHeight;\n\t\t}\n\t\tif (ismaxh && ch) {\n\t\t\tdata.top = dh - o.maxHeight;\n\t\t}\n\n\t\t// fixing jump error on top/left - bug #2330\n\t\tif (!data.width && !data.height && !data.left && data.top) {\n\t\t\tdata.top = null;\n\t\t} else if (!data.width && !data.height && !data.top && data.left) {\n\t\t\tdata.left = null;\n\t\t}\n\n\t\treturn data;\n\t},\n\n\t_proportionallyResize: function() {\n\n\t\tif (!this._proportionallyResizeElements.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar i, j, borders, paddings, prel,\n\t\t\telement = this.helper || this.element;\n\n\t\tfor ( i=0; i < this._proportionallyResizeElements.length; i++) {\n\n\t\t\tprel = this._proportionallyResizeElements[i];\n\n\t\t\tif (!this.borderDif) {\n\t\t\t\tthis.borderDif = [];\n\t\t\t\tborders = [prel.css(\"borderTopWidth\"), prel.css(\"borderRightWidth\"), prel.css(\"borderBottomWidth\"), prel.css(\"borderLeftWidth\")];\n\t\t\t\tpaddings = [prel.css(\"paddingTop\"), prel.css(\"paddingRight\"), prel.css(\"paddingBottom\"), prel.css(\"paddingLeft\")];\n\n\t\t\t\tfor ( j = 0; j < borders.length; j++ ) {\n\t\t\t\t\tthis.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tprel.css({\n\t\t\t\theight: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,\n\t\t\t\twidth: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0\n\t\t\t});\n\n\t\t}\n\n\t},\n\n\t_renderProxy: function() {\n\n\t\tvar el = this.element, o = this.options;\n\t\tthis.elementOffset = el.offset();\n\n\t\tif(this._helper) {\n\n\t\t\tthis.helper = this.helper || $(\"<div style='overflow:hidden;'></div>\");\n\n\t\t\tthis.helper.addClass(this._helper).css({\n\t\t\t\twidth: this.element.outerWidth() - 1,\n\t\t\t\theight: this.element.outerHeight() - 1,\n\t\t\t\tposition: \"absolute\",\n\t\t\t\tleft: this.elementOffset.left +\"px\",\n\t\t\t\ttop: this.elementOffset.top +\"px\",\n\t\t\t\tzIndex: ++o.zIndex //TODO: Don't modify option\n\t\t\t});\n\n\t\t\tthis.helper\n\t\t\t\t.appendTo(\"body\")\n\t\t\t\t.disableSelection();\n\n\t\t} else {\n\t\t\tthis.helper = this.element;\n\t\t}\n\n\t},\n\n\t_change: {\n\t\te: function(event, dx) {\n\t\t\treturn { width: this.originalSize.width + dx };\n\t\t},\n\t\tw: function(event, dx) {\n\t\t\tvar cs = this.originalSize, sp = this.originalPosition;\n\t\t\treturn { left: sp.left + dx, width: cs.width - dx };\n\t\t},\n\t\tn: function(event, dx, dy) {\n\t\t\tvar cs = this.originalSize, sp = this.originalPosition;\n\t\t\treturn { top: sp.top + dy, height: cs.height - dy };\n\t\t},\n\t\ts: function(event, dx, dy) {\n\t\t\treturn { height: this.originalSize.height + dy };\n\t\t},\n\t\tse: function(event, dx, dy) {\n\t\t\treturn $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));\n\t\t},\n\t\tsw: function(event, dx, dy) {\n\t\t\treturn $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));\n\t\t},\n\t\tne: function(event, dx, dy) {\n\t\t\treturn $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));\n\t\t},\n\t\tnw: function(event, dx, dy) {\n\t\t\treturn $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));\n\t\t}\n\t},\n\n\t_propagate: function(n, event) {\n\t\t$.ui.plugin.call(this, n, [event, this.ui()]);\n\t\t(n !== \"resize\" && this._trigger(n, event, this.ui()));\n\t},\n\n\tplugins: {},\n\n\tui: function() {\n\t\treturn {\n\t\t\toriginalElement: this.originalElement,\n\t\t\telement: this.element,\n\t\t\thelper: this.helper,\n\t\t\tposition: this.position,\n\t\t\tsize: this.size,\n\t\t\toriginalSize: this.originalSize,\n\t\t\toriginalPosition: this.originalPosition\n\t\t};\n\t}\n\n});\n\n/*\n * Resizable Extensions\n */\n\n$.ui.plugin.add(\"resizable\", \"animate\", {\n\n\tstop: function( event ) {\n\t\tvar that = $(this).data(\"ui-resizable\"),\n\t\t\to = that.options,\n\t\t\tpr = that._proportionallyResizeElements,\n\t\t\tista = pr.length && (/textarea/i).test(pr[0].nodeName),\n\t\t\tsoffseth = ista && $.ui.hasScroll(pr[0], \"left\") /* TODO - jump height */ ? 0 : that.sizeDiff.height,\n\t\t\tsoffsetw = ista ? 0 : that.sizeDiff.width,\n\t\t\tstyle = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },\n\t\t\tleft = (parseInt(that.element.css(\"left\"), 10) + (that.position.left - that.originalPosition.left)) || null,\n\t\t\ttop = (parseInt(that.element.css(\"top\"), 10) + (that.position.top - that.originalPosition.top)) || null;\n\n\t\tthat.element.animate(\n\t\t\t$.extend(style, top && left ? { top: top, left: left } : {}), {\n\t\t\t\tduration: o.animateDuration,\n\t\t\t\teasing: o.animateEasing,\n\t\t\t\tstep: function() {\n\n\t\t\t\t\tvar data = {\n\t\t\t\t\t\twidth: parseInt(that.element.css(\"width\"), 10),\n\t\t\t\t\t\theight: parseInt(that.element.css(\"height\"), 10),\n\t\t\t\t\t\ttop: parseInt(that.element.css(\"top\"), 10),\n\t\t\t\t\t\tleft: parseInt(that.element.css(\"left\"), 10)\n\t\t\t\t\t};\n\n\t\t\t\t\tif (pr && pr.length) {\n\t\t\t\t\t\t$(pr[0]).css({ width: data.width, height: data.height });\n\t\t\t\t\t}\n\n\t\t\t\t\t// propagating resize, and updating values for each animation step\n\t\t\t\t\tthat._updateCache(data);\n\t\t\t\t\tthat._propagate(\"resize\", event);\n\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t}\n\n});\n\n$.ui.plugin.add(\"resizable\", \"containment\", {\n\n\tstart: function() {\n\t\tvar element, p, co, ch, cw, width, height,\n\t\t\tthat = $(this).data(\"ui-resizable\"),\n\t\t\to = that.options,\n\t\t\tel = that.element,\n\t\t\toc = o.containment,\n\t\t\tce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;\n\n\t\tif (!ce) {\n\t\t\treturn;\n\t\t}\n\n\t\tthat.containerElement = $(ce);\n\n\t\tif (/document/.test(oc) || oc === document) {\n\t\t\tthat.containerOffset = { left: 0, top: 0 };\n\t\t\tthat.containerPosition = { left: 0, top: 0 };\n\n\t\t\tthat.parentData = {\n\t\t\t\telement: $(document), left: 0, top: 0,\n\t\t\t\twidth: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight\n\t\t\t};\n\t\t}\n\n\t\t// i'm a node, so compute top, left, right, bottom\n\t\telse {\n\t\t\telement = $(ce);\n\t\t\tp = [];\n\t\t\t$([ \"Top\", \"Right\", \"Left\", \"Bottom\" ]).each(function(i, name) { p[i] = num(element.css(\"padding\" + name)); });\n\n\t\t\tthat.containerOffset = element.offset();\n\t\t\tthat.containerPosition = element.position();\n\t\t\tthat.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };\n\n\t\t\tco = that.containerOffset;\n\t\t\tch = that.containerSize.height;\n\t\t\tcw = that.containerSize.width;\n\t\t\twidth = ($.ui.hasScroll(ce, \"left\") ? ce.scrollWidth : cw );\n\t\t\theight = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);\n\n\t\t\tthat.parentData = {\n\t\t\t\telement: ce, left: co.left, top: co.top, width: width, height: height\n\t\t\t};\n\t\t}\n\t},\n\n\tresize: function( event ) {\n\t\tvar woset, hoset, isParent, isOffsetRelative,\n\t\t\tthat = $(this).data(\"ui-resizable\"),\n\t\t\to = that.options,\n\t\t\tco = that.containerOffset, cp = that.position,\n\t\t\tpRatio = that._aspectRatio || event.shiftKey,\n\t\t\tcop = { top:0, left:0 }, ce = that.containerElement;\n\n\t\tif (ce[0] !== document && (/static/).test(ce.css(\"position\"))) {\n\t\t\tcop = co;\n\t\t}\n\n\t\tif (cp.left < (that._helper ? co.left : 0)) {\n\t\t\tthat.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));\n\t\t\tif (pRatio) {\n\t\t\t\tthat.size.height = that.size.width / that.aspectRatio;\n\t\t\t}\n\t\t\tthat.position.left = o.helper ? co.left : 0;\n\t\t}\n\n\t\tif (cp.top < (that._helper ? co.top : 0)) {\n\t\t\tthat.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);\n\t\t\tif (pRatio) {\n\t\t\t\tthat.size.width = that.size.height * that.aspectRatio;\n\t\t\t}\n\t\t\tthat.position.top = that._helper ? co.top : 0;\n\t\t}\n\n\t\tthat.offset.left = that.parentData.left+that.position.left;\n\t\tthat.offset.top = that.parentData.top+that.position.top;\n\n\t\twoset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width );\n\t\thoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );\n\n\t\tisParent = that.containerElement.get(0) === that.element.parent().get(0);\n\t\tisOffsetRelative = /relative|absolute/.test(that.containerElement.css(\"position\"));\n\n\t\tif(isParent && isOffsetRelative) {\n\t\t\twoset -= that.parentData.left;\n\t\t}\n\n\t\tif (woset + that.size.width >= that.parentData.width) {\n\t\t\tthat.size.width = that.parentData.width - woset;\n\t\t\tif (pRatio) {\n\t\t\t\tthat.size.height = that.size.width / that.aspectRatio;\n\t\t\t}\n\t\t}\n\n\t\tif (hoset + that.size.height >= that.parentData.height) {\n\t\t\tthat.size.height = that.parentData.height - hoset;\n\t\t\tif (pRatio) {\n\t\t\t\tthat.size.width = that.size.height * that.aspectRatio;\n\t\t\t}\n\t\t}\n\t},\n\n\tstop: function(){\n\t\tvar that = $(this).data(\"ui-resizable\"),\n\t\t\to = that.options,\n\t\t\tco = that.containerOffset,\n\t\t\tcop = that.containerPosition,\n\t\t\tce = that.containerElement,\n\t\t\thelper = $(that.helper),\n\t\t\tho = helper.offset(),\n\t\t\tw = helper.outerWidth() - that.sizeDiff.width,\n\t\t\th = helper.outerHeight() - that.sizeDiff.height;\n\n\t\tif (that._helper && !o.animate && (/relative/).test(ce.css(\"position\"))) {\n\t\t\t$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });\n\t\t}\n\n\t\tif (that._helper && !o.animate && (/static/).test(ce.css(\"position\"))) {\n\t\t\t$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });\n\t\t}\n\n\t}\n});\n\n$.ui.plugin.add(\"resizable\", \"alsoResize\", {\n\n\tstart: function () {\n\t\tvar that = $(this).data(\"ui-resizable\"),\n\t\t\to = that.options,\n\t\t\t_store = function (exp) {\n\t\t\t\t$(exp).each(function() {\n\t\t\t\t\tvar el = $(this);\n\t\t\t\t\tel.data(\"ui-resizable-alsoresize\", {\n\t\t\t\t\t\twidth: parseInt(el.width(), 10), height: parseInt(el.height(), 10),\n\t\t\t\t\t\tleft: parseInt(el.css(\"left\"), 10), top: parseInt(el.css(\"top\"), 10)\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t};\n\n\t\tif (typeof(o.alsoResize) === \"object\" && !o.alsoResize.parentNode) {\n\t\t\tif (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }\n\t\t\telse { $.each(o.alsoResize, function (exp) { _store(exp); }); }\n\t\t}else{\n\t\t\t_store(o.alsoResize);\n\t\t}\n\t},\n\n\tresize: function (event, ui) {\n\t\tvar that = $(this).data(\"ui-resizable\"),\n\t\t\to = that.options,\n\t\t\tos = that.originalSize,\n\t\t\top = that.originalPosition,\n\t\t\tdelta = {\n\t\t\t\theight: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,\n\t\t\t\ttop: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0\n\t\t\t},\n\n\t\t\t_alsoResize = function (exp, c) {\n\t\t\t\t$(exp).each(function() {\n\t\t\t\t\tvar el = $(this), start = $(this).data(\"ui-resizable-alsoresize\"), style = {},\n\t\t\t\t\t\tcss = c && c.length ? c : el.parents(ui.originalElement[0]).length ? [\"width\", \"height\"] : [\"width\", \"height\", \"top\", \"left\"];\n\n\t\t\t\t\t$.each(css, function (i, prop) {\n\t\t\t\t\t\tvar sum = (start[prop]||0) + (delta[prop]||0);\n\t\t\t\t\t\tif (sum && sum >= 0) {\n\t\t\t\t\t\t\tstyle[prop] = sum || null;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tel.css(style);\n\t\t\t\t});\n\t\t\t};\n\n\t\tif (typeof(o.alsoResize) === \"object\" && !o.alsoResize.nodeType) {\n\t\t\t$.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });\n\t\t}else{\n\t\t\t_alsoResize(o.alsoResize);\n\t\t}\n\t},\n\n\tstop: function () {\n\t\t$(this).removeData(\"resizable-alsoresize\");\n\t}\n});\n\n$.ui.plugin.add(\"resizable\", \"ghost\", {\n\n\tstart: function() {\n\n\t\tvar that = $(this).data(\"ui-resizable\"), o = that.options, cs = that.size;\n\n\t\tthat.ghost = that.originalElement.clone();\n\t\tthat.ghost\n\t\t\t.css({ opacity: 0.25, display: \"block\", position: \"relative\", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })\n\t\t\t.addClass(\"ui-resizable-ghost\")\n\t\t\t.addClass(typeof o.ghost === \"string\" ? o.ghost : \"\");\n\n\t\tthat.ghost.appendTo(that.helper);\n\n\t},\n\n\tresize: function(){\n\t\tvar that = $(this).data(\"ui-resizable\");\n\t\tif (that.ghost) {\n\t\t\tthat.ghost.css({ position: \"relative\", height: that.size.height, width: that.size.width });\n\t\t}\n\t},\n\n\tstop: function() {\n\t\tvar that = $(this).data(\"ui-resizable\");\n\t\tif (that.ghost && that.helper) {\n\t\t\tthat.helper.get(0).removeChild(that.ghost.get(0));\n\t\t}\n\t}\n\n});\n\n$.ui.plugin.add(\"resizable\", \"grid\", {\n\n\tresize: function() {\n\t\tvar that = $(this).data(\"ui-resizable\"),\n\t\t\to = that.options,\n\t\t\tcs = that.size,\n\t\t\tos = that.originalSize,\n\t\t\top = that.originalPosition,\n\t\t\ta = that.axis,\n\t\t\tgrid = typeof o.grid === \"number\" ? [o.grid, o.grid] : o.grid,\n\t\t\tgridX = (grid[0]||1),\n\t\t\tgridY = (grid[1]||1),\n\t\t\tox = Math.round((cs.width - os.width) / gridX) * gridX,\n\t\t\toy = Math.round((cs.height - os.height) / gridY) * gridY,\n\t\t\tnewWidth = os.width + ox,\n\t\t\tnewHeight = os.height + oy,\n\t\t\tisMaxWidth = o.maxWidth && (o.maxWidth < newWidth),\n\t\t\tisMaxHeight = o.maxHeight && (o.maxHeight < newHeight),\n\t\t\tisMinWidth = o.minWidth && (o.minWidth > newWidth),\n\t\t\tisMinHeight = o.minHeight && (o.minHeight > newHeight);\n\n\t\to.grid = grid;\n\n\t\tif (isMinWidth) {\n\t\t\tnewWidth = newWidth + gridX;\n\t\t}\n\t\tif (isMinHeight) {\n\t\t\tnewHeight = newHeight + gridY;\n\t\t}\n\t\tif (isMaxWidth) {\n\t\t\tnewWidth = newWidth - gridX;\n\t\t}\n\t\tif (isMaxHeight) {\n\t\t\tnewHeight = newHeight - gridY;\n\t\t}\n\n\t\tif (/^(se|s|e)$/.test(a)) {\n\t\t\tthat.size.width = newWidth;\n\t\t\tthat.size.height = newHeight;\n\t\t} else if (/^(ne)$/.test(a)) {\n\t\t\tthat.size.width = newWidth;\n\t\t\tthat.size.height = newHeight;\n\t\t\tthat.position.top = op.top - oy;\n\t\t} else if (/^(sw)$/.test(a)) {\n\t\t\tthat.size.width = newWidth;\n\t\t\tthat.size.height = newHeight;\n\t\t\tthat.position.left = op.left - ox;\n\t\t} else {\n\t\t\tthat.size.width = newWidth;\n\t\t\tthat.size.height = newHeight;\n\t\t\tthat.position.top = op.top - oy;\n\t\t\tthat.position.left = op.left - ox;\n\t\t}\n\t}\n\n});\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.widget(\"ui.selectable\", $.ui.mouse, {\n\tversion: \"1.10.3\",\n\toptions: {\n\t\tappendTo: \"body\",\n\t\tautoRefresh: true,\n\t\tdistance: 0,\n\t\tfilter: \"*\",\n\t\ttolerance: \"touch\",\n\n\t\t// callbacks\n\t\tselected: null,\n\t\tselecting: null,\n\t\tstart: null,\n\t\tstop: null,\n\t\tunselected: null,\n\t\tunselecting: null\n\t},\n\t_create: function() {\n\t\tvar selectees,\n\t\t\tthat = this;\n\n\t\tthis.element.addClass(\"ui-selectable\");\n\n\t\tthis.dragged = false;\n\n\t\t// cache selectee children based on filter\n\t\tthis.refresh = function() {\n\t\t\tselectees = $(that.options.filter, that.element[0]);\n\t\t\tselectees.addClass(\"ui-selectee\");\n\t\t\tselectees.each(function() {\n\t\t\t\tvar $this = $(this),\n\t\t\t\t\tpos = $this.offset();\n\t\t\t\t$.data(this, \"selectable-item\", {\n\t\t\t\t\telement: this,\n\t\t\t\t\t$element: $this,\n\t\t\t\t\tleft: pos.left,\n\t\t\t\t\ttop: pos.top,\n\t\t\t\t\tright: pos.left + $this.outerWidth(),\n\t\t\t\t\tbottom: pos.top + $this.outerHeight(),\n\t\t\t\t\tstartselected: false,\n\t\t\t\t\tselected: $this.hasClass(\"ui-selected\"),\n\t\t\t\t\tselecting: $this.hasClass(\"ui-selecting\"),\n\t\t\t\t\tunselecting: $this.hasClass(\"ui-unselecting\")\n\t\t\t\t});\n\t\t\t});\n\t\t};\n\t\tthis.refresh();\n\n\t\tthis.selectees = selectees.addClass(\"ui-selectee\");\n\n\t\tthis._mouseInit();\n\n\t\tthis.helper = $(\"<div class='ui-selectable-helper'></div>\");\n\t},\n\n\t_destroy: function() {\n\t\tthis.selectees\n\t\t\t.removeClass(\"ui-selectee\")\n\t\t\t.removeData(\"selectable-item\");\n\t\tthis.element\n\t\t\t.removeClass(\"ui-selectable ui-selectable-disabled\");\n\t\tthis._mouseDestroy();\n\t},\n\n\t_mouseStart: function(event) {\n\t\tvar that = this,\n\t\t\toptions = this.options;\n\n\t\tthis.opos = [event.pageX, event.pageY];\n\n\t\tif (this.options.disabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.selectees = $(options.filter, this.element[0]);\n\n\t\tthis._trigger(\"start\", event);\n\n\t\t$(options.appendTo).append(this.helper);\n\t\t// position helper (lasso)\n\t\tthis.helper.css({\n\t\t\t\"left\": event.pageX,\n\t\t\t\"top\": event.pageY,\n\t\t\t\"width\": 0,\n\t\t\t\"height\": 0\n\t\t});\n\n\t\tif (options.autoRefresh) {\n\t\t\tthis.refresh();\n\t\t}\n\n\t\tthis.selectees.filter(\".ui-selected\").each(function() {\n\t\t\tvar selectee = $.data(this, \"selectable-item\");\n\t\t\tselectee.startselected = true;\n\t\t\tif (!event.metaKey && !event.ctrlKey) {\n\t\t\t\tselectee.$element.removeClass(\"ui-selected\");\n\t\t\t\tselectee.selected = false;\n\t\t\t\tselectee.$element.addClass(\"ui-unselecting\");\n\t\t\t\tselectee.unselecting = true;\n\t\t\t\t// selectable UNSELECTING callback\n\t\t\t\tthat._trigger(\"unselecting\", event, {\n\t\t\t\t\tunselecting: selectee.element\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t$(event.target).parents().addBack().each(function() {\n\t\t\tvar doSelect,\n\t\t\t\tselectee = $.data(this, \"selectable-item\");\n\t\t\tif (selectee) {\n\t\t\t\tdoSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass(\"ui-selected\");\n\t\t\t\tselectee.$element\n\t\t\t\t\t.removeClass(doSelect ? \"ui-unselecting\" : \"ui-selected\")\n\t\t\t\t\t.addClass(doSelect ? \"ui-selecting\" : \"ui-unselecting\");\n\t\t\t\tselectee.unselecting = !doSelect;\n\t\t\t\tselectee.selecting = doSelect;\n\t\t\t\tselectee.selected = doSelect;\n\t\t\t\t// selectable (UN)SELECTING callback\n\t\t\t\tif (doSelect) {\n\t\t\t\t\tthat._trigger(\"selecting\", event, {\n\t\t\t\t\t\tselecting: selectee.element\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tthat._trigger(\"unselecting\", event, {\n\t\t\t\t\t\tunselecting: selectee.element\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\n\t},\n\n\t_mouseDrag: function(event) {\n\n\t\tthis.dragged = true;\n\n\t\tif (this.options.disabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar tmp,\n\t\t\tthat = this,\n\t\t\toptions = this.options,\n\t\t\tx1 = this.opos[0],\n\t\t\ty1 = this.opos[1],\n\t\t\tx2 = event.pageX,\n\t\t\ty2 = event.pageY;\n\n\t\tif (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }\n\t\tif (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }\n\t\tthis.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});\n\n\t\tthis.selectees.each(function() {\n\t\t\tvar selectee = $.data(this, \"selectable-item\"),\n\t\t\t\thit = false;\n\n\t\t\t//prevent helper from being selected if appendTo: selectable\n\t\t\tif (!selectee || selectee.element === that.element[0]) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (options.tolerance === \"touch\") {\n\t\t\t\thit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );\n\t\t\t} else if (options.tolerance === \"fit\") {\n\t\t\t\thit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);\n\t\t\t}\n\n\t\t\tif (hit) {\n\t\t\t\t// SELECT\n\t\t\t\tif (selectee.selected) {\n\t\t\t\t\tselectee.$element.removeClass(\"ui-selected\");\n\t\t\t\t\tselectee.selected = false;\n\t\t\t\t}\n\t\t\t\tif (selectee.unselecting) {\n\t\t\t\t\tselectee.$element.removeClass(\"ui-unselecting\");\n\t\t\t\t\tselectee.unselecting = false;\n\t\t\t\t}\n\t\t\t\tif (!selectee.selecting) {\n\t\t\t\t\tselectee.$element.addClass(\"ui-selecting\");\n\t\t\t\t\tselectee.selecting = true;\n\t\t\t\t\t// selectable SELECTING callback\n\t\t\t\t\tthat._trigger(\"selecting\", event, {\n\t\t\t\t\t\tselecting: selectee.element\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// UNSELECT\n\t\t\t\tif (selectee.selecting) {\n\t\t\t\t\tif ((event.metaKey || event.ctrlKey) && selectee.startselected) {\n\t\t\t\t\t\tselectee.$element.removeClass(\"ui-selecting\");\n\t\t\t\t\t\tselectee.selecting = false;\n\t\t\t\t\t\tselectee.$element.addClass(\"ui-selected\");\n\t\t\t\t\t\tselectee.selected = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tselectee.$element.removeClass(\"ui-selecting\");\n\t\t\t\t\t\tselectee.selecting = false;\n\t\t\t\t\t\tif (selectee.startselected) {\n\t\t\t\t\t\t\tselectee.$element.addClass(\"ui-unselecting\");\n\t\t\t\t\t\t\tselectee.unselecting = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// selectable UNSELECTING callback\n\t\t\t\t\t\tthat._trigger(\"unselecting\", event, {\n\t\t\t\t\t\t\tunselecting: selectee.element\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (selectee.selected) {\n\t\t\t\t\tif (!event.metaKey && !event.ctrlKey && !selectee.startselected) {\n\t\t\t\t\t\tselectee.$element.removeClass(\"ui-selected\");\n\t\t\t\t\t\tselectee.selected = false;\n\n\t\t\t\t\t\tselectee.$element.addClass(\"ui-unselecting\");\n\t\t\t\t\t\tselectee.unselecting = true;\n\t\t\t\t\t\t// selectable UNSELECTING callback\n\t\t\t\t\t\tthat._trigger(\"unselecting\", event, {\n\t\t\t\t\t\t\tunselecting: selectee.element\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn false;\n\t},\n\n\t_mouseStop: function(event) {\n\t\tvar that = this;\n\n\t\tthis.dragged = false;\n\n\t\t$(\".ui-unselecting\", this.element[0]).each(function() {\n\t\t\tvar selectee = $.data(this, \"selectable-item\");\n\t\t\tselectee.$element.removeClass(\"ui-unselecting\");\n\t\t\tselectee.unselecting = false;\n\t\t\tselectee.startselected = false;\n\t\t\tthat._trigger(\"unselected\", event, {\n\t\t\t\tunselected: selectee.element\n\t\t\t});\n\t\t});\n\t\t$(\".ui-selecting\", this.element[0]).each(function() {\n\t\t\tvar selectee = $.data(this, \"selectable-item\");\n\t\t\tselectee.$element.removeClass(\"ui-selecting\").addClass(\"ui-selected\");\n\t\t\tselectee.selecting = false;\n\t\t\tselectee.selected = true;\n\t\t\tselectee.startselected = true;\n\t\t\tthat._trigger(\"selected\", event, {\n\t\t\t\tselected: selectee.element\n\t\t\t});\n\t\t});\n\t\tthis._trigger(\"stop\", event);\n\n\t\tthis.helper.remove();\n\n\t\treturn false;\n\t}\n\n});\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n/*jshint loopfunc: true */\n\nfunction isOverAxis( x, reference, size ) {\n\treturn ( x > reference ) && ( x < ( reference + size ) );\n}\n\nfunction isFloating(item) {\n\treturn (/left|right/).test(item.css(\"float\")) || (/inline|table-cell/).test(item.css(\"display\"));\n}\n\n$.widget(\"ui.sortable\", $.ui.mouse, {\n\tversion: \"1.10.3\",\n\twidgetEventPrefix: \"sort\",\n\tready: false,\n\toptions: {\n\t\tappendTo: \"parent\",\n\t\taxis: false,\n\t\tconnectWith: false,\n\t\tcontainment: false,\n\t\tcursor: \"auto\",\n\t\tcursorAt: false,\n\t\tdropOnEmpty: true,\n\t\tforcePlaceholderSize: false,\n\t\tforceHelperSize: false,\n\t\tgrid: false,\n\t\thandle: false,\n\t\thelper: \"original\",\n\t\titems: \"> *\",\n\t\topacity: false,\n\t\tplaceholder: false,\n\t\trevert: false,\n\t\tscroll: true,\n\t\tscrollSensitivity: 20,\n\t\tscrollSpeed: 20,\n\t\tscope: \"default\",\n\t\ttolerance: \"intersect\",\n\t\tzIndex: 1000,\n\n\t\t// callbacks\n\t\tactivate: null,\n\t\tbeforeStop: null,\n\t\tchange: null,\n\t\tdeactivate: null,\n\t\tout: null,\n\t\tover: null,\n\t\treceive: null,\n\t\tremove: null,\n\t\tsort: null,\n\t\tstart: null,\n\t\tstop: null,\n\t\tupdate: null\n\t},\n\t_create: function() {\n\n\t\tvar o = this.options;\n\t\tthis.containerCache = {};\n\t\tthis.element.addClass(\"ui-sortable\");\n\n\t\t//Get the items\n\t\tthis.refresh();\n\n\t\t//Let's determine if the items are being displayed horizontally\n\t\tthis.floating = this.items.length ? o.axis === \"x\" || isFloating(this.items[0].item) : false;\n\n\t\t//Let's determine the parent's offset\n\t\tthis.offset = this.element.offset();\n\n\t\t//Initialize mouse events for interaction\n\t\tthis._mouseInit();\n\n\t\t//We're ready to go\n\t\tthis.ready = true;\n\n\t},\n\n\t_destroy: function() {\n\t\tthis.element\n\t\t\t.removeClass(\"ui-sortable ui-sortable-disabled\");\n\t\tthis._mouseDestroy();\n\n\t\tfor ( var i = this.items.length - 1; i >= 0; i-- ) {\n\t\t\tthis.items[i].item.removeData(this.widgetName + \"-item\");\n\t\t}\n\n\t\treturn this;\n\t},\n\n\t_setOption: function(key, value){\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.options[ key ] = value;\n\n\t\t\tthis.widget().toggleClass( \"ui-sortable-disabled\", !!value );\n\t\t} else {\n\t\t\t// Don't call widget base _setOption for disable as it adds ui-state-disabled class\n\t\t\t$.Widget.prototype._setOption.apply(this, arguments);\n\t\t}\n\t},\n\n\t_mouseCapture: function(event, overrideHandle) {\n\t\tvar currentItem = null,\n\t\t\tvalidHandle = false,\n\t\t\tthat = this;\n\n\t\tif (this.reverting) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(this.options.disabled || this.options.type === \"static\") {\n\t\t\treturn false;\n\t\t}\n\n\t\t//We have to refresh the items data once first\n\t\tthis._refreshItems(event);\n\n\t\t//Find out if the clicked node (or one of its parents) is a actual item in this.items\n\t\t$(event.target).parents().each(function() {\n\t\t\tif($.data(this, that.widgetName + \"-item\") === that) {\n\t\t\t\tcurrentItem = $(this);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t\tif($.data(event.target, that.widgetName + \"-item\") === that) {\n\t\t\tcurrentItem = $(event.target);\n\t\t}\n\n\t\tif(!currentItem) {\n\t\t\treturn false;\n\t\t}\n\t\tif(this.options.handle && !overrideHandle) {\n\t\t\t$(this.options.handle, currentItem).find(\"*\").addBack().each(function() {\n\t\t\t\tif(this === event.target) {\n\t\t\t\t\tvalidHandle = true;\n\t\t\t\t}\n\t\t\t});\n\t\t\tif(!validHandle) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tthis.currentItem = currentItem;\n\t\tthis._removeCurrentsFromItems();\n\t\treturn true;\n\n\t},\n\n\t_mouseStart: function(event, overrideHandle, noActivation) {\n\n\t\tvar i, body,\n\t\t\to = this.options;\n\n\t\tthis.currentContainer = this;\n\n\t\t//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture\n\t\tthis.refreshPositions();\n\n\t\t//Create and append the visible helper\n\t\tthis.helper = this._createHelper(event);\n\n\t\t//Cache the helper size\n\t\tthis._cacheHelperProportions();\n\n\t\t/*\n\t\t * - Position generation -\n\t\t * This block generates everything position related - it's the core of draggables.\n\t\t */\n\n\t\t//Cache the margins of the original element\n\t\tthis._cacheMargins();\n\n\t\t//Get the next scrolling parent\n\t\tthis.scrollParent = this.helper.scrollParent();\n\n\t\t//The element's absolute position on the page minus margins\n\t\tthis.offset = this.currentItem.offset();\n\t\tthis.offset = {\n\t\t\ttop: this.offset.top - this.margins.top,\n\t\t\tleft: this.offset.left - this.margins.left\n\t\t};\n\n\t\t$.extend(this.offset, {\n\t\t\tclick: { //Where the click happened, relative to the element\n\t\t\t\tleft: event.pageX - this.offset.left,\n\t\t\t\ttop: event.pageY - this.offset.top\n\t\t\t},\n\t\t\tparent: this._getParentOffset(),\n\t\t\trelative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper\n\t\t});\n\n\t\t// Only after we got the offset, we can change the helper's position to absolute\n\t\t// TODO: Still need to figure out a way to make relative sorting possible\n\t\tthis.helper.css(\"position\", \"absolute\");\n\t\tthis.cssPosition = this.helper.css(\"position\");\n\n\t\t//Generate the original position\n\t\tthis.originalPosition = this._generatePosition(event);\n\t\tthis.originalPageX = event.pageX;\n\t\tthis.originalPageY = event.pageY;\n\n\t\t//Adjust the mouse offset relative to the helper if \"cursorAt\" is supplied\n\t\t(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));\n\n\t\t//Cache the former DOM position\n\t\tthis.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };\n\n\t\t//If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way\n\t\tif(this.helper[0] !== this.currentItem[0]) {\n\t\t\tthis.currentItem.hide();\n\t\t}\n\n\t\t//Create the placeholder\n\t\tthis._createPlaceholder();\n\n\t\t//Set a containment if given in the options\n\t\tif(o.containment) {\n\t\t\tthis._setContainment();\n\t\t}\n\n\t\tif( o.cursor && o.cursor !== \"auto\" ) { // cursor option\n\t\t\tbody = this.document.find( \"body\" );\n\n\t\t\t// support: IE\n\t\t\tthis.storedCursor = body.css( \"cursor\" );\n\t\t\tbody.css( \"cursor\", o.cursor );\n\n\t\t\tthis.storedStylesheet = $( \"<style>*{ cursor: \"+o.cursor+\" !important; }</style>\" ).appendTo( body );\n\t\t}\n\n\t\tif(o.opacity) { // opacity option\n\t\t\tif (this.helper.css(\"opacity\")) {\n\t\t\t\tthis._storedOpacity = this.helper.css(\"opacity\");\n\t\t\t}\n\t\t\tthis.helper.css(\"opacity\", o.opacity);\n\t\t}\n\n\t\tif(o.zIndex) { // zIndex option\n\t\t\tif (this.helper.css(\"zIndex\")) {\n\t\t\t\tthis._storedZIndex = this.helper.css(\"zIndex\");\n\t\t\t}\n\t\t\tthis.helper.css(\"zIndex\", o.zIndex);\n\t\t}\n\n\t\t//Prepare scrolling\n\t\tif(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== \"HTML\") {\n\t\t\tthis.overflowOffset = this.scrollParent.offset();\n\t\t}\n\n\t\t//Call callbacks\n\t\tthis._trigger(\"start\", event, this._uiHash());\n\n\t\t//Recache the helper size\n\t\tif(!this._preserveHelperProportions) {\n\t\t\tthis._cacheHelperProportions();\n\t\t}\n\n\n\t\t//Post \"activate\" events to possible containers\n\t\tif( !noActivation ) {\n\t\t\tfor ( i = this.containers.length - 1; i >= 0; i-- ) {\n\t\t\t\tthis.containers[ i ]._trigger( \"activate\", event, this._uiHash( this ) );\n\t\t\t}\n\t\t}\n\n\t\t//Prepare possible droppables\n\t\tif($.ui.ddmanager) {\n\t\t\t$.ui.ddmanager.current = this;\n\t\t}\n\n\t\tif ($.ui.ddmanager && !o.dropBehaviour) {\n\t\t\t$.ui.ddmanager.prepareOffsets(this, event);\n\t\t}\n\n\t\tthis.dragging = true;\n\n\t\tthis.helper.addClass(\"ui-sortable-helper\");\n\t\tthis._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position\n\t\treturn true;\n\n\t},\n\n\t_mouseDrag: function(event) {\n\t\tvar i, item, itemElement, intersection,\n\t\t\to = this.options,\n\t\t\tscrolled = false;\n\n\t\t//Compute the helpers position\n\t\tthis.position = this._generatePosition(event);\n\t\tthis.positionAbs = this._convertPositionTo(\"absolute\");\n\n\t\tif (!this.lastPositionAbs) {\n\t\t\tthis.lastPositionAbs = this.positionAbs;\n\t\t}\n\n\t\t//Do scrolling\n\t\tif(this.options.scroll) {\n\t\t\tif(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== \"HTML\") {\n\n\t\t\t\tif((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {\n\t\t\t\t\tthis.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;\n\t\t\t\t} else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {\n\t\t\t\t\tthis.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;\n\t\t\t\t}\n\n\t\t\t\tif((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {\n\t\t\t\t\tthis.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;\n\t\t\t\t} else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {\n\t\t\t\t\tthis.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tif(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);\n\t\t\t\t} else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);\n\t\t\t\t}\n\n\t\t\t\tif(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);\n\t\t\t\t} else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {\n\t\t\t\t$.ui.ddmanager.prepareOffsets(this, event);\n\t\t\t}\n\t\t}\n\n\t\t//Regenerate the absolute position used for position checks\n\t\tthis.positionAbs = this._convertPositionTo(\"absolute\");\n\n\t\t//Set the helper position\n\t\tif(!this.options.axis || this.options.axis !== \"y\") {\n\t\t\tthis.helper[0].style.left = this.position.left+\"px\";\n\t\t}\n\t\tif(!this.options.axis || this.options.axis !== \"x\") {\n\t\t\tthis.helper[0].style.top = this.position.top+\"px\";\n\t\t}\n\n\t\t//Rearrange\n\t\tfor (i = this.items.length - 1; i >= 0; i--) {\n\n\t\t\t//Cache variables and intersection, continue if no intersection\n\t\t\titem = this.items[i];\n\t\t\titemElement = item.item[0];\n\t\t\tintersection = this._intersectsWithPointer(item);\n\t\t\tif (!intersection) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Only put the placeholder inside the current Container, skip all\n\t\t\t// items form other containers. This works because when moving\n\t\t\t// an item from one container to another the\n\t\t\t// currentContainer is switched before the placeholder is moved.\n\t\t\t//\n\t\t\t// Without this moving items in \"sub-sortables\" can cause the placeholder to jitter\n\t\t\t// beetween the outer and inner container.\n\t\t\tif (item.instance !== this.currentContainer) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// cannot intersect with itself\n\t\t\t// no useless actions that have been done before\n\t\t\t// no action if the item moved is the parent of the item checked\n\t\t\tif (itemElement !== this.currentItem[0] &&\n\t\t\t\tthis.placeholder[intersection === 1 ? \"next\" : \"prev\"]()[0] !== itemElement &&\n\t\t\t\t!$.contains(this.placeholder[0], itemElement) &&\n\t\t\t\t(this.options.type === \"semi-dynamic\" ? !$.contains(this.element[0], itemElement) : true)\n\t\t\t) {\n\n\t\t\t\tthis.direction = intersection === 1 ? \"down\" : \"up\";\n\n\t\t\t\tif (this.options.tolerance === \"pointer\" || this._intersectsWithSides(item)) {\n\t\t\t\t\tthis._rearrange(event, item);\n\t\t\t\t} else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tthis._trigger(\"change\", event, this._uiHash());\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t//Post events to containers\n\t\tthis._contactContainers(event);\n\n\t\t//Interconnect with droppables\n\t\tif($.ui.ddmanager) {\n\t\t\t$.ui.ddmanager.drag(this, event);\n\t\t}\n\n\t\t//Call callbacks\n\t\tthis._trigger(\"sort\", event, this._uiHash());\n\n\t\tthis.lastPositionAbs = this.positionAbs;\n\t\treturn false;\n\n\t},\n\n\t_mouseStop: function(event, noPropagation) {\n\n\t\tif(!event) {\n\t\t\treturn;\n\t\t}\n\n\t\t//If we are using droppables, inform the manager about the drop\n\t\tif ($.ui.ddmanager && !this.options.dropBehaviour) {\n\t\t\t$.ui.ddmanager.drop(this, event);\n\t\t}\n\n\t\tif(this.options.revert) {\n\t\t\tvar that = this,\n\t\t\t\tcur = this.placeholder.offset(),\n\t\t\t\taxis = this.options.axis,\n\t\t\t\tanimation = {};\n\n\t\t\tif ( !axis || axis === \"x\" ) {\n\t\t\t\tanimation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);\n\t\t\t}\n\t\t\tif ( !axis || axis === \"y\" ) {\n\t\t\t\tanimation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);\n\t\t\t}\n\t\t\tthis.reverting = true;\n\t\t\t$(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {\n\t\t\t\tthat._clear(event);\n\t\t\t});\n\t\t} else {\n\t\t\tthis._clear(event, noPropagation);\n\t\t}\n\n\t\treturn false;\n\n\t},\n\n\tcancel: function() {\n\n\t\tif(this.dragging) {\n\n\t\t\tthis._mouseUp({ target: null });\n\n\t\t\tif(this.options.helper === \"original\") {\n\t\t\t\tthis.currentItem.css(this._storedCSS).removeClass(\"ui-sortable-helper\");\n\t\t\t} else {\n\t\t\t\tthis.currentItem.show();\n\t\t\t}\n\n\t\t\t//Post deactivating events to containers\n\t\t\tfor (var i = this.containers.length - 1; i >= 0; i--){\n\t\t\t\tthis.containers[i]._trigger(\"deactivate\", null, this._uiHash(this));\n\t\t\t\tif(this.containers[i].containerCache.over) {\n\t\t\t\t\tthis.containers[i]._trigger(\"out\", null, this._uiHash(this));\n\t\t\t\t\tthis.containers[i].containerCache.over = 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\tif (this.placeholder) {\n\t\t\t//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!\n\t\t\tif(this.placeholder[0].parentNode) {\n\t\t\t\tthis.placeholder[0].parentNode.removeChild(this.placeholder[0]);\n\t\t\t}\n\t\t\tif(this.options.helper !== \"original\" && this.helper && this.helper[0].parentNode) {\n\t\t\t\tthis.helper.remove();\n\t\t\t}\n\n\t\t\t$.extend(this, {\n\t\t\t\thelper: null,\n\t\t\t\tdragging: false,\n\t\t\t\treverting: false,\n\t\t\t\t_noFinalSort: null\n\t\t\t});\n\n\t\t\tif(this.domPosition.prev) {\n\t\t\t\t$(this.domPosition.prev).after(this.currentItem);\n\t\t\t} else {\n\t\t\t\t$(this.domPosition.parent).prepend(this.currentItem);\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\n\t},\n\n\tserialize: function(o) {\n\n\t\tvar items = this._getItemsAsjQuery(o && o.connected),\n\t\t\tstr = [];\n\t\to = o || {};\n\n\t\t$(items).each(function() {\n\t\t\tvar res = ($(o.item || this).attr(o.attribute || \"id\") || \"\").match(o.expression || (/(.+)[\\-=_](.+)/));\n\t\t\tif (res) {\n\t\t\t\tstr.push((o.key || res[1]+\"[]\")+\"=\"+(o.key && o.expression ? res[1] : res[2]));\n\t\t\t}\n\t\t});\n\n\t\tif(!str.length && o.key) {\n\t\t\tstr.push(o.key + \"=\");\n\t\t}\n\n\t\treturn str.join(\"&\");\n\n\t},\n\n\ttoArray: function(o) {\n\n\t\tvar items = this._getItemsAsjQuery(o && o.connected),\n\t\t\tret = [];\n\n\t\to = o || {};\n\n\t\titems.each(function() { ret.push($(o.item || this).attr(o.attribute || \"id\") || \"\"); });\n\t\treturn ret;\n\n\t},\n\n\t/* Be careful with the following core functions */\n\t_intersectsWith: function(item) {\n\n\t\tvar x1 = this.positionAbs.left,\n\t\t\tx2 = x1 + this.helperProportions.width,\n\t\t\ty1 = this.positionAbs.top,\n\t\t\ty2 = y1 + this.helperProportions.height,\n\t\t\tl = item.left,\n\t\t\tr = l + item.width,\n\t\t\tt = item.top,\n\t\t\tb = t + item.height,\n\t\t\tdyClick = this.offset.click.top,\n\t\t\tdxClick = this.offset.click.left,\n\t\t\tisOverElementHeight = ( this.options.axis === \"x\" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),\n\t\t\tisOverElementWidth = ( this.options.axis === \"y\" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),\n\t\t\tisOverElement = isOverElementHeight && isOverElementWidth;\n\n\t\tif ( this.options.tolerance === \"pointer\" ||\n\t\t\tthis.options.forcePointerForContainers ||\n\t\t\t(this.options.tolerance !== \"pointer\" && this.helperProportions[this.floating ? \"width\" : \"height\"] > item[this.floating ? \"width\" : \"height\"])\n\t\t) {\n\t\t\treturn isOverElement;\n\t\t} else {\n\n\t\t\treturn (l < x1 + (this.helperProportions.width / 2) && // Right Half\n\t\t\t\tx2 - (this.helperProportions.width / 2) < r && // Left Half\n\t\t\t\tt < y1 + (this.helperProportions.height / 2) && // Bottom Half\n\t\t\t\ty2 - (this.helperProportions.height / 2) < b ); // Top Half\n\n\t\t}\n\t},\n\n\t_intersectsWithPointer: function(item) {\n\n\t\tvar isOverElementHeight = (this.options.axis === \"x\") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),\n\t\t\tisOverElementWidth = (this.options.axis === \"y\") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),\n\t\t\tisOverElement = isOverElementHeight && isOverElementWidth,\n\t\t\tverticalDirection = this._getDragVerticalDirection(),\n\t\t\thorizontalDirection = this._getDragHorizontalDirection();\n\n\t\tif (!isOverElement) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn this.floating ?\n\t\t\t( ((horizontalDirection && horizontalDirection === \"right\") || verticalDirection === \"down\") ? 2 : 1 )\n\t\t\t: ( verticalDirection && (verticalDirection === \"down\" ? 2 : 1) );\n\n\t},\n\n\t_intersectsWithSides: function(item) {\n\n\t\tvar isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),\n\t\t\tisOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),\n\t\t\tverticalDirection = this._getDragVerticalDirection(),\n\t\t\thorizontalDirection = this._getDragHorizontalDirection();\n\n\t\tif (this.floating && horizontalDirection) {\n\t\t\treturn ((horizontalDirection === \"right\" && isOverRightHalf) || (horizontalDirection === \"left\" && !isOverRightHalf));\n\t\t} else {\n\t\t\treturn verticalDirection && ((verticalDirection === \"down\" && isOverBottomHalf) || (verticalDirection === \"up\" && !isOverBottomHalf));\n\t\t}\n\n\t},\n\n\t_getDragVerticalDirection: function() {\n\t\tvar delta = this.positionAbs.top - this.lastPositionAbs.top;\n\t\treturn delta !== 0 && (delta > 0 ? \"down\" : \"up\");\n\t},\n\n\t_getDragHorizontalDirection: function() {\n\t\tvar delta = this.positionAbs.left - this.lastPositionAbs.left;\n\t\treturn delta !== 0 && (delta > 0 ? \"right\" : \"left\");\n\t},\n\n\trefresh: function(event) {\n\t\tthis._refreshItems(event);\n\t\tthis.refreshPositions();\n\t\treturn this;\n\t},\n\n\t_connectWith: function() {\n\t\tvar options = this.options;\n\t\treturn options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;\n\t},\n\n\t_getItemsAsjQuery: function(connected) {\n\n\t\tvar i, j, cur, inst,\n\t\t\titems = [],\n\t\t\tqueries = [],\n\t\t\tconnectWith = this._connectWith();\n\n\t\tif(connectWith && connected) {\n\t\t\tfor (i = connectWith.length - 1; i >= 0; i--){\n\t\t\t\tcur = $(connectWith[i]);\n\t\t\t\tfor ( j = cur.length - 1; j >= 0; j--){\n\t\t\t\t\tinst = $.data(cur[j], this.widgetFullName);\n\t\t\t\t\tif(inst && inst !== this && !inst.options.disabled) {\n\t\t\t\t\t\tqueries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(\".ui-sortable-helper\").not(\".ui-sortable-placeholder\"), inst]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tqueries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(\".ui-sortable-helper\").not(\".ui-sortable-placeholder\"), this]);\n\n\t\tfor (i = queries.length - 1; i >= 0; i--){\n\t\t\tqueries[i][0].each(function() {\n\t\t\t\titems.push(this);\n\t\t\t});\n\t\t}\n\n\t\treturn $(items);\n\n\t},\n\n\t_removeCurrentsFromItems: function() {\n\n\t\tvar list = this.currentItem.find(\":data(\" + this.widgetName + \"-item)\");\n\n\t\tthis.items = $.grep(this.items, function (item) {\n\t\t\tfor (var j=0; j < list.length; j++) {\n\t\t\t\tif(list[j] === item.item[0]) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t});\n\n\t},\n\n\t_refreshItems: function(event) {\n\n\t\tthis.items = [];\n\t\tthis.containers = [this];\n\n\t\tvar i, j, cur, inst, targetData, _queries, item, queriesLength,\n\t\t\titems = this.items,\n\t\t\tqueries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],\n\t\t\tconnectWith = this._connectWith();\n\n\t\tif(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down\n\t\t\tfor (i = connectWith.length - 1; i >= 0; i--){\n\t\t\t\tcur = $(connectWith[i]);\n\t\t\t\tfor (j = cur.length - 1; j >= 0; j--){\n\t\t\t\t\tinst = $.data(cur[j], this.widgetFullName);\n\t\t\t\t\tif(inst && inst !== this && !inst.options.disabled) {\n\t\t\t\t\t\tqueries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);\n\t\t\t\t\t\tthis.containers.push(inst);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (i = queries.length - 1; i >= 0; i--) {\n\t\t\ttargetData = queries[i][1];\n\t\t\t_queries = queries[i][0];\n\n\t\t\tfor (j=0, queriesLength = _queries.length; j < queriesLength; j++) {\n\t\t\t\titem = $(_queries[j]);\n\n\t\t\t\titem.data(this.widgetName + \"-item\", targetData); // Data for target checking (mouse manager)\n\n\t\t\t\titems.push({\n\t\t\t\t\titem: item,\n\t\t\t\t\tinstance: targetData,\n\t\t\t\t\twidth: 0, height: 0,\n\t\t\t\t\tleft: 0, top: 0\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t},\n\n\trefreshPositions: function(fast) {\n\n\t\t//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change\n\t\tif(this.offsetParent && this.helper) {\n\t\t\tthis.offset.parent = this._getParentOffset();\n\t\t}\n\n\t\tvar i, item, t, p;\n\n\t\tfor (i = this.items.length - 1; i >= 0; i--){\n\t\t\titem = this.items[i];\n\n\t\t\t//We ignore calculating positions of all connected containers when we're not over them\n\t\t\tif(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tt = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;\n\n\t\t\tif (!fast) {\n\t\t\t\titem.width = t.outerWidth();\n\t\t\t\titem.height = t.outerHeight();\n\t\t\t}\n\n\t\t\tp = t.offset();\n\t\t\titem.left = p.left;\n\t\t\titem.top = p.top;\n\t\t}\n\n\t\tif(this.options.custom && this.options.custom.refreshContainers) {\n\t\t\tthis.options.custom.refreshContainers.call(this);\n\t\t} else {\n\t\t\tfor (i = this.containers.length - 1; i >= 0; i--){\n\t\t\t\tp = this.containers[i].element.offset();\n\t\t\t\tthis.containers[i].containerCache.left = p.left;\n\t\t\t\tthis.containers[i].containerCache.top = p.top;\n\t\t\t\tthis.containers[i].containerCache.width\t= this.containers[i].element.outerWidth();\n\t\t\t\tthis.containers[i].containerCache.height = this.containers[i].element.outerHeight();\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\t_createPlaceholder: function(that) {\n\t\tthat = that || this;\n\t\tvar className,\n\t\t\to = that.options;\n\n\t\tif(!o.placeholder || o.placeholder.constructor === String) {\n\t\t\tclassName = o.placeholder;\n\t\t\to.placeholder = {\n\t\t\t\telement: function() {\n\n\t\t\t\t\tvar nodeName = that.currentItem[0].nodeName.toLowerCase(),\n\t\t\t\t\t\telement = $( \"<\" + nodeName + \">\", that.document[0] )\n\t\t\t\t\t\t\t.addClass(className || that.currentItem[0].className+\" ui-sortable-placeholder\")\n\t\t\t\t\t\t\t.removeClass(\"ui-sortable-helper\");\n\n\t\t\t\t\tif ( nodeName === \"tr\" ) {\n\t\t\t\t\t\tthat.currentItem.children().each(function() {\n\t\t\t\t\t\t\t$( \"<td>&#160;</td>\", that.document[0] )\n\t\t\t\t\t\t\t\t.attr( \"colspan\", $( this ).attr( \"colspan\" ) || 1 )\n\t\t\t\t\t\t\t\t.appendTo( element );\n\t\t\t\t\t\t});\n\t\t\t\t\t} else if ( nodeName === \"img\" ) {\n\t\t\t\t\t\telement.attr( \"src\", that.currentItem.attr( \"src\" ) );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !className ) {\n\t\t\t\t\t\telement.css( \"visibility\", \"hidden\" );\n\t\t\t\t\t}\n\n\t\t\t\t\treturn element;\n\t\t\t\t},\n\t\t\t\tupdate: function(container, p) {\n\n\t\t\t\t\t// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that\n\t\t\t\t\t// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified\n\t\t\t\t\tif(className && !o.forcePlaceholderSize) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t//If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item\n\t\t\t\t\tif(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css(\"paddingTop\")||0, 10) - parseInt(that.currentItem.css(\"paddingBottom\")||0, 10)); }\n\t\t\t\t\tif(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css(\"paddingLeft\")||0, 10) - parseInt(that.currentItem.css(\"paddingRight\")||0, 10)); }\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\t//Create the placeholder\n\t\tthat.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));\n\n\t\t//Append it after the actual current item\n\t\tthat.currentItem.after(that.placeholder);\n\n\t\t//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)\n\t\to.placeholder.update(that, that.placeholder);\n\n\t},\n\n\t_contactContainers: function(event) {\n\t\tvar i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating,\n\t\t\tinnermostContainer = null,\n\t\t\tinnermostIndex = null;\n\n\t\t// get innermost container that intersects with item\n\t\tfor (i = this.containers.length - 1; i >= 0; i--) {\n\n\t\t\t// never consider a container that's located within the item itself\n\t\t\tif($.contains(this.currentItem[0], this.containers[i].element[0])) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif(this._intersectsWith(this.containers[i].containerCache)) {\n\n\t\t\t\t// if we've already found a container and it's more \"inner\" than this, then continue\n\t\t\t\tif(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tinnermostContainer = this.containers[i];\n\t\t\t\tinnermostIndex = i;\n\n\t\t\t} else {\n\t\t\t\t// container doesn't intersect. trigger \"out\" event if necessary\n\t\t\t\tif(this.containers[i].containerCache.over) {\n\t\t\t\t\tthis.containers[i]._trigger(\"out\", event, this._uiHash(this));\n\t\t\t\t\tthis.containers[i].containerCache.over = 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\t// if no intersecting containers found, return\n\t\tif(!innermostContainer) {\n\t\t\treturn;\n\t\t}\n\n\t\t// move the item into the container if it's not there already\n\t\tif(this.containers.length === 1) {\n\t\t\tif (!this.containers[innermostIndex].containerCache.over) {\n\t\t\t\tthis.containers[innermostIndex]._trigger(\"over\", event, this._uiHash(this));\n\t\t\t\tthis.containers[innermostIndex].containerCache.over = 1;\n\t\t\t}\n\t\t} else {\n\n\t\t\t//When entering a new container, we will find the item with the least distance and append our item near it\n\t\t\tdist = 10000;\n\t\t\titemWithLeastDistance = null;\n\t\t\tfloating = innermostContainer.floating || isFloating(this.currentItem);\n\t\t\tposProperty = floating ? \"left\" : \"top\";\n\t\t\tsizeProperty = floating ? \"width\" : \"height\";\n\t\t\tbase = this.positionAbs[posProperty] + this.offset.click[posProperty];\n\t\t\tfor (j = this.items.length - 1; j >= 0; j--) {\n\t\t\t\tif(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif(this.items[j].item[0] === this.currentItem[0]) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tcur = this.items[j].item.offset()[posProperty];\n\t\t\t\tnearBottom = false;\n\t\t\t\tif(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){\n\t\t\t\t\tnearBottom = true;\n\t\t\t\t\tcur += this.items[j][sizeProperty];\n\t\t\t\t}\n\n\t\t\t\tif(Math.abs(cur - base) < dist) {\n\t\t\t\t\tdist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];\n\t\t\t\t\tthis.direction = nearBottom ? \"up\": \"down\";\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t//Check if dropOnEmpty is enabled\n\t\t\tif(!itemWithLeastDistance && !this.options.dropOnEmpty) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif(this.currentContainer === this.containers[innermostIndex]) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\titemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);\n\t\t\tthis._trigger(\"change\", event, this._uiHash());\n\t\t\tthis.containers[innermostIndex]._trigger(\"change\", event, this._uiHash(this));\n\t\t\tthis.currentContainer = this.containers[innermostIndex];\n\n\t\t\t//Update the placeholder\n\t\t\tthis.options.placeholder.update(this.currentContainer, this.placeholder);\n\n\t\t\tthis.containers[innermostIndex]._trigger(\"over\", event, this._uiHash(this));\n\t\t\tthis.containers[innermostIndex].containerCache.over = 1;\n\t\t}\n\n\n\t},\n\n\t_createHelper: function(event) {\n\n\t\tvar o = this.options,\n\t\t\thelper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === \"clone\" ? this.currentItem.clone() : this.currentItem);\n\n\t\t//Add the helper to the DOM if that didn't happen already\n\t\tif(!helper.parents(\"body\").length) {\n\t\t\t$(o.appendTo !== \"parent\" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);\n\t\t}\n\n\t\tif(helper[0] === this.currentItem[0]) {\n\t\t\tthis._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css(\"position\"), top: this.currentItem.css(\"top\"), left: this.currentItem.css(\"left\") };\n\t\t}\n\n\t\tif(!helper[0].style.width || o.forceHelperSize) {\n\t\t\thelper.width(this.currentItem.width());\n\t\t}\n\t\tif(!helper[0].style.height || o.forceHelperSize) {\n\t\t\thelper.height(this.currentItem.height());\n\t\t}\n\n\t\treturn helper;\n\n\t},\n\n\t_adjustOffsetFromHelper: function(obj) {\n\t\tif (typeof obj === \"string\") {\n\t\t\tobj = obj.split(\" \");\n\t\t}\n\t\tif ($.isArray(obj)) {\n\t\t\tobj = {left: +obj[0], top: +obj[1] || 0};\n\t\t}\n\t\tif (\"left\" in obj) {\n\t\t\tthis.offset.click.left = obj.left + this.margins.left;\n\t\t}\n\t\tif (\"right\" in obj) {\n\t\t\tthis.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;\n\t\t}\n\t\tif (\"top\" in obj) {\n\t\t\tthis.offset.click.top = obj.top + this.margins.top;\n\t\t}\n\t\tif (\"bottom\" in obj) {\n\t\t\tthis.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;\n\t\t}\n\t},\n\n\t_getParentOffset: function() {\n\n\n\t\t//Get the offsetParent and cache its position\n\t\tthis.offsetParent = this.helper.offsetParent();\n\t\tvar po = this.offsetParent.offset();\n\n\t\t// This is a special case where we need to modify a offset calculated on start, since the following happened:\n\t\t// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent\n\t\t// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that\n\t\t//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag\n\t\tif(this.cssPosition === \"absolute\" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {\n\t\t\tpo.left += this.scrollParent.scrollLeft();\n\t\t\tpo.top += this.scrollParent.scrollTop();\n\t\t}\n\n\t\t// This needs to be actually done for all browsers, since pageX/pageY includes this information\n\t\t// with an ugly IE fix\n\t\tif( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === \"html\" && $.ui.ie)) {\n\t\t\tpo = { top: 0, left: 0 };\n\t\t}\n\n\t\treturn {\n\t\t\ttop: po.top + (parseInt(this.offsetParent.css(\"borderTopWidth\"),10) || 0),\n\t\t\tleft: po.left + (parseInt(this.offsetParent.css(\"borderLeftWidth\"),10) || 0)\n\t\t};\n\n\t},\n\n\t_getRelativeOffset: function() {\n\n\t\tif(this.cssPosition === \"relative\") {\n\t\t\tvar p = this.currentItem.position();\n\t\t\treturn {\n\t\t\t\ttop: p.top - (parseInt(this.helper.css(\"top\"),10) || 0) + this.scrollParent.scrollTop(),\n\t\t\t\tleft: p.left - (parseInt(this.helper.css(\"left\"),10) || 0) + this.scrollParent.scrollLeft()\n\t\t\t};\n\t\t} else {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t},\n\n\t_cacheMargins: function() {\n\t\tthis.margins = {\n\t\t\tleft: (parseInt(this.currentItem.css(\"marginLeft\"),10) || 0),\n\t\t\ttop: (parseInt(this.currentItem.css(\"marginTop\"),10) || 0)\n\t\t};\n\t},\n\n\t_cacheHelperProportions: function() {\n\t\tthis.helperProportions = {\n\t\t\twidth: this.helper.outerWidth(),\n\t\t\theight: this.helper.outerHeight()\n\t\t};\n\t},\n\n\t_setContainment: function() {\n\n\t\tvar ce, co, over,\n\t\t\to = this.options;\n\t\tif(o.containment === \"parent\") {\n\t\t\to.containment = this.helper[0].parentNode;\n\t\t}\n\t\tif(o.containment === \"document\" || o.containment === \"window\") {\n\t\t\tthis.containment = [\n\t\t\t\t0 - this.offset.relative.left - this.offset.parent.left,\n\t\t\t\t0 - this.offset.relative.top - this.offset.parent.top,\n\t\t\t\t$(o.containment === \"document\" ? document : window).width() - this.helperProportions.width - this.margins.left,\n\t\t\t\t($(o.containment === \"document\" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top\n\t\t\t];\n\t\t}\n\n\t\tif(!(/^(document|window|parent)$/).test(o.containment)) {\n\t\t\tce = $(o.containment)[0];\n\t\t\tco = $(o.containment).offset();\n\t\t\tover = ($(ce).css(\"overflow\") !== \"hidden\");\n\n\t\t\tthis.containment = [\n\t\t\t\tco.left + (parseInt($(ce).css(\"borderLeftWidth\"),10) || 0) + (parseInt($(ce).css(\"paddingLeft\"),10) || 0) - this.margins.left,\n\t\t\t\tco.top + (parseInt($(ce).css(\"borderTopWidth\"),10) || 0) + (parseInt($(ce).css(\"paddingTop\"),10) || 0) - this.margins.top,\n\t\t\t\tco.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css(\"borderLeftWidth\"),10) || 0) - (parseInt($(ce).css(\"paddingRight\"),10) || 0) - this.helperProportions.width - this.margins.left,\n\t\t\t\tco.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css(\"borderTopWidth\"),10) || 0) - (parseInt($(ce).css(\"paddingBottom\"),10) || 0) - this.helperProportions.height - this.margins.top\n\t\t\t];\n\t\t}\n\n\t},\n\n\t_convertPositionTo: function(d, pos) {\n\n\t\tif(!pos) {\n\t\t\tpos = this.position;\n\t\t}\n\t\tvar mod = d === \"absolute\" ? 1 : -1,\n\t\t\tscroll = this.cssPosition === \"absolute\" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,\n\t\t\tscrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);\n\n\t\treturn {\n\t\t\ttop: (\n\t\t\t\tpos.top\t+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.relative.top * mod +\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.top * mod -\t\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)\n\t\t\t),\n\t\t\tleft: (\n\t\t\t\tpos.left +\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.relative.left * mod +\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.left * mod\t-\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)\n\t\t\t)\n\t\t};\n\n\t},\n\n\t_generatePosition: function(event) {\n\n\t\tvar top, left,\n\t\t\to = this.options,\n\t\t\tpageX = event.pageX,\n\t\t\tpageY = event.pageY,\n\t\t\tscroll = this.cssPosition === \"absolute\" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);\n\n\t\t// This is another very weird special case that only happens for relative elements:\n\t\t// 1. If the css position is relative\n\t\t// 2. and the scroll parent is the document or similar to the offset parent\n\t\t// we have to refresh the relative offset during the scroll so there are no jumps\n\t\tif(this.cssPosition === \"relative\" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {\n\t\t\tthis.offset.relative = this._getRelativeOffset();\n\t\t}\n\n\t\t/*\n\t\t * - Position constraining -\n\t\t * Constrain the position to a mix of grid, containment.\n\t\t */\n\n\t\tif(this.originalPosition) { //If we are not dragging yet, we won't check for options\n\n\t\t\tif(this.containment) {\n\t\t\t\tif(event.pageX - this.offset.click.left < this.containment[0]) {\n\t\t\t\t\tpageX = this.containment[0] + this.offset.click.left;\n\t\t\t\t}\n\t\t\t\tif(event.pageY - this.offset.click.top < this.containment[1]) {\n\t\t\t\t\tpageY = this.containment[1] + this.offset.click.top;\n\t\t\t\t}\n\t\t\t\tif(event.pageX - this.offset.click.left > this.containment[2]) {\n\t\t\t\t\tpageX = this.containment[2] + this.offset.click.left;\n\t\t\t\t}\n\t\t\t\tif(event.pageY - this.offset.click.top > this.containment[3]) {\n\t\t\t\t\tpageY = this.containment[3] + this.offset.click.top;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(o.grid) {\n\t\t\t\ttop = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];\n\t\t\t\tpageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;\n\n\t\t\t\tleft = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];\n\t\t\t\tpageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\t\t\ttop: (\n\t\t\t\tpageY -\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.click.top -\t\t\t\t\t\t\t\t\t\t\t\t\t// Click offset (relative to the element)\n\t\t\t\tthis.offset.relative.top\t-\t\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.top +\t\t\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))\n\t\t\t),\n\t\t\tleft: (\n\t\t\t\tpageX -\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.click.left -\t\t\t\t\t\t\t\t\t\t\t\t// Click offset (relative to the element)\n\t\t\t\tthis.offset.relative.left\t-\t\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.left +\t\t\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))\n\t\t\t)\n\t\t};\n\n\t},\n\n\t_rearrange: function(event, i, a, hardRefresh) {\n\n\t\ta ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === \"down\" ? i.item[0] : i.item[0].nextSibling));\n\n\t\t//Various things done here to improve the performance:\n\t\t// 1. we create a setTimeout, that calls refreshPositions\n\t\t// 2. on the instance, we have a counter variable, that get's higher after every append\n\t\t// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same\n\t\t// 4. this lets only the last addition to the timeout stack through\n\t\tthis.counter = this.counter ? ++this.counter : 1;\n\t\tvar counter = this.counter;\n\n\t\tthis._delay(function() {\n\t\t\tif(counter === this.counter) {\n\t\t\t\tthis.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove\n\t\t\t}\n\t\t});\n\n\t},\n\n\t_clear: function(event, noPropagation) {\n\n\t\tthis.reverting = false;\n\t\t// We delay all events that have to be triggered to after the point where the placeholder has been removed and\n\t\t// everything else normalized again\n\t\tvar i,\n\t\t\tdelayedTriggers = [];\n\n\t\t// We first have to update the dom position of the actual currentItem\n\t\t// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)\n\t\tif(!this._noFinalSort && this.currentItem.parent().length) {\n\t\t\tthis.placeholder.before(this.currentItem);\n\t\t}\n\t\tthis._noFinalSort = null;\n\n\t\tif(this.helper[0] === this.currentItem[0]) {\n\t\t\tfor(i in this._storedCSS) {\n\t\t\t\tif(this._storedCSS[i] === \"auto\" || this._storedCSS[i] === \"static\") {\n\t\t\t\t\tthis._storedCSS[i] = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.currentItem.css(this._storedCSS).removeClass(\"ui-sortable-helper\");\n\t\t} else {\n\t\t\tthis.currentItem.show();\n\t\t}\n\n\t\tif(this.fromOutside && !noPropagation) {\n\t\t\tdelayedTriggers.push(function(event) { this._trigger(\"receive\", event, this._uiHash(this.fromOutside)); });\n\t\t}\n\t\tif((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(\".ui-sortable-helper\")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {\n\t\t\tdelayedTriggers.push(function(event) { this._trigger(\"update\", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed\n\t\t}\n\n\t\t// Check if the items Container has Changed and trigger appropriate\n\t\t// events.\n\t\tif (this !== this.currentContainer) {\n\t\t\tif(!noPropagation) {\n\t\t\t\tdelayedTriggers.push(function(event) { this._trigger(\"remove\", event, this._uiHash()); });\n\t\t\t\tdelayedTriggers.push((function(c) { return function(event) { c._trigger(\"receive\", event, this._uiHash(this)); };  }).call(this, this.currentContainer));\n\t\t\t\tdelayedTriggers.push((function(c) { return function(event) { c._trigger(\"update\", event, this._uiHash(this));  }; }).call(this, this.currentContainer));\n\t\t\t}\n\t\t}\n\n\n\t\t//Post events to containers\n\t\tfor (i = this.containers.length - 1; i >= 0; i--){\n\t\t\tif(!noPropagation) {\n\t\t\t\tdelayedTriggers.push((function(c) { return function(event) { c._trigger(\"deactivate\", event, this._uiHash(this)); };  }).call(this, this.containers[i]));\n\t\t\t}\n\t\t\tif(this.containers[i].containerCache.over) {\n\t\t\t\tdelayedTriggers.push((function(c) { return function(event) { c._trigger(\"out\", event, this._uiHash(this)); };  }).call(this, this.containers[i]));\n\t\t\t\tthis.containers[i].containerCache.over = 0;\n\t\t\t}\n\t\t}\n\n\t\t//Do what was originally in plugins\n\t\tif ( this.storedCursor ) {\n\t\t\tthis.document.find( \"body\" ).css( \"cursor\", this.storedCursor );\n\t\t\tthis.storedStylesheet.remove();\n\t\t}\n\t\tif(this._storedOpacity) {\n\t\t\tthis.helper.css(\"opacity\", this._storedOpacity);\n\t\t}\n\t\tif(this._storedZIndex) {\n\t\t\tthis.helper.css(\"zIndex\", this._storedZIndex === \"auto\" ? \"\" : this._storedZIndex);\n\t\t}\n\n\t\tthis.dragging = false;\n\t\tif(this.cancelHelperRemoval) {\n\t\t\tif(!noPropagation) {\n\t\t\t\tthis._trigger(\"beforeStop\", event, this._uiHash());\n\t\t\t\tfor (i=0; i < delayedTriggers.length; i++) {\n\t\t\t\t\tdelayedTriggers[i].call(this, event);\n\t\t\t\t} //Trigger all delayed events\n\t\t\t\tthis._trigger(\"stop\", event, this._uiHash());\n\t\t\t}\n\n\t\t\tthis.fromOutside = false;\n\t\t\treturn false;\n\t\t}\n\n\t\tif(!noPropagation) {\n\t\t\tthis._trigger(\"beforeStop\", event, this._uiHash());\n\t\t}\n\n\t\t//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!\n\t\tthis.placeholder[0].parentNode.removeChild(this.placeholder[0]);\n\n\t\tif(this.helper[0] !== this.currentItem[0]) {\n\t\t\tthis.helper.remove();\n\t\t}\n\t\tthis.helper = null;\n\n\t\tif(!noPropagation) {\n\t\t\tfor (i=0; i < delayedTriggers.length; i++) {\n\t\t\t\tdelayedTriggers[i].call(this, event);\n\t\t\t} //Trigger all delayed events\n\t\t\tthis._trigger(\"stop\", event, this._uiHash());\n\t\t}\n\n\t\tthis.fromOutside = false;\n\t\treturn true;\n\n\t},\n\n\t_trigger: function() {\n\t\tif ($.Widget.prototype._trigger.apply(this, arguments) === false) {\n\t\t\tthis.cancel();\n\t\t}\n\t},\n\n\t_uiHash: function(_inst) {\n\t\tvar inst = _inst || this;\n\t\treturn {\n\t\t\thelper: inst.helper,\n\t\t\tplaceholder: inst.placeholder || $([]),\n\t\t\tposition: inst.position,\n\t\t\toriginalPosition: inst.originalPosition,\n\t\t\toffset: inst.positionAbs,\n\t\t\titem: inst.currentItem,\n\t\t\tsender: _inst ? _inst.element : null\n\t\t};\n\t}\n\n});\n\n})(jQuery);\n\n(function($, undefined) {\n\nvar dataSpace = \"ui-effects-\";\n\n$.effects = {\n\teffect: {}\n};\n\n/*!\n * jQuery Color Animations v2.1.2\n * https://github.com/jquery/jquery-color\n *\n * Copyright 2013 jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * Date: Wed Jan 16 08:47:09 2013 -0600\n */\n(function( jQuery, undefined ) {\n\n\tvar stepHooks = \"backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor\",\n\n\t// plusequals test for += 100 -= 100\n\trplusequals = /^([\\-+])=\\s*(\\d+\\.?\\d*)/,\n\t// a set of RE's that can match strings and generate color tuples.\n\tstringParsers = [{\n\t\t\tre: /rgba?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*(?:,\\s*(\\d?(?:\\.\\d+)?)\\s*)?\\)/,\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\texecResult[ 1 ],\n\t\t\t\t\texecResult[ 2 ],\n\t\t\t\t\texecResult[ 3 ],\n\t\t\t\t\texecResult[ 4 ]\n\t\t\t\t];\n\t\t\t}\n\t\t}, {\n\t\t\tre: /rgba?\\(\\s*(\\d+(?:\\.\\d+)?)\\%\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*(?:,\\s*(\\d?(?:\\.\\d+)?)\\s*)?\\)/,\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\texecResult[ 1 ] * 2.55,\n\t\t\t\t\texecResult[ 2 ] * 2.55,\n\t\t\t\t\texecResult[ 3 ] * 2.55,\n\t\t\t\t\texecResult[ 4 ]\n\t\t\t\t];\n\t\t\t}\n\t\t}, {\n\t\t\t// this regex ignores A-F because it's compared against an already lowercased string\n\t\t\tre: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\tparseInt( execResult[ 1 ], 16 ),\n\t\t\t\t\tparseInt( execResult[ 2 ], 16 ),\n\t\t\t\t\tparseInt( execResult[ 3 ], 16 )\n\t\t\t\t];\n\t\t\t}\n\t\t}, {\n\t\t\t// this regex ignores A-F because it's compared against an already lowercased string\n\t\t\tre: /#([a-f0-9])([a-f0-9])([a-f0-9])/,\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\tparseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),\n\t\t\t\t\tparseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),\n\t\t\t\t\tparseInt( execResult[ 3 ] + execResult[ 3 ], 16 )\n\t\t\t\t];\n\t\t\t}\n\t\t}, {\n\t\t\tre: /hsla?\\(\\s*(\\d+(?:\\.\\d+)?)\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*(?:,\\s*(\\d?(?:\\.\\d+)?)\\s*)?\\)/,\n\t\t\tspace: \"hsla\",\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\texecResult[ 1 ],\n\t\t\t\t\texecResult[ 2 ] / 100,\n\t\t\t\t\texecResult[ 3 ] / 100,\n\t\t\t\t\texecResult[ 4 ]\n\t\t\t\t];\n\t\t\t}\n\t\t}],\n\n\t// jQuery.Color( )\n\tcolor = jQuery.Color = function( color, green, blue, alpha ) {\n\t\treturn new jQuery.Color.fn.parse( color, green, blue, alpha );\n\t},\n\tspaces = {\n\t\trgba: {\n\t\t\tprops: {\n\t\t\t\tred: {\n\t\t\t\t\tidx: 0,\n\t\t\t\t\ttype: \"byte\"\n\t\t\t\t},\n\t\t\t\tgreen: {\n\t\t\t\t\tidx: 1,\n\t\t\t\t\ttype: \"byte\"\n\t\t\t\t},\n\t\t\t\tblue: {\n\t\t\t\t\tidx: 2,\n\t\t\t\t\ttype: \"byte\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\thsla: {\n\t\t\tprops: {\n\t\t\t\thue: {\n\t\t\t\t\tidx: 0,\n\t\t\t\t\ttype: \"degrees\"\n\t\t\t\t},\n\t\t\t\tsaturation: {\n\t\t\t\t\tidx: 1,\n\t\t\t\t\ttype: \"percent\"\n\t\t\t\t},\n\t\t\t\tlightness: {\n\t\t\t\t\tidx: 2,\n\t\t\t\t\ttype: \"percent\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\tpropTypes = {\n\t\t\"byte\": {\n\t\t\tfloor: true,\n\t\t\tmax: 255\n\t\t},\n\t\t\"percent\": {\n\t\t\tmax: 1\n\t\t},\n\t\t\"degrees\": {\n\t\t\tmod: 360,\n\t\t\tfloor: true\n\t\t}\n\t},\n\tsupport = color.support = {},\n\n\t// element for support tests\n\tsupportElem = jQuery( \"<p>\" )[ 0 ],\n\n\t// colors = jQuery.Color.names\n\tcolors,\n\n\t// local aliases of functions called often\n\teach = jQuery.each;\n\n// determine rgba support immediately\nsupportElem.style.cssText = \"background-color:rgba(1,1,1,.5)\";\nsupport.rgba = supportElem.style.backgroundColor.indexOf( \"rgba\" ) > -1;\n\n// define cache name and alpha properties\n// for rgba and hsla spaces\neach( spaces, function( spaceName, space ) {\n\tspace.cache = \"_\" + spaceName;\n\tspace.props.alpha = {\n\t\tidx: 3,\n\t\ttype: \"percent\",\n\t\tdef: 1\n\t};\n});\n\nfunction clamp( value, prop, allowEmpty ) {\n\tvar type = propTypes[ prop.type ] || {};\n\n\tif ( value == null ) {\n\t\treturn (allowEmpty || !prop.def) ? null : prop.def;\n\t}\n\n\t// ~~ is an short way of doing floor for positive numbers\n\tvalue = type.floor ? ~~value : parseFloat( value );\n\n\t// IE will pass in empty strings as value for alpha,\n\t// which will hit this case\n\tif ( isNaN( value ) ) {\n\t\treturn prop.def;\n\t}\n\n\tif ( type.mod ) {\n\t\t// we add mod before modding to make sure that negatives values\n\t\t// get converted properly: -10 -> 350\n\t\treturn (value + type.mod) % type.mod;\n\t}\n\n\t// for now all property types without mod have min and max\n\treturn 0 > value ? 0 : type.max < value ? type.max : value;\n}\n\nfunction stringParse( string ) {\n\tvar inst = color(),\n\t\trgba = inst._rgba = [];\n\n\tstring = string.toLowerCase();\n\n\teach( stringParsers, function( i, parser ) {\n\t\tvar parsed,\n\t\t\tmatch = parser.re.exec( string ),\n\t\t\tvalues = match && parser.parse( match ),\n\t\t\tspaceName = parser.space || \"rgba\";\n\n\t\tif ( values ) {\n\t\t\tparsed = inst[ spaceName ]( values );\n\n\t\t\t// if this was an rgba parse the assignment might happen twice\n\t\t\t// oh well....\n\t\t\tinst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];\n\t\t\trgba = inst._rgba = parsed._rgba;\n\n\t\t\t// exit each( stringParsers ) here because we matched\n\t\t\treturn false;\n\t\t}\n\t});\n\n\t// Found a stringParser that handled it\n\tif ( rgba.length ) {\n\n\t\t// if this came from a parsed string, force \"transparent\" when alpha is 0\n\t\t// chrome, (and maybe others) return \"transparent\" as rgba(0,0,0,0)\n\t\tif ( rgba.join() === \"0,0,0,0\" ) {\n\t\t\tjQuery.extend( rgba, colors.transparent );\n\t\t}\n\t\treturn inst;\n\t}\n\n\t// named colors\n\treturn colors[ string ];\n}\n\ncolor.fn = jQuery.extend( color.prototype, {\n\tparse: function( red, green, blue, alpha ) {\n\t\tif ( red === undefined ) {\n\t\t\tthis._rgba = [ null, null, null, null ];\n\t\t\treturn this;\n\t\t}\n\t\tif ( red.jquery || red.nodeType ) {\n\t\t\tred = jQuery( red ).css( green );\n\t\t\tgreen = undefined;\n\t\t}\n\n\t\tvar inst = this,\n\t\t\ttype = jQuery.type( red ),\n\t\t\trgba = this._rgba = [];\n\n\t\t// more than 1 argument specified - assume ( red, green, blue, alpha )\n\t\tif ( green !== undefined ) {\n\t\t\tred = [ red, green, blue, alpha ];\n\t\t\ttype = \"array\";\n\t\t}\n\n\t\tif ( type === \"string\" ) {\n\t\t\treturn this.parse( stringParse( red ) || colors._default );\n\t\t}\n\n\t\tif ( type === \"array\" ) {\n\t\t\teach( spaces.rgba.props, function( key, prop ) {\n\t\t\t\trgba[ prop.idx ] = clamp( red[ prop.idx ], prop );\n\t\t\t});\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( type === \"object\" ) {\n\t\t\tif ( red instanceof color ) {\n\t\t\t\teach( spaces, function( spaceName, space ) {\n\t\t\t\t\tif ( red[ space.cache ] ) {\n\t\t\t\t\t\tinst[ space.cache ] = red[ space.cache ].slice();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\teach( spaces, function( spaceName, space ) {\n\t\t\t\t\tvar cache = space.cache;\n\t\t\t\t\teach( space.props, function( key, prop ) {\n\n\t\t\t\t\t\t// if the cache doesn't exist, and we know how to convert\n\t\t\t\t\t\tif ( !inst[ cache ] && space.to ) {\n\n\t\t\t\t\t\t\t// if the value was null, we don't need to copy it\n\t\t\t\t\t\t\t// if the key was alpha, we don't need to copy it either\n\t\t\t\t\t\t\tif ( key === \"alpha\" || red[ key ] == null ) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tinst[ cache ] = space.to( inst._rgba );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// this is the only case where we allow nulls for ALL properties.\n\t\t\t\t\t\t// call clamp with alwaysAllowEmpty\n\t\t\t\t\t\tinst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );\n\t\t\t\t\t});\n\n\t\t\t\t\t// everything defined but alpha?\n\t\t\t\t\tif ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {\n\t\t\t\t\t\t// use the default of 1\n\t\t\t\t\t\tinst[ cache ][ 3 ] = 1;\n\t\t\t\t\t\tif ( space.from ) {\n\t\t\t\t\t\t\tinst._rgba = space.from( inst[ cache ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t},\n\tis: function( compare ) {\n\t\tvar is = color( compare ),\n\t\t\tsame = true,\n\t\t\tinst = this;\n\n\t\teach( spaces, function( _, space ) {\n\t\t\tvar localCache,\n\t\t\t\tisCache = is[ space.cache ];\n\t\t\tif (isCache) {\n\t\t\t\tlocalCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];\n\t\t\t\teach( space.props, function( _, prop ) {\n\t\t\t\t\tif ( isCache[ prop.idx ] != null ) {\n\t\t\t\t\t\tsame = ( isCache[ prop.idx ] === localCache[ prop.idx ] );\n\t\t\t\t\t\treturn same;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn same;\n\t\t});\n\t\treturn same;\n\t},\n\t_space: function() {\n\t\tvar used = [],\n\t\t\tinst = this;\n\t\teach( spaces, function( spaceName, space ) {\n\t\t\tif ( inst[ space.cache ] ) {\n\t\t\t\tused.push( spaceName );\n\t\t\t}\n\t\t});\n\t\treturn used.pop();\n\t},\n\ttransition: function( other, distance ) {\n\t\tvar end = color( other ),\n\t\t\tspaceName = end._space(),\n\t\t\tspace = spaces[ spaceName ],\n\t\t\tstartColor = this.alpha() === 0 ? color( \"transparent\" ) : this,\n\t\t\tstart = startColor[ space.cache ] || space.to( startColor._rgba ),\n\t\t\tresult = start.slice();\n\n\t\tend = end[ space.cache ];\n\t\teach( space.props, function( key, prop ) {\n\t\t\tvar index = prop.idx,\n\t\t\t\tstartValue = start[ index ],\n\t\t\t\tendValue = end[ index ],\n\t\t\t\ttype = propTypes[ prop.type ] || {};\n\n\t\t\t// if null, don't override start value\n\t\t\tif ( endValue === null ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// if null - use end\n\t\t\tif ( startValue === null ) {\n\t\t\t\tresult[ index ] = endValue;\n\t\t\t} else {\n\t\t\t\tif ( type.mod ) {\n\t\t\t\t\tif ( endValue - startValue > type.mod / 2 ) {\n\t\t\t\t\t\tstartValue += type.mod;\n\t\t\t\t\t} else if ( startValue - endValue > type.mod / 2 ) {\n\t\t\t\t\t\tstartValue -= type.mod;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tresult[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );\n\t\t\t}\n\t\t});\n\t\treturn this[ spaceName ]( result );\n\t},\n\tblend: function( opaque ) {\n\t\t// if we are already opaque - return ourself\n\t\tif ( this._rgba[ 3 ] === 1 ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tvar rgb = this._rgba.slice(),\n\t\t\ta = rgb.pop(),\n\t\t\tblend = color( opaque )._rgba;\n\n\t\treturn color( jQuery.map( rgb, function( v, i ) {\n\t\t\treturn ( 1 - a ) * blend[ i ] + a * v;\n\t\t}));\n\t},\n\ttoRgbaString: function() {\n\t\tvar prefix = \"rgba(\",\n\t\t\trgba = jQuery.map( this._rgba, function( v, i ) {\n\t\t\t\treturn v == null ? ( i > 2 ? 1 : 0 ) : v;\n\t\t\t});\n\n\t\tif ( rgba[ 3 ] === 1 ) {\n\t\t\trgba.pop();\n\t\t\tprefix = \"rgb(\";\n\t\t}\n\n\t\treturn prefix + rgba.join() + \")\";\n\t},\n\ttoHslaString: function() {\n\t\tvar prefix = \"hsla(\",\n\t\t\thsla = jQuery.map( this.hsla(), function( v, i ) {\n\t\t\t\tif ( v == null ) {\n\t\t\t\t\tv = i > 2 ? 1 : 0;\n\t\t\t\t}\n\n\t\t\t\t// catch 1 and 2\n\t\t\t\tif ( i && i < 3 ) {\n\t\t\t\t\tv = Math.round( v * 100 ) + \"%\";\n\t\t\t\t}\n\t\t\t\treturn v;\n\t\t\t});\n\n\t\tif ( hsla[ 3 ] === 1 ) {\n\t\t\thsla.pop();\n\t\t\tprefix = \"hsl(\";\n\t\t}\n\t\treturn prefix + hsla.join() + \")\";\n\t},\n\ttoHexString: function( includeAlpha ) {\n\t\tvar rgba = this._rgba.slice(),\n\t\t\talpha = rgba.pop();\n\n\t\tif ( includeAlpha ) {\n\t\t\trgba.push( ~~( alpha * 255 ) );\n\t\t}\n\n\t\treturn \"#\" + jQuery.map( rgba, function( v ) {\n\n\t\t\t// default to 0 when nulls exist\n\t\t\tv = ( v || 0 ).toString( 16 );\n\t\t\treturn v.length === 1 ? \"0\" + v : v;\n\t\t}).join(\"\");\n\t},\n\ttoString: function() {\n\t\treturn this._rgba[ 3 ] === 0 ? \"transparent\" : this.toRgbaString();\n\t}\n});\ncolor.fn.parse.prototype = color.fn;\n\n// hsla conversions adapted from:\n// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021\n\nfunction hue2rgb( p, q, h ) {\n\th = ( h + 1 ) % 1;\n\tif ( h * 6 < 1 ) {\n\t\treturn p + (q - p) * h * 6;\n\t}\n\tif ( h * 2 < 1) {\n\t\treturn q;\n\t}\n\tif ( h * 3 < 2 ) {\n\t\treturn p + (q - p) * ((2/3) - h) * 6;\n\t}\n\treturn p;\n}\n\nspaces.hsla.to = function ( rgba ) {\n\tif ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {\n\t\treturn [ null, null, null, rgba[ 3 ] ];\n\t}\n\tvar r = rgba[ 0 ] / 255,\n\t\tg = rgba[ 1 ] / 255,\n\t\tb = rgba[ 2 ] / 255,\n\t\ta = rgba[ 3 ],\n\t\tmax = Math.max( r, g, b ),\n\t\tmin = Math.min( r, g, b ),\n\t\tdiff = max - min,\n\t\tadd = max + min,\n\t\tl = add * 0.5,\n\t\th, s;\n\n\tif ( min === max ) {\n\t\th = 0;\n\t} else if ( r === max ) {\n\t\th = ( 60 * ( g - b ) / diff ) + 360;\n\t} else if ( g === max ) {\n\t\th = ( 60 * ( b - r ) / diff ) + 120;\n\t} else {\n\t\th = ( 60 * ( r - g ) / diff ) + 240;\n\t}\n\n\t// chroma (diff) == 0 means greyscale which, by definition, saturation = 0%\n\t// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)\n\tif ( diff === 0 ) {\n\t\ts = 0;\n\t} else if ( l <= 0.5 ) {\n\t\ts = diff / add;\n\t} else {\n\t\ts = diff / ( 2 - add );\n\t}\n\treturn [ Math.round(h) % 360, s, l, a == null ? 1 : a ];\n};\n\nspaces.hsla.from = function ( hsla ) {\n\tif ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {\n\t\treturn [ null, null, null, hsla[ 3 ] ];\n\t}\n\tvar h = hsla[ 0 ] / 360,\n\t\ts = hsla[ 1 ],\n\t\tl = hsla[ 2 ],\n\t\ta = hsla[ 3 ],\n\t\tq = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,\n\t\tp = 2 * l - q;\n\n\treturn [\n\t\tMath.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),\n\t\tMath.round( hue2rgb( p, q, h ) * 255 ),\n\t\tMath.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),\n\t\ta\n\t];\n};\n\n\neach( spaces, function( spaceName, space ) {\n\tvar props = space.props,\n\t\tcache = space.cache,\n\t\tto = space.to,\n\t\tfrom = space.from;\n\n\t// makes rgba() and hsla()\n\tcolor.fn[ spaceName ] = function( value ) {\n\n\t\t// generate a cache for this space if it doesn't exist\n\t\tif ( to && !this[ cache ] ) {\n\t\t\tthis[ cache ] = to( this._rgba );\n\t\t}\n\t\tif ( value === undefined ) {\n\t\t\treturn this[ cache ].slice();\n\t\t}\n\n\t\tvar ret,\n\t\t\ttype = jQuery.type( value ),\n\t\t\tarr = ( type === \"array\" || type === \"object\" ) ? value : arguments,\n\t\t\tlocal = this[ cache ].slice();\n\n\t\teach( props, function( key, prop ) {\n\t\t\tvar val = arr[ type === \"object\" ? key : prop.idx ];\n\t\t\tif ( val == null ) {\n\t\t\t\tval = local[ prop.idx ];\n\t\t\t}\n\t\t\tlocal[ prop.idx ] = clamp( val, prop );\n\t\t});\n\n\t\tif ( from ) {\n\t\t\tret = color( from( local ) );\n\t\t\tret[ cache ] = local;\n\t\t\treturn ret;\n\t\t} else {\n\t\t\treturn color( local );\n\t\t}\n\t};\n\n\t// makes red() green() blue() alpha() hue() saturation() lightness()\n\teach( props, function( key, prop ) {\n\t\t// alpha is included in more than one space\n\t\tif ( color.fn[ key ] ) {\n\t\t\treturn;\n\t\t}\n\t\tcolor.fn[ key ] = function( value ) {\n\t\t\tvar vtype = jQuery.type( value ),\n\t\t\t\tfn = ( key === \"alpha\" ? ( this._hsla ? \"hsla\" : \"rgba\" ) : spaceName ),\n\t\t\t\tlocal = this[ fn ](),\n\t\t\t\tcur = local[ prop.idx ],\n\t\t\t\tmatch;\n\n\t\t\tif ( vtype === \"undefined\" ) {\n\t\t\t\treturn cur;\n\t\t\t}\n\n\t\t\tif ( vtype === \"function\" ) {\n\t\t\t\tvalue = value.call( this, cur );\n\t\t\t\tvtype = jQuery.type( value );\n\t\t\t}\n\t\t\tif ( value == null && prop.empty ) {\n\t\t\t\treturn this;\n\t\t\t}\n\t\t\tif ( vtype === \"string\" ) {\n\t\t\t\tmatch = rplusequals.exec( value );\n\t\t\t\tif ( match ) {\n\t\t\t\t\tvalue = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === \"+\" ? 1 : -1 );\n\t\t\t\t}\n\t\t\t}\n\t\t\tlocal[ prop.idx ] = value;\n\t\t\treturn this[ fn ]( local );\n\t\t};\n\t});\n});\n\n// add cssHook and .fx.step function for each named hook.\n// accept a space separated string of properties\ncolor.hook = function( hook ) {\n\tvar hooks = hook.split( \" \" );\n\teach( hooks, function( i, hook ) {\n\t\tjQuery.cssHooks[ hook ] = {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar parsed, curElem,\n\t\t\t\t\tbackgroundColor = \"\";\n\n\t\t\t\tif ( value !== \"transparent\" && ( jQuery.type( value ) !== \"string\" || ( parsed = stringParse( value ) ) ) ) {\n\t\t\t\t\tvalue = color( parsed || value );\n\t\t\t\t\tif ( !support.rgba && value._rgba[ 3 ] !== 1 ) {\n\t\t\t\t\t\tcurElem = hook === \"backgroundColor\" ? elem.parentNode : elem;\n\t\t\t\t\t\twhile (\n\t\t\t\t\t\t\t(backgroundColor === \"\" || backgroundColor === \"transparent\") &&\n\t\t\t\t\t\t\tcurElem && curElem.style\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tbackgroundColor = jQuery.css( curElem, \"backgroundColor\" );\n\t\t\t\t\t\t\t\tcurElem = curElem.parentNode;\n\t\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvalue = value.blend( backgroundColor && backgroundColor !== \"transparent\" ?\n\t\t\t\t\t\t\tbackgroundColor :\n\t\t\t\t\t\t\t\"_default\" );\n\t\t\t\t\t}\n\n\t\t\t\t\tvalue = value.toRgbaString();\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\telem.style[ hook ] = value;\n\t\t\t\t} catch( e ) {\n\t\t\t\t\t// wrapped to prevent IE from throwing errors on \"invalid\" values like 'auto' or 'inherit'\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tjQuery.fx.step[ hook ] = function( fx ) {\n\t\t\tif ( !fx.colorInit ) {\n\t\t\t\tfx.start = color( fx.elem, hook );\n\t\t\t\tfx.end = color( fx.end );\n\t\t\t\tfx.colorInit = true;\n\t\t\t}\n\t\t\tjQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );\n\t\t};\n\t});\n\n};\n\ncolor.hook( stepHooks );\n\njQuery.cssHooks.borderColor = {\n\texpand: function( value ) {\n\t\tvar expanded = {};\n\n\t\teach( [ \"Top\", \"Right\", \"Bottom\", \"Left\" ], function( i, part ) {\n\t\t\texpanded[ \"border\" + part + \"Color\" ] = value;\n\t\t});\n\t\treturn expanded;\n\t}\n};\n\n// Basic color names only.\n// Usage of any of the other color names requires adding yourself or including\n// jquery.color.svg-names.js.\ncolors = jQuery.Color.names = {\n\t// 4.1. Basic color keywords\n\taqua: \"#00ffff\",\n\tblack: \"#000000\",\n\tblue: \"#0000ff\",\n\tfuchsia: \"#ff00ff\",\n\tgray: \"#808080\",\n\tgreen: \"#008000\",\n\tlime: \"#00ff00\",\n\tmaroon: \"#800000\",\n\tnavy: \"#000080\",\n\tolive: \"#808000\",\n\tpurple: \"#800080\",\n\tred: \"#ff0000\",\n\tsilver: \"#c0c0c0\",\n\tteal: \"#008080\",\n\twhite: \"#ffffff\",\n\tyellow: \"#ffff00\",\n\n\t// 4.2.3. \"transparent\" color keyword\n\ttransparent: [ null, null, null, 0 ],\n\n\t_default: \"#ffffff\"\n};\n\n})( jQuery );\n\n\n/******************************************************************************/\n/****************************** CLASS ANIMATIONS ******************************/\n/******************************************************************************/\n(function() {\n\nvar classAnimationActions = [ \"add\", \"remove\", \"toggle\" ],\n\tshorthandStyles = {\n\t\tborder: 1,\n\t\tborderBottom: 1,\n\t\tborderColor: 1,\n\t\tborderLeft: 1,\n\t\tborderRight: 1,\n\t\tborderTop: 1,\n\t\tborderWidth: 1,\n\t\tmargin: 1,\n\t\tpadding: 1\n\t};\n\n$.each([ \"borderLeftStyle\", \"borderRightStyle\", \"borderBottomStyle\", \"borderTopStyle\" ], function( _, prop ) {\n\t$.fx.step[ prop ] = function( fx ) {\n\t\tif ( fx.end !== \"none\" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {\n\t\t\tjQuery.style( fx.elem, prop, fx.end );\n\t\t\tfx.setAttr = true;\n\t\t}\n\t};\n});\n\nfunction getElementStyles( elem ) {\n\tvar key, len,\n\t\tstyle = elem.ownerDocument.defaultView ?\n\t\t\telem.ownerDocument.defaultView.getComputedStyle( elem, null ) :\n\t\t\telem.currentStyle,\n\t\tstyles = {};\n\n\tif ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {\n\t\tlen = style.length;\n\t\twhile ( len-- ) {\n\t\t\tkey = style[ len ];\n\t\t\tif ( typeof style[ key ] === \"string\" ) {\n\t\t\t\tstyles[ $.camelCase( key ) ] = style[ key ];\n\t\t\t}\n\t\t}\n\t// support: Opera, IE <9\n\t} else {\n\t\tfor ( key in style ) {\n\t\t\tif ( typeof style[ key ] === \"string\" ) {\n\t\t\t\tstyles[ key ] = style[ key ];\n\t\t\t}\n\t\t}\n\t}\n\n\treturn styles;\n}\n\n\nfunction styleDifference( oldStyle, newStyle ) {\n\tvar diff = {},\n\t\tname, value;\n\n\tfor ( name in newStyle ) {\n\t\tvalue = newStyle[ name ];\n\t\tif ( oldStyle[ name ] !== value ) {\n\t\t\tif ( !shorthandStyles[ name ] ) {\n\t\t\t\tif ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {\n\t\t\t\t\tdiff[ name ] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn diff;\n}\n\n// support: jQuery <1.8\nif ( !$.fn.addBack ) {\n\t$.fn.addBack = function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t};\n}\n\n$.effects.animateClass = function( value, duration, easing, callback ) {\n\tvar o = $.speed( duration, easing, callback );\n\n\treturn this.queue( function() {\n\t\tvar animated = $( this ),\n\t\t\tbaseClass = animated.attr( \"class\" ) || \"\",\n\t\t\tapplyClassChange,\n\t\t\tallAnimations = o.children ? animated.find( \"*\" ).addBack() : animated;\n\n\t\t// map the animated objects to store the original styles.\n\t\tallAnimations = allAnimations.map(function() {\n\t\t\tvar el = $( this );\n\t\t\treturn {\n\t\t\t\tel: el,\n\t\t\t\tstart: getElementStyles( this )\n\t\t\t};\n\t\t});\n\n\t\t// apply class change\n\t\tapplyClassChange = function() {\n\t\t\t$.each( classAnimationActions, function(i, action) {\n\t\t\t\tif ( value[ action ] ) {\n\t\t\t\t\tanimated[ action + \"Class\" ]( value[ action ] );\n\t\t\t\t}\n\t\t\t});\n\t\t};\n\t\tapplyClassChange();\n\n\t\t// map all animated objects again - calculate new styles and diff\n\t\tallAnimations = allAnimations.map(function() {\n\t\t\tthis.end = getElementStyles( this.el[ 0 ] );\n\t\t\tthis.diff = styleDifference( this.start, this.end );\n\t\t\treturn this;\n\t\t});\n\n\t\t// apply original class\n\t\tanimated.attr( \"class\", baseClass );\n\n\t\t// map all animated objects again - this time collecting a promise\n\t\tallAnimations = allAnimations.map(function() {\n\t\t\tvar styleInfo = this,\n\t\t\t\tdfd = $.Deferred(),\n\t\t\t\topts = $.extend({}, o, {\n\t\t\t\t\tqueue: false,\n\t\t\t\t\tcomplete: function() {\n\t\t\t\t\t\tdfd.resolve( styleInfo );\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\tthis.el.animate( this.diff, opts );\n\t\t\treturn dfd.promise();\n\t\t});\n\n\t\t// once all animations have completed:\n\t\t$.when.apply( $, allAnimations.get() ).done(function() {\n\n\t\t\t// set the final class\n\t\t\tapplyClassChange();\n\n\t\t\t// for each animated element,\n\t\t\t// clear all css properties that were animated\n\t\t\t$.each( arguments, function() {\n\t\t\t\tvar el = this.el;\n\t\t\t\t$.each( this.diff, function(key) {\n\t\t\t\t\tel.css( key, \"\" );\n\t\t\t\t});\n\t\t\t});\n\n\t\t\t// this is guarnteed to be there if you use jQuery.speed()\n\t\t\t// it also handles dequeuing the next anim...\n\t\t\to.complete.call( animated[ 0 ] );\n\t\t});\n\t});\n};\n\n$.fn.extend({\n\taddClass: (function( orig ) {\n\t\treturn function( classNames, speed, easing, callback ) {\n\t\t\treturn speed ?\n\t\t\t\t$.effects.animateClass.call( this,\n\t\t\t\t\t{ add: classNames }, speed, easing, callback ) :\n\t\t\t\torig.apply( this, arguments );\n\t\t};\n\t})( $.fn.addClass ),\n\n\tremoveClass: (function( orig ) {\n\t\treturn function( classNames, speed, easing, callback ) {\n\t\t\treturn arguments.length > 1 ?\n\t\t\t\t$.effects.animateClass.call( this,\n\t\t\t\t\t{ remove: classNames }, speed, easing, callback ) :\n\t\t\t\torig.apply( this, arguments );\n\t\t};\n\t})( $.fn.removeClass ),\n\n\ttoggleClass: (function( orig ) {\n\t\treturn function( classNames, force, speed, easing, callback ) {\n\t\t\tif ( typeof force === \"boolean\" || force === undefined ) {\n\t\t\t\tif ( !speed ) {\n\t\t\t\t\t// without speed parameter\n\t\t\t\t\treturn orig.apply( this, arguments );\n\t\t\t\t} else {\n\t\t\t\t\treturn $.effects.animateClass.call( this,\n\t\t\t\t\t\t(force ? { add: classNames } : { remove: classNames }),\n\t\t\t\t\t\tspeed, easing, callback );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// without force parameter\n\t\t\t\treturn $.effects.animateClass.call( this,\n\t\t\t\t\t{ toggle: classNames }, force, speed, easing );\n\t\t\t}\n\t\t};\n\t})( $.fn.toggleClass ),\n\n\tswitchClass: function( remove, add, speed, easing, callback) {\n\t\treturn $.effects.animateClass.call( this, {\n\t\t\tadd: add,\n\t\t\tremove: remove\n\t\t}, speed, easing, callback );\n\t}\n});\n\n})();\n\n/******************************************************************************/\n/*********************************** EFFECTS **********************************/\n/******************************************************************************/\n\n(function() {\n\n$.extend( $.effects, {\n\tversion: \"1.10.3\",\n\n\t// Saves a set of properties in a data storage\n\tsave: function( element, set ) {\n\t\tfor( var i=0; i < set.length; i++ ) {\n\t\t\tif ( set[ i ] !== null ) {\n\t\t\t\telement.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );\n\t\t\t}\n\t\t}\n\t},\n\n\t// Restores a set of previously saved properties from a data storage\n\trestore: function( element, set ) {\n\t\tvar val, i;\n\t\tfor( i=0; i < set.length; i++ ) {\n\t\t\tif ( set[ i ] !== null ) {\n\t\t\t\tval = element.data( dataSpace + set[ i ] );\n\t\t\t\t// support: jQuery 1.6.2\n\t\t\t\t// http://bugs.jquery.com/ticket/9917\n\t\t\t\t// jQuery 1.6.2 incorrectly returns undefined for any falsy value.\n\t\t\t\t// We can't differentiate between \"\" and 0 here, so we just assume\n\t\t\t\t// empty string since it's likely to be a more common value...\n\t\t\t\tif ( val === undefined ) {\n\t\t\t\t\tval = \"\";\n\t\t\t\t}\n\t\t\t\telement.css( set[ i ], val );\n\t\t\t}\n\t\t}\n\t},\n\n\tsetMode: function( el, mode ) {\n\t\tif (mode === \"toggle\") {\n\t\t\tmode = el.is( \":hidden\" ) ? \"show\" : \"hide\";\n\t\t}\n\t\treturn mode;\n\t},\n\n\t// Translates a [top,left] array into a baseline value\n\t// this should be a little more flexible in the future to handle a string & hash\n\tgetBaseline: function( origin, original ) {\n\t\tvar y, x;\n\t\tswitch ( origin[ 0 ] ) {\n\t\t\tcase \"top\": y = 0; break;\n\t\t\tcase \"middle\": y = 0.5; break;\n\t\t\tcase \"bottom\": y = 1; break;\n\t\t\tdefault: y = origin[ 0 ] / original.height;\n\t\t}\n\t\tswitch ( origin[ 1 ] ) {\n\t\t\tcase \"left\": x = 0; break;\n\t\t\tcase \"center\": x = 0.5; break;\n\t\t\tcase \"right\": x = 1; break;\n\t\t\tdefault: x = origin[ 1 ] / original.width;\n\t\t}\n\t\treturn {\n\t\t\tx: x,\n\t\t\ty: y\n\t\t};\n\t},\n\n\t// Wraps the element around a wrapper that copies position properties\n\tcreateWrapper: function( element ) {\n\n\t\t// if the element is already wrapped, return it\n\t\tif ( element.parent().is( \".ui-effects-wrapper\" )) {\n\t\t\treturn element.parent();\n\t\t}\n\n\t\t// wrap the element\n\t\tvar props = {\n\t\t\t\twidth: element.outerWidth(true),\n\t\t\t\theight: element.outerHeight(true),\n\t\t\t\t\"float\": element.css( \"float\" )\n\t\t\t},\n\t\t\twrapper = $( \"<div></div>\" )\n\t\t\t\t.addClass( \"ui-effects-wrapper\" )\n\t\t\t\t.css({\n\t\t\t\t\tfontSize: \"100%\",\n\t\t\t\t\tbackground: \"transparent\",\n\t\t\t\t\tborder: \"none\",\n\t\t\t\t\tmargin: 0,\n\t\t\t\t\tpadding: 0\n\t\t\t\t}),\n\t\t\t// Store the size in case width/height are defined in % - Fixes #5245\n\t\t\tsize = {\n\t\t\t\twidth: element.width(),\n\t\t\t\theight: element.height()\n\t\t\t},\n\t\t\tactive = document.activeElement;\n\n\t\t// support: Firefox\n\t\t// Firefox incorrectly exposes anonymous content\n\t\t// https://bugzilla.mozilla.org/show_bug.cgi?id=561664\n\t\ttry {\n\t\t\tactive.id;\n\t\t} catch( e ) {\n\t\t\tactive = document.body;\n\t\t}\n\n\t\telement.wrap( wrapper );\n\n\t\t// Fixes #7595 - Elements lose focus when wrapped.\n\t\tif ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {\n\t\t\t$( active ).focus();\n\t\t}\n\n\t\twrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element\n\n\t\t// transfer positioning properties to the wrapper\n\t\tif ( element.css( \"position\" ) === \"static\" ) {\n\t\t\twrapper.css({ position: \"relative\" });\n\t\t\telement.css({ position: \"relative\" });\n\t\t} else {\n\t\t\t$.extend( props, {\n\t\t\t\tposition: element.css( \"position\" ),\n\t\t\t\tzIndex: element.css( \"z-index\" )\n\t\t\t});\n\t\t\t$.each([ \"top\", \"left\", \"bottom\", \"right\" ], function(i, pos) {\n\t\t\t\tprops[ pos ] = element.css( pos );\n\t\t\t\tif ( isNaN( parseInt( props[ pos ], 10 ) ) ) {\n\t\t\t\t\tprops[ pos ] = \"auto\";\n\t\t\t\t}\n\t\t\t});\n\t\t\telement.css({\n\t\t\t\tposition: \"relative\",\n\t\t\t\ttop: 0,\n\t\t\t\tleft: 0,\n\t\t\t\tright: \"auto\",\n\t\t\t\tbottom: \"auto\"\n\t\t\t});\n\t\t}\n\t\telement.css(size);\n\n\t\treturn wrapper.css( props ).show();\n\t},\n\n\tremoveWrapper: function( element ) {\n\t\tvar active = document.activeElement;\n\n\t\tif ( element.parent().is( \".ui-effects-wrapper\" ) ) {\n\t\t\telement.parent().replaceWith( element );\n\n\t\t\t// Fixes #7595 - Elements lose focus when wrapped.\n\t\t\tif ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {\n\t\t\t\t$( active ).focus();\n\t\t\t}\n\t\t}\n\n\n\t\treturn element;\n\t},\n\n\tsetTransition: function( element, list, factor, value ) {\n\t\tvalue = value || {};\n\t\t$.each( list, function( i, x ) {\n\t\t\tvar unit = element.cssUnit( x );\n\t\t\tif ( unit[ 0 ] > 0 ) {\n\t\t\t\tvalue[ x ] = unit[ 0 ] * factor + unit[ 1 ];\n\t\t\t}\n\t\t});\n\t\treturn value;\n\t}\n});\n\n// return an effect options object for the given parameters:\nfunction _normalizeArguments( effect, options, speed, callback ) {\n\n\t// allow passing all options as the first parameter\n\tif ( $.isPlainObject( effect ) ) {\n\t\toptions = effect;\n\t\teffect = effect.effect;\n\t}\n\n\t// convert to an object\n\teffect = { effect: effect };\n\n\t// catch (effect, null, ...)\n\tif ( options == null ) {\n\t\toptions = {};\n\t}\n\n\t// catch (effect, callback)\n\tif ( $.isFunction( options ) ) {\n\t\tcallback = options;\n\t\tspeed = null;\n\t\toptions = {};\n\t}\n\n\t// catch (effect, speed, ?)\n\tif ( typeof options === \"number\" || $.fx.speeds[ options ] ) {\n\t\tcallback = speed;\n\t\tspeed = options;\n\t\toptions = {};\n\t}\n\n\t// catch (effect, options, callback)\n\tif ( $.isFunction( speed ) ) {\n\t\tcallback = speed;\n\t\tspeed = null;\n\t}\n\n\t// add options to effect\n\tif ( options ) {\n\t\t$.extend( effect, options );\n\t}\n\n\tspeed = speed || options.duration;\n\teffect.duration = $.fx.off ? 0 :\n\t\ttypeof speed === \"number\" ? speed :\n\t\tspeed in $.fx.speeds ? $.fx.speeds[ speed ] :\n\t\t$.fx.speeds._default;\n\n\teffect.complete = callback || options.complete;\n\n\treturn effect;\n}\n\nfunction standardAnimationOption( option ) {\n\t// Valid standard speeds (nothing, number, named speed)\n\tif ( !option || typeof option === \"number\" || $.fx.speeds[ option ] ) {\n\t\treturn true;\n\t}\n\n\t// Invalid strings - treat as \"normal\" speed\n\tif ( typeof option === \"string\" && !$.effects.effect[ option ] ) {\n\t\treturn true;\n\t}\n\n\t// Complete callback\n\tif ( $.isFunction( option ) ) {\n\t\treturn true;\n\t}\n\n\t// Options hash (but not naming an effect)\n\tif ( typeof option === \"object\" && !option.effect ) {\n\t\treturn true;\n\t}\n\n\t// Didn't match any standard API\n\treturn false;\n}\n\n$.fn.extend({\n\teffect: function( /* effect, options, speed, callback */ ) {\n\t\tvar args = _normalizeArguments.apply( this, arguments ),\n\t\t\tmode = args.mode,\n\t\t\tqueue = args.queue,\n\t\t\teffectMethod = $.effects.effect[ args.effect ];\n\n\t\tif ( $.fx.off || !effectMethod ) {\n\t\t\t// delegate to the original method (e.g., .show()) if possible\n\t\t\tif ( mode ) {\n\t\t\t\treturn this[ mode ]( args.duration, args.complete );\n\t\t\t} else {\n\t\t\t\treturn this.each( function() {\n\t\t\t\t\tif ( args.complete ) {\n\t\t\t\t\t\targs.complete.call( this );\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tfunction run( next ) {\n\t\t\tvar elem = $( this ),\n\t\t\t\tcomplete = args.complete,\n\t\t\t\tmode = args.mode;\n\n\t\t\tfunction done() {\n\t\t\t\tif ( $.isFunction( complete ) ) {\n\t\t\t\t\tcomplete.call( elem[0] );\n\t\t\t\t}\n\t\t\t\tif ( $.isFunction( next ) ) {\n\t\t\t\t\tnext();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If the element already has the correct final state, delegate to\n\t\t\t// the core methods so the internal tracking of \"olddisplay\" works.\n\t\t\tif ( elem.is( \":hidden\" ) ? mode === \"hide\" : mode === \"show\" ) {\n\t\t\t\telem[ mode ]();\n\t\t\t\tdone();\n\t\t\t} else {\n\t\t\t\teffectMethod.call( elem[0], args, done );\n\t\t\t}\n\t\t}\n\n\t\treturn queue === false ? this.each( run ) : this.queue( queue || \"fx\", run );\n\t},\n\n\tshow: (function( orig ) {\n\t\treturn function( option ) {\n\t\t\tif ( standardAnimationOption( option ) ) {\n\t\t\t\treturn orig.apply( this, arguments );\n\t\t\t} else {\n\t\t\t\tvar args = _normalizeArguments.apply( this, arguments );\n\t\t\t\targs.mode = \"show\";\n\t\t\t\treturn this.effect.call( this, args );\n\t\t\t}\n\t\t};\n\t})( $.fn.show ),\n\n\thide: (function( orig ) {\n\t\treturn function( option ) {\n\t\t\tif ( standardAnimationOption( option ) ) {\n\t\t\t\treturn orig.apply( this, arguments );\n\t\t\t} else {\n\t\t\t\tvar args = _normalizeArguments.apply( this, arguments );\n\t\t\t\targs.mode = \"hide\";\n\t\t\t\treturn this.effect.call( this, args );\n\t\t\t}\n\t\t};\n\t})( $.fn.hide ),\n\n\ttoggle: (function( orig ) {\n\t\treturn function( option ) {\n\t\t\tif ( standardAnimationOption( option ) || typeof option === \"boolean\" ) {\n\t\t\t\treturn orig.apply( this, arguments );\n\t\t\t} else {\n\t\t\t\tvar args = _normalizeArguments.apply( this, arguments );\n\t\t\t\targs.mode = \"toggle\";\n\t\t\t\treturn this.effect.call( this, args );\n\t\t\t}\n\t\t};\n\t})( $.fn.toggle ),\n\n\t// helper functions\n\tcssUnit: function(key) {\n\t\tvar style = this.css( key ),\n\t\t\tval = [];\n\n\t\t$.each( [ \"em\", \"px\", \"%\", \"pt\" ], function( i, unit ) {\n\t\t\tif ( style.indexOf( unit ) > 0 ) {\n\t\t\t\tval = [ parseFloat( style ), unit ];\n\t\t\t}\n\t\t});\n\t\treturn val;\n\t}\n});\n\n})();\n\n/******************************************************************************/\n/*********************************** EASING ***********************************/\n/******************************************************************************/\n\n(function() {\n\n// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)\n\nvar baseEasings = {};\n\n$.each( [ \"Quad\", \"Cubic\", \"Quart\", \"Quint\", \"Expo\" ], function( i, name ) {\n\tbaseEasings[ name ] = function( p ) {\n\t\treturn Math.pow( p, i + 2 );\n\t};\n});\n\n$.extend( baseEasings, {\n\tSine: function ( p ) {\n\t\treturn 1 - Math.cos( p * Math.PI / 2 );\n\t},\n\tCirc: function ( p ) {\n\t\treturn 1 - Math.sqrt( 1 - p * p );\n\t},\n\tElastic: function( p ) {\n\t\treturn p === 0 || p === 1 ? p :\n\t\t\t-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );\n\t},\n\tBack: function( p ) {\n\t\treturn p * p * ( 3 * p - 2 );\n\t},\n\tBounce: function ( p ) {\n\t\tvar pow2,\n\t\t\tbounce = 4;\n\n\t\twhile ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}\n\t\treturn 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );\n\t}\n});\n\n$.each( baseEasings, function( name, easeIn ) {\n\t$.easing[ \"easeIn\" + name ] = easeIn;\n\t$.easing[ \"easeOut\" + name ] = function( p ) {\n\t\treturn 1 - easeIn( 1 - p );\n\t};\n\t$.easing[ \"easeInOut\" + name ] = function( p ) {\n\t\treturn p < 0.5 ?\n\t\t\teaseIn( p * 2 ) / 2 :\n\t\t\t1 - easeIn( p * -2 + 2 ) / 2;\n\t};\n});\n\n})();\n\n})(jQuery);\n\n(function( $, undefined ) {\n\nvar uid = 0,\n\thideProps = {},\n\tshowProps = {};\n\nhideProps.height = hideProps.paddingTop = hideProps.paddingBottom =\n\thideProps.borderTopWidth = hideProps.borderBottomWidth = \"hide\";\nshowProps.height = showProps.paddingTop = showProps.paddingBottom =\n\tshowProps.borderTopWidth = showProps.borderBottomWidth = \"show\";\n\n$.widget( \"ui.accordion\", {\n\tversion: \"1.10.3\",\n\toptions: {\n\t\tactive: 0,\n\t\tanimate: {},\n\t\tcollapsible: false,\n\t\tevent: \"click\",\n\t\theader: \"> li > :first-child,> :not(li):even\",\n\t\theightStyle: \"auto\",\n\t\ticons: {\n\t\t\tactiveHeader: \"ui-icon-triangle-1-s\",\n\t\t\theader: \"ui-icon-triangle-1-e\"\n\t\t},\n\n\t\t// callbacks\n\t\tactivate: null,\n\t\tbeforeActivate: null\n\t},\n\n\t_create: function() {\n\t\tvar options = this.options;\n\t\tthis.prevShow = this.prevHide = $();\n\t\tthis.element.addClass( \"ui-accordion ui-widget ui-helper-reset\" )\n\t\t\t// ARIA\n\t\t\t.attr( \"role\", \"tablist\" );\n\n\t\t// don't allow collapsible: false and active: false / null\n\t\tif ( !options.collapsible && (options.active === false || options.active == null) ) {\n\t\t\toptions.active = 0;\n\t\t}\n\n\t\tthis._processPanels();\n\t\t// handle negative values\n\t\tif ( options.active < 0 ) {\n\t\t\toptions.active += this.headers.length;\n\t\t}\n\t\tthis._refresh();\n\t},\n\n\t_getCreateEventData: function() {\n\t\treturn {\n\t\t\theader: this.active,\n\t\t\tpanel: !this.active.length ? $() : this.active.next(),\n\t\t\tcontent: !this.active.length ? $() : this.active.next()\n\t\t};\n\t},\n\n\t_createIcons: function() {\n\t\tvar icons = this.options.icons;\n\t\tif ( icons ) {\n\t\t\t$( \"<span>\" )\n\t\t\t\t.addClass( \"ui-accordion-header-icon ui-icon \" + icons.header )\n\t\t\t\t.prependTo( this.headers );\n\t\t\tthis.active.children( \".ui-accordion-header-icon\" )\n\t\t\t\t.removeClass( icons.header )\n\t\t\t\t.addClass( icons.activeHeader );\n\t\t\tthis.headers.addClass( \"ui-accordion-icons\" );\n\t\t}\n\t},\n\n\t_destroyIcons: function() {\n\t\tthis.headers\n\t\t\t.removeClass( \"ui-accordion-icons\" )\n\t\t\t.children( \".ui-accordion-header-icon\" )\n\t\t\t\t.remove();\n\t},\n\n\t_destroy: function() {\n\t\tvar contents;\n\n\t\t// clean up main element\n\t\tthis.element\n\t\t\t.removeClass( \"ui-accordion ui-widget ui-helper-reset\" )\n\t\t\t.removeAttr( \"role\" );\n\n\t\t// clean up headers\n\t\tthis.headers\n\t\t\t.removeClass( \"ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-selected\" )\n\t\t\t.removeAttr( \"aria-controls\" )\n\t\t\t.removeAttr( \"tabIndex\" )\n\t\t\t.each(function() {\n\t\t\t\tif ( /^ui-accordion/.test( this.id ) ) {\n\t\t\t\t\tthis.removeAttribute( \"id\" );\n\t\t\t\t}\n\t\t\t});\n\t\tthis._destroyIcons();\n\n\t\t// clean up content panels\n\t\tcontents = this.headers.next()\n\t\t\t.css( \"display\", \"\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-expanded\" )\n\t\t\t.removeAttr( \"aria-hidden\" )\n\t\t\t.removeAttr( \"aria-labelledby\" )\n\t\t\t.removeClass( \"ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled\" )\n\t\t\t.each(function() {\n\t\t\t\tif ( /^ui-accordion/.test( this.id ) ) {\n\t\t\t\t\tthis.removeAttribute( \"id\" );\n\t\t\t\t}\n\t\t\t});\n\t\tif ( this.options.heightStyle !== \"content\" ) {\n\t\t\tcontents.css( \"height\", \"\" );\n\t\t}\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"active\" ) {\n\t\t\t// _activate() will handle invalid values and update this.options\n\t\t\tthis._activate( value );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key === \"event\" ) {\n\t\t\tif ( this.options.event ) {\n\t\t\t\tthis._off( this.headers, this.options.event );\n\t\t\t}\n\t\t\tthis._setupEvents( value );\n\t\t}\n\n\t\tthis._super( key, value );\n\n\t\t// setting collapsible: false while collapsed; open first panel\n\t\tif ( key === \"collapsible\" && !value && this.options.active === false ) {\n\t\t\tthis._activate( 0 );\n\t\t}\n\n\t\tif ( key === \"icons\" ) {\n\t\t\tthis._destroyIcons();\n\t\t\tif ( value ) {\n\t\t\t\tthis._createIcons();\n\t\t\t}\n\t\t}\n\n\t\t// #5332 - opacity doesn't cascade to positioned elements in IE\n\t\t// so we need to add the disabled class to the headers and panels\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.headers.add( this.headers.next() )\n\t\t\t\t.toggleClass( \"ui-state-disabled\", !!value );\n\t\t}\n\t},\n\n\t_keydown: function( event ) {\n\t\t/*jshint maxcomplexity:15*/\n\t\tif ( event.altKey || event.ctrlKey ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar keyCode = $.ui.keyCode,\n\t\t\tlength = this.headers.length,\n\t\t\tcurrentIndex = this.headers.index( event.target ),\n\t\t\ttoFocus = false;\n\n\t\tswitch ( event.keyCode ) {\n\t\t\tcase keyCode.RIGHT:\n\t\t\tcase keyCode.DOWN:\n\t\t\t\ttoFocus = this.headers[ ( currentIndex + 1 ) % length ];\n\t\t\t\tbreak;\n\t\t\tcase keyCode.LEFT:\n\t\t\tcase keyCode.UP:\n\t\t\t\ttoFocus = this.headers[ ( currentIndex - 1 + length ) % length ];\n\t\t\t\tbreak;\n\t\t\tcase keyCode.SPACE:\n\t\t\tcase keyCode.ENTER:\n\t\t\t\tthis._eventHandler( event );\n\t\t\t\tbreak;\n\t\t\tcase keyCode.HOME:\n\t\t\t\ttoFocus = this.headers[ 0 ];\n\t\t\t\tbreak;\n\t\t\tcase keyCode.END:\n\t\t\t\ttoFocus = this.headers[ length - 1 ];\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif ( toFocus ) {\n\t\t\t$( event.target ).attr( \"tabIndex\", -1 );\n\t\t\t$( toFocus ).attr( \"tabIndex\", 0 );\n\t\t\ttoFocus.focus();\n\t\t\tevent.preventDefault();\n\t\t}\n\t},\n\n\t_panelKeyDown : function( event ) {\n\t\tif ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {\n\t\t\t$( event.currentTarget ).prev().focus();\n\t\t}\n\t},\n\n\trefresh: function() {\n\t\tvar options = this.options;\n\t\tthis._processPanels();\n\n\t\t// was collapsed or no panel\n\t\tif ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {\n\t\t\toptions.active = false;\n\t\t\tthis.active = $();\n\t\t// active false only when collapsible is true\n\t\t} else if ( options.active === false ) {\n\t\t\tthis._activate( 0 );\n\t\t// was active, but active panel is gone\n\t\t} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {\n\t\t\t// all remaining panel are disabled\n\t\t\tif ( this.headers.length === this.headers.find(\".ui-state-disabled\").length ) {\n\t\t\t\toptions.active = false;\n\t\t\t\tthis.active = $();\n\t\t\t// activate previous panel\n\t\t\t} else {\n\t\t\t\tthis._activate( Math.max( 0, options.active - 1 ) );\n\t\t\t}\n\t\t// was active, active panel still exists\n\t\t} else {\n\t\t\t// make sure active index is correct\n\t\t\toptions.active = this.headers.index( this.active );\n\t\t}\n\n\t\tthis._destroyIcons();\n\n\t\tthis._refresh();\n\t},\n\n\t_processPanels: function() {\n\t\tthis.headers = this.element.find( this.options.header )\n\t\t\t.addClass( \"ui-accordion-header ui-helper-reset ui-state-default ui-corner-all\" );\n\n\t\tthis.headers.next()\n\t\t\t.addClass( \"ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom\" )\n\t\t\t.filter(\":not(.ui-accordion-content-active)\")\n\t\t\t.hide();\n\t},\n\n\t_refresh: function() {\n\t\tvar maxHeight,\n\t\t\toptions = this.options,\n\t\t\theightStyle = options.heightStyle,\n\t\t\tparent = this.element.parent(),\n\t\t\taccordionId = this.accordionId = \"ui-accordion-\" +\n\t\t\t\t(this.element.attr( \"id\" ) || ++uid);\n\n\t\tthis.active = this._findActive( options.active )\n\t\t\t.addClass( \"ui-accordion-header-active ui-state-active ui-corner-top\" )\n\t\t\t.removeClass( \"ui-corner-all\" );\n\t\tthis.active.next()\n\t\t\t.addClass( \"ui-accordion-content-active\" )\n\t\t\t.show();\n\n\t\tthis.headers\n\t\t\t.attr( \"role\", \"tab\" )\n\t\t\t.each(function( i ) {\n\t\t\t\tvar header = $( this ),\n\t\t\t\t\theaderId = header.attr( \"id\" ),\n\t\t\t\t\tpanel = header.next(),\n\t\t\t\t\tpanelId = panel.attr( \"id\" );\n\t\t\t\tif ( !headerId ) {\n\t\t\t\t\theaderId = accordionId + \"-header-\" + i;\n\t\t\t\t\theader.attr( \"id\", headerId );\n\t\t\t\t}\n\t\t\t\tif ( !panelId ) {\n\t\t\t\t\tpanelId = accordionId + \"-panel-\" + i;\n\t\t\t\t\tpanel.attr( \"id\", panelId );\n\t\t\t\t}\n\t\t\t\theader.attr( \"aria-controls\", panelId );\n\t\t\t\tpanel.attr( \"aria-labelledby\", headerId );\n\t\t\t})\n\t\t\t.next()\n\t\t\t\t.attr( \"role\", \"tabpanel\" );\n\n\t\tthis.headers\n\t\t\t.not( this.active )\n\t\t\t.attr({\n\t\t\t\t\"aria-selected\": \"false\",\n\t\t\t\ttabIndex: -1\n\t\t\t})\n\t\t\t.next()\n\t\t\t\t.attr({\n\t\t\t\t\t\"aria-expanded\": \"false\",\n\t\t\t\t\t\"aria-hidden\": \"true\"\n\t\t\t\t})\n\t\t\t\t.hide();\n\n\t\t// make sure at least one header is in the tab order\n\t\tif ( !this.active.length ) {\n\t\t\tthis.headers.eq( 0 ).attr( \"tabIndex\", 0 );\n\t\t} else {\n\t\t\tthis.active.attr({\n\t\t\t\t\"aria-selected\": \"true\",\n\t\t\t\ttabIndex: 0\n\t\t\t})\n\t\t\t.next()\n\t\t\t\t.attr({\n\t\t\t\t\t\"aria-expanded\": \"true\",\n\t\t\t\t\t\"aria-hidden\": \"false\"\n\t\t\t\t});\n\t\t}\n\n\t\tthis._createIcons();\n\n\t\tthis._setupEvents( options.event );\n\n\t\tif ( heightStyle === \"fill\" ) {\n\t\t\tmaxHeight = parent.height();\n\t\t\tthis.element.siblings( \":visible\" ).each(function() {\n\t\t\t\tvar elem = $( this ),\n\t\t\t\t\tposition = elem.css( \"position\" );\n\n\t\t\t\tif ( position === \"absolute\" || position === \"fixed\" ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tmaxHeight -= elem.outerHeight( true );\n\t\t\t});\n\n\t\t\tthis.headers.each(function() {\n\t\t\t\tmaxHeight -= $( this ).outerHeight( true );\n\t\t\t});\n\n\t\t\tthis.headers.next()\n\t\t\t\t.each(function() {\n\t\t\t\t\t$( this ).height( Math.max( 0, maxHeight -\n\t\t\t\t\t\t$( this ).innerHeight() + $( this ).height() ) );\n\t\t\t\t})\n\t\t\t\t.css( \"overflow\", \"auto\" );\n\t\t} else if ( heightStyle === \"auto\" ) {\n\t\t\tmaxHeight = 0;\n\t\t\tthis.headers.next()\n\t\t\t\t.each(function() {\n\t\t\t\t\tmaxHeight = Math.max( maxHeight, $( this ).css( \"height\", \"\" ).height() );\n\t\t\t\t})\n\t\t\t\t.height( maxHeight );\n\t\t}\n\t},\n\n\t_activate: function( index ) {\n\t\tvar active = this._findActive( index )[ 0 ];\n\n\t\t// trying to activate the already active panel\n\t\tif ( active === this.active[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// trying to collapse, simulate a click on the currently active header\n\t\tactive = active || this.active[ 0 ];\n\n\t\tthis._eventHandler({\n\t\t\ttarget: active,\n\t\t\tcurrentTarget: active,\n\t\t\tpreventDefault: $.noop\n\t\t});\n\t},\n\n\t_findActive: function( selector ) {\n\t\treturn typeof selector === \"number\" ? this.headers.eq( selector ) : $();\n\t},\n\n\t_setupEvents: function( event ) {\n\t\tvar events = {\n\t\t\tkeydown: \"_keydown\"\n\t\t};\n\t\tif ( event ) {\n\t\t\t$.each( event.split(\" \"), function( index, eventName ) {\n\t\t\t\tevents[ eventName ] = \"_eventHandler\";\n\t\t\t});\n\t\t}\n\n\t\tthis._off( this.headers.add( this.headers.next() ) );\n\t\tthis._on( this.headers, events );\n\t\tthis._on( this.headers.next(), { keydown: \"_panelKeyDown\" });\n\t\tthis._hoverable( this.headers );\n\t\tthis._focusable( this.headers );\n\t},\n\n\t_eventHandler: function( event ) {\n\t\tvar options = this.options,\n\t\t\tactive = this.active,\n\t\t\tclicked = $( event.currentTarget ),\n\t\t\tclickedIsActive = clicked[ 0 ] === active[ 0 ],\n\t\t\tcollapsing = clickedIsActive && options.collapsible,\n\t\t\ttoShow = collapsing ? $() : clicked.next(),\n\t\t\ttoHide = active.next(),\n\t\t\teventData = {\n\t\t\t\toldHeader: active,\n\t\t\t\toldPanel: toHide,\n\t\t\t\tnewHeader: collapsing ? $() : clicked,\n\t\t\t\tnewPanel: toShow\n\t\t\t};\n\n\t\tevent.preventDefault();\n\n\t\tif (\n\t\t\t\t// click on active header, but not collapsible\n\t\t\t\t( clickedIsActive && !options.collapsible ) ||\n\t\t\t\t// allow canceling activation\n\t\t\t\t( this._trigger( \"beforeActivate\", event, eventData ) === false ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\toptions.active = collapsing ? false : this.headers.index( clicked );\n\n\t\t// when the call to ._toggle() comes after the class changes\n\t\t// it causes a very odd bug in IE 8 (see #6720)\n\t\tthis.active = clickedIsActive ? $() : clicked;\n\t\tthis._toggle( eventData );\n\n\t\t// switch classes\n\t\t// corner classes on the previously active header stay after the animation\n\t\tactive.removeClass( \"ui-accordion-header-active ui-state-active\" );\n\t\tif ( options.icons ) {\n\t\t\tactive.children( \".ui-accordion-header-icon\" )\n\t\t\t\t.removeClass( options.icons.activeHeader )\n\t\t\t\t.addClass( options.icons.header );\n\t\t}\n\n\t\tif ( !clickedIsActive ) {\n\t\t\tclicked\n\t\t\t\t.removeClass( \"ui-corner-all\" )\n\t\t\t\t.addClass( \"ui-accordion-header-active ui-state-active ui-corner-top\" );\n\t\t\tif ( options.icons ) {\n\t\t\t\tclicked.children( \".ui-accordion-header-icon\" )\n\t\t\t\t\t.removeClass( options.icons.header )\n\t\t\t\t\t.addClass( options.icons.activeHeader );\n\t\t\t}\n\n\t\t\tclicked\n\t\t\t\t.next()\n\t\t\t\t.addClass( \"ui-accordion-content-active\" );\n\t\t}\n\t},\n\n\t_toggle: function( data ) {\n\t\tvar toShow = data.newPanel,\n\t\t\ttoHide = this.prevShow.length ? this.prevShow : data.oldPanel;\n\n\t\t// handle activating a panel during the animation for another activation\n\t\tthis.prevShow.add( this.prevHide ).stop( true, true );\n\t\tthis.prevShow = toShow;\n\t\tthis.prevHide = toHide;\n\n\t\tif ( this.options.animate ) {\n\t\t\tthis._animate( toShow, toHide, data );\n\t\t} else {\n\t\t\ttoHide.hide();\n\t\t\ttoShow.show();\n\t\t\tthis._toggleComplete( data );\n\t\t}\n\n\t\ttoHide.attr({\n\t\t\t\"aria-expanded\": \"false\",\n\t\t\t\"aria-hidden\": \"true\"\n\t\t});\n\t\ttoHide.prev().attr( \"aria-selected\", \"false\" );\n\t\t// if we're switching panels, remove the old header from the tab order\n\t\t// if we're opening from collapsed state, remove the previous header from the tab order\n\t\t// if we're collapsing, then keep the collapsing header in the tab order\n\t\tif ( toShow.length && toHide.length ) {\n\t\t\ttoHide.prev().attr( \"tabIndex\", -1 );\n\t\t} else if ( toShow.length ) {\n\t\t\tthis.headers.filter(function() {\n\t\t\t\treturn $( this ).attr( \"tabIndex\" ) === 0;\n\t\t\t})\n\t\t\t.attr( \"tabIndex\", -1 );\n\t\t}\n\n\t\ttoShow\n\t\t\t.attr({\n\t\t\t\t\"aria-expanded\": \"true\",\n\t\t\t\t\"aria-hidden\": \"false\"\n\t\t\t})\n\t\t\t.prev()\n\t\t\t\t.attr({\n\t\t\t\t\t\"aria-selected\": \"true\",\n\t\t\t\t\ttabIndex: 0\n\t\t\t\t});\n\t},\n\n\t_animate: function( toShow, toHide, data ) {\n\t\tvar total, easing, duration,\n\t\t\tthat = this,\n\t\t\tadjust = 0,\n\t\t\tdown = toShow.length &&\n\t\t\t\t( !toHide.length || ( toShow.index() < toHide.index() ) ),\n\t\t\tanimate = this.options.animate || {},\n\t\t\toptions = down && animate.down || animate,\n\t\t\tcomplete = function() {\n\t\t\t\tthat._toggleComplete( data );\n\t\t\t};\n\n\t\tif ( typeof options === \"number\" ) {\n\t\t\tduration = options;\n\t\t}\n\t\tif ( typeof options === \"string\" ) {\n\t\t\teasing = options;\n\t\t}\n\t\t// fall back from options to animation in case of partial down settings\n\t\teasing = easing || options.easing || animate.easing;\n\t\tduration = duration || options.duration || animate.duration;\n\n\t\tif ( !toHide.length ) {\n\t\t\treturn toShow.animate( showProps, duration, easing, complete );\n\t\t}\n\t\tif ( !toShow.length ) {\n\t\t\treturn toHide.animate( hideProps, duration, easing, complete );\n\t\t}\n\n\t\ttotal = toShow.show().outerHeight();\n\t\ttoHide.animate( hideProps, {\n\t\t\tduration: duration,\n\t\t\teasing: easing,\n\t\t\tstep: function( now, fx ) {\n\t\t\t\tfx.now = Math.round( now );\n\t\t\t}\n\t\t});\n\t\ttoShow\n\t\t\t.hide()\n\t\t\t.animate( showProps, {\n\t\t\t\tduration: duration,\n\t\t\t\teasing: easing,\n\t\t\t\tcomplete: complete,\n\t\t\t\tstep: function( now, fx ) {\n\t\t\t\t\tfx.now = Math.round( now );\n\t\t\t\t\tif ( fx.prop !== \"height\" ) {\n\t\t\t\t\t\tadjust += fx.now;\n\t\t\t\t\t} else if ( that.options.heightStyle !== \"content\" ) {\n\t\t\t\t\t\tfx.now = Math.round( total - toHide.outerHeight() - adjust );\n\t\t\t\t\t\tadjust = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t},\n\n\t_toggleComplete: function( data ) {\n\t\tvar toHide = data.oldPanel;\n\n\t\ttoHide\n\t\t\t.removeClass( \"ui-accordion-content-active\" )\n\t\t\t.prev()\n\t\t\t\t.removeClass( \"ui-corner-top\" )\n\t\t\t\t.addClass( \"ui-corner-all\" );\n\n\t\t// Work around for rendering bug in IE (#5421)\n\t\tif ( toHide.length ) {\n\t\t\ttoHide.parent()[0].className = toHide.parent()[0].className;\n\t\t}\n\n\t\tthis._trigger( \"activate\", null, data );\n\t}\n});\n\n})( jQuery );\n\n(function( $, undefined ) {\n\n// used to prevent race conditions with remote data sources\nvar requestIndex = 0;\n\n$.widget( \"ui.autocomplete\", {\n\tversion: \"1.10.3\",\n\tdefaultElement: \"<input>\",\n\toptions: {\n\t\tappendTo: null,\n\t\tautoFocus: false,\n\t\tdelay: 300,\n\t\tminLength: 1,\n\t\tposition: {\n\t\t\tmy: \"left top\",\n\t\t\tat: \"left bottom\",\n\t\t\tcollision: \"none\"\n\t\t},\n\t\tsource: null,\n\n\t\t// callbacks\n\t\tchange: null,\n\t\tclose: null,\n\t\tfocus: null,\n\t\topen: null,\n\t\tresponse: null,\n\t\tsearch: null,\n\t\tselect: null\n\t},\n\n\tpending: 0,\n\n\t_create: function() {\n\t\t// Some browsers only repeat keydown events, not keypress events,\n\t\t// so we use the suppressKeyPress flag to determine if we've already\n\t\t// handled the keydown event. #7269\n\t\t// Unfortunately the code for & in keypress is the same as the up arrow,\n\t\t// so we use the suppressKeyPressRepeat flag to avoid handling keypress\n\t\t// events when we know the keydown event was used to modify the\n\t\t// search term. #7799\n\t\tvar suppressKeyPress, suppressKeyPressRepeat, suppressInput,\n\t\t\tnodeName = this.element[0].nodeName.toLowerCase(),\n\t\t\tisTextarea = nodeName === \"textarea\",\n\t\t\tisInput = nodeName === \"input\";\n\n\t\tthis.isMultiLine =\n\t\t\t// Textareas are always multi-line\n\t\t\tisTextarea ? true :\n\t\t\t// Inputs are always single-line, even if inside a contentEditable element\n\t\t\t// IE also treats inputs as contentEditable\n\t\t\tisInput ? false :\n\t\t\t// All other element types are determined by whether or not they're contentEditable\n\t\t\tthis.element.prop( \"isContentEditable\" );\n\n\t\tthis.valueMethod = this.element[ isTextarea || isInput ? \"val\" : \"text\" ];\n\t\tthis.isNewMenu = true;\n\n\t\tthis.element\n\t\t\t.addClass( \"ui-autocomplete-input\" )\n\t\t\t.attr( \"autocomplete\", \"off\" );\n\n\t\tthis._on( this.element, {\n\t\t\tkeydown: function( event ) {\n\t\t\t\t/*jshint maxcomplexity:15*/\n\t\t\t\tif ( this.element.prop( \"readOnly\" ) ) {\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tsuppressInput = true;\n\t\t\t\t\tsuppressKeyPressRepeat = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tsuppressKeyPress = false;\n\t\t\t\tsuppressInput = false;\n\t\t\t\tsuppressKeyPressRepeat = false;\n\t\t\t\tvar keyCode = $.ui.keyCode;\n\t\t\t\tswitch( event.keyCode ) {\n\t\t\t\tcase keyCode.PAGE_UP:\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tthis._move( \"previousPage\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.PAGE_DOWN:\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tthis._move( \"nextPage\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.UP:\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tthis._keyEvent( \"previous\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.DOWN:\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tthis._keyEvent( \"next\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.ENTER:\n\t\t\t\tcase keyCode.NUMPAD_ENTER:\n\t\t\t\t\t// when menu is open and has focus\n\t\t\t\t\tif ( this.menu.active ) {\n\t\t\t\t\t\t// #6055 - Opera still allows the keypress to occur\n\t\t\t\t\t\t// which causes forms to submit\n\t\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tthis.menu.select( event );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.TAB:\n\t\t\t\t\tif ( this.menu.active ) {\n\t\t\t\t\t\tthis.menu.select( event );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.ESCAPE:\n\t\t\t\t\tif ( this.menu.element.is( \":visible\" ) ) {\n\t\t\t\t\t\tthis._value( this.term );\n\t\t\t\t\t\tthis.close( event );\n\t\t\t\t\t\t// Different browsers have different default behavior for escape\n\t\t\t\t\t\t// Single press can mean undo or clear\n\t\t\t\t\t\t// Double press in IE means clear the whole form\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tsuppressKeyPressRepeat = true;\n\t\t\t\t\t// search timeout should be triggered before the input value is changed\n\t\t\t\t\tthis._searchTimeout( event );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t},\n\t\t\tkeypress: function( event ) {\n\t\t\t\tif ( suppressKeyPress ) {\n\t\t\t\t\tsuppressKeyPress = false;\n\t\t\t\t\tif ( !this.isMultiLine || this.menu.element.is( \":visible\" ) ) {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif ( suppressKeyPressRepeat ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// replicate some key handlers to allow them to repeat in Firefox and Opera\n\t\t\t\tvar keyCode = $.ui.keyCode;\n\t\t\t\tswitch( event.keyCode ) {\n\t\t\t\tcase keyCode.PAGE_UP:\n\t\t\t\t\tthis._move( \"previousPage\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.PAGE_DOWN:\n\t\t\t\t\tthis._move( \"nextPage\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.UP:\n\t\t\t\t\tthis._keyEvent( \"previous\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.DOWN:\n\t\t\t\t\tthis._keyEvent( \"next\", event );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t},\n\t\t\tinput: function( event ) {\n\t\t\t\tif ( suppressInput ) {\n\t\t\t\t\tsuppressInput = false;\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis._searchTimeout( event );\n\t\t\t},\n\t\t\tfocus: function() {\n\t\t\t\tthis.selectedItem = null;\n\t\t\t\tthis.previous = this._value();\n\t\t\t},\n\t\t\tblur: function( event ) {\n\t\t\t\tif ( this.cancelBlur ) {\n\t\t\t\t\tdelete this.cancelBlur;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tclearTimeout( this.searching );\n\t\t\t\tthis.close( event );\n\t\t\t\tthis._change( event );\n\t\t\t}\n\t\t});\n\n\t\tthis._initSource();\n\t\tthis.menu = $( \"<ul>\" )\n\t\t\t.addClass( \"ui-autocomplete ui-front\" )\n\t\t\t.appendTo( this._appendTo() )\n\t\t\t.menu({\n\t\t\t\t// disable ARIA support, the live region takes care of that\n\t\t\t\trole: null\n\t\t\t})\n\t\t\t.hide()\n\t\t\t.data( \"ui-menu\" );\n\n\t\tthis._on( this.menu.element, {\n\t\t\tmousedown: function( event ) {\n\t\t\t\t// prevent moving focus out of the text field\n\t\t\t\tevent.preventDefault();\n\n\t\t\t\t// IE doesn't prevent moving focus even with event.preventDefault()\n\t\t\t\t// so we set a flag to know when we should ignore the blur event\n\t\t\t\tthis.cancelBlur = true;\n\t\t\t\tthis._delay(function() {\n\t\t\t\t\tdelete this.cancelBlur;\n\t\t\t\t});\n\n\t\t\t\t// clicking on the scrollbar causes focus to shift to the body\n\t\t\t\t// but we can't detect a mouseup or a click immediately afterward\n\t\t\t\t// so we have to track the next mousedown and close the menu if\n\t\t\t\t// the user clicks somewhere outside of the autocomplete\n\t\t\t\tvar menuElement = this.menu.element[ 0 ];\n\t\t\t\tif ( !$( event.target ).closest( \".ui-menu-item\" ).length ) {\n\t\t\t\t\tthis._delay(function() {\n\t\t\t\t\t\tvar that = this;\n\t\t\t\t\t\tthis.document.one( \"mousedown\", function( event ) {\n\t\t\t\t\t\t\tif ( event.target !== that.element[ 0 ] &&\n\t\t\t\t\t\t\t\t\tevent.target !== menuElement &&\n\t\t\t\t\t\t\t\t\t!$.contains( menuElement, event.target ) ) {\n\t\t\t\t\t\t\t\tthat.close();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t},\n\t\t\tmenufocus: function( event, ui ) {\n\t\t\t\t// support: Firefox\n\t\t\t\t// Prevent accidental activation of menu items in Firefox (#7024 #9118)\n\t\t\t\tif ( this.isNewMenu ) {\n\t\t\t\t\tthis.isNewMenu = false;\n\t\t\t\t\tif ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {\n\t\t\t\t\t\tthis.menu.blur();\n\n\t\t\t\t\t\tthis.document.one( \"mousemove\", function() {\n\t\t\t\t\t\t\t$( event.target ).trigger( event.originalEvent );\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar item = ui.item.data( \"ui-autocomplete-item\" );\n\t\t\t\tif ( false !== this._trigger( \"focus\", event, { item: item } ) ) {\n\t\t\t\t\t// use value to match what will end up in the input, if it was a key event\n\t\t\t\t\tif ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {\n\t\t\t\t\t\tthis._value( item.value );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Normally the input is populated with the item's value as the\n\t\t\t\t\t// menu is navigated, causing screen readers to notice a change and\n\t\t\t\t\t// announce the item. Since the focus event was canceled, this doesn't\n\t\t\t\t\t// happen, so we update the live region so that screen readers can\n\t\t\t\t\t// still notice the change and announce it.\n\t\t\t\t\tthis.liveRegion.text( item.value );\n\t\t\t\t}\n\t\t\t},\n\t\t\tmenuselect: function( event, ui ) {\n\t\t\t\tvar item = ui.item.data( \"ui-autocomplete-item\" ),\n\t\t\t\t\tprevious = this.previous;\n\n\t\t\t\t// only trigger when focus was lost (click on menu)\n\t\t\t\tif ( this.element[0] !== this.document[0].activeElement ) {\n\t\t\t\t\tthis.element.focus();\n\t\t\t\t\tthis.previous = previous;\n\t\t\t\t\t// #6109 - IE triggers two focus events and the second\n\t\t\t\t\t// is asynchronous, so we need to reset the previous\n\t\t\t\t\t// term synchronously and asynchronously :-(\n\t\t\t\t\tthis._delay(function() {\n\t\t\t\t\t\tthis.previous = previous;\n\t\t\t\t\t\tthis.selectedItem = item;\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif ( false !== this._trigger( \"select\", event, { item: item } ) ) {\n\t\t\t\t\tthis._value( item.value );\n\t\t\t\t}\n\t\t\t\t// reset the term after the select event\n\t\t\t\t// this allows custom select handling to work properly\n\t\t\t\tthis.term = this._value();\n\n\t\t\t\tthis.close( event );\n\t\t\t\tthis.selectedItem = item;\n\t\t\t}\n\t\t});\n\n\t\tthis.liveRegion = $( \"<span>\", {\n\t\t\t\trole: \"status\",\n\t\t\t\t\"aria-live\": \"polite\"\n\t\t\t})\n\t\t\t.addClass( \"ui-helper-hidden-accessible\" )\n\t\t\t.insertBefore( this.element );\n\n\t\t// turning off autocomplete prevents the browser from remembering the\n\t\t// value when navigating through history, so we re-enable autocomplete\n\t\t// if the page is unloaded before the widget is destroyed. #7790\n\t\tthis._on( this.window, {\n\t\t\tbeforeunload: function() {\n\t\t\t\tthis.element.removeAttr( \"autocomplete\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_destroy: function() {\n\t\tclearTimeout( this.searching );\n\t\tthis.element\n\t\t\t.removeClass( \"ui-autocomplete-input\" )\n\t\t\t.removeAttr( \"autocomplete\" );\n\t\tthis.menu.element.remove();\n\t\tthis.liveRegion.remove();\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tthis._super( key, value );\n\t\tif ( key === \"source\" ) {\n\t\t\tthis._initSource();\n\t\t}\n\t\tif ( key === \"appendTo\" ) {\n\t\t\tthis.menu.element.appendTo( this._appendTo() );\n\t\t}\n\t\tif ( key === \"disabled\" && value && this.xhr ) {\n\t\t\tthis.xhr.abort();\n\t\t}\n\t},\n\n\t_appendTo: function() {\n\t\tvar element = this.options.appendTo;\n\n\t\tif ( element ) {\n\t\t\telement = element.jquery || element.nodeType ?\n\t\t\t\t$( element ) :\n\t\t\t\tthis.document.find( element ).eq( 0 );\n\t\t}\n\n\t\tif ( !element ) {\n\t\t\telement = this.element.closest( \".ui-front\" );\n\t\t}\n\n\t\tif ( !element.length ) {\n\t\t\telement = this.document[0].body;\n\t\t}\n\n\t\treturn element;\n\t},\n\n\t_initSource: function() {\n\t\tvar array, url,\n\t\t\tthat = this;\n\t\tif ( $.isArray(this.options.source) ) {\n\t\t\tarray = this.options.source;\n\t\t\tthis.source = function( request, response ) {\n\t\t\t\tresponse( $.ui.autocomplete.filter( array, request.term ) );\n\t\t\t};\n\t\t} else if ( typeof this.options.source === \"string\" ) {\n\t\t\turl = this.options.source;\n\t\t\tthis.source = function( request, response ) {\n\t\t\t\tif ( that.xhr ) {\n\t\t\t\t\tthat.xhr.abort();\n\t\t\t\t}\n\t\t\t\tthat.xhr = $.ajax({\n\t\t\t\t\turl: url,\n\t\t\t\t\tdata: request,\n\t\t\t\t\tdataType: \"json\",\n\t\t\t\t\tsuccess: function( data ) {\n\t\t\t\t\t\tresponse( data );\n\t\t\t\t\t},\n\t\t\t\t\terror: function() {\n\t\t\t\t\t\tresponse( [] );\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t};\n\t\t} else {\n\t\t\tthis.source = this.options.source;\n\t\t}\n\t},\n\n\t_searchTimeout: function( event ) {\n\t\tclearTimeout( this.searching );\n\t\tthis.searching = this._delay(function() {\n\t\t\t// only search if the value has changed\n\t\t\tif ( this.term !== this._value() ) {\n\t\t\t\tthis.selectedItem = null;\n\t\t\t\tthis.search( null, event );\n\t\t\t}\n\t\t}, this.options.delay );\n\t},\n\n\tsearch: function( value, event ) {\n\t\tvalue = value != null ? value : this._value();\n\n\t\t// always save the actual value, not the one passed as an argument\n\t\tthis.term = this._value();\n\n\t\tif ( value.length < this.options.minLength ) {\n\t\t\treturn this.close( event );\n\t\t}\n\n\t\tif ( this._trigger( \"search\", event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn this._search( value );\n\t},\n\n\t_search: function( value ) {\n\t\tthis.pending++;\n\t\tthis.element.addClass( \"ui-autocomplete-loading\" );\n\t\tthis.cancelSearch = false;\n\n\t\tthis.source( { term: value }, this._response() );\n\t},\n\n\t_response: function() {\n\t\tvar that = this,\n\t\t\tindex = ++requestIndex;\n\n\t\treturn function( content ) {\n\t\t\tif ( index === requestIndex ) {\n\t\t\t\tthat.__response( content );\n\t\t\t}\n\n\t\t\tthat.pending--;\n\t\t\tif ( !that.pending ) {\n\t\t\t\tthat.element.removeClass( \"ui-autocomplete-loading\" );\n\t\t\t}\n\t\t};\n\t},\n\n\t__response: function( content ) {\n\t\tif ( content ) {\n\t\t\tcontent = this._normalize( content );\n\t\t}\n\t\tthis._trigger( \"response\", null, { content: content } );\n\t\tif ( !this.options.disabled && content && content.length && !this.cancelSearch ) {\n\t\t\tthis._suggest( content );\n\t\t\tthis._trigger( \"open\" );\n\t\t} else {\n\t\t\t// use ._close() instead of .close() so we don't cancel future searches\n\t\t\tthis._close();\n\t\t}\n\t},\n\n\tclose: function( event ) {\n\t\tthis.cancelSearch = true;\n\t\tthis._close( event );\n\t},\n\n\t_close: function( event ) {\n\t\tif ( this.menu.element.is( \":visible\" ) ) {\n\t\t\tthis.menu.element.hide();\n\t\t\tthis.menu.blur();\n\t\t\tthis.isNewMenu = true;\n\t\t\tthis._trigger( \"close\", event );\n\t\t}\n\t},\n\n\t_change: function( event ) {\n\t\tif ( this.previous !== this._value() ) {\n\t\t\tthis._trigger( \"change\", event, { item: this.selectedItem } );\n\t\t}\n\t},\n\n\t_normalize: function( items ) {\n\t\t// assume all items have the right format when the first item is complete\n\t\tif ( items.length && items[0].label && items[0].value ) {\n\t\t\treturn items;\n\t\t}\n\t\treturn $.map( items, function( item ) {\n\t\t\tif ( typeof item === \"string\" ) {\n\t\t\t\treturn {\n\t\t\t\t\tlabel: item,\n\t\t\t\t\tvalue: item\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn $.extend({\n\t\t\t\tlabel: item.label || item.value,\n\t\t\t\tvalue: item.value || item.label\n\t\t\t}, item );\n\t\t});\n\t},\n\n\t_suggest: function( items ) {\n\t\tvar ul = this.menu.element.empty();\n\t\tthis._renderMenu( ul, items );\n\t\tthis.isNewMenu = true;\n\t\tthis.menu.refresh();\n\n\t\t// size and position menu\n\t\tul.show();\n\t\tthis._resizeMenu();\n\t\tul.position( $.extend({\n\t\t\tof: this.element\n\t\t}, this.options.position ));\n\n\t\tif ( this.options.autoFocus ) {\n\t\t\tthis.menu.next();\n\t\t}\n\t},\n\n\t_resizeMenu: function() {\n\t\tvar ul = this.menu.element;\n\t\tul.outerWidth( Math.max(\n\t\t\t// Firefox wraps long text (possibly a rounding bug)\n\t\t\t// so we add 1px to avoid the wrapping (#7513)\n\t\t\tul.width( \"\" ).outerWidth() + 1,\n\t\t\tthis.element.outerWidth()\n\t\t) );\n\t},\n\n\t_renderMenu: function( ul, items ) {\n\t\tvar that = this;\n\t\t$.each( items, function( index, item ) {\n\t\t\tthat._renderItemData( ul, item );\n\t\t});\n\t},\n\n\t_renderItemData: function( ul, item ) {\n\t\treturn this._renderItem( ul, item ).data( \"ui-autocomplete-item\", item );\n\t},\n\n\t_renderItem: function( ul, item ) {\n\t\treturn $( \"<li>\" )\n\t\t\t.append( $( \"<a>\" ).text( item.label ) )\n\t\t\t.appendTo( ul );\n\t},\n\n\t_move: function( direction, event ) {\n\t\tif ( !this.menu.element.is( \":visible\" ) ) {\n\t\t\tthis.search( null, event );\n\t\t\treturn;\n\t\t}\n\t\tif ( this.menu.isFirstItem() && /^previous/.test( direction ) ||\n\t\t\t\tthis.menu.isLastItem() && /^next/.test( direction ) ) {\n\t\t\tthis._value( this.term );\n\t\t\tthis.menu.blur();\n\t\t\treturn;\n\t\t}\n\t\tthis.menu[ direction ]( event );\n\t},\n\n\twidget: function() {\n\t\treturn this.menu.element;\n\t},\n\n\t_value: function() {\n\t\treturn this.valueMethod.apply( this.element, arguments );\n\t},\n\n\t_keyEvent: function( keyEvent, event ) {\n\t\tif ( !this.isMultiLine || this.menu.element.is( \":visible\" ) ) {\n\t\t\tthis._move( keyEvent, event );\n\n\t\t\t// prevents moving cursor to beginning/end of the text field in some browsers\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n});\n\n$.extend( $.ui.autocomplete, {\n\tescapeRegex: function( value ) {\n\t\treturn value.replace(/[\\-\\[\\]{}()*+?.,\\\\\\^$|#\\s]/g, \"\\\\$&\");\n\t},\n\tfilter: function(array, term) {\n\t\tvar matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), \"i\" );\n\t\treturn $.grep( array, function(value) {\n\t\t\treturn matcher.test( value.label || value.value || value );\n\t\t});\n\t}\n});\n\n\n// live region extension, adding a `messages` option\n// NOTE: This is an experimental API. We are still investigating\n// a full solution for string manipulation and internationalization.\n$.widget( \"ui.autocomplete\", $.ui.autocomplete, {\n\toptions: {\n\t\tmessages: {\n\t\t\tnoResults: \"No search results.\",\n\t\t\tresults: function( amount ) {\n\t\t\t\treturn amount + ( amount > 1 ? \" results are\" : \" result is\" ) +\n\t\t\t\t\t\" available, use up and down arrow keys to navigate.\";\n\t\t\t}\n\t\t}\n\t},\n\n\t__response: function( content ) {\n\t\tvar message;\n\t\tthis._superApply( arguments );\n\t\tif ( this.options.disabled || this.cancelSearch ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( content && content.length ) {\n\t\t\tmessage = this.options.messages.results( content.length );\n\t\t} else {\n\t\t\tmessage = this.options.messages.noResults;\n\t\t}\n\t\tthis.liveRegion.text( message );\n\t}\n});\n\n}( jQuery ));\n\n(function( $, undefined ) {\n\nvar lastActive, startXPos, startYPos, clickDragged,\n\tbaseClasses = \"ui-button ui-widget ui-state-default ui-corner-all\",\n\tstateClasses = \"ui-state-hover ui-state-active \",\n\ttypeClasses = \"ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only\",\n\tformResetHandler = function() {\n\t\tvar form = $( this );\n\t\tsetTimeout(function() {\n\t\t\tform.find( \":ui-button\" ).button( \"refresh\" );\n\t\t}, 1 );\n\t},\n\tradioGroup = function( radio ) {\n\t\tvar name = radio.name,\n\t\t\tform = radio.form,\n\t\t\tradios = $( [] );\n\t\tif ( name ) {\n\t\t\tname = name.replace( /'/g, \"\\\\'\" );\n\t\t\tif ( form ) {\n\t\t\t\tradios = $( form ).find( \"[name='\" + name + \"']\" );\n\t\t\t} else {\n\t\t\t\tradios = $( \"[name='\" + name + \"']\", radio.ownerDocument )\n\t\t\t\t\t.filter(function() {\n\t\t\t\t\t\treturn !this.form;\n\t\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn radios;\n\t};\n\n$.widget( \"ui.button\", {\n\tversion: \"1.10.3\",\n\tdefaultElement: \"<button>\",\n\toptions: {\n\t\tdisabled: null,\n\t\ttext: true,\n\t\tlabel: null,\n\t\ticons: {\n\t\t\tprimary: null,\n\t\t\tsecondary: null\n\t\t}\n\t},\n\t_create: function() {\n\t\tthis.element.closest( \"form\" )\n\t\t\t.unbind( \"reset\" + this.eventNamespace )\n\t\t\t.bind( \"reset\" + this.eventNamespace, formResetHandler );\n\n\t\tif ( typeof this.options.disabled !== \"boolean\" ) {\n\t\t\tthis.options.disabled = !!this.element.prop( \"disabled\" );\n\t\t} else {\n\t\t\tthis.element.prop( \"disabled\", this.options.disabled );\n\t\t}\n\n\t\tthis._determineButtonType();\n\t\tthis.hasTitle = !!this.buttonElement.attr( \"title\" );\n\n\t\tvar that = this,\n\t\t\toptions = this.options,\n\t\t\ttoggleButton = this.type === \"checkbox\" || this.type === \"radio\",\n\t\t\tactiveClass = !toggleButton ? \"ui-state-active\" : \"\",\n\t\t\tfocusClass = \"ui-state-focus\";\n\n\t\tif ( options.label === null ) {\n\t\t\toptions.label = (this.type === \"input\" ? this.buttonElement.val() : this.buttonElement.html());\n\t\t}\n\n\t\tthis._hoverable( this.buttonElement );\n\n\t\tthis.buttonElement\n\t\t\t.addClass( baseClasses )\n\t\t\t.attr( \"role\", \"button\" )\n\t\t\t.bind( \"mouseenter\" + this.eventNamespace, function() {\n\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif ( this === lastActive ) {\n\t\t\t\t\t$( this ).addClass( \"ui-state-active\" );\n\t\t\t\t}\n\t\t\t})\n\t\t\t.bind( \"mouseleave\" + this.eventNamespace, function() {\n\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t$( this ).removeClass( activeClass );\n\t\t\t})\n\t\t\t.bind( \"click\" + this.eventNamespace, function( event ) {\n\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t}\n\t\t\t});\n\n\t\tthis.element\n\t\t\t.bind( \"focus\" + this.eventNamespace, function() {\n\t\t\t\t// no need to check disabled, focus won't be triggered anyway\n\t\t\t\tthat.buttonElement.addClass( focusClass );\n\t\t\t})\n\t\t\t.bind( \"blur\" + this.eventNamespace, function() {\n\t\t\t\tthat.buttonElement.removeClass( focusClass );\n\t\t\t});\n\n\t\tif ( toggleButton ) {\n\t\t\tthis.element.bind( \"change\" + this.eventNamespace, function() {\n\t\t\t\tif ( clickDragged ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthat.refresh();\n\t\t\t});\n\t\t\t// if mouse moves between mousedown and mouseup (drag) set clickDragged flag\n\t\t\t// prevents issue where button state changes but checkbox/radio checked state\n\t\t\t// does not in Firefox (see ticket #6970)\n\t\t\tthis.buttonElement\n\t\t\t\t.bind( \"mousedown\" + this.eventNamespace, function( event ) {\n\t\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tclickDragged = false;\n\t\t\t\t\tstartXPos = event.pageX;\n\t\t\t\t\tstartYPos = event.pageY;\n\t\t\t\t})\n\t\t\t\t.bind( \"mouseup\" + this.eventNamespace, function( event ) {\n\t\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif ( startXPos !== event.pageX || startYPos !== event.pageY ) {\n\t\t\t\t\t\tclickDragged = true;\n\t\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tif ( this.type === \"checkbox\" ) {\n\t\t\tthis.buttonElement.bind( \"click\" + this.eventNamespace, function() {\n\t\t\t\tif ( options.disabled || clickDragged ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\t\t} else if ( this.type === \"radio\" ) {\n\t\t\tthis.buttonElement.bind( \"click\" + this.eventNamespace, function() {\n\t\t\t\tif ( options.disabled || clickDragged ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t$( this ).addClass( \"ui-state-active\" );\n\t\t\t\tthat.buttonElement.attr( \"aria-pressed\", \"true\" );\n\n\t\t\t\tvar radio = that.element[ 0 ];\n\t\t\t\tradioGroup( radio )\n\t\t\t\t\t.not( radio )\n\t\t\t\t\t.map(function() {\n\t\t\t\t\t\treturn $( this ).button( \"widget\" )[ 0 ];\n\t\t\t\t\t})\n\t\t\t\t\t.removeClass( \"ui-state-active\" )\n\t\t\t\t\t.attr( \"aria-pressed\", \"false\" );\n\t\t\t});\n\t\t} else {\n\t\t\tthis.buttonElement\n\t\t\t\t.bind( \"mousedown\" + this.eventNamespace, function() {\n\t\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\t$( this ).addClass( \"ui-state-active\" );\n\t\t\t\t\tlastActive = this;\n\t\t\t\t\tthat.document.one( \"mouseup\", function() {\n\t\t\t\t\t\tlastActive = null;\n\t\t\t\t\t});\n\t\t\t\t})\n\t\t\t\t.bind( \"mouseup\" + this.eventNamespace, function() {\n\t\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\t$( this ).removeClass( \"ui-state-active\" );\n\t\t\t\t})\n\t\t\t\t.bind( \"keydown\" + this.eventNamespace, function(event) {\n\t\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {\n\t\t\t\t\t\t$( this ).addClass( \"ui-state-active\" );\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t// see #8559, we bind to blur here in case the button element loses\n\t\t\t\t// focus between keydown and keyup, it would be left in an \"active\" state\n\t\t\t\t.bind( \"keyup\" + this.eventNamespace + \" blur\" + this.eventNamespace, function() {\n\t\t\t\t\t$( this ).removeClass( \"ui-state-active\" );\n\t\t\t\t});\n\n\t\t\tif ( this.buttonElement.is(\"a\") ) {\n\t\t\t\tthis.buttonElement.keyup(function(event) {\n\t\t\t\t\tif ( event.keyCode === $.ui.keyCode.SPACE ) {\n\t\t\t\t\t\t// TODO pass through original event correctly (just as 2nd argument doesn't work)\n\t\t\t\t\t\t$( this ).click();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// TODO: pull out $.Widget's handling for the disabled option into\n\t\t// $.Widget.prototype._setOptionDisabled so it's easy to proxy and can\n\t\t// be overridden by individual plugins\n\t\tthis._setOption( \"disabled\", options.disabled );\n\t\tthis._resetButton();\n\t},\n\n\t_determineButtonType: function() {\n\t\tvar ancestor, labelSelector, checked;\n\n\t\tif ( this.element.is(\"[type=checkbox]\") ) {\n\t\t\tthis.type = \"checkbox\";\n\t\t} else if ( this.element.is(\"[type=radio]\") ) {\n\t\t\tthis.type = \"radio\";\n\t\t} else if ( this.element.is(\"input\") ) {\n\t\t\tthis.type = \"input\";\n\t\t} else {\n\t\t\tthis.type = \"button\";\n\t\t}\n\n\t\tif ( this.type === \"checkbox\" || this.type === \"radio\" ) {\n\t\t\t// we don't search against the document in case the element\n\t\t\t// is disconnected from the DOM\n\t\t\tancestor = this.element.parents().last();\n\t\t\tlabelSelector = \"label[for='\" + this.element.attr(\"id\") + \"']\";\n\t\t\tthis.buttonElement = ancestor.find( labelSelector );\n\t\t\tif ( !this.buttonElement.length ) {\n\t\t\t\tancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();\n\t\t\t\tthis.buttonElement = ancestor.filter( labelSelector );\n\t\t\t\tif ( !this.buttonElement.length ) {\n\t\t\t\t\tthis.buttonElement = ancestor.find( labelSelector );\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.element.addClass( \"ui-helper-hidden-accessible\" );\n\n\t\t\tchecked = this.element.is( \":checked\" );\n\t\t\tif ( checked ) {\n\t\t\t\tthis.buttonElement.addClass( \"ui-state-active\" );\n\t\t\t}\n\t\t\tthis.buttonElement.prop( \"aria-pressed\", checked );\n\t\t} else {\n\t\t\tthis.buttonElement = this.element;\n\t\t}\n\t},\n\n\twidget: function() {\n\t\treturn this.buttonElement;\n\t},\n\n\t_destroy: function() {\n\t\tthis.element\n\t\t\t.removeClass( \"ui-helper-hidden-accessible\" );\n\t\tthis.buttonElement\n\t\t\t.removeClass( baseClasses + \" \" + stateClasses + \" \" + typeClasses )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-pressed\" )\n\t\t\t.html( this.buttonElement.find(\".ui-button-text\").html() );\n\n\t\tif ( !this.hasTitle ) {\n\t\t\tthis.buttonElement.removeAttr( \"title\" );\n\t\t}\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tthis._super( key, value );\n\t\tif ( key === \"disabled\" ) {\n\t\t\tif ( value ) {\n\t\t\t\tthis.element.prop( \"disabled\", true );\n\t\t\t} else {\n\t\t\t\tthis.element.prop( \"disabled\", false );\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tthis._resetButton();\n\t},\n\n\trefresh: function() {\n\t\t//See #8237 & #8828\n\t\tvar isDisabled = this.element.is( \"input, button\" ) ? this.element.is( \":disabled\" ) : this.element.hasClass( \"ui-button-disabled\" );\n\n\t\tif ( isDisabled !== this.options.disabled ) {\n\t\t\tthis._setOption( \"disabled\", isDisabled );\n\t\t}\n\t\tif ( this.type === \"radio\" ) {\n\t\t\tradioGroup( this.element[0] ).each(function() {\n\t\t\t\tif ( $( this ).is( \":checked\" ) ) {\n\t\t\t\t\t$( this ).button( \"widget\" )\n\t\t\t\t\t\t.addClass( \"ui-state-active\" )\n\t\t\t\t\t\t.attr( \"aria-pressed\", \"true\" );\n\t\t\t\t} else {\n\t\t\t\t\t$( this ).button( \"widget\" )\n\t\t\t\t\t\t.removeClass( \"ui-state-active\" )\n\t\t\t\t\t\t.attr( \"aria-pressed\", \"false\" );\n\t\t\t\t}\n\t\t\t});\n\t\t} else if ( this.type === \"checkbox\" ) {\n\t\t\tif ( this.element.is( \":checked\" ) ) {\n\t\t\t\tthis.buttonElement\n\t\t\t\t\t.addClass( \"ui-state-active\" )\n\t\t\t\t\t.attr( \"aria-pressed\", \"true\" );\n\t\t\t} else {\n\t\t\t\tthis.buttonElement\n\t\t\t\t\t.removeClass( \"ui-state-active\" )\n\t\t\t\t\t.attr( \"aria-pressed\", \"false\" );\n\t\t\t}\n\t\t}\n\t},\n\n\t_resetButton: function() {\n\t\tif ( this.type === \"input\" ) {\n\t\t\tif ( this.options.label ) {\n\t\t\t\tthis.element.val( this.options.label );\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tvar buttonElement = this.buttonElement.removeClass( typeClasses ),\n\t\t\tbuttonText = $( \"<span></span>\", this.document[0] )\n\t\t\t\t.addClass( \"ui-button-text\" )\n\t\t\t\t.html( this.options.label )\n\t\t\t\t.appendTo( buttonElement.empty() )\n\t\t\t\t.text(),\n\t\t\ticons = this.options.icons,\n\t\t\tmultipleIcons = icons.primary && icons.secondary,\n\t\t\tbuttonClasses = [];\n\n\t\tif ( icons.primary || icons.secondary ) {\n\t\t\tif ( this.options.text ) {\n\t\t\t\tbuttonClasses.push( \"ui-button-text-icon\" + ( multipleIcons ? \"s\" : ( icons.primary ? \"-primary\" : \"-secondary\" ) ) );\n\t\t\t}\n\n\t\t\tif ( icons.primary ) {\n\t\t\t\tbuttonElement.prepend( \"<span class='ui-button-icon-primary ui-icon \" + icons.primary + \"'></span>\" );\n\t\t\t}\n\n\t\t\tif ( icons.secondary ) {\n\t\t\t\tbuttonElement.append( \"<span class='ui-button-icon-secondary ui-icon \" + icons.secondary + \"'></span>\" );\n\t\t\t}\n\n\t\t\tif ( !this.options.text ) {\n\t\t\t\tbuttonClasses.push( multipleIcons ? \"ui-button-icons-only\" : \"ui-button-icon-only\" );\n\n\t\t\t\tif ( !this.hasTitle ) {\n\t\t\t\t\tbuttonElement.attr( \"title\", $.trim( buttonText ) );\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tbuttonClasses.push( \"ui-button-text-only\" );\n\t\t}\n\t\tbuttonElement.addClass( buttonClasses.join( \" \" ) );\n\t}\n});\n\n$.widget( \"ui.buttonset\", {\n\tversion: \"1.10.3\",\n\toptions: {\n\t\titems: \"button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)\"\n\t},\n\n\t_create: function() {\n\t\tthis.element.addClass( \"ui-buttonset\" );\n\t},\n\n\t_init: function() {\n\t\tthis.refresh();\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.buttons.button( \"option\", key, value );\n\t\t}\n\n\t\tthis._super( key, value );\n\t},\n\n\trefresh: function() {\n\t\tvar rtl = this.element.css( \"direction\" ) === \"rtl\";\n\n\t\tthis.buttons = this.element.find( this.options.items )\n\t\t\t.filter( \":ui-button\" )\n\t\t\t\t.button( \"refresh\" )\n\t\t\t.end()\n\t\t\t.not( \":ui-button\" )\n\t\t\t\t.button()\n\t\t\t.end()\n\t\t\t.map(function() {\n\t\t\t\treturn $( this ).button( \"widget\" )[ 0 ];\n\t\t\t})\n\t\t\t\t.removeClass( \"ui-corner-all ui-corner-left ui-corner-right\" )\n\t\t\t\t.filter( \":first\" )\n\t\t\t\t\t.addClass( rtl ? \"ui-corner-right\" : \"ui-corner-left\" )\n\t\t\t\t.end()\n\t\t\t\t.filter( \":last\" )\n\t\t\t\t\t.addClass( rtl ? \"ui-corner-left\" : \"ui-corner-right\" )\n\t\t\t\t.end()\n\t\t\t.end();\n\t},\n\n\t_destroy: function() {\n\t\tthis.element.removeClass( \"ui-buttonset\" );\n\t\tthis.buttons\n\t\t\t.map(function() {\n\t\t\t\treturn $( this ).button( \"widget\" )[ 0 ];\n\t\t\t})\n\t\t\t\t.removeClass( \"ui-corner-left ui-corner-right\" )\n\t\t\t.end()\n\t\t\t.button( \"destroy\" );\n\t}\n});\n\n}( jQuery ) );\n\n(function( $, undefined ) {\n\n$.extend($.ui, { datepicker: { version: \"1.10.3\" } });\n\nvar PROP_NAME = \"datepicker\",\n\tinstActive;\n\n/* Date picker manager.\n   Use the singleton instance of this class, $.datepicker, to interact with the date picker.\n   Settings for (groups of) date pickers are maintained in an instance object,\n   allowing multiple different settings on the same page. */\n\nfunction Datepicker() {\n\tthis._curInst = null; // The current instance in use\n\tthis._keyEvent = false; // If the last event was a key event\n\tthis._disabledInputs = []; // List of date picker inputs that have been disabled\n\tthis._datepickerShowing = false; // True if the popup picker is showing , false if not\n\tthis._inDialog = false; // True if showing within a \"dialog\", false if not\n\tthis._mainDivId = \"ui-datepicker-div\"; // The ID of the main datepicker division\n\tthis._inlineClass = \"ui-datepicker-inline\"; // The name of the inline marker class\n\tthis._appendClass = \"ui-datepicker-append\"; // The name of the append marker class\n\tthis._triggerClass = \"ui-datepicker-trigger\"; // The name of the trigger marker class\n\tthis._dialogClass = \"ui-datepicker-dialog\"; // The name of the dialog marker class\n\tthis._disableClass = \"ui-datepicker-disabled\"; // The name of the disabled covering marker class\n\tthis._unselectableClass = \"ui-datepicker-unselectable\"; // The name of the unselectable cell marker class\n\tthis._currentClass = \"ui-datepicker-current-day\"; // The name of the current day marker class\n\tthis._dayOverClass = \"ui-datepicker-days-cell-over\"; // The name of the day hover marker class\n\tthis.regional = []; // Available regional settings, indexed by language code\n\tthis.regional[\"\"] = { // Default regional settings\n\t\tcloseText: \"Done\", // Display text for close link\n\t\tprevText: \"Prev\", // Display text for previous month link\n\t\tnextText: \"Next\", // Display text for next month link\n\t\tcurrentText: \"Today\", // Display text for current month link\n\t\tmonthNames: [\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\n\t\t\t\"July\",\"August\",\"September\",\"October\",\"November\",\"December\"], // Names of months for drop-down and formatting\n\t\tmonthNamesShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"], // For formatting\n\t\tdayNames: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"], // For formatting\n\t\tdayNamesShort: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"], // For formatting\n\t\tdayNamesMin: [\"Su\",\"Mo\",\"Tu\",\"We\",\"Th\",\"Fr\",\"Sa\"], // Column headings for days starting at Sunday\n\t\tweekHeader: \"Wk\", // Column header for week of the year\n\t\tdateFormat: \"mm/dd/yy\", // See format options on parseDate\n\t\tfirstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...\n\t\tisRTL: false, // True if right-to-left language, false if left-to-right\n\t\tshowMonthAfterYear: false, // True if the year select precedes month, false for month then year\n\t\tyearSuffix: \"\" // Additional text to append to the year in the month headers\n\t};\n\tthis._defaults = { // Global defaults for all the date picker instances\n\t\tshowOn: \"focus\", // \"focus\" for popup on focus,\n\t\t\t// \"button\" for trigger button, or \"both\" for either\n\t\tshowAnim: \"fadeIn\", // Name of jQuery animation for popup\n\t\tshowOptions: {}, // Options for enhanced animations\n\t\tdefaultDate: null, // Used when field is blank: actual date,\n\t\t\t// +/-number for offset from today, null for today\n\t\tappendText: \"\", // Display text following the input box, e.g. showing the format\n\t\tbuttonText: \"...\", // Text for trigger button\n\t\tbuttonImage: \"\", // URL for trigger button image\n\t\tbuttonImageOnly: false, // True if the image appears alone, false if it appears on a button\n\t\thideIfNoPrevNext: false, // True to hide next/previous month links\n\t\t\t// if not applicable, false to just disable them\n\t\tnavigationAsDateFormat: false, // True if date formatting applied to prev/today/next links\n\t\tgotoCurrent: false, // True if today link goes back to current selection instead\n\t\tchangeMonth: false, // True if month can be selected directly, false if only prev/next\n\t\tchangeYear: false, // True if year can be selected directly, false if only prev/next\n\t\tyearRange: \"c-10:c+10\", // Range of years to display in drop-down,\n\t\t\t// either relative to today's year (-nn:+nn), relative to currently displayed year\n\t\t\t// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)\n\t\tshowOtherMonths: false, // True to show dates in other months, false to leave blank\n\t\tselectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable\n\t\tshowWeek: false, // True to show week of the year, false to not show it\n\t\tcalculateWeek: this.iso8601Week, // How to calculate the week of the year,\n\t\t\t// takes a Date and returns the number of the week for it\n\t\tshortYearCutoff: \"+10\", // Short year values < this are in the current century,\n\t\t\t// > this are in the previous century,\n\t\t\t// string value starting with \"+\" for current year + value\n\t\tminDate: null, // The earliest selectable date, or null for no limit\n\t\tmaxDate: null, // The latest selectable date, or null for no limit\n\t\tduration: \"fast\", // Duration of display/closure\n\t\tbeforeShowDay: null, // Function that takes a date and returns an array with\n\t\t\t// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or \"\",\n\t\t\t// [2] = cell title (optional), e.g. $.datepicker.noWeekends\n\t\tbeforeShow: null, // Function that takes an input field and\n\t\t\t// returns a set of custom settings for the date picker\n\t\tonSelect: null, // Define a callback function when a date is selected\n\t\tonChangeMonthYear: null, // Define a callback function when the month or year is changed\n\t\tonClose: null, // Define a callback function when the datepicker is closed\n\t\tnumberOfMonths: 1, // Number of months to show at a time\n\t\tshowCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)\n\t\tstepMonths: 1, // Number of months to step back/forward\n\t\tstepBigMonths: 12, // Number of months to step back/forward for the big links\n\t\taltField: \"\", // Selector for an alternate field to store selected dates into\n\t\taltFormat: \"\", // The date format to use for the alternate field\n\t\tconstrainInput: true, // The input is constrained by the current date format\n\t\tshowButtonPanel: false, // True to show button panel, false to not show it\n\t\tautoSize: false, // True to size the input for the date format, false to leave as is\n\t\tdisabled: false // The initial disabled state\n\t};\n\t$.extend(this._defaults, this.regional[\"\"]);\n\tthis.dpDiv = bindHover($(\"<div id='\" + this._mainDivId + \"' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>\"));\n}\n\n$.extend(Datepicker.prototype, {\n\t/* Class name added to elements to indicate already configured with a date picker. */\n\tmarkerClassName: \"hasDatepicker\",\n\n\t//Keep track of the maximum number of rows displayed (see #7043)\n\tmaxRows: 4,\n\n\t// TODO rename to \"widget\" when switching to widget factory\n\t_widgetDatepicker: function() {\n\t\treturn this.dpDiv;\n\t},\n\n\t/* Override the default settings for all instances of the date picker.\n\t * @param  settings  object - the new settings to use as defaults (anonymous object)\n\t * @return the manager object\n\t */\n\tsetDefaults: function(settings) {\n\t\textendRemove(this._defaults, settings || {});\n\t\treturn this;\n\t},\n\n\t/* Attach the date picker to a jQuery selection.\n\t * @param  target\telement - the target input field or division or span\n\t * @param  settings  object - the new settings to use for this date picker instance (anonymous)\n\t */\n\t_attachDatepicker: function(target, settings) {\n\t\tvar nodeName, inline, inst;\n\t\tnodeName = target.nodeName.toLowerCase();\n\t\tinline = (nodeName === \"div\" || nodeName === \"span\");\n\t\tif (!target.id) {\n\t\t\tthis.uuid += 1;\n\t\t\ttarget.id = \"dp\" + this.uuid;\n\t\t}\n\t\tinst = this._newInst($(target), inline);\n\t\tinst.settings = $.extend({}, settings || {});\n\t\tif (nodeName === \"input\") {\n\t\t\tthis._connectDatepicker(target, inst);\n\t\t} else if (inline) {\n\t\t\tthis._inlineDatepicker(target, inst);\n\t\t}\n\t},\n\n\t/* Create a new instance object. */\n\t_newInst: function(target, inline) {\n\t\tvar id = target[0].id.replace(/([^A-Za-z0-9_\\-])/g, \"\\\\\\\\$1\"); // escape jQuery meta chars\n\t\treturn {id: id, input: target, // associated target\n\t\t\tselectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection\n\t\t\tdrawMonth: 0, drawYear: 0, // month being drawn\n\t\t\tinline: inline, // is datepicker inline or not\n\t\t\tdpDiv: (!inline ? this.dpDiv : // presentation div\n\t\t\tbindHover($(\"<div class='\" + this._inlineClass + \" ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>\")))};\n\t},\n\n\t/* Attach the date picker to an input field. */\n\t_connectDatepicker: function(target, inst) {\n\t\tvar input = $(target);\n\t\tinst.append = $([]);\n\t\tinst.trigger = $([]);\n\t\tif (input.hasClass(this.markerClassName)) {\n\t\t\treturn;\n\t\t}\n\t\tthis._attachments(input, inst);\n\t\tinput.addClass(this.markerClassName).keydown(this._doKeyDown).\n\t\t\tkeypress(this._doKeyPress).keyup(this._doKeyUp);\n\t\tthis._autoSize(inst);\n\t\t$.data(target, PROP_NAME, inst);\n\t\t//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)\n\t\tif( inst.settings.disabled ) {\n\t\t\tthis._disableDatepicker( target );\n\t\t}\n\t},\n\n\t/* Make attachments based on settings. */\n\t_attachments: function(input, inst) {\n\t\tvar showOn, buttonText, buttonImage,\n\t\t\tappendText = this._get(inst, \"appendText\"),\n\t\t\tisRTL = this._get(inst, \"isRTL\");\n\n\t\tif (inst.append) {\n\t\t\tinst.append.remove();\n\t\t}\n\t\tif (appendText) {\n\t\t\tinst.append = $(\"<span class='\" + this._appendClass + \"'>\" + appendText + \"</span>\");\n\t\t\tinput[isRTL ? \"before\" : \"after\"](inst.append);\n\t\t}\n\n\t\tinput.unbind(\"focus\", this._showDatepicker);\n\n\t\tif (inst.trigger) {\n\t\t\tinst.trigger.remove();\n\t\t}\n\n\t\tshowOn = this._get(inst, \"showOn\");\n\t\tif (showOn === \"focus\" || showOn === \"both\") { // pop-up date picker when in the marked field\n\t\t\tinput.focus(this._showDatepicker);\n\t\t}\n\t\tif (showOn === \"button\" || showOn === \"both\") { // pop-up date picker when button clicked\n\t\t\tbuttonText = this._get(inst, \"buttonText\");\n\t\t\tbuttonImage = this._get(inst, \"buttonImage\");\n\t\t\tinst.trigger = $(this._get(inst, \"buttonImageOnly\") ?\n\t\t\t\t$(\"<img/>\").addClass(this._triggerClass).\n\t\t\t\t\tattr({ src: buttonImage, alt: buttonText, title: buttonText }) :\n\t\t\t\t$(\"<button type='button'></button>\").addClass(this._triggerClass).\n\t\t\t\t\thtml(!buttonImage ? buttonText : $(\"<img/>\").attr(\n\t\t\t\t\t{ src:buttonImage, alt:buttonText, title:buttonText })));\n\t\t\tinput[isRTL ? \"before\" : \"after\"](inst.trigger);\n\t\t\tinst.trigger.click(function() {\n\t\t\t\tif ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {\n\t\t\t\t\t$.datepicker._hideDatepicker();\n\t\t\t\t} else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {\n\t\t\t\t\t$.datepicker._hideDatepicker();\n\t\t\t\t\t$.datepicker._showDatepicker(input[0]);\n\t\t\t\t} else {\n\t\t\t\t\t$.datepicker._showDatepicker(input[0]);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t});\n\t\t}\n\t},\n\n\t/* Apply the maximum length for the date format. */\n\t_autoSize: function(inst) {\n\t\tif (this._get(inst, \"autoSize\") && !inst.inline) {\n\t\t\tvar findMax, max, maxI, i,\n\t\t\t\tdate = new Date(2009, 12 - 1, 20), // Ensure double digits\n\t\t\t\tdateFormat = this._get(inst, \"dateFormat\");\n\n\t\t\tif (dateFormat.match(/[DM]/)) {\n\t\t\t\tfindMax = function(names) {\n\t\t\t\t\tmax = 0;\n\t\t\t\t\tmaxI = 0;\n\t\t\t\t\tfor (i = 0; i < names.length; i++) {\n\t\t\t\t\t\tif (names[i].length > max) {\n\t\t\t\t\t\t\tmax = names[i].length;\n\t\t\t\t\t\t\tmaxI = i;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn maxI;\n\t\t\t\t};\n\t\t\t\tdate.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?\n\t\t\t\t\t\"monthNames\" : \"monthNamesShort\"))));\n\t\t\t\tdate.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?\n\t\t\t\t\t\"dayNames\" : \"dayNamesShort\"))) + 20 - date.getDay());\n\t\t\t}\n\t\t\tinst.input.attr(\"size\", this._formatDate(inst, date).length);\n\t\t}\n\t},\n\n\t/* Attach an inline date picker to a div. */\n\t_inlineDatepicker: function(target, inst) {\n\t\tvar divSpan = $(target);\n\t\tif (divSpan.hasClass(this.markerClassName)) {\n\t\t\treturn;\n\t\t}\n\t\tdivSpan.addClass(this.markerClassName).append(inst.dpDiv);\n\t\t$.data(target, PROP_NAME, inst);\n\t\tthis._setDate(inst, this._getDefaultDate(inst), true);\n\t\tthis._updateDatepicker(inst);\n\t\tthis._updateAlternate(inst);\n\t\t//If disabled option is true, disable the datepicker before showing it (see ticket #5665)\n\t\tif( inst.settings.disabled ) {\n\t\t\tthis._disableDatepicker( target );\n\t\t}\n\t\t// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements\n\t\t// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height\n\t\tinst.dpDiv.css( \"display\", \"block\" );\n\t},\n\n\t/* Pop-up the date picker in a \"dialog\" box.\n\t * @param  input element - ignored\n\t * @param  date\tstring or Date - the initial date to display\n\t * @param  onSelect  function - the function to call when a date is selected\n\t * @param  settings  object - update the dialog date picker instance's settings (anonymous object)\n\t * @param  pos int[2] - coordinates for the dialog's position within the screen or\n\t *\t\t\t\t\tevent - with x/y coordinates or\n\t *\t\t\t\t\tleave empty for default (screen centre)\n\t * @return the manager object\n\t */\n\t_dialogDatepicker: function(input, date, onSelect, settings, pos) {\n\t\tvar id, browserWidth, browserHeight, scrollX, scrollY,\n\t\t\tinst = this._dialogInst; // internal instance\n\n\t\tif (!inst) {\n\t\t\tthis.uuid += 1;\n\t\t\tid = \"dp\" + this.uuid;\n\t\t\tthis._dialogInput = $(\"<input type='text' id='\" + id +\n\t\t\t\t\"' style='position: absolute; top: -100px; width: 0px;'/>\");\n\t\t\tthis._dialogInput.keydown(this._doKeyDown);\n\t\t\t$(\"body\").append(this._dialogInput);\n\t\t\tinst = this._dialogInst = this._newInst(this._dialogInput, false);\n\t\t\tinst.settings = {};\n\t\t\t$.data(this._dialogInput[0], PROP_NAME, inst);\n\t\t}\n\t\textendRemove(inst.settings, settings || {});\n\t\tdate = (date && date.constructor === Date ? this._formatDate(inst, date) : date);\n\t\tthis._dialogInput.val(date);\n\n\t\tthis._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);\n\t\tif (!this._pos) {\n\t\t\tbrowserWidth = document.documentElement.clientWidth;\n\t\t\tbrowserHeight = document.documentElement.clientHeight;\n\t\t\tscrollX = document.documentElement.scrollLeft || document.body.scrollLeft;\n\t\t\tscrollY = document.documentElement.scrollTop || document.body.scrollTop;\n\t\t\tthis._pos = // should use actual width/height below\n\t\t\t\t[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];\n\t\t}\n\n\t\t// move input on screen for focus, but hidden behind dialog\n\t\tthis._dialogInput.css(\"left\", (this._pos[0] + 20) + \"px\").css(\"top\", this._pos[1] + \"px\");\n\t\tinst.settings.onSelect = onSelect;\n\t\tthis._inDialog = true;\n\t\tthis.dpDiv.addClass(this._dialogClass);\n\t\tthis._showDatepicker(this._dialogInput[0]);\n\t\tif ($.blockUI) {\n\t\t\t$.blockUI(this.dpDiv);\n\t\t}\n\t\t$.data(this._dialogInput[0], PROP_NAME, inst);\n\t\treturn this;\n\t},\n\n\t/* Detach a datepicker from its control.\n\t * @param  target\telement - the target input field or division or span\n\t */\n\t_destroyDatepicker: function(target) {\n\t\tvar nodeName,\n\t\t\t$target = $(target),\n\t\t\tinst = $.data(target, PROP_NAME);\n\n\t\tif (!$target.hasClass(this.markerClassName)) {\n\t\t\treturn;\n\t\t}\n\n\t\tnodeName = target.nodeName.toLowerCase();\n\t\t$.removeData(target, PROP_NAME);\n\t\tif (nodeName === \"input\") {\n\t\t\tinst.append.remove();\n\t\t\tinst.trigger.remove();\n\t\t\t$target.removeClass(this.markerClassName).\n\t\t\t\tunbind(\"focus\", this._showDatepicker).\n\t\t\t\tunbind(\"keydown\", this._doKeyDown).\n\t\t\t\tunbind(\"keypress\", this._doKeyPress).\n\t\t\t\tunbind(\"keyup\", this._doKeyUp);\n\t\t} else if (nodeName === \"div\" || nodeName === \"span\") {\n\t\t\t$target.removeClass(this.markerClassName).empty();\n\t\t}\n\t},\n\n\t/* Enable the date picker to a jQuery selection.\n\t * @param  target\telement - the target input field or division or span\n\t */\n\t_enableDatepicker: function(target) {\n\t\tvar nodeName, inline,\n\t\t\t$target = $(target),\n\t\t\tinst = $.data(target, PROP_NAME);\n\n\t\tif (!$target.hasClass(this.markerClassName)) {\n\t\t\treturn;\n\t\t}\n\n\t\tnodeName = target.nodeName.toLowerCase();\n\t\tif (nodeName === \"input\") {\n\t\t\ttarget.disabled = false;\n\t\t\tinst.trigger.filter(\"button\").\n\t\t\t\teach(function() { this.disabled = false; }).end().\n\t\t\t\tfilter(\"img\").css({opacity: \"1.0\", cursor: \"\"});\n\t\t} else if (nodeName === \"div\" || nodeName === \"span\") {\n\t\t\tinline = $target.children(\".\" + this._inlineClass);\n\t\t\tinline.children().removeClass(\"ui-state-disabled\");\n\t\t\tinline.find(\"select.ui-datepicker-month, select.ui-datepicker-year\").\n\t\t\t\tprop(\"disabled\", false);\n\t\t}\n\t\tthis._disabledInputs = $.map(this._disabledInputs,\n\t\t\tfunction(value) { return (value === target ? null : value); }); // delete entry\n\t},\n\n\t/* Disable the date picker to a jQuery selection.\n\t * @param  target\telement - the target input field or division or span\n\t */\n\t_disableDatepicker: function(target) {\n\t\tvar nodeName, inline,\n\t\t\t$target = $(target),\n\t\t\tinst = $.data(target, PROP_NAME);\n\n\t\tif (!$target.hasClass(this.markerClassName)) {\n\t\t\treturn;\n\t\t}\n\n\t\tnodeName = target.nodeName.toLowerCase();\n\t\tif (nodeName === \"input\") {\n\t\t\ttarget.disabled = true;\n\t\t\tinst.trigger.filter(\"button\").\n\t\t\t\teach(function() { this.disabled = true; }).end().\n\t\t\t\tfilter(\"img\").css({opacity: \"0.5\", cursor: \"default\"});\n\t\t} else if (nodeName === \"div\" || nodeName === \"span\") {\n\t\t\tinline = $target.children(\".\" + this._inlineClass);\n\t\t\tinline.children().addClass(\"ui-state-disabled\");\n\t\t\tinline.find(\"select.ui-datepicker-month, select.ui-datepicker-year\").\n\t\t\t\tprop(\"disabled\", true);\n\t\t}\n\t\tthis._disabledInputs = $.map(this._disabledInputs,\n\t\t\tfunction(value) { return (value === target ? null : value); }); // delete entry\n\t\tthis._disabledInputs[this._disabledInputs.length] = target;\n\t},\n\n\t/* Is the first field in a jQuery collection disabled as a datepicker?\n\t * @param  target\telement - the target input field or division or span\n\t * @return boolean - true if disabled, false if enabled\n\t */\n\t_isDisabledDatepicker: function(target) {\n\t\tif (!target) {\n\t\t\treturn false;\n\t\t}\n\t\tfor (var i = 0; i < this._disabledInputs.length; i++) {\n\t\t\tif (this._disabledInputs[i] === target) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t},\n\n\t/* Retrieve the instance data for the target control.\n\t * @param  target  element - the target input field or division or span\n\t * @return  object - the associated instance data\n\t * @throws  error if a jQuery problem getting data\n\t */\n\t_getInst: function(target) {\n\t\ttry {\n\t\t\treturn $.data(target, PROP_NAME);\n\t\t}\n\t\tcatch (err) {\n\t\t\tthrow \"Missing instance data for this datepicker\";\n\t\t}\n\t},\n\n\t/* Update or retrieve the settings for a date picker attached to an input field or division.\n\t * @param  target  element - the target input field or division or span\n\t * @param  name\tobject - the new settings to update or\n\t *\t\t\t\tstring - the name of the setting to change or retrieve,\n\t *\t\t\t\twhen retrieving also \"all\" for all instance settings or\n\t *\t\t\t\t\"defaults\" for all global defaults\n\t * @param  value   any - the new value for the setting\n\t *\t\t\t\t(omit if above is an object or to retrieve a value)\n\t */\n\t_optionDatepicker: function(target, name, value) {\n\t\tvar settings, date, minDate, maxDate,\n\t\t\tinst = this._getInst(target);\n\n\t\tif (arguments.length === 2 && typeof name === \"string\") {\n\t\t\treturn (name === \"defaults\" ? $.extend({}, $.datepicker._defaults) :\n\t\t\t\t(inst ? (name === \"all\" ? $.extend({}, inst.settings) :\n\t\t\t\tthis._get(inst, name)) : null));\n\t\t}\n\n\t\tsettings = name || {};\n\t\tif (typeof name === \"string\") {\n\t\t\tsettings = {};\n\t\t\tsettings[name] = value;\n\t\t}\n\n\t\tif (inst) {\n\t\t\tif (this._curInst === inst) {\n\t\t\t\tthis._hideDatepicker();\n\t\t\t}\n\n\t\t\tdate = this._getDateDatepicker(target, true);\n\t\t\tminDate = this._getMinMaxDate(inst, \"min\");\n\t\t\tmaxDate = this._getMinMaxDate(inst, \"max\");\n\t\t\textendRemove(inst.settings, settings);\n\t\t\t// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided\n\t\t\tif (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {\n\t\t\t\tinst.settings.minDate = this._formatDate(inst, minDate);\n\t\t\t}\n\t\t\tif (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {\n\t\t\t\tinst.settings.maxDate = this._formatDate(inst, maxDate);\n\t\t\t}\n\t\t\tif ( \"disabled\" in settings ) {\n\t\t\t\tif ( settings.disabled ) {\n\t\t\t\t\tthis._disableDatepicker(target);\n\t\t\t\t} else {\n\t\t\t\t\tthis._enableDatepicker(target);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._attachments($(target), inst);\n\t\t\tthis._autoSize(inst);\n\t\t\tthis._setDate(inst, date);\n\t\t\tthis._updateAlternate(inst);\n\t\t\tthis._updateDatepicker(inst);\n\t\t}\n\t},\n\n\t// change method deprecated\n\t_changeDatepicker: function(target, name, value) {\n\t\tthis._optionDatepicker(target, name, value);\n\t},\n\n\t/* Redraw the date picker attached to an input field or division.\n\t * @param  target  element - the target input field or division or span\n\t */\n\t_refreshDatepicker: function(target) {\n\t\tvar inst = this._getInst(target);\n\t\tif (inst) {\n\t\t\tthis._updateDatepicker(inst);\n\t\t}\n\t},\n\n\t/* Set the dates for a jQuery selection.\n\t * @param  target element - the target input field or division or span\n\t * @param  date\tDate - the new date\n\t */\n\t_setDateDatepicker: function(target, date) {\n\t\tvar inst = this._getInst(target);\n\t\tif (inst) {\n\t\t\tthis._setDate(inst, date);\n\t\t\tthis._updateDatepicker(inst);\n\t\t\tthis._updateAlternate(inst);\n\t\t}\n\t},\n\n\t/* Get the date(s) for the first entry in a jQuery selection.\n\t * @param  target element - the target input field or division or span\n\t * @param  noDefault boolean - true if no default date is to be used\n\t * @return Date - the current date\n\t */\n\t_getDateDatepicker: function(target, noDefault) {\n\t\tvar inst = this._getInst(target);\n\t\tif (inst && !inst.inline) {\n\t\t\tthis._setDateFromField(inst, noDefault);\n\t\t}\n\t\treturn (inst ? this._getDate(inst) : null);\n\t},\n\n\t/* Handle keystrokes. */\n\t_doKeyDown: function(event) {\n\t\tvar onSelect, dateStr, sel,\n\t\t\tinst = $.datepicker._getInst(event.target),\n\t\t\thandled = true,\n\t\t\tisRTL = inst.dpDiv.is(\".ui-datepicker-rtl\");\n\n\t\tinst._keyEvent = true;\n\t\tif ($.datepicker._datepickerShowing) {\n\t\t\tswitch (event.keyCode) {\n\t\t\t\tcase 9: $.datepicker._hideDatepicker();\n\t\t\t\t\t\thandled = false;\n\t\t\t\t\t\tbreak; // hide on tab out\n\t\t\t\tcase 13: sel = $(\"td.\" + $.datepicker._dayOverClass + \":not(.\" +\n\t\t\t\t\t\t\t\t\t$.datepicker._currentClass + \")\", inst.dpDiv);\n\t\t\t\t\t\tif (sel[0]) {\n\t\t\t\t\t\t\t$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tonSelect = $.datepicker._get(inst, \"onSelect\");\n\t\t\t\t\t\tif (onSelect) {\n\t\t\t\t\t\t\tdateStr = $.datepicker._formatDate(inst);\n\n\t\t\t\t\t\t\t// trigger custom callback\n\t\t\t\t\t\t\tonSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$.datepicker._hideDatepicker();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn false; // don't submit the form\n\t\t\t\tcase 27: $.datepicker._hideDatepicker();\n\t\t\t\t\t\tbreak; // hide on escape\n\t\t\t\tcase 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?\n\t\t\t\t\t\t\t-$.datepicker._get(inst, \"stepBigMonths\") :\n\t\t\t\t\t\t\t-$.datepicker._get(inst, \"stepMonths\")), \"M\");\n\t\t\t\t\t\tbreak; // previous month/year on page up/+ ctrl\n\t\t\t\tcase 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?\n\t\t\t\t\t\t\t+$.datepicker._get(inst, \"stepBigMonths\") :\n\t\t\t\t\t\t\t+$.datepicker._get(inst, \"stepMonths\")), \"M\");\n\t\t\t\t\t\tbreak; // next month/year on page down/+ ctrl\n\t\t\t\tcase 35: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._clearDate(event.target);\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\tbreak; // clear on ctrl or command +end\n\t\t\t\tcase 36: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._gotoToday(event.target);\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\tbreak; // current on ctrl or command +home\n\t\t\t\tcase 37: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), \"D\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\t// -1 day on ctrl or command +left\n\t\t\t\t\t\tif (event.originalEvent.altKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, (event.ctrlKey ?\n\t\t\t\t\t\t\t\t-$.datepicker._get(inst, \"stepBigMonths\") :\n\t\t\t\t\t\t\t\t-$.datepicker._get(inst, \"stepMonths\")), \"M\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// next month/year on alt +left on Mac\n\t\t\t\t\t\tbreak;\n\t\t\t\tcase 38: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, -7, \"D\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\tbreak; // -1 week on ctrl or command +up\n\t\t\t\tcase 39: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), \"D\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\t// +1 day on ctrl or command +right\n\t\t\t\t\t\tif (event.originalEvent.altKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, (event.ctrlKey ?\n\t\t\t\t\t\t\t\t+$.datepicker._get(inst, \"stepBigMonths\") :\n\t\t\t\t\t\t\t\t+$.datepicker._get(inst, \"stepMonths\")), \"M\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// next month/year on alt +right\n\t\t\t\t\t\tbreak;\n\t\t\t\tcase 40: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, +7, \"D\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\tbreak; // +1 week on ctrl or command +down\n\t\t\t\tdefault: handled = false;\n\t\t\t}\n\t\t} else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home\n\t\t\t$.datepicker._showDatepicker(this);\n\t\t} else {\n\t\t\thandled = false;\n\t\t}\n\n\t\tif (handled) {\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t}\n\t},\n\n\t/* Filter entered characters - based on date format. */\n\t_doKeyPress: function(event) {\n\t\tvar chars, chr,\n\t\t\tinst = $.datepicker._getInst(event.target);\n\n\t\tif ($.datepicker._get(inst, \"constrainInput\")) {\n\t\t\tchars = $.datepicker._possibleChars($.datepicker._get(inst, \"dateFormat\"));\n\t\t\tchr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);\n\t\t\treturn event.ctrlKey || event.metaKey || (chr < \" \" || !chars || chars.indexOf(chr) > -1);\n\t\t}\n\t},\n\n\t/* Synchronise manual entry and field/alternate field. */\n\t_doKeyUp: function(event) {\n\t\tvar date,\n\t\t\tinst = $.datepicker._getInst(event.target);\n\n\t\tif (inst.input.val() !== inst.lastVal) {\n\t\t\ttry {\n\t\t\t\tdate = $.datepicker.parseDate($.datepicker._get(inst, \"dateFormat\"),\n\t\t\t\t\t(inst.input ? inst.input.val() : null),\n\t\t\t\t\t$.datepicker._getFormatConfig(inst));\n\n\t\t\t\tif (date) { // only if valid\n\t\t\t\t\t$.datepicker._setDateFromField(inst);\n\t\t\t\t\t$.datepicker._updateAlternate(inst);\n\t\t\t\t\t$.datepicker._updateDatepicker(inst);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (err) {\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t},\n\n\t/* Pop-up the date picker for a given input field.\n\t * If false returned from beforeShow event handler do not show.\n\t * @param  input  element - the input field attached to the date picker or\n\t *\t\t\t\t\tevent - if triggered by focus\n\t */\n\t_showDatepicker: function(input) {\n\t\tinput = input.target || input;\n\t\tif (input.nodeName.toLowerCase() !== \"input\") { // find from button/image trigger\n\t\t\tinput = $(\"input\", input.parentNode)[0];\n\t\t}\n\n\t\tif ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here\n\t\t\treturn;\n\t\t}\n\n\t\tvar inst, beforeShow, beforeShowSettings, isFixed,\n\t\t\toffset, showAnim, duration;\n\n\t\tinst = $.datepicker._getInst(input);\n\t\tif ($.datepicker._curInst && $.datepicker._curInst !== inst) {\n\t\t\t$.datepicker._curInst.dpDiv.stop(true, true);\n\t\t\tif ( inst && $.datepicker._datepickerShowing ) {\n\t\t\t\t$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );\n\t\t\t}\n\t\t}\n\n\t\tbeforeShow = $.datepicker._get(inst, \"beforeShow\");\n\t\tbeforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};\n\t\tif(beforeShowSettings === false){\n\t\t\treturn;\n\t\t}\n\t\textendRemove(inst.settings, beforeShowSettings);\n\n\t\tinst.lastVal = null;\n\t\t$.datepicker._lastInput = input;\n\t\t$.datepicker._setDateFromField(inst);\n\n\t\tif ($.datepicker._inDialog) { // hide cursor\n\t\t\tinput.value = \"\";\n\t\t}\n\t\tif (!$.datepicker._pos) { // position below input\n\t\t\t$.datepicker._pos = $.datepicker._findPos(input);\n\t\t\t$.datepicker._pos[1] += input.offsetHeight; // add the height\n\t\t}\n\n\t\tisFixed = false;\n\t\t$(input).parents().each(function() {\n\t\t\tisFixed |= $(this).css(\"position\") === \"fixed\";\n\t\t\treturn !isFixed;\n\t\t});\n\n\t\toffset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};\n\t\t$.datepicker._pos = null;\n\t\t//to avoid flashes on Firefox\n\t\tinst.dpDiv.empty();\n\t\t// determine sizing offscreen\n\t\tinst.dpDiv.css({position: \"absolute\", display: \"block\", top: \"-1000px\"});\n\t\t$.datepicker._updateDatepicker(inst);\n\t\t// fix width for dynamic number of date pickers\n\t\t// and adjust position before showing\n\t\toffset = $.datepicker._checkOffset(inst, offset, isFixed);\n\t\tinst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?\n\t\t\t\"static\" : (isFixed ? \"fixed\" : \"absolute\")), display: \"none\",\n\t\t\tleft: offset.left + \"px\", top: offset.top + \"px\"});\n\n\t\tif (!inst.inline) {\n\t\t\tshowAnim = $.datepicker._get(inst, \"showAnim\");\n\t\t\tduration = $.datepicker._get(inst, \"duration\");\n\t\t\tinst.dpDiv.zIndex($(input).zIndex()+1);\n\t\t\t$.datepicker._datepickerShowing = true;\n\n\t\t\tif ( $.effects && $.effects.effect[ showAnim ] ) {\n\t\t\t\tinst.dpDiv.show(showAnim, $.datepicker._get(inst, \"showOptions\"), duration);\n\t\t\t} else {\n\t\t\t\tinst.dpDiv[showAnim || \"show\"](showAnim ? duration : null);\n\t\t\t}\n\n\t\t\tif ( $.datepicker._shouldFocusInput( inst ) ) {\n\t\t\t\tinst.input.focus();\n\t\t\t}\n\n\t\t\t$.datepicker._curInst = inst;\n\t\t}\n\t},\n\n\t/* Generate the date picker content. */\n\t_updateDatepicker: function(inst) {\n\t\tthis.maxRows = 4; //Reset the max number of rows being displayed (see #7043)\n\t\tinstActive = inst; // for delegate hover events\n\t\tinst.dpDiv.empty().append(this._generateHTML(inst));\n\t\tthis._attachHandlers(inst);\n\t\tinst.dpDiv.find(\".\" + this._dayOverClass + \" a\").mouseover();\n\n\t\tvar origyearshtml,\n\t\t\tnumMonths = this._getNumberOfMonths(inst),\n\t\t\tcols = numMonths[1],\n\t\t\twidth = 17;\n\n\t\tinst.dpDiv.removeClass(\"ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4\").width(\"\");\n\t\tif (cols > 1) {\n\t\t\tinst.dpDiv.addClass(\"ui-datepicker-multi-\" + cols).css(\"width\", (width * cols) + \"em\");\n\t\t}\n\t\tinst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? \"add\" : \"remove\") +\n\t\t\t\"Class\"](\"ui-datepicker-multi\");\n\t\tinst.dpDiv[(this._get(inst, \"isRTL\") ? \"add\" : \"remove\") +\n\t\t\t\"Class\"](\"ui-datepicker-rtl\");\n\n\t\tif (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {\n\t\t\tinst.input.focus();\n\t\t}\n\n\t\t// deffered render of the years select (to avoid flashes on Firefox)\n\t\tif( inst.yearshtml ){\n\t\t\torigyearshtml = inst.yearshtml;\n\t\t\tsetTimeout(function(){\n\t\t\t\t//assure that inst.yearshtml didn't change.\n\t\t\t\tif( origyearshtml === inst.yearshtml && inst.yearshtml ){\n\t\t\t\t\tinst.dpDiv.find(\"select.ui-datepicker-year:first\").replaceWith(inst.yearshtml);\n\t\t\t\t}\n\t\t\t\torigyearshtml = inst.yearshtml = null;\n\t\t\t}, 0);\n\t\t}\n\t},\n\n\t// #6694 - don't focus the input if it's already focused\n\t// this breaks the change event in IE\n\t// Support: IE and jQuery <1.9\n\t_shouldFocusInput: function( inst ) {\n\t\treturn inst.input && inst.input.is( \":visible\" ) && !inst.input.is( \":disabled\" ) && !inst.input.is( \":focus\" );\n\t},\n\n\t/* Check positioning to remain on screen. */\n\t_checkOffset: function(inst, offset, isFixed) {\n\t\tvar dpWidth = inst.dpDiv.outerWidth(),\n\t\t\tdpHeight = inst.dpDiv.outerHeight(),\n\t\t\tinputWidth = inst.input ? inst.input.outerWidth() : 0,\n\t\t\tinputHeight = inst.input ? inst.input.outerHeight() : 0,\n\t\t\tviewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),\n\t\t\tviewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());\n\n\t\toffset.left -= (this._get(inst, \"isRTL\") ? (dpWidth - inputWidth) : 0);\n\t\toffset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;\n\t\toffset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;\n\n\t\t// now check if datepicker is showing outside window viewport - move to a better place if so.\n\t\toffset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?\n\t\t\tMath.abs(offset.left + dpWidth - viewWidth) : 0);\n\t\toffset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?\n\t\t\tMath.abs(dpHeight + inputHeight) : 0);\n\n\t\treturn offset;\n\t},\n\n\t/* Find an object's position on the screen. */\n\t_findPos: function(obj) {\n\t\tvar position,\n\t\t\tinst = this._getInst(obj),\n\t\t\tisRTL = this._get(inst, \"isRTL\");\n\n\t\twhile (obj && (obj.type === \"hidden\" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {\n\t\t\tobj = obj[isRTL ? \"previousSibling\" : \"nextSibling\"];\n\t\t}\n\n\t\tposition = $(obj).offset();\n\t\treturn [position.left, position.top];\n\t},\n\n\t/* Hide the date picker from view.\n\t * @param  input  element - the input field attached to the date picker\n\t */\n\t_hideDatepicker: function(input) {\n\t\tvar showAnim, duration, postProcess, onClose,\n\t\t\tinst = this._curInst;\n\n\t\tif (!inst || (input && inst !== $.data(input, PROP_NAME))) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this._datepickerShowing) {\n\t\t\tshowAnim = this._get(inst, \"showAnim\");\n\t\t\tduration = this._get(inst, \"duration\");\n\t\t\tpostProcess = function() {\n\t\t\t\t$.datepicker._tidyDialog(inst);\n\t\t\t};\n\n\t\t\t// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed\n\t\t\tif ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {\n\t\t\t\tinst.dpDiv.hide(showAnim, $.datepicker._get(inst, \"showOptions\"), duration, postProcess);\n\t\t\t} else {\n\t\t\t\tinst.dpDiv[(showAnim === \"slideDown\" ? \"slideUp\" :\n\t\t\t\t\t(showAnim === \"fadeIn\" ? \"fadeOut\" : \"hide\"))]((showAnim ? duration : null), postProcess);\n\t\t\t}\n\n\t\t\tif (!showAnim) {\n\t\t\t\tpostProcess();\n\t\t\t}\n\t\t\tthis._datepickerShowing = false;\n\n\t\t\tonClose = this._get(inst, \"onClose\");\n\t\t\tif (onClose) {\n\t\t\t\tonClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : \"\"), inst]);\n\t\t\t}\n\n\t\t\tthis._lastInput = null;\n\t\t\tif (this._inDialog) {\n\t\t\t\tthis._dialogInput.css({ position: \"absolute\", left: \"0\", top: \"-100px\" });\n\t\t\t\tif ($.blockUI) {\n\t\t\t\t\t$.unblockUI();\n\t\t\t\t\t$(\"body\").append(this.dpDiv);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._inDialog = false;\n\t\t}\n\t},\n\n\t/* Tidy up after a dialog display. */\n\t_tidyDialog: function(inst) {\n\t\tinst.dpDiv.removeClass(this._dialogClass).unbind(\".ui-datepicker-calendar\");\n\t},\n\n\t/* Close date picker if clicked elsewhere. */\n\t_checkExternalClick: function(event) {\n\t\tif (!$.datepicker._curInst) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar $target = $(event.target),\n\t\t\tinst = $.datepicker._getInst($target[0]);\n\n\t\tif ( ( ( $target[0].id !== $.datepicker._mainDivId &&\n\t\t\t\t$target.parents(\"#\" + $.datepicker._mainDivId).length === 0 &&\n\t\t\t\t!$target.hasClass($.datepicker.markerClassName) &&\n\t\t\t\t!$target.closest(\".\" + $.datepicker._triggerClass).length &&\n\t\t\t\t$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||\n\t\t\t( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {\n\t\t\t\t$.datepicker._hideDatepicker();\n\t\t}\n\t},\n\n\t/* Adjust one of the date sub-fields. */\n\t_adjustDate: function(id, offset, period) {\n\t\tvar target = $(id),\n\t\t\tinst = this._getInst(target[0]);\n\n\t\tif (this._isDisabledDatepicker(target[0])) {\n\t\t\treturn;\n\t\t}\n\t\tthis._adjustInstDate(inst, offset +\n\t\t\t(period === \"M\" ? this._get(inst, \"showCurrentAtPos\") : 0), // undo positioning\n\t\t\tperiod);\n\t\tthis._updateDatepicker(inst);\n\t},\n\n\t/* Action for current link. */\n\t_gotoToday: function(id) {\n\t\tvar date,\n\t\t\ttarget = $(id),\n\t\t\tinst = this._getInst(target[0]);\n\n\t\tif (this._get(inst, \"gotoCurrent\") && inst.currentDay) {\n\t\t\tinst.selectedDay = inst.currentDay;\n\t\t\tinst.drawMonth = inst.selectedMonth = inst.currentMonth;\n\t\t\tinst.drawYear = inst.selectedYear = inst.currentYear;\n\t\t} else {\n\t\t\tdate = new Date();\n\t\t\tinst.selectedDay = date.getDate();\n\t\t\tinst.drawMonth = inst.selectedMonth = date.getMonth();\n\t\t\tinst.drawYear = inst.selectedYear = date.getFullYear();\n\t\t}\n\t\tthis._notifyChange(inst);\n\t\tthis._adjustDate(target);\n\t},\n\n\t/* Action for selecting a new month/year. */\n\t_selectMonthYear: function(id, select, period) {\n\t\tvar target = $(id),\n\t\t\tinst = this._getInst(target[0]);\n\n\t\tinst[\"selected\" + (period === \"M\" ? \"Month\" : \"Year\")] =\n\t\tinst[\"draw\" + (period === \"M\" ? \"Month\" : \"Year\")] =\n\t\t\tparseInt(select.options[select.selectedIndex].value,10);\n\n\t\tthis._notifyChange(inst);\n\t\tthis._adjustDate(target);\n\t},\n\n\t/* Action for selecting a day. */\n\t_selectDay: function(id, month, year, td) {\n\t\tvar inst,\n\t\t\ttarget = $(id);\n\n\t\tif ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {\n\t\t\treturn;\n\t\t}\n\n\t\tinst = this._getInst(target[0]);\n\t\tinst.selectedDay = inst.currentDay = $(\"a\", td).html();\n\t\tinst.selectedMonth = inst.currentMonth = month;\n\t\tinst.selectedYear = inst.currentYear = year;\n\t\tthis._selectDate(id, this._formatDate(inst,\n\t\t\tinst.currentDay, inst.currentMonth, inst.currentYear));\n\t},\n\n\t/* Erase the input field and hide the date picker. */\n\t_clearDate: function(id) {\n\t\tvar target = $(id);\n\t\tthis._selectDate(target, \"\");\n\t},\n\n\t/* Update the input field with the selected date. */\n\t_selectDate: function(id, dateStr) {\n\t\tvar onSelect,\n\t\t\ttarget = $(id),\n\t\t\tinst = this._getInst(target[0]);\n\n\t\tdateStr = (dateStr != null ? dateStr : this._formatDate(inst));\n\t\tif (inst.input) {\n\t\t\tinst.input.val(dateStr);\n\t\t}\n\t\tthis._updateAlternate(inst);\n\n\t\tonSelect = this._get(inst, \"onSelect\");\n\t\tif (onSelect) {\n\t\t\tonSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback\n\t\t} else if (inst.input) {\n\t\t\tinst.input.trigger(\"change\"); // fire the change event\n\t\t}\n\n\t\tif (inst.inline){\n\t\t\tthis._updateDatepicker(inst);\n\t\t} else {\n\t\t\tthis._hideDatepicker();\n\t\t\tthis._lastInput = inst.input[0];\n\t\t\tif (typeof(inst.input[0]) !== \"object\") {\n\t\t\t\tinst.input.focus(); // restore focus\n\t\t\t}\n\t\t\tthis._lastInput = null;\n\t\t}\n\t},\n\n\t/* Update any alternate field to synchronise with the main field. */\n\t_updateAlternate: function(inst) {\n\t\tvar altFormat, date, dateStr,\n\t\t\taltField = this._get(inst, \"altField\");\n\n\t\tif (altField) { // update alternate field too\n\t\t\taltFormat = this._get(inst, \"altFormat\") || this._get(inst, \"dateFormat\");\n\t\t\tdate = this._getDate(inst);\n\t\t\tdateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));\n\t\t\t$(altField).each(function() { $(this).val(dateStr); });\n\t\t}\n\t},\n\n\t/* Set as beforeShowDay function to prevent selection of weekends.\n\t * @param  date  Date - the date to customise\n\t * @return [boolean, string] - is this date selectable?, what is its CSS class?\n\t */\n\tnoWeekends: function(date) {\n\t\tvar day = date.getDay();\n\t\treturn [(day > 0 && day < 6), \"\"];\n\t},\n\n\t/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.\n\t * @param  date  Date - the date to get the week for\n\t * @return  number - the number of the week within the year that contains this date\n\t */\n\tiso8601Week: function(date) {\n\t\tvar time,\n\t\t\tcheckDate = new Date(date.getTime());\n\n\t\t// Find Thursday of this week starting on Monday\n\t\tcheckDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));\n\n\t\ttime = checkDate.getTime();\n\t\tcheckDate.setMonth(0); // Compare with Jan 1\n\t\tcheckDate.setDate(1);\n\t\treturn Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;\n\t},\n\n\t/* Parse a string value into a date object.\n\t * See formatDate below for the possible formats.\n\t *\n\t * @param  format string - the expected format of the date\n\t * @param  value string - the date in the above format\n\t * @param  settings Object - attributes include:\n\t *\t\t\t\t\tshortYearCutoff  number - the cutoff year for determining the century (optional)\n\t *\t\t\t\t\tdayNamesShort\tstring[7] - abbreviated names of the days from Sunday (optional)\n\t *\t\t\t\t\tdayNames\t\tstring[7] - names of the days from Sunday (optional)\n\t *\t\t\t\t\tmonthNamesShort string[12] - abbreviated names of the months (optional)\n\t *\t\t\t\t\tmonthNames\t\tstring[12] - names of the months (optional)\n\t * @return  Date - the extracted date value or null if value is blank\n\t */\n\tparseDate: function (format, value, settings) {\n\t\tif (format == null || value == null) {\n\t\t\tthrow \"Invalid arguments\";\n\t\t}\n\n\t\tvalue = (typeof value === \"object\" ? value.toString() : value + \"\");\n\t\tif (value === \"\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar iFormat, dim, extra,\n\t\t\tiValue = 0,\n\t\t\tshortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,\n\t\t\tshortYearCutoff = (typeof shortYearCutoffTemp !== \"string\" ? shortYearCutoffTemp :\n\t\t\t\tnew Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),\n\t\t\tdayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,\n\t\t\tdayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,\n\t\t\tmonthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,\n\t\t\tmonthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,\n\t\t\tyear = -1,\n\t\t\tmonth = -1,\n\t\t\tday = -1,\n\t\t\tdoy = -1,\n\t\t\tliteral = false,\n\t\t\tdate,\n\t\t\t// Check whether a format character is doubled\n\t\t\tlookAhead = function(match) {\n\t\t\t\tvar matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);\n\t\t\t\tif (matches) {\n\t\t\t\t\tiFormat++;\n\t\t\t\t}\n\t\t\t\treturn matches;\n\t\t\t},\n\t\t\t// Extract a number from the string value\n\t\t\tgetNumber = function(match) {\n\t\t\t\tvar isDoubled = lookAhead(match),\n\t\t\t\t\tsize = (match === \"@\" ? 14 : (match === \"!\" ? 20 :\n\t\t\t\t\t(match === \"y\" && isDoubled ? 4 : (match === \"o\" ? 3 : 2)))),\n\t\t\t\t\tdigits = new RegExp(\"^\\\\d{1,\" + size + \"}\"),\n\t\t\t\t\tnum = value.substring(iValue).match(digits);\n\t\t\t\tif (!num) {\n\t\t\t\t\tthrow \"Missing number at position \" + iValue;\n\t\t\t\t}\n\t\t\t\tiValue += num[0].length;\n\t\t\t\treturn parseInt(num[0], 10);\n\t\t\t},\n\t\t\t// Extract a name from the string value and convert to an index\n\t\t\tgetName = function(match, shortNames, longNames) {\n\t\t\t\tvar index = -1,\n\t\t\t\t\tnames = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {\n\t\t\t\t\t\treturn [ [k, v] ];\n\t\t\t\t\t}).sort(function (a, b) {\n\t\t\t\t\t\treturn -(a[1].length - b[1].length);\n\t\t\t\t\t});\n\n\t\t\t\t$.each(names, function (i, pair) {\n\t\t\t\t\tvar name = pair[1];\n\t\t\t\t\tif (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {\n\t\t\t\t\t\tindex = pair[0];\n\t\t\t\t\t\tiValue += name.length;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tif (index !== -1) {\n\t\t\t\t\treturn index + 1;\n\t\t\t\t} else {\n\t\t\t\t\tthrow \"Unknown name at position \" + iValue;\n\t\t\t\t}\n\t\t\t},\n\t\t\t// Confirm that a literal character matches the string value\n\t\t\tcheckLiteral = function() {\n\t\t\t\tif (value.charAt(iValue) !== format.charAt(iFormat)) {\n\t\t\t\t\tthrow \"Unexpected literal at position \" + iValue;\n\t\t\t\t}\n\t\t\t\tiValue++;\n\t\t\t};\n\n\t\tfor (iFormat = 0; iFormat < format.length; iFormat++) {\n\t\t\tif (literal) {\n\t\t\t\tif (format.charAt(iFormat) === \"'\" && !lookAhead(\"'\")) {\n\t\t\t\t\tliteral = false;\n\t\t\t\t} else {\n\t\t\t\t\tcheckLiteral();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tswitch (format.charAt(iFormat)) {\n\t\t\t\t\tcase \"d\":\n\t\t\t\t\t\tday = getNumber(\"d\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"D\":\n\t\t\t\t\t\tgetName(\"D\", dayNamesShort, dayNames);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"o\":\n\t\t\t\t\t\tdoy = getNumber(\"o\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"m\":\n\t\t\t\t\t\tmonth = getNumber(\"m\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"M\":\n\t\t\t\t\t\tmonth = getName(\"M\", monthNamesShort, monthNames);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"y\":\n\t\t\t\t\t\tyear = getNumber(\"y\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"@\":\n\t\t\t\t\t\tdate = new Date(getNumber(\"@\"));\n\t\t\t\t\t\tyear = date.getFullYear();\n\t\t\t\t\t\tmonth = date.getMonth() + 1;\n\t\t\t\t\t\tday = date.getDate();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"!\":\n\t\t\t\t\t\tdate = new Date((getNumber(\"!\") - this._ticksTo1970) / 10000);\n\t\t\t\t\t\tyear = date.getFullYear();\n\t\t\t\t\t\tmonth = date.getMonth() + 1;\n\t\t\t\t\t\tday = date.getDate();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"'\":\n\t\t\t\t\t\tif (lookAhead(\"'\")){\n\t\t\t\t\t\t\tcheckLiteral();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tliteral = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tcheckLiteral();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (iValue < value.length){\n\t\t\textra = value.substr(iValue);\n\t\t\tif (!/^\\s+/.test(extra)) {\n\t\t\t\tthrow \"Extra/unparsed characters found in date: \" + extra;\n\t\t\t}\n\t\t}\n\n\t\tif (year === -1) {\n\t\t\tyear = new Date().getFullYear();\n\t\t} else if (year < 100) {\n\t\t\tyear += new Date().getFullYear() - new Date().getFullYear() % 100 +\n\t\t\t\t(year <= shortYearCutoff ? 0 : -100);\n\t\t}\n\n\t\tif (doy > -1) {\n\t\t\tmonth = 1;\n\t\t\tday = doy;\n\t\t\tdo {\n\t\t\t\tdim = this._getDaysInMonth(year, month - 1);\n\t\t\t\tif (day <= dim) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tmonth++;\n\t\t\t\tday -= dim;\n\t\t\t} while (true);\n\t\t}\n\n\t\tdate = this._daylightSavingAdjust(new Date(year, month - 1, day));\n\t\tif (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {\n\t\t\tthrow \"Invalid date\"; // E.g. 31/02/00\n\t\t}\n\t\treturn date;\n\t},\n\n\t/* Standard date formats. */\n\tATOM: \"yy-mm-dd\", // RFC 3339 (ISO 8601)\n\tCOOKIE: \"D, dd M yy\",\n\tISO_8601: \"yy-mm-dd\",\n\tRFC_822: \"D, d M y\",\n\tRFC_850: \"DD, dd-M-y\",\n\tRFC_1036: \"D, d M y\",\n\tRFC_1123: \"D, d M yy\",\n\tRFC_2822: \"D, d M yy\",\n\tRSS: \"D, d M y\", // RFC 822\n\tTICKS: \"!\",\n\tTIMESTAMP: \"@\",\n\tW3C: \"yy-mm-dd\", // ISO 8601\n\n\t_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +\n\t\tMath.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),\n\n\t/* Format a date object into a string value.\n\t * The format can be combinations of the following:\n\t * d  - day of month (no leading zero)\n\t * dd - day of month (two digit)\n\t * o  - day of year (no leading zeros)\n\t * oo - day of year (three digit)\n\t * D  - day name short\n\t * DD - day name long\n\t * m  - month of year (no leading zero)\n\t * mm - month of year (two digit)\n\t * M  - month name short\n\t * MM - month name long\n\t * y  - year (two digit)\n\t * yy - year (four digit)\n\t * @ - Unix timestamp (ms since 01/01/1970)\n\t * ! - Windows ticks (100ns since 01/01/0001)\n\t * \"...\" - literal text\n\t * '' - single quote\n\t *\n\t * @param  format string - the desired format of the date\n\t * @param  date Date - the date value to format\n\t * @param  settings Object - attributes include:\n\t *\t\t\t\t\tdayNamesShort\tstring[7] - abbreviated names of the days from Sunday (optional)\n\t *\t\t\t\t\tdayNames\t\tstring[7] - names of the days from Sunday (optional)\n\t *\t\t\t\t\tmonthNamesShort string[12] - abbreviated names of the months (optional)\n\t *\t\t\t\t\tmonthNames\t\tstring[12] - names of the months (optional)\n\t * @return  string - the date in the above format\n\t */\n\tformatDate: function (format, date, settings) {\n\t\tif (!date) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tvar iFormat,\n\t\t\tdayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,\n\t\t\tdayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,\n\t\t\tmonthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,\n\t\t\tmonthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,\n\t\t\t// Check whether a format character is doubled\n\t\t\tlookAhead = function(match) {\n\t\t\t\tvar matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);\n\t\t\t\tif (matches) {\n\t\t\t\t\tiFormat++;\n\t\t\t\t}\n\t\t\t\treturn matches;\n\t\t\t},\n\t\t\t// Format a number, with leading zero if necessary\n\t\t\tformatNumber = function(match, value, len) {\n\t\t\t\tvar num = \"\" + value;\n\t\t\t\tif (lookAhead(match)) {\n\t\t\t\t\twhile (num.length < len) {\n\t\t\t\t\t\tnum = \"0\" + num;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn num;\n\t\t\t},\n\t\t\t// Format a name, short or long as requested\n\t\t\tformatName = function(match, value, shortNames, longNames) {\n\t\t\t\treturn (lookAhead(match) ? longNames[value] : shortNames[value]);\n\t\t\t},\n\t\t\toutput = \"\",\n\t\t\tliteral = false;\n\n\t\tif (date) {\n\t\t\tfor (iFormat = 0; iFormat < format.length; iFormat++) {\n\t\t\t\tif (literal) {\n\t\t\t\t\tif (format.charAt(iFormat) === \"'\" && !lookAhead(\"'\")) {\n\t\t\t\t\t\tliteral = false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\toutput += format.charAt(iFormat);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tswitch (format.charAt(iFormat)) {\n\t\t\t\t\t\tcase \"d\":\n\t\t\t\t\t\t\toutput += formatNumber(\"d\", date.getDate(), 2);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"D\":\n\t\t\t\t\t\t\toutput += formatName(\"D\", date.getDay(), dayNamesShort, dayNames);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"o\":\n\t\t\t\t\t\t\toutput += formatNumber(\"o\",\n\t\t\t\t\t\t\t\tMath.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"m\":\n\t\t\t\t\t\t\toutput += formatNumber(\"m\", date.getMonth() + 1, 2);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"M\":\n\t\t\t\t\t\t\toutput += formatName(\"M\", date.getMonth(), monthNamesShort, monthNames);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"y\":\n\t\t\t\t\t\t\toutput += (lookAhead(\"y\") ? date.getFullYear() :\n\t\t\t\t\t\t\t\t(date.getYear() % 100 < 10 ? \"0\" : \"\") + date.getYear() % 100);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"@\":\n\t\t\t\t\t\t\toutput += date.getTime();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"!\":\n\t\t\t\t\t\t\toutput += date.getTime() * 10000 + this._ticksTo1970;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"'\":\n\t\t\t\t\t\t\tif (lookAhead(\"'\")) {\n\t\t\t\t\t\t\t\toutput += \"'\";\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tliteral = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\toutput += format.charAt(iFormat);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn output;\n\t},\n\n\t/* Extract all possible characters from the date format. */\n\t_possibleChars: function (format) {\n\t\tvar iFormat,\n\t\t\tchars = \"\",\n\t\t\tliteral = false,\n\t\t\t// Check whether a format character is doubled\n\t\t\tlookAhead = function(match) {\n\t\t\t\tvar matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);\n\t\t\t\tif (matches) {\n\t\t\t\t\tiFormat++;\n\t\t\t\t}\n\t\t\t\treturn matches;\n\t\t\t};\n\n\t\tfor (iFormat = 0; iFormat < format.length; iFormat++) {\n\t\t\tif (literal) {\n\t\t\t\tif (format.charAt(iFormat) === \"'\" && !lookAhead(\"'\")) {\n\t\t\t\t\tliteral = false;\n\t\t\t\t} else {\n\t\t\t\t\tchars += format.charAt(iFormat);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tswitch (format.charAt(iFormat)) {\n\t\t\t\t\tcase \"d\": case \"m\": case \"y\": case \"@\":\n\t\t\t\t\t\tchars += \"0123456789\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"D\": case \"M\":\n\t\t\t\t\t\treturn null; // Accept anything\n\t\t\t\t\tcase \"'\":\n\t\t\t\t\t\tif (lookAhead(\"'\")) {\n\t\t\t\t\t\t\tchars += \"'\";\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tliteral = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tchars += format.charAt(iFormat);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn chars;\n\t},\n\n\t/* Get a setting value, defaulting if necessary. */\n\t_get: function(inst, name) {\n\t\treturn inst.settings[name] !== undefined ?\n\t\t\tinst.settings[name] : this._defaults[name];\n\t},\n\n\t/* Parse existing date and initialise date picker. */\n\t_setDateFromField: function(inst, noDefault) {\n\t\tif (inst.input.val() === inst.lastVal) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar dateFormat = this._get(inst, \"dateFormat\"),\n\t\t\tdates = inst.lastVal = inst.input ? inst.input.val() : null,\n\t\t\tdefaultDate = this._getDefaultDate(inst),\n\t\t\tdate = defaultDate,\n\t\t\tsettings = this._getFormatConfig(inst);\n\n\t\ttry {\n\t\t\tdate = this.parseDate(dateFormat, dates, settings) || defaultDate;\n\t\t} catch (event) {\n\t\t\tdates = (noDefault ? \"\" : dates);\n\t\t}\n\t\tinst.selectedDay = date.getDate();\n\t\tinst.drawMonth = inst.selectedMonth = date.getMonth();\n\t\tinst.drawYear = inst.selectedYear = date.getFullYear();\n\t\tinst.currentDay = (dates ? date.getDate() : 0);\n\t\tinst.currentMonth = (dates ? date.getMonth() : 0);\n\t\tinst.currentYear = (dates ? date.getFullYear() : 0);\n\t\tthis._adjustInstDate(inst);\n\t},\n\n\t/* Retrieve the default date shown on opening. */\n\t_getDefaultDate: function(inst) {\n\t\treturn this._restrictMinMax(inst,\n\t\t\tthis._determineDate(inst, this._get(inst, \"defaultDate\"), new Date()));\n\t},\n\n\t/* A date may be specified as an exact value or a relative one. */\n\t_determineDate: function(inst, date, defaultDate) {\n\t\tvar offsetNumeric = function(offset) {\n\t\t\t\tvar date = new Date();\n\t\t\t\tdate.setDate(date.getDate() + offset);\n\t\t\t\treturn date;\n\t\t\t},\n\t\t\toffsetString = function(offset) {\n\t\t\t\ttry {\n\t\t\t\t\treturn $.datepicker.parseDate($.datepicker._get(inst, \"dateFormat\"),\n\t\t\t\t\t\toffset, $.datepicker._getFormatConfig(inst));\n\t\t\t\t}\n\t\t\t\tcatch (e) {\n\t\t\t\t\t// Ignore\n\t\t\t\t}\n\n\t\t\t\tvar date = (offset.toLowerCase().match(/^c/) ?\n\t\t\t\t\t$.datepicker._getDate(inst) : null) || new Date(),\n\t\t\t\t\tyear = date.getFullYear(),\n\t\t\t\t\tmonth = date.getMonth(),\n\t\t\t\t\tday = date.getDate(),\n\t\t\t\t\tpattern = /([+\\-]?[0-9]+)\\s*(d|D|w|W|m|M|y|Y)?/g,\n\t\t\t\t\tmatches = pattern.exec(offset);\n\n\t\t\t\twhile (matches) {\n\t\t\t\t\tswitch (matches[2] || \"d\") {\n\t\t\t\t\t\tcase \"d\" : case \"D\" :\n\t\t\t\t\t\t\tday += parseInt(matches[1],10); break;\n\t\t\t\t\t\tcase \"w\" : case \"W\" :\n\t\t\t\t\t\t\tday += parseInt(matches[1],10) * 7; break;\n\t\t\t\t\t\tcase \"m\" : case \"M\" :\n\t\t\t\t\t\t\tmonth += parseInt(matches[1],10);\n\t\t\t\t\t\t\tday = Math.min(day, $.datepicker._getDaysInMonth(year, month));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"y\": case \"Y\" :\n\t\t\t\t\t\t\tyear += parseInt(matches[1],10);\n\t\t\t\t\t\t\tday = Math.min(day, $.datepicker._getDaysInMonth(year, month));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tmatches = pattern.exec(offset);\n\t\t\t\t}\n\t\t\t\treturn new Date(year, month, day);\n\t\t\t},\n\t\t\tnewDate = (date == null || date === \"\" ? defaultDate : (typeof date === \"string\" ? offsetString(date) :\n\t\t\t\t(typeof date === \"number\" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));\n\n\t\tnewDate = (newDate && newDate.toString() === \"Invalid Date\" ? defaultDate : newDate);\n\t\tif (newDate) {\n\t\t\tnewDate.setHours(0);\n\t\t\tnewDate.setMinutes(0);\n\t\t\tnewDate.setSeconds(0);\n\t\t\tnewDate.setMilliseconds(0);\n\t\t}\n\t\treturn this._daylightSavingAdjust(newDate);\n\t},\n\n\t/* Handle switch to/from daylight saving.\n\t * Hours may be non-zero on daylight saving cut-over:\n\t * > 12 when midnight changeover, but then cannot generate\n\t * midnight datetime, so jump to 1AM, otherwise reset.\n\t * @param  date  (Date) the date to check\n\t * @return  (Date) the corrected date\n\t */\n\t_daylightSavingAdjust: function(date) {\n\t\tif (!date) {\n\t\t\treturn null;\n\t\t}\n\t\tdate.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);\n\t\treturn date;\n\t},\n\n\t/* Set the date(s) directly. */\n\t_setDate: function(inst, date, noChange) {\n\t\tvar clear = !date,\n\t\t\torigMonth = inst.selectedMonth,\n\t\t\torigYear = inst.selectedYear,\n\t\t\tnewDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));\n\n\t\tinst.selectedDay = inst.currentDay = newDate.getDate();\n\t\tinst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();\n\t\tinst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();\n\t\tif ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {\n\t\t\tthis._notifyChange(inst);\n\t\t}\n\t\tthis._adjustInstDate(inst);\n\t\tif (inst.input) {\n\t\t\tinst.input.val(clear ? \"\" : this._formatDate(inst));\n\t\t}\n\t},\n\n\t/* Retrieve the date(s) directly. */\n\t_getDate: function(inst) {\n\t\tvar startDate = (!inst.currentYear || (inst.input && inst.input.val() === \"\") ? null :\n\t\t\tthis._daylightSavingAdjust(new Date(\n\t\t\tinst.currentYear, inst.currentMonth, inst.currentDay)));\n\t\t\treturn startDate;\n\t},\n\n\t/* Attach the onxxx handlers.  These are declared statically so\n\t * they work with static code transformers like Caja.\n\t */\n\t_attachHandlers: function(inst) {\n\t\tvar stepMonths = this._get(inst, \"stepMonths\"),\n\t\t\tid = \"#\" + inst.id.replace( /\\\\\\\\/g, \"\\\\\" );\n\t\tinst.dpDiv.find(\"[data-handler]\").map(function () {\n\t\t\tvar handler = {\n\t\t\t\tprev: function () {\n\t\t\t\t\t$.datepicker._adjustDate(id, -stepMonths, \"M\");\n\t\t\t\t},\n\t\t\t\tnext: function () {\n\t\t\t\t\t$.datepicker._adjustDate(id, +stepMonths, \"M\");\n\t\t\t\t},\n\t\t\t\thide: function () {\n\t\t\t\t\t$.datepicker._hideDatepicker();\n\t\t\t\t},\n\t\t\t\ttoday: function () {\n\t\t\t\t\t$.datepicker._gotoToday(id);\n\t\t\t\t},\n\t\t\t\tselectDay: function () {\n\t\t\t\t\t$.datepicker._selectDay(id, +this.getAttribute(\"data-month\"), +this.getAttribute(\"data-year\"), this);\n\t\t\t\t\treturn false;\n\t\t\t\t},\n\t\t\t\tselectMonth: function () {\n\t\t\t\t\t$.datepicker._selectMonthYear(id, this, \"M\");\n\t\t\t\t\treturn false;\n\t\t\t\t},\n\t\t\t\tselectYear: function () {\n\t\t\t\t\t$.datepicker._selectMonthYear(id, this, \"Y\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t};\n\t\t\t$(this).bind(this.getAttribute(\"data-event\"), handler[this.getAttribute(\"data-handler\")]);\n\t\t});\n\t},\n\n\t/* Generate the HTML for the current state of the date picker. */\n\t_generateHTML: function(inst) {\n\t\tvar maxDraw, prevText, prev, nextText, next, currentText, gotoDate,\n\t\t\tcontrols, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,\n\t\t\tmonthNames, monthNamesShort, beforeShowDay, showOtherMonths,\n\t\t\tselectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,\n\t\t\tcornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,\n\t\t\tprintDate, dRow, tbody, daySettings, otherMonth, unselectable,\n\t\t\ttempDate = new Date(),\n\t\t\ttoday = this._daylightSavingAdjust(\n\t\t\t\tnew Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time\n\t\t\tisRTL = this._get(inst, \"isRTL\"),\n\t\t\tshowButtonPanel = this._get(inst, \"showButtonPanel\"),\n\t\t\thideIfNoPrevNext = this._get(inst, \"hideIfNoPrevNext\"),\n\t\t\tnavigationAsDateFormat = this._get(inst, \"navigationAsDateFormat\"),\n\t\t\tnumMonths = this._getNumberOfMonths(inst),\n\t\t\tshowCurrentAtPos = this._get(inst, \"showCurrentAtPos\"),\n\t\t\tstepMonths = this._get(inst, \"stepMonths\"),\n\t\t\tisMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),\n\t\t\tcurrentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :\n\t\t\t\tnew Date(inst.currentYear, inst.currentMonth, inst.currentDay))),\n\t\t\tminDate = this._getMinMaxDate(inst, \"min\"),\n\t\t\tmaxDate = this._getMinMaxDate(inst, \"max\"),\n\t\t\tdrawMonth = inst.drawMonth - showCurrentAtPos,\n\t\t\tdrawYear = inst.drawYear;\n\n\t\tif (drawMonth < 0) {\n\t\t\tdrawMonth += 12;\n\t\t\tdrawYear--;\n\t\t}\n\t\tif (maxDate) {\n\t\t\tmaxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),\n\t\t\t\tmaxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));\n\t\t\tmaxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);\n\t\t\twhile (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {\n\t\t\t\tdrawMonth--;\n\t\t\t\tif (drawMonth < 0) {\n\t\t\t\t\tdrawMonth = 11;\n\t\t\t\t\tdrawYear--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tinst.drawMonth = drawMonth;\n\t\tinst.drawYear = drawYear;\n\n\t\tprevText = this._get(inst, \"prevText\");\n\t\tprevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,\n\t\t\tthis._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),\n\t\t\tthis._getFormatConfig(inst)));\n\n\t\tprev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?\n\t\t\t\"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'\" +\n\t\t\t\" title='\" + prevText + \"'><span class='ui-icon ui-icon-circle-triangle-\" + ( isRTL ? \"e\" : \"w\") + \"'>\" + prevText + \"</span></a>\" :\n\t\t\t(hideIfNoPrevNext ? \"\" : \"<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='\"+ prevText +\"'><span class='ui-icon ui-icon-circle-triangle-\" + ( isRTL ? \"e\" : \"w\") + \"'>\" + prevText + \"</span></a>\"));\n\n\t\tnextText = this._get(inst, \"nextText\");\n\t\tnextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,\n\t\t\tthis._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),\n\t\t\tthis._getFormatConfig(inst)));\n\n\t\tnext = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?\n\t\t\t\"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'\" +\n\t\t\t\" title='\" + nextText + \"'><span class='ui-icon ui-icon-circle-triangle-\" + ( isRTL ? \"w\" : \"e\") + \"'>\" + nextText + \"</span></a>\" :\n\t\t\t(hideIfNoPrevNext ? \"\" : \"<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='\"+ nextText + \"'><span class='ui-icon ui-icon-circle-triangle-\" + ( isRTL ? \"w\" : \"e\") + \"'>\" + nextText + \"</span></a>\"));\n\n\t\tcurrentText = this._get(inst, \"currentText\");\n\t\tgotoDate = (this._get(inst, \"gotoCurrent\") && inst.currentDay ? currentDate : today);\n\t\tcurrentText = (!navigationAsDateFormat ? currentText :\n\t\t\tthis.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));\n\n\t\tcontrols = (!inst.inline ? \"<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>\" +\n\t\t\tthis._get(inst, \"closeText\") + \"</button>\" : \"\");\n\n\t\tbuttonPanel = (showButtonPanel) ? \"<div class='ui-datepicker-buttonpane ui-widget-content'>\" + (isRTL ? controls : \"\") +\n\t\t\t(this._isInRange(inst, gotoDate) ? \"<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'\" +\n\t\t\t\">\" + currentText + \"</button>\" : \"\") + (isRTL ? \"\" : controls) + \"</div>\" : \"\";\n\n\t\tfirstDay = parseInt(this._get(inst, \"firstDay\"),10);\n\t\tfirstDay = (isNaN(firstDay) ? 0 : firstDay);\n\n\t\tshowWeek = this._get(inst, \"showWeek\");\n\t\tdayNames = this._get(inst, \"dayNames\");\n\t\tdayNamesMin = this._get(inst, \"dayNamesMin\");\n\t\tmonthNames = this._get(inst, \"monthNames\");\n\t\tmonthNamesShort = this._get(inst, \"monthNamesShort\");\n\t\tbeforeShowDay = this._get(inst, \"beforeShowDay\");\n\t\tshowOtherMonths = this._get(inst, \"showOtherMonths\");\n\t\tselectOtherMonths = this._get(inst, \"selectOtherMonths\");\n\t\tdefaultDate = this._getDefaultDate(inst);\n\t\thtml = \"\";\n\t\tdow;\n\t\tfor (row = 0; row < numMonths[0]; row++) {\n\t\t\tgroup = \"\";\n\t\t\tthis.maxRows = 4;\n\t\t\tfor (col = 0; col < numMonths[1]; col++) {\n\t\t\t\tselectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));\n\t\t\t\tcornerClass = \" ui-corner-all\";\n\t\t\t\tcalender = \"\";\n\t\t\t\tif (isMultiMonth) {\n\t\t\t\t\tcalender += \"<div class='ui-datepicker-group\";\n\t\t\t\t\tif (numMonths[1] > 1) {\n\t\t\t\t\t\tswitch (col) {\n\t\t\t\t\t\t\tcase 0: calender += \" ui-datepicker-group-first\";\n\t\t\t\t\t\t\t\tcornerClass = \" ui-corner-\" + (isRTL ? \"right\" : \"left\"); break;\n\t\t\t\t\t\t\tcase numMonths[1]-1: calender += \" ui-datepicker-group-last\";\n\t\t\t\t\t\t\t\tcornerClass = \" ui-corner-\" + (isRTL ? \"left\" : \"right\"); break;\n\t\t\t\t\t\t\tdefault: calender += \" ui-datepicker-group-middle\"; cornerClass = \"\"; break;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcalender += \"'>\";\n\t\t\t\t}\n\t\t\t\tcalender += \"<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix\" + cornerClass + \"'>\" +\n\t\t\t\t\t(/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : \"\") +\n\t\t\t\t\t(/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : \"\") +\n\t\t\t\t\tthis._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,\n\t\t\t\t\trow > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers\n\t\t\t\t\t\"</div><table class='ui-datepicker-calendar'><thead>\" +\n\t\t\t\t\t\"<tr>\";\n\t\t\t\tthead = (showWeek ? \"<th class='ui-datepicker-week-col'>\" + this._get(inst, \"weekHeader\") + \"</th>\" : \"\");\n\t\t\t\tfor (dow = 0; dow < 7; dow++) { // days of the week\n\t\t\t\t\tday = (dow + firstDay) % 7;\n\t\t\t\t\tthead += \"<th\" + ((dow + firstDay + 6) % 7 >= 5 ? \" class='ui-datepicker-week-end'\" : \"\") + \">\" +\n\t\t\t\t\t\t\"<span title='\" + dayNames[day] + \"'>\" + dayNamesMin[day] + \"</span></th>\";\n\t\t\t\t}\n\t\t\t\tcalender += thead + \"</tr></thead><tbody>\";\n\t\t\t\tdaysInMonth = this._getDaysInMonth(drawYear, drawMonth);\n\t\t\t\tif (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {\n\t\t\t\t\tinst.selectedDay = Math.min(inst.selectedDay, daysInMonth);\n\t\t\t\t}\n\t\t\t\tleadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;\n\t\t\t\tcurRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate\n\t\t\t\tnumRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)\n\t\t\t\tthis.maxRows = numRows;\n\t\t\t\tprintDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));\n\t\t\t\tfor (dRow = 0; dRow < numRows; dRow++) { // create date picker rows\n\t\t\t\t\tcalender += \"<tr>\";\n\t\t\t\t\ttbody = (!showWeek ? \"\" : \"<td class='ui-datepicker-week-col'>\" +\n\t\t\t\t\t\tthis._get(inst, \"calculateWeek\")(printDate) + \"</td>\");\n\t\t\t\t\tfor (dow = 0; dow < 7; dow++) { // create date picker days\n\t\t\t\t\t\tdaySettings = (beforeShowDay ?\n\t\t\t\t\t\t\tbeforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, \"\"]);\n\t\t\t\t\t\totherMonth = (printDate.getMonth() !== drawMonth);\n\t\t\t\t\t\tunselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||\n\t\t\t\t\t\t\t(minDate && printDate < minDate) || (maxDate && printDate > maxDate);\n\t\t\t\t\t\ttbody += \"<td class='\" +\n\t\t\t\t\t\t\t((dow + firstDay + 6) % 7 >= 5 ? \" ui-datepicker-week-end\" : \"\") + // highlight weekends\n\t\t\t\t\t\t\t(otherMonth ? \" ui-datepicker-other-month\" : \"\") + // highlight days from other months\n\t\t\t\t\t\t\t((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key\n\t\t\t\t\t\t\t(defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?\n\t\t\t\t\t\t\t// or defaultDate is current printedDate and defaultDate is selectedDate\n\t\t\t\t\t\t\t\" \" + this._dayOverClass : \"\") + // highlight selected day\n\t\t\t\t\t\t\t(unselectable ? \" \" + this._unselectableClass + \" ui-state-disabled\": \"\") +  // highlight unselectable days\n\t\t\t\t\t\t\t(otherMonth && !showOtherMonths ? \"\" : \" \" + daySettings[1] + // highlight custom dates\n\t\t\t\t\t\t\t(printDate.getTime() === currentDate.getTime() ? \" \" + this._currentClass : \"\") + // highlight selected day\n\t\t\t\t\t\t\t(printDate.getTime() === today.getTime() ? \" ui-datepicker-today\" : \"\")) + \"'\" + // highlight today (if different)\n\t\t\t\t\t\t\t((!otherMonth || showOtherMonths) && daySettings[2] ? \" title='\" + daySettings[2].replace(/'/g, \"&#39;\") + \"'\" : \"\") + // cell title\n\t\t\t\t\t\t\t(unselectable ? \"\" : \" data-handler='selectDay' data-event='click' data-month='\" + printDate.getMonth() + \"' data-year='\" + printDate.getFullYear() + \"'\") + \">\" + // actions\n\t\t\t\t\t\t\t(otherMonth && !showOtherMonths ? \"&#xa0;\" : // display for other months\n\t\t\t\t\t\t\t(unselectable ? \"<span class='ui-state-default'>\" + printDate.getDate() + \"</span>\" : \"<a class='ui-state-default\" +\n\t\t\t\t\t\t\t(printDate.getTime() === today.getTime() ? \" ui-state-highlight\" : \"\") +\n\t\t\t\t\t\t\t(printDate.getTime() === currentDate.getTime() ? \" ui-state-active\" : \"\") + // highlight selected day\n\t\t\t\t\t\t\t(otherMonth ? \" ui-priority-secondary\" : \"\") + // distinguish dates from other months\n\t\t\t\t\t\t\t\"' href='#'>\" + printDate.getDate() + \"</a>\")) + \"</td>\"; // display selectable date\n\t\t\t\t\t\tprintDate.setDate(printDate.getDate() + 1);\n\t\t\t\t\t\tprintDate = this._daylightSavingAdjust(printDate);\n\t\t\t\t\t}\n\t\t\t\t\tcalender += tbody + \"</tr>\";\n\t\t\t\t}\n\t\t\t\tdrawMonth++;\n\t\t\t\tif (drawMonth > 11) {\n\t\t\t\t\tdrawMonth = 0;\n\t\t\t\t\tdrawYear++;\n\t\t\t\t}\n\t\t\t\tcalender += \"</tbody></table>\" + (isMultiMonth ? \"</div>\" +\n\t\t\t\t\t\t\t((numMonths[0] > 0 && col === numMonths[1]-1) ? \"<div class='ui-datepicker-row-break'></div>\" : \"\") : \"\");\n\t\t\t\tgroup += calender;\n\t\t\t}\n\t\t\thtml += group;\n\t\t}\n\t\thtml += buttonPanel;\n\t\tinst._keyEvent = false;\n\t\treturn html;\n\t},\n\n\t/* Generate the month and year header. */\n\t_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,\n\t\t\tsecondary, monthNames, monthNamesShort) {\n\n\t\tvar inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,\n\t\t\tchangeMonth = this._get(inst, \"changeMonth\"),\n\t\t\tchangeYear = this._get(inst, \"changeYear\"),\n\t\t\tshowMonthAfterYear = this._get(inst, \"showMonthAfterYear\"),\n\t\t\thtml = \"<div class='ui-datepicker-title'>\",\n\t\t\tmonthHtml = \"\";\n\n\t\t// month selection\n\t\tif (secondary || !changeMonth) {\n\t\t\tmonthHtml += \"<span class='ui-datepicker-month'>\" + monthNames[drawMonth] + \"</span>\";\n\t\t} else {\n\t\t\tinMinYear = (minDate && minDate.getFullYear() === drawYear);\n\t\t\tinMaxYear = (maxDate && maxDate.getFullYear() === drawYear);\n\t\t\tmonthHtml += \"<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>\";\n\t\t\tfor ( month = 0; month < 12; month++) {\n\t\t\t\tif ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {\n\t\t\t\t\tmonthHtml += \"<option value='\" + month + \"'\" +\n\t\t\t\t\t\t(month === drawMonth ? \" selected='selected'\" : \"\") +\n\t\t\t\t\t\t\">\" + monthNamesShort[month] + \"</option>\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tmonthHtml += \"</select>\";\n\t\t}\n\n\t\tif (!showMonthAfterYear) {\n\t\t\thtml += monthHtml + (secondary || !(changeMonth && changeYear) ? \"&#xa0;\" : \"\");\n\t\t}\n\n\t\t// year selection\n\t\tif ( !inst.yearshtml ) {\n\t\t\tinst.yearshtml = \"\";\n\t\t\tif (secondary || !changeYear) {\n\t\t\t\thtml += \"<span class='ui-datepicker-year'>\" + drawYear + \"</span>\";\n\t\t\t} else {\n\t\t\t\t// determine range of years to display\n\t\t\t\tyears = this._get(inst, \"yearRange\").split(\":\");\n\t\t\t\tthisYear = new Date().getFullYear();\n\t\t\t\tdetermineYear = function(value) {\n\t\t\t\t\tvar year = (value.match(/c[+\\-].*/) ? drawYear + parseInt(value.substring(1), 10) :\n\t\t\t\t\t\t(value.match(/[+\\-].*/) ? thisYear + parseInt(value, 10) :\n\t\t\t\t\t\tparseInt(value, 10)));\n\t\t\t\t\treturn (isNaN(year) ? thisYear : year);\n\t\t\t\t};\n\t\t\t\tyear = determineYear(years[0]);\n\t\t\t\tendYear = Math.max(year, determineYear(years[1] || \"\"));\n\t\t\t\tyear = (minDate ? Math.max(year, minDate.getFullYear()) : year);\n\t\t\t\tendYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);\n\t\t\t\tinst.yearshtml += \"<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>\";\n\t\t\t\tfor (; year <= endYear; year++) {\n\t\t\t\t\tinst.yearshtml += \"<option value='\" + year + \"'\" +\n\t\t\t\t\t\t(year === drawYear ? \" selected='selected'\" : \"\") +\n\t\t\t\t\t\t\">\" + year + \"</option>\";\n\t\t\t\t}\n\t\t\t\tinst.yearshtml += \"</select>\";\n\n\t\t\t\thtml += inst.yearshtml;\n\t\t\t\tinst.yearshtml = null;\n\t\t\t}\n\t\t}\n\n\t\thtml += this._get(inst, \"yearSuffix\");\n\t\tif (showMonthAfterYear) {\n\t\t\thtml += (secondary || !(changeMonth && changeYear) ? \"&#xa0;\" : \"\") + monthHtml;\n\t\t}\n\t\thtml += \"</div>\"; // Close datepicker_header\n\t\treturn html;\n\t},\n\n\t/* Adjust one of the date sub-fields. */\n\t_adjustInstDate: function(inst, offset, period) {\n\t\tvar year = inst.drawYear + (period === \"Y\" ? offset : 0),\n\t\t\tmonth = inst.drawMonth + (period === \"M\" ? offset : 0),\n\t\t\tday = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === \"D\" ? offset : 0),\n\t\t\tdate = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));\n\n\t\tinst.selectedDay = date.getDate();\n\t\tinst.drawMonth = inst.selectedMonth = date.getMonth();\n\t\tinst.drawYear = inst.selectedYear = date.getFullYear();\n\t\tif (period === \"M\" || period === \"Y\") {\n\t\t\tthis._notifyChange(inst);\n\t\t}\n\t},\n\n\t/* Ensure a date is within any min/max bounds. */\n\t_restrictMinMax: function(inst, date) {\n\t\tvar minDate = this._getMinMaxDate(inst, \"min\"),\n\t\t\tmaxDate = this._getMinMaxDate(inst, \"max\"),\n\t\t\tnewDate = (minDate && date < minDate ? minDate : date);\n\t\treturn (maxDate && newDate > maxDate ? maxDate : newDate);\n\t},\n\n\t/* Notify change of month/year. */\n\t_notifyChange: function(inst) {\n\t\tvar onChange = this._get(inst, \"onChangeMonthYear\");\n\t\tif (onChange) {\n\t\t\tonChange.apply((inst.input ? inst.input[0] : null),\n\t\t\t\t[inst.selectedYear, inst.selectedMonth + 1, inst]);\n\t\t}\n\t},\n\n\t/* Determine the number of months to show. */\n\t_getNumberOfMonths: function(inst) {\n\t\tvar numMonths = this._get(inst, \"numberOfMonths\");\n\t\treturn (numMonths == null ? [1, 1] : (typeof numMonths === \"number\" ? [1, numMonths] : numMonths));\n\t},\n\n\t/* Determine the current maximum date - ensure no time components are set. */\n\t_getMinMaxDate: function(inst, minMax) {\n\t\treturn this._determineDate(inst, this._get(inst, minMax + \"Date\"), null);\n\t},\n\n\t/* Find the number of days in a given month. */\n\t_getDaysInMonth: function(year, month) {\n\t\treturn 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();\n\t},\n\n\t/* Find the day of the week of the first of a month. */\n\t_getFirstDayOfMonth: function(year, month) {\n\t\treturn new Date(year, month, 1).getDay();\n\t},\n\n\t/* Determines if we should allow a \"next/prev\" month display change. */\n\t_canAdjustMonth: function(inst, offset, curYear, curMonth) {\n\t\tvar numMonths = this._getNumberOfMonths(inst),\n\t\t\tdate = this._daylightSavingAdjust(new Date(curYear,\n\t\t\tcurMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));\n\n\t\tif (offset < 0) {\n\t\t\tdate.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));\n\t\t}\n\t\treturn this._isInRange(inst, date);\n\t},\n\n\t/* Is the given date in the accepted range? */\n\t_isInRange: function(inst, date) {\n\t\tvar yearSplit, currentYear,\n\t\t\tminDate = this._getMinMaxDate(inst, \"min\"),\n\t\t\tmaxDate = this._getMinMaxDate(inst, \"max\"),\n\t\t\tminYear = null,\n\t\t\tmaxYear = null,\n\t\t\tyears = this._get(inst, \"yearRange\");\n\t\t\tif (years){\n\t\t\t\tyearSplit = years.split(\":\");\n\t\t\t\tcurrentYear = new Date().getFullYear();\n\t\t\t\tminYear = parseInt(yearSplit[0], 10);\n\t\t\t\tmaxYear = parseInt(yearSplit[1], 10);\n\t\t\t\tif ( yearSplit[0].match(/[+\\-].*/) ) {\n\t\t\t\t\tminYear += currentYear;\n\t\t\t\t}\n\t\t\t\tif ( yearSplit[1].match(/[+\\-].*/) ) {\n\t\t\t\t\tmaxYear += currentYear;\n\t\t\t\t}\n\t\t\t}\n\n\t\treturn ((!minDate || date.getTime() >= minDate.getTime()) &&\n\t\t\t(!maxDate || date.getTime() <= maxDate.getTime()) &&\n\t\t\t(!minYear || date.getFullYear() >= minYear) &&\n\t\t\t(!maxYear || date.getFullYear() <= maxYear));\n\t},\n\n\t/* Provide the configuration settings for formatting/parsing. */\n\t_getFormatConfig: function(inst) {\n\t\tvar shortYearCutoff = this._get(inst, \"shortYearCutoff\");\n\t\tshortYearCutoff = (typeof shortYearCutoff !== \"string\" ? shortYearCutoff :\n\t\t\tnew Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));\n\t\treturn {shortYearCutoff: shortYearCutoff,\n\t\t\tdayNamesShort: this._get(inst, \"dayNamesShort\"), dayNames: this._get(inst, \"dayNames\"),\n\t\t\tmonthNamesShort: this._get(inst, \"monthNamesShort\"), monthNames: this._get(inst, \"monthNames\")};\n\t},\n\n\t/* Format the given date for display. */\n\t_formatDate: function(inst, day, month, year) {\n\t\tif (!day) {\n\t\t\tinst.currentDay = inst.selectedDay;\n\t\t\tinst.currentMonth = inst.selectedMonth;\n\t\t\tinst.currentYear = inst.selectedYear;\n\t\t}\n\t\tvar date = (day ? (typeof day === \"object\" ? day :\n\t\t\tthis._daylightSavingAdjust(new Date(year, month, day))) :\n\t\t\tthis._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));\n\t\treturn this.formatDate(this._get(inst, \"dateFormat\"), date, this._getFormatConfig(inst));\n\t}\n});\n\n/*\n * Bind hover events for datepicker elements.\n * Done via delegate so the binding only occurs once in the lifetime of the parent div.\n * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.\n */\nfunction bindHover(dpDiv) {\n\tvar selector = \"button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a\";\n\treturn dpDiv.delegate(selector, \"mouseout\", function() {\n\t\t\t$(this).removeClass(\"ui-state-hover\");\n\t\t\tif (this.className.indexOf(\"ui-datepicker-prev\") !== -1) {\n\t\t\t\t$(this).removeClass(\"ui-datepicker-prev-hover\");\n\t\t\t}\n\t\t\tif (this.className.indexOf(\"ui-datepicker-next\") !== -1) {\n\t\t\t\t$(this).removeClass(\"ui-datepicker-next-hover\");\n\t\t\t}\n\t\t})\n\t\t.delegate(selector, \"mouseover\", function(){\n\t\t\tif (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {\n\t\t\t\t$(this).parents(\".ui-datepicker-calendar\").find(\"a\").removeClass(\"ui-state-hover\");\n\t\t\t\t$(this).addClass(\"ui-state-hover\");\n\t\t\t\tif (this.className.indexOf(\"ui-datepicker-prev\") !== -1) {\n\t\t\t\t\t$(this).addClass(\"ui-datepicker-prev-hover\");\n\t\t\t\t}\n\t\t\t\tif (this.className.indexOf(\"ui-datepicker-next\") !== -1) {\n\t\t\t\t\t$(this).addClass(\"ui-datepicker-next-hover\");\n\t\t\t\t}\n\t\t\t}\n\t\t});\n}\n\n/* jQuery extend now ignores nulls! */\nfunction extendRemove(target, props) {\n\t$.extend(target, props);\n\tfor (var name in props) {\n\t\tif (props[name] == null) {\n\t\t\ttarget[name] = props[name];\n\t\t}\n\t}\n\treturn target;\n}\n\n/* Invoke the datepicker functionality.\n   @param  options  string - a command, optionally followed by additional parameters or\n\t\t\t\t\tObject - settings for attaching new datepicker functionality\n   @return  jQuery object */\n$.fn.datepicker = function(options){\n\n\t/* Verify an empty collection wasn't passed - Fixes #6976 */\n\tif ( !this.length ) {\n\t\treturn this;\n\t}\n\n\t/* Initialise the date picker. */\n\tif (!$.datepicker.initialized) {\n\t\t$(document).mousedown($.datepicker._checkExternalClick);\n\t\t$.datepicker.initialized = true;\n\t}\n\n\t/* Append datepicker main container to body if not exist. */\n\tif ($(\"#\"+$.datepicker._mainDivId).length === 0) {\n\t\t$(\"body\").append($.datepicker.dpDiv);\n\t}\n\n\tvar otherArgs = Array.prototype.slice.call(arguments, 1);\n\tif (typeof options === \"string\" && (options === \"isDisabled\" || options === \"getDate\" || options === \"widget\")) {\n\t\treturn $.datepicker[\"_\" + options + \"Datepicker\"].\n\t\t\tapply($.datepicker, [this[0]].concat(otherArgs));\n\t}\n\tif (options === \"option\" && arguments.length === 2 && typeof arguments[1] === \"string\") {\n\t\treturn $.datepicker[\"_\" + options + \"Datepicker\"].\n\t\t\tapply($.datepicker, [this[0]].concat(otherArgs));\n\t}\n\treturn this.each(function() {\n\t\ttypeof options === \"string\" ?\n\t\t\t$.datepicker[\"_\" + options + \"Datepicker\"].\n\t\t\t\tapply($.datepicker, [this].concat(otherArgs)) :\n\t\t\t$.datepicker._attachDatepicker(this, options);\n\t});\n};\n\n$.datepicker = new Datepicker(); // singleton instance\n$.datepicker.initialized = false;\n$.datepicker.uuid = new Date().getTime();\n$.datepicker.version = \"1.10.3\";\n\n})(jQuery);\n\n(function( $, undefined ) {\n\nvar sizeRelatedOptions = {\n\t\tbuttons: true,\n\t\theight: true,\n\t\tmaxHeight: true,\n\t\tmaxWidth: true,\n\t\tminHeight: true,\n\t\tminWidth: true,\n\t\twidth: true\n\t},\n\tresizableRelatedOptions = {\n\t\tmaxHeight: true,\n\t\tmaxWidth: true,\n\t\tminHeight: true,\n\t\tminWidth: true\n\t};\n\n$.widget( \"ui.dialog\", {\n\tversion: \"1.10.3\",\n\toptions: {\n\t\tappendTo: \"body\",\n\t\tautoOpen: true,\n\t\tbuttons: [],\n\t\tcloseOnEscape: true,\n\t\tcloseText: \"close\",\n\t\tdialogClass: \"\",\n\t\tdraggable: true,\n\t\thide: null,\n\t\theight: \"auto\",\n\t\tmaxHeight: null,\n\t\tmaxWidth: null,\n\t\tminHeight: 150,\n\t\tminWidth: 150,\n\t\tmodal: false,\n\t\tposition: {\n\t\t\tmy: \"center\",\n\t\t\tat: \"center\",\n\t\t\tof: window,\n\t\t\tcollision: \"fit\",\n\t\t\t// Ensure the titlebar is always visible\n\t\t\tusing: function( pos ) {\n\t\t\t\tvar topOffset = $( this ).css( pos ).offset().top;\n\t\t\t\tif ( topOffset < 0 ) {\n\t\t\t\t\t$( this ).css( \"top\", pos.top - topOffset );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tresizable: true,\n\t\tshow: null,\n\t\ttitle: null,\n\t\twidth: 300,\n\n\t\t// callbacks\n\t\tbeforeClose: null,\n\t\tclose: null,\n\t\tdrag: null,\n\t\tdragStart: null,\n\t\tdragStop: null,\n\t\tfocus: null,\n\t\topen: null,\n\t\tresize: null,\n\t\tresizeStart: null,\n\t\tresizeStop: null\n\t},\n\n\t_create: function() {\n\t\tthis.originalCss = {\n\t\t\tdisplay: this.element[0].style.display,\n\t\t\twidth: this.element[0].style.width,\n\t\t\tminHeight: this.element[0].style.minHeight,\n\t\t\tmaxHeight: this.element[0].style.maxHeight,\n\t\t\theight: this.element[0].style.height\n\t\t};\n\t\tthis.originalPosition = {\n\t\t\tparent: this.element.parent(),\n\t\t\tindex: this.element.parent().children().index( this.element )\n\t\t};\n\t\tthis.originalTitle = this.element.attr(\"title\");\n\t\tthis.options.title = this.options.title || this.originalTitle;\n\n\t\tthis._createWrapper();\n\n\t\tthis.element\n\t\t\t.show()\n\t\t\t.removeAttr(\"title\")\n\t\t\t.addClass(\"ui-dialog-content ui-widget-content\")\n\t\t\t.appendTo( this.uiDialog );\n\n\t\tthis._createTitlebar();\n\t\tthis._createButtonPane();\n\n\t\tif ( this.options.draggable && $.fn.draggable ) {\n\t\t\tthis._makeDraggable();\n\t\t}\n\t\tif ( this.options.resizable && $.fn.resizable ) {\n\t\t\tthis._makeResizable();\n\t\t}\n\n\t\tthis._isOpen = false;\n\t},\n\n\t_init: function() {\n\t\tif ( this.options.autoOpen ) {\n\t\t\tthis.open();\n\t\t}\n\t},\n\n\t_appendTo: function() {\n\t\tvar element = this.options.appendTo;\n\t\tif ( element && (element.jquery || element.nodeType) ) {\n\t\t\treturn $( element );\n\t\t}\n\t\treturn this.document.find( element || \"body\" ).eq( 0 );\n\t},\n\n\t_destroy: function() {\n\t\tvar next,\n\t\t\toriginalPosition = this.originalPosition;\n\n\t\tthis._destroyOverlay();\n\n\t\tthis.element\n\t\t\t.removeUniqueId()\n\t\t\t.removeClass(\"ui-dialog-content ui-widget-content\")\n\t\t\t.css( this.originalCss )\n\t\t\t// Without detaching first, the following becomes really slow\n\t\t\t.detach();\n\n\t\tthis.uiDialog.stop( true, true ).remove();\n\n\t\tif ( this.originalTitle ) {\n\t\t\tthis.element.attr( \"title\", this.originalTitle );\n\t\t}\n\n\t\tnext = originalPosition.parent.children().eq( originalPosition.index );\n\t\t// Don't try to place the dialog next to itself (#8613)\n\t\tif ( next.length && next[0] !== this.element[0] ) {\n\t\t\tnext.before( this.element );\n\t\t} else {\n\t\t\toriginalPosition.parent.append( this.element );\n\t\t}\n\t},\n\n\twidget: function() {\n\t\treturn this.uiDialog;\n\t},\n\n\tdisable: $.noop,\n\tenable: $.noop,\n\n\tclose: function( event ) {\n\t\tvar that = this;\n\n\t\tif ( !this._isOpen || this._trigger( \"beforeClose\", event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._isOpen = false;\n\t\tthis._destroyOverlay();\n\n\t\tif ( !this.opener.filter(\":focusable\").focus().length ) {\n\t\t\t// Hiding a focused element doesn't trigger blur in WebKit\n\t\t\t// so in case we have nothing to focus on, explicitly blur the active element\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=47182\n\t\t\t$( this.document[0].activeElement ).blur();\n\t\t}\n\n\t\tthis._hide( this.uiDialog, this.options.hide, function() {\n\t\t\tthat._trigger( \"close\", event );\n\t\t});\n\t},\n\n\tisOpen: function() {\n\t\treturn this._isOpen;\n\t},\n\n\tmoveToTop: function() {\n\t\tthis._moveToTop();\n\t},\n\n\t_moveToTop: function( event, silent ) {\n\t\tvar moved = !!this.uiDialog.nextAll(\":visible\").insertBefore( this.uiDialog ).length;\n\t\tif ( moved && !silent ) {\n\t\t\tthis._trigger( \"focus\", event );\n\t\t}\n\t\treturn moved;\n\t},\n\n\topen: function() {\n\t\tvar that = this;\n\t\tif ( this._isOpen ) {\n\t\t\tif ( this._moveToTop() ) {\n\t\t\t\tthis._focusTabbable();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tthis._isOpen = true;\n\t\tthis.opener = $( this.document[0].activeElement );\n\n\t\tthis._size();\n\t\tthis._position();\n\t\tthis._createOverlay();\n\t\tthis._moveToTop( null, true );\n\t\tthis._show( this.uiDialog, this.options.show, function() {\n\t\t\tthat._focusTabbable();\n\t\t\tthat._trigger(\"focus\");\n\t\t});\n\n\t\tthis._trigger(\"open\");\n\t},\n\n\t_focusTabbable: function() {\n\t\t// Set focus to the first match:\n\t\t// 1. First element inside the dialog matching [autofocus]\n\t\t// 2. Tabbable element inside the content element\n\t\t// 3. Tabbable element inside the buttonpane\n\t\t// 4. The close button\n\t\t// 5. The dialog itself\n\t\tvar hasFocus = this.element.find(\"[autofocus]\");\n\t\tif ( !hasFocus.length ) {\n\t\t\thasFocus = this.element.find(\":tabbable\");\n\t\t}\n\t\tif ( !hasFocus.length ) {\n\t\t\thasFocus = this.uiDialogButtonPane.find(\":tabbable\");\n\t\t}\n\t\tif ( !hasFocus.length ) {\n\t\t\thasFocus = this.uiDialogTitlebarClose.filter(\":tabbable\");\n\t\t}\n\t\tif ( !hasFocus.length ) {\n\t\t\thasFocus = this.uiDialog;\n\t\t}\n\t\thasFocus.eq( 0 ).focus();\n\t},\n\n\t_keepFocus: function( event ) {\n\t\tfunction checkFocus() {\n\t\t\tvar activeElement = this.document[0].activeElement,\n\t\t\t\tisActive = this.uiDialog[0] === activeElement ||\n\t\t\t\t\t$.contains( this.uiDialog[0], activeElement );\n\t\t\tif ( !isActive ) {\n\t\t\t\tthis._focusTabbable();\n\t\t\t}\n\t\t}\n\t\tevent.preventDefault();\n\t\tcheckFocus.call( this );\n\t\t// support: IE\n\t\t// IE <= 8 doesn't prevent moving focus even with event.preventDefault()\n\t\t// so we check again later\n\t\tthis._delay( checkFocus );\n\t},\n\n\t_createWrapper: function() {\n\t\tthis.uiDialog = $(\"<div>\")\n\t\t\t.addClass( \"ui-dialog ui-widget ui-widget-content ui-corner-all ui-front \" +\n\t\t\t\tthis.options.dialogClass )\n\t\t\t.hide()\n\t\t\t.attr({\n\t\t\t\t// Setting tabIndex makes the div focusable\n\t\t\t\ttabIndex: -1,\n\t\t\t\trole: \"dialog\"\n\t\t\t})\n\t\t\t.appendTo( this._appendTo() );\n\n\t\tthis._on( this.uiDialog, {\n\t\t\tkeydown: function( event ) {\n\t\t\t\tif ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&\n\t\t\t\t\t\tevent.keyCode === $.ui.keyCode.ESCAPE ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tthis.close( event );\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// prevent tabbing out of dialogs\n\t\t\t\tif ( event.keyCode !== $.ui.keyCode.TAB ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tvar tabbables = this.uiDialog.find(\":tabbable\"),\n\t\t\t\t\tfirst = tabbables.filter(\":first\"),\n\t\t\t\t\tlast  = tabbables.filter(\":last\");\n\n\t\t\t\tif ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {\n\t\t\t\t\tfirst.focus( 1 );\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t} else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {\n\t\t\t\t\tlast.focus( 1 );\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t},\n\t\t\tmousedown: function( event ) {\n\t\t\t\tif ( this._moveToTop( event ) ) {\n\t\t\t\t\tthis._focusTabbable();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// We assume that any existing aria-describedby attribute means\n\t\t// that the dialog content is marked up properly\n\t\t// otherwise we brute force the content as the description\n\t\tif ( !this.element.find(\"[aria-describedby]\").length ) {\n\t\t\tthis.uiDialog.attr({\n\t\t\t\t\"aria-describedby\": this.element.uniqueId().attr(\"id\")\n\t\t\t});\n\t\t}\n\t},\n\n\t_createTitlebar: function() {\n\t\tvar uiDialogTitle;\n\n\t\tthis.uiDialogTitlebar = $(\"<div>\")\n\t\t\t.addClass(\"ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix\")\n\t\t\t.prependTo( this.uiDialog );\n\t\tthis._on( this.uiDialogTitlebar, {\n\t\t\tmousedown: function( event ) {\n\t\t\t\t// Don't prevent click on close button (#8838)\n\t\t\t\t// Focusing a dialog that is partially scrolled out of view\n\t\t\t\t// causes the browser to scroll it into view, preventing the click event\n\t\t\t\tif ( !$( event.target ).closest(\".ui-dialog-titlebar-close\") ) {\n\t\t\t\t\t// Dialog isn't getting focus when dragging (#8063)\n\t\t\t\t\tthis.uiDialog.focus();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.uiDialogTitlebarClose = $(\"<button></button>\")\n\t\t\t.button({\n\t\t\t\tlabel: this.options.closeText,\n\t\t\t\ticons: {\n\t\t\t\t\tprimary: \"ui-icon-closethick\"\n\t\t\t\t},\n\t\t\t\ttext: false\n\t\t\t})\n\t\t\t.addClass(\"ui-dialog-titlebar-close\")\n\t\t\t.appendTo( this.uiDialogTitlebar );\n\t\tthis._on( this.uiDialogTitlebarClose, {\n\t\t\tclick: function( event ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tthis.close( event );\n\t\t\t}\n\t\t});\n\n\t\tuiDialogTitle = $(\"<span>\")\n\t\t\t.uniqueId()\n\t\t\t.addClass(\"ui-dialog-title\")\n\t\t\t.prependTo( this.uiDialogTitlebar );\n\t\tthis._title( uiDialogTitle );\n\n\t\tthis.uiDialog.attr({\n\t\t\t\"aria-labelledby\": uiDialogTitle.attr(\"id\")\n\t\t});\n\t},\n\n\t_title: function( title ) {\n\t\tif ( !this.options.title ) {\n\t\t\ttitle.html(\"&#160;\");\n\t\t}\n\t\ttitle.text( this.options.title );\n\t},\n\n\t_createButtonPane: function() {\n\t\tthis.uiDialogButtonPane = $(\"<div>\")\n\t\t\t.addClass(\"ui-dialog-buttonpane ui-widget-content ui-helper-clearfix\");\n\n\t\tthis.uiButtonSet = $(\"<div>\")\n\t\t\t.addClass(\"ui-dialog-buttonset\")\n\t\t\t.appendTo( this.uiDialogButtonPane );\n\n\t\tthis._createButtons();\n\t},\n\n\t_createButtons: function() {\n\t\tvar that = this,\n\t\t\tbuttons = this.options.buttons;\n\n\t\t// if we already have a button pane, remove it\n\t\tthis.uiDialogButtonPane.remove();\n\t\tthis.uiButtonSet.empty();\n\n\t\tif ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {\n\t\t\tthis.uiDialog.removeClass(\"ui-dialog-buttons\");\n\t\t\treturn;\n\t\t}\n\n\t\t$.each( buttons, function( name, props ) {\n\t\t\tvar click, buttonOptions;\n\t\t\tprops = $.isFunction( props ) ?\n\t\t\t\t{ click: props, text: name } :\n\t\t\t\tprops;\n\t\t\t// Default to a non-submitting button\n\t\t\tprops = $.extend( { type: \"button\" }, props );\n\t\t\t// Change the context for the click callback to be the main element\n\t\t\tclick = props.click;\n\t\t\tprops.click = function() {\n\t\t\t\tclick.apply( that.element[0], arguments );\n\t\t\t};\n\t\t\tbuttonOptions = {\n\t\t\t\ticons: props.icons,\n\t\t\t\ttext: props.showText\n\t\t\t};\n\t\t\tdelete props.icons;\n\t\t\tdelete props.showText;\n\t\t\t$( \"<button></button>\", props )\n\t\t\t\t.button( buttonOptions )\n\t\t\t\t.appendTo( that.uiButtonSet );\n\t\t});\n\t\tthis.uiDialog.addClass(\"ui-dialog-buttons\");\n\t\tthis.uiDialogButtonPane.appendTo( this.uiDialog );\n\t},\n\n\t_makeDraggable: function() {\n\t\tvar that = this,\n\t\t\toptions = this.options;\n\n\t\tfunction filteredUi( ui ) {\n\t\t\treturn {\n\t\t\t\tposition: ui.position,\n\t\t\t\toffset: ui.offset\n\t\t\t};\n\t\t}\n\n\t\tthis.uiDialog.draggable({\n\t\t\tcancel: \".ui-dialog-content, .ui-dialog-titlebar-close\",\n\t\t\thandle: \".ui-dialog-titlebar\",\n\t\t\tcontainment: \"document\",\n\t\t\tstart: function( event, ui ) {\n\t\t\t\t$( this ).addClass(\"ui-dialog-dragging\");\n\t\t\t\tthat._blockFrames();\n\t\t\t\tthat._trigger( \"dragStart\", event, filteredUi( ui ) );\n\t\t\t},\n\t\t\tdrag: function( event, ui ) {\n\t\t\t\tthat._trigger( \"drag\", event, filteredUi( ui ) );\n\t\t\t},\n\t\t\tstop: function( event, ui ) {\n\t\t\t\toptions.position = [\n\t\t\t\t\tui.position.left - that.document.scrollLeft(),\n\t\t\t\t\tui.position.top - that.document.scrollTop()\n\t\t\t\t];\n\t\t\t\t$( this ).removeClass(\"ui-dialog-dragging\");\n\t\t\t\tthat._unblockFrames();\n\t\t\t\tthat._trigger( \"dragStop\", event, filteredUi( ui ) );\n\t\t\t}\n\t\t});\n\t},\n\n\t_makeResizable: function() {\n\t\tvar that = this,\n\t\t\toptions = this.options,\n\t\t\thandles = options.resizable,\n\t\t\t// .ui-resizable has position: relative defined in the stylesheet\n\t\t\t// but dialogs have to use absolute or fixed positioning\n\t\t\tposition = this.uiDialog.css(\"position\"),\n\t\t\tresizeHandles = typeof handles === \"string\" ?\n\t\t\t\thandles\t:\n\t\t\t\t\"n,e,s,w,se,sw,ne,nw\";\n\n\t\tfunction filteredUi( ui ) {\n\t\t\treturn {\n\t\t\t\toriginalPosition: ui.originalPosition,\n\t\t\t\toriginalSize: ui.originalSize,\n\t\t\t\tposition: ui.position,\n\t\t\t\tsize: ui.size\n\t\t\t};\n\t\t}\n\n\t\tthis.uiDialog.resizable({\n\t\t\tcancel: \".ui-dialog-content\",\n\t\t\tcontainment: \"document\",\n\t\t\talsoResize: this.element,\n\t\t\tmaxWidth: options.maxWidth,\n\t\t\tmaxHeight: options.maxHeight,\n\t\t\tminWidth: options.minWidth,\n\t\t\tminHeight: this._minHeight(),\n\t\t\thandles: resizeHandles,\n\t\t\tstart: function( event, ui ) {\n\t\t\t\t$( this ).addClass(\"ui-dialog-resizing\");\n\t\t\t\tthat._blockFrames();\n\t\t\t\tthat._trigger( \"resizeStart\", event, filteredUi( ui ) );\n\t\t\t},\n\t\t\tresize: function( event, ui ) {\n\t\t\t\tthat._trigger( \"resize\", event, filteredUi( ui ) );\n\t\t\t},\n\t\t\tstop: function( event, ui ) {\n\t\t\t\toptions.height = $( this ).height();\n\t\t\t\toptions.width = $( this ).width();\n\t\t\t\t$( this ).removeClass(\"ui-dialog-resizing\");\n\t\t\t\tthat._unblockFrames();\n\t\t\t\tthat._trigger( \"resizeStop\", event, filteredUi( ui ) );\n\t\t\t}\n\t\t})\n\t\t.css( \"position\", position );\n\t},\n\n\t_minHeight: function() {\n\t\tvar options = this.options;\n\n\t\treturn options.height === \"auto\" ?\n\t\t\toptions.minHeight :\n\t\t\tMath.min( options.minHeight, options.height );\n\t},\n\n\t_position: function() {\n\t\t// Need to show the dialog to get the actual offset in the position plugin\n\t\tvar isVisible = this.uiDialog.is(\":visible\");\n\t\tif ( !isVisible ) {\n\t\t\tthis.uiDialog.show();\n\t\t}\n\t\tthis.uiDialog.position( this.options.position );\n\t\tif ( !isVisible ) {\n\t\t\tthis.uiDialog.hide();\n\t\t}\n\t},\n\n\t_setOptions: function( options ) {\n\t\tvar that = this,\n\t\t\tresize = false,\n\t\t\tresizableOptions = {};\n\n\t\t$.each( options, function( key, value ) {\n\t\t\tthat._setOption( key, value );\n\n\t\t\tif ( key in sizeRelatedOptions ) {\n\t\t\t\tresize = true;\n\t\t\t}\n\t\t\tif ( key in resizableRelatedOptions ) {\n\t\t\t\tresizableOptions[ key ] = value;\n\t\t\t}\n\t\t});\n\n\t\tif ( resize ) {\n\t\t\tthis._size();\n\t\t\tthis._position();\n\t\t}\n\t\tif ( this.uiDialog.is(\":data(ui-resizable)\") ) {\n\t\t\tthis.uiDialog.resizable( \"option\", resizableOptions );\n\t\t}\n\t},\n\n\t_setOption: function( key, value ) {\n\t\t/*jshint maxcomplexity:15*/\n\t\tvar isDraggable, isResizable,\n\t\t\tuiDialog = this.uiDialog;\n\n\t\tif ( key === \"dialogClass\" ) {\n\t\t\tuiDialog\n\t\t\t\t.removeClass( this.options.dialogClass )\n\t\t\t\t.addClass( value );\n\t\t}\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._super( key, value );\n\n\t\tif ( key === \"appendTo\" ) {\n\t\t\tthis.uiDialog.appendTo( this._appendTo() );\n\t\t}\n\n\t\tif ( key === \"buttons\" ) {\n\t\t\tthis._createButtons();\n\t\t}\n\n\t\tif ( key === \"closeText\" ) {\n\t\t\tthis.uiDialogTitlebarClose.button({\n\t\t\t\t// Ensure that we always pass a string\n\t\t\t\tlabel: \"\" + value\n\t\t\t});\n\t\t}\n\n\t\tif ( key === \"draggable\" ) {\n\t\t\tisDraggable = uiDialog.is(\":data(ui-draggable)\");\n\t\t\tif ( isDraggable && !value ) {\n\t\t\t\tuiDialog.draggable(\"destroy\");\n\t\t\t}\n\n\t\t\tif ( !isDraggable && value ) {\n\t\t\t\tthis._makeDraggable();\n\t\t\t}\n\t\t}\n\n\t\tif ( key === \"position\" ) {\n\t\t\tthis._position();\n\t\t}\n\n\t\tif ( key === \"resizable\" ) {\n\t\t\t// currently resizable, becoming non-resizable\n\t\t\tisResizable = uiDialog.is(\":data(ui-resizable)\");\n\t\t\tif ( isResizable && !value ) {\n\t\t\t\tuiDialog.resizable(\"destroy\");\n\t\t\t}\n\n\t\t\t// currently resizable, changing handles\n\t\t\tif ( isResizable && typeof value === \"string\" ) {\n\t\t\t\tuiDialog.resizable( \"option\", \"handles\", value );\n\t\t\t}\n\n\t\t\t// currently non-resizable, becoming resizable\n\t\t\tif ( !isResizable && value !== false ) {\n\t\t\t\tthis._makeResizable();\n\t\t\t}\n\t\t}\n\n\t\tif ( key === \"title\" ) {\n\t\t\tthis._title( this.uiDialogTitlebar.find(\".ui-dialog-title\") );\n\t\t}\n\t},\n\n\t_size: function() {\n\t\t// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content\n\t\t// divs will both have width and height set, so we need to reset them\n\t\tvar nonContentHeight, minContentHeight, maxContentHeight,\n\t\t\toptions = this.options;\n\n\t\t// Reset content sizing\n\t\tthis.element.show().css({\n\t\t\twidth: \"auto\",\n\t\t\tminHeight: 0,\n\t\t\tmaxHeight: \"none\",\n\t\t\theight: 0\n\t\t});\n\n\t\tif ( options.minWidth > options.width ) {\n\t\t\toptions.width = options.minWidth;\n\t\t}\n\n\t\t// reset wrapper sizing\n\t\t// determine the height of all the non-content elements\n\t\tnonContentHeight = this.uiDialog.css({\n\t\t\t\theight: \"auto\",\n\t\t\t\twidth: options.width\n\t\t\t})\n\t\t\t.outerHeight();\n\t\tminContentHeight = Math.max( 0, options.minHeight - nonContentHeight );\n\t\tmaxContentHeight = typeof options.maxHeight === \"number\" ?\n\t\t\tMath.max( 0, options.maxHeight - nonContentHeight ) :\n\t\t\t\"none\";\n\n\t\tif ( options.height === \"auto\" ) {\n\t\t\tthis.element.css({\n\t\t\t\tminHeight: minContentHeight,\n\t\t\t\tmaxHeight: maxContentHeight,\n\t\t\t\theight: \"auto\"\n\t\t\t});\n\t\t} else {\n\t\t\tthis.element.height( Math.max( 0, options.height - nonContentHeight ) );\n\t\t}\n\n\t\tif (this.uiDialog.is(\":data(ui-resizable)\") ) {\n\t\t\tthis.uiDialog.resizable( \"option\", \"minHeight\", this._minHeight() );\n\t\t}\n\t},\n\n\t_blockFrames: function() {\n\t\tthis.iframeBlocks = this.document.find( \"iframe\" ).map(function() {\n\t\t\tvar iframe = $( this );\n\n\t\t\treturn $( \"<div>\" )\n\t\t\t\t.css({\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\twidth: iframe.outerWidth(),\n\t\t\t\t\theight: iframe.outerHeight()\n\t\t\t\t})\n\t\t\t\t.appendTo( iframe.parent() )\n\t\t\t\t.offset( iframe.offset() )[0];\n\t\t});\n\t},\n\n\t_unblockFrames: function() {\n\t\tif ( this.iframeBlocks ) {\n\t\t\tthis.iframeBlocks.remove();\n\t\t\tdelete this.iframeBlocks;\n\t\t}\n\t},\n\n\t_allowInteraction: function( event ) {\n\t\tif ( $( event.target ).closest(\".ui-dialog\").length ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// TODO: Remove hack when datepicker implements\n\t\t// the .ui-front logic (#8989)\n\t\treturn !!$( event.target ).closest(\".ui-datepicker\").length;\n\t},\n\n\t_createOverlay: function() {\n\t\tif ( !this.options.modal ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar that = this,\n\t\t\twidgetFullName = this.widgetFullName;\n\t\tif ( !$.ui.dialog.overlayInstances ) {\n\t\t\t// Prevent use of anchors and inputs.\n\t\t\t// We use a delay in case the overlay is created from an\n\t\t\t// event that we're going to be cancelling. (#2804)\n\t\t\tthis._delay(function() {\n\t\t\t\t// Handle .dialog().dialog(\"close\") (#4065)\n\t\t\t\tif ( $.ui.dialog.overlayInstances ) {\n\t\t\t\t\tthis.document.bind( \"focusin.dialog\", function( event ) {\n\t\t\t\t\t\tif ( !that._allowInteraction( event ) ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t$(\".ui-dialog:visible:last .ui-dialog-content\")\n\t\t\t\t\t\t\t\t.data( widgetFullName )._focusTabbable();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tthis.overlay = $(\"<div>\")\n\t\t\t.addClass(\"ui-widget-overlay ui-front\")\n\t\t\t.appendTo( this._appendTo() );\n\t\tthis._on( this.overlay, {\n\t\t\tmousedown: \"_keepFocus\"\n\t\t});\n\t\t$.ui.dialog.overlayInstances++;\n\t},\n\n\t_destroyOverlay: function() {\n\t\tif ( !this.options.modal ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( this.overlay ) {\n\t\t\t$.ui.dialog.overlayInstances--;\n\n\t\t\tif ( !$.ui.dialog.overlayInstances ) {\n\t\t\t\tthis.document.unbind( \"focusin.dialog\" );\n\t\t\t}\n\t\t\tthis.overlay.remove();\n\t\t\tthis.overlay = null;\n\t\t}\n\t}\n});\n\n$.ui.dialog.overlayInstances = 0;\n\n// DEPRECATED\nif ( $.uiBackCompat !== false ) {\n\t// position option with array notation\n\t// just override with old implementation\n\t$.widget( \"ui.dialog\", $.ui.dialog, {\n\t\t_position: function() {\n\t\t\tvar position = this.options.position,\n\t\t\t\tmyAt = [],\n\t\t\t\toffset = [ 0, 0 ],\n\t\t\t\tisVisible;\n\n\t\t\tif ( position ) {\n\t\t\t\tif ( typeof position === \"string\" || (typeof position === \"object\" && \"0\" in position ) ) {\n\t\t\t\t\tmyAt = position.split ? position.split(\" \") : [ position[0], position[1] ];\n\t\t\t\t\tif ( myAt.length === 1 ) {\n\t\t\t\t\t\tmyAt[1] = myAt[0];\n\t\t\t\t\t}\n\n\t\t\t\t\t$.each( [ \"left\", \"top\" ], function( i, offsetPosition ) {\n\t\t\t\t\t\tif ( +myAt[ i ] === myAt[ i ] ) {\n\t\t\t\t\t\t\toffset[ i ] = myAt[ i ];\n\t\t\t\t\t\t\tmyAt[ i ] = offsetPosition;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tposition = {\n\t\t\t\t\t\tmy: myAt[0] + (offset[0] < 0 ? offset[0] : \"+\" + offset[0]) + \" \" +\n\t\t\t\t\t\t\tmyAt[1] + (offset[1] < 0 ? offset[1] : \"+\" + offset[1]),\n\t\t\t\t\t\tat: myAt.join(\" \")\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tposition = $.extend( {}, $.ui.dialog.prototype.options.position, position );\n\t\t\t} else {\n\t\t\t\tposition = $.ui.dialog.prototype.options.position;\n\t\t\t}\n\n\t\t\t// need to show the dialog to get the actual offset in the position plugin\n\t\t\tisVisible = this.uiDialog.is(\":visible\");\n\t\t\tif ( !isVisible ) {\n\t\t\t\tthis.uiDialog.show();\n\t\t\t}\n\t\t\tthis.uiDialog.position( position );\n\t\t\tif ( !isVisible ) {\n\t\t\t\tthis.uiDialog.hide();\n\t\t\t}\n\t\t}\n\t});\n}\n\n}( jQuery ) );\n\n(function( $, undefined ) {\n\nvar rvertical = /up|down|vertical/,\n\trpositivemotion = /up|left|vertical|horizontal/;\n\n$.effects.effect.blind = function( o, done ) {\n\t// Create element\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"height\", \"width\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"hide\" ),\n\t\tdirection = o.direction || \"up\",\n\t\tvertical = rvertical.test( direction ),\n\t\tref = vertical ? \"height\" : \"width\",\n\t\tref2 = vertical ? \"top\" : \"left\",\n\t\tmotion = rpositivemotion.test( direction ),\n\t\tanimation = {},\n\t\tshow = mode === \"show\",\n\t\twrapper, distance, margin;\n\n\t// if already wrapped, the wrapper's properties are my property. #6245\n\tif ( el.parent().is( \".ui-effects-wrapper\" ) ) {\n\t\t$.effects.save( el.parent(), props );\n\t} else {\n\t\t$.effects.save( el, props );\n\t}\n\tel.show();\n\twrapper = $.effects.createWrapper( el ).css({\n\t\toverflow: \"hidden\"\n\t});\n\n\tdistance = wrapper[ ref ]();\n\tmargin = parseFloat( wrapper.css( ref2 ) ) || 0;\n\n\tanimation[ ref ] = show ? distance : 0;\n\tif ( !motion ) {\n\t\tel\n\t\t\t.css( vertical ? \"bottom\" : \"right\", 0 )\n\t\t\t.css( vertical ? \"top\" : \"left\", \"auto\" )\n\t\t\t.css({ position: \"absolute\" });\n\n\t\tanimation[ ref2 ] = show ? margin : distance + margin;\n\t}\n\n\t// start at 0 if we are showing\n\tif ( show ) {\n\t\twrapper.css( ref, 0 );\n\t\tif ( ! motion ) {\n\t\t\twrapper.css( ref2, margin + distance );\n\t\t}\n\t}\n\n\t// Animate\n\twrapper.animate( animation, {\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tqueue: false,\n\t\tcomplete: function() {\n\t\t\tif ( mode === \"hide\" ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t}\n\t});\n\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.effects.effect.bounce = function( o, done ) {\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"height\", \"width\" ],\n\n\t\t// defaults:\n\t\tmode = $.effects.setMode( el, o.mode || \"effect\" ),\n\t\thide = mode === \"hide\",\n\t\tshow = mode === \"show\",\n\t\tdirection = o.direction || \"up\",\n\t\tdistance = o.distance,\n\t\ttimes = o.times || 5,\n\n\t\t// number of internal animations\n\t\tanims = times * 2 + ( show || hide ? 1 : 0 ),\n\t\tspeed = o.duration / anims,\n\t\teasing = o.easing,\n\n\t\t// utility:\n\t\tref = ( direction === \"up\" || direction === \"down\" ) ? \"top\" : \"left\",\n\t\tmotion = ( direction === \"up\" || direction === \"left\" ),\n\t\ti,\n\t\tupAnim,\n\t\tdownAnim,\n\n\t\t// we will need to re-assemble the queue to stack our animations in place\n\t\tqueue = el.queue(),\n\t\tqueuelen = queue.length;\n\n\t// Avoid touching opacity to prevent clearType and PNG issues in IE\n\tif ( show || hide ) {\n\t\tprops.push( \"opacity\" );\n\t}\n\n\t$.effects.save( el, props );\n\tel.show();\n\t$.effects.createWrapper( el ); // Create Wrapper\n\n\t// default distance for the BIGGEST bounce is the outer Distance / 3\n\tif ( !distance ) {\n\t\tdistance = el[ ref === \"top\" ? \"outerHeight\" : \"outerWidth\" ]() / 3;\n\t}\n\n\tif ( show ) {\n\t\tdownAnim = { opacity: 1 };\n\t\tdownAnim[ ref ] = 0;\n\n\t\t// if we are showing, force opacity 0 and set the initial position\n\t\t// then do the \"first\" animation\n\t\tel.css( \"opacity\", 0 )\n\t\t\t.css( ref, motion ? -distance * 2 : distance * 2 )\n\t\t\t.animate( downAnim, speed, easing );\n\t}\n\n\t// start at the smallest distance if we are hiding\n\tif ( hide ) {\n\t\tdistance = distance / Math.pow( 2, times - 1 );\n\t}\n\n\tdownAnim = {};\n\tdownAnim[ ref ] = 0;\n\t// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here\n\tfor ( i = 0; i < times; i++ ) {\n\t\tupAnim = {};\n\t\tupAnim[ ref ] = ( motion ? \"-=\" : \"+=\" ) + distance;\n\n\t\tel.animate( upAnim, speed, easing )\n\t\t\t.animate( downAnim, speed, easing );\n\n\t\tdistance = hide ? distance * 2 : distance / 2;\n\t}\n\n\t// Last Bounce when Hiding\n\tif ( hide ) {\n\t\tupAnim = { opacity: 0 };\n\t\tupAnim[ ref ] = ( motion ? \"-=\" : \"+=\" ) + distance;\n\n\t\tel.animate( upAnim, speed, easing );\n\t}\n\n\tel.queue(function() {\n\t\tif ( hide ) {\n\t\t\tel.hide();\n\t\t}\n\t\t$.effects.restore( el, props );\n\t\t$.effects.removeWrapper( el );\n\t\tdone();\n\t});\n\n\t// inject all the animations we just queued to be first in line (after \"inprogress\")\n\tif ( queuelen > 1) {\n\t\tqueue.splice.apply( queue,\n\t\t\t[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );\n\t}\n\tel.dequeue();\n\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.effects.effect.clip = function( o, done ) {\n\t// Create element\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"height\", \"width\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"hide\" ),\n\t\tshow = mode === \"show\",\n\t\tdirection = o.direction || \"vertical\",\n\t\tvert = direction === \"vertical\",\n\t\tsize = vert ? \"height\" : \"width\",\n\t\tposition = vert ? \"top\" : \"left\",\n\t\tanimation = {},\n\t\twrapper, animate, distance;\n\n\t// Save & Show\n\t$.effects.save( el, props );\n\tel.show();\n\n\t// Create Wrapper\n\twrapper = $.effects.createWrapper( el ).css({\n\t\toverflow: \"hidden\"\n\t});\n\tanimate = ( el[0].tagName === \"IMG\" ) ? wrapper : el;\n\tdistance = animate[ size ]();\n\n\t// Shift\n\tif ( show ) {\n\t\tanimate.css( size, 0 );\n\t\tanimate.css( position, distance / 2 );\n\t}\n\n\t// Create Animation Object:\n\tanimation[ size ] = show ? distance : 0;\n\tanimation[ position ] = show ? 0 : distance / 2;\n\n\t// Animate\n\tanimate.animate( animation, {\n\t\tqueue: false,\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tcomplete: function() {\n\t\t\tif ( !show ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t}\n\t});\n\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.effects.effect.drop = function( o, done ) {\n\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"opacity\", \"height\", \"width\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"hide\" ),\n\t\tshow = mode === \"show\",\n\t\tdirection = o.direction || \"left\",\n\t\tref = ( direction === \"up\" || direction === \"down\" ) ? \"top\" : \"left\",\n\t\tmotion = ( direction === \"up\" || direction === \"left\" ) ? \"pos\" : \"neg\",\n\t\tanimation = {\n\t\t\topacity: show ? 1 : 0\n\t\t},\n\t\tdistance;\n\n\t// Adjust\n\t$.effects.save( el, props );\n\tel.show();\n\t$.effects.createWrapper( el );\n\n\tdistance = o.distance || el[ ref === \"top\" ? \"outerHeight\": \"outerWidth\" ]( true ) / 2;\n\n\tif ( show ) {\n\t\tel\n\t\t\t.css( \"opacity\", 0 )\n\t\t\t.css( ref, motion === \"pos\" ? -distance : distance );\n\t}\n\n\t// Animation\n\tanimation[ ref ] = ( show ?\n\t\t( motion === \"pos\" ? \"+=\" : \"-=\" ) :\n\t\t( motion === \"pos\" ? \"-=\" : \"+=\" ) ) +\n\t\tdistance;\n\n\t// Animate\n\tel.animate( animation, {\n\t\tqueue: false,\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tcomplete: function() {\n\t\t\tif ( mode === \"hide\" ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t}\n\t});\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.effects.effect.explode = function( o, done ) {\n\n\tvar rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,\n\t\tcells = rows,\n\t\tel = $( this ),\n\t\tmode = $.effects.setMode( el, o.mode || \"hide\" ),\n\t\tshow = mode === \"show\",\n\n\t\t// show and then visibility:hidden the element before calculating offset\n\t\toffset = el.show().css( \"visibility\", \"hidden\" ).offset(),\n\n\t\t// width and height of a piece\n\t\twidth = Math.ceil( el.outerWidth() / cells ),\n\t\theight = Math.ceil( el.outerHeight() / rows ),\n\t\tpieces = [],\n\n\t\t// loop\n\t\ti, j, left, top, mx, my;\n\n\t// children animate complete:\n\tfunction childComplete() {\n\t\tpieces.push( this );\n\t\tif ( pieces.length === rows * cells ) {\n\t\t\tanimComplete();\n\t\t}\n\t}\n\n\t// clone the element for each row and cell.\n\tfor( i = 0; i < rows ; i++ ) { // ===>\n\t\ttop = offset.top + i * height;\n\t\tmy = i - ( rows - 1 ) / 2 ;\n\n\t\tfor( j = 0; j < cells ; j++ ) { // |||\n\t\t\tleft = offset.left + j * width;\n\t\t\tmx = j - ( cells - 1 ) / 2 ;\n\n\t\t\t// Create a clone of the now hidden main element that will be absolute positioned\n\t\t\t// within a wrapper div off the -left and -top equal to size of our pieces\n\t\t\tel\n\t\t\t\t.clone()\n\t\t\t\t.appendTo( \"body\" )\n\t\t\t\t.wrap( \"<div></div>\" )\n\t\t\t\t.css({\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tvisibility: \"visible\",\n\t\t\t\t\tleft: -j * width,\n\t\t\t\t\ttop: -i * height\n\t\t\t\t})\n\n\t\t\t// select the wrapper - make it overflow: hidden and absolute positioned based on\n\t\t\t// where the original was located +left and +top equal to the size of pieces\n\t\t\t\t.parent()\n\t\t\t\t.addClass( \"ui-effects-explode\" )\n\t\t\t\t.css({\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\twidth: width,\n\t\t\t\t\theight: height,\n\t\t\t\t\tleft: left + ( show ? mx * width : 0 ),\n\t\t\t\t\ttop: top + ( show ? my * height : 0 ),\n\t\t\t\t\topacity: show ? 0 : 1\n\t\t\t\t}).animate({\n\t\t\t\t\tleft: left + ( show ? 0 : mx * width ),\n\t\t\t\t\ttop: top + ( show ? 0 : my * height ),\n\t\t\t\t\topacity: show ? 1 : 0\n\t\t\t\t}, o.duration || 500, o.easing, childComplete );\n\t\t}\n\t}\n\n\tfunction animComplete() {\n\t\tel.css({\n\t\t\tvisibility: \"visible\"\n\t\t});\n\t\t$( pieces ).remove();\n\t\tif ( !show ) {\n\t\t\tel.hide();\n\t\t}\n\t\tdone();\n\t}\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.effects.effect.fade = function( o, done ) {\n\tvar el = $( this ),\n\t\tmode = $.effects.setMode( el, o.mode || \"toggle\" );\n\n\tel.animate({\n\t\topacity: mode\n\t}, {\n\t\tqueue: false,\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tcomplete: done\n\t});\n};\n\n})( jQuery );\n\n(function( $, undefined ) {\n\n$.effects.effect.fold = function( o, done ) {\n\n\t// Create element\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"height\", \"width\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"hide\" ),\n\t\tshow = mode === \"show\",\n\t\thide = mode === \"hide\",\n\t\tsize = o.size || 15,\n\t\tpercent = /([0-9]+)%/.exec( size ),\n\t\thorizFirst = !!o.horizFirst,\n\t\twidthFirst = show !== horizFirst,\n\t\tref = widthFirst ? [ \"width\", \"height\" ] : [ \"height\", \"width\" ],\n\t\tduration = o.duration / 2,\n\t\twrapper, distance,\n\t\tanimation1 = {},\n\t\tanimation2 = {};\n\n\t$.effects.save( el, props );\n\tel.show();\n\n\t// Create Wrapper\n\twrapper = $.effects.createWrapper( el ).css({\n\t\toverflow: \"hidden\"\n\t});\n\tdistance = widthFirst ?\n\t\t[ wrapper.width(), wrapper.height() ] :\n\t\t[ wrapper.height(), wrapper.width() ];\n\n\tif ( percent ) {\n\t\tsize = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];\n\t}\n\tif ( show ) {\n\t\twrapper.css( horizFirst ? {\n\t\t\theight: 0,\n\t\t\twidth: size\n\t\t} : {\n\t\t\theight: size,\n\t\t\twidth: 0\n\t\t});\n\t}\n\n\t// Animation\n\tanimation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;\n\tanimation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;\n\n\t// Animate\n\twrapper\n\t\t.animate( animation1, duration, o.easing )\n\t\t.animate( animation2, duration, o.easing, function() {\n\t\t\tif ( hide ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t});\n\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.effects.effect.highlight = function( o, done ) {\n\tvar elem = $( this ),\n\t\tprops = [ \"backgroundImage\", \"backgroundColor\", \"opacity\" ],\n\t\tmode = $.effects.setMode( elem, o.mode || \"show\" ),\n\t\tanimation = {\n\t\t\tbackgroundColor: elem.css( \"backgroundColor\" )\n\t\t};\n\n\tif (mode === \"hide\") {\n\t\tanimation.opacity = 0;\n\t}\n\n\t$.effects.save( elem, props );\n\n\telem\n\t\t.show()\n\t\t.css({\n\t\t\tbackgroundImage: \"none\",\n\t\t\tbackgroundColor: o.color || \"#ffff99\"\n\t\t})\n\t\t.animate( animation, {\n\t\t\tqueue: false,\n\t\t\tduration: o.duration,\n\t\t\teasing: o.easing,\n\t\t\tcomplete: function() {\n\t\t\t\tif ( mode === \"hide\" ) {\n\t\t\t\t\telem.hide();\n\t\t\t\t}\n\t\t\t\t$.effects.restore( elem, props );\n\t\t\t\tdone();\n\t\t\t}\n\t\t});\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.effects.effect.pulsate = function( o, done ) {\n\tvar elem = $( this ),\n\t\tmode = $.effects.setMode( elem, o.mode || \"show\" ),\n\t\tshow = mode === \"show\",\n\t\thide = mode === \"hide\",\n\t\tshowhide = ( show || mode === \"hide\" ),\n\n\t\t// showing or hiding leaves of the \"last\" animation\n\t\tanims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),\n\t\tduration = o.duration / anims,\n\t\tanimateTo = 0,\n\t\tqueue = elem.queue(),\n\t\tqueuelen = queue.length,\n\t\ti;\n\n\tif ( show || !elem.is(\":visible\")) {\n\t\telem.css( \"opacity\", 0 ).show();\n\t\tanimateTo = 1;\n\t}\n\n\t// anims - 1 opacity \"toggles\"\n\tfor ( i = 1; i < anims; i++ ) {\n\t\telem.animate({\n\t\t\topacity: animateTo\n\t\t}, duration, o.easing );\n\t\tanimateTo = 1 - animateTo;\n\t}\n\n\telem.animate({\n\t\topacity: animateTo\n\t}, duration, o.easing);\n\n\telem.queue(function() {\n\t\tif ( hide ) {\n\t\t\telem.hide();\n\t\t}\n\t\tdone();\n\t});\n\n\t// We just queued up \"anims\" animations, we need to put them next in the queue\n\tif ( queuelen > 1 ) {\n\t\tqueue.splice.apply( queue,\n\t\t\t[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );\n\t}\n\telem.dequeue();\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.effects.effect.puff = function( o, done ) {\n\tvar elem = $( this ),\n\t\tmode = $.effects.setMode( elem, o.mode || \"hide\" ),\n\t\thide = mode === \"hide\",\n\t\tpercent = parseInt( o.percent, 10 ) || 150,\n\t\tfactor = percent / 100,\n\t\toriginal = {\n\t\t\theight: elem.height(),\n\t\t\twidth: elem.width(),\n\t\t\touterHeight: elem.outerHeight(),\n\t\t\touterWidth: elem.outerWidth()\n\t\t};\n\n\t$.extend( o, {\n\t\teffect: \"scale\",\n\t\tqueue: false,\n\t\tfade: true,\n\t\tmode: mode,\n\t\tcomplete: done,\n\t\tpercent: hide ? percent : 100,\n\t\tfrom: hide ?\n\t\t\toriginal :\n\t\t\t{\n\t\t\t\theight: original.height * factor,\n\t\t\t\twidth: original.width * factor,\n\t\t\t\touterHeight: original.outerHeight * factor,\n\t\t\t\touterWidth: original.outerWidth * factor\n\t\t\t}\n\t});\n\n\telem.effect( o );\n};\n\n$.effects.effect.scale = function( o, done ) {\n\n\t// Create element\n\tvar el = $( this ),\n\t\toptions = $.extend( true, {}, o ),\n\t\tmode = $.effects.setMode( el, o.mode || \"effect\" ),\n\t\tpercent = parseInt( o.percent, 10 ) ||\n\t\t\t( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === \"hide\" ? 0 : 100 ) ),\n\t\tdirection = o.direction || \"both\",\n\t\torigin = o.origin,\n\t\toriginal = {\n\t\t\theight: el.height(),\n\t\t\twidth: el.width(),\n\t\t\touterHeight: el.outerHeight(),\n\t\t\touterWidth: el.outerWidth()\n\t\t},\n\t\tfactor = {\n\t\t\ty: direction !== \"horizontal\" ? (percent / 100) : 1,\n\t\t\tx: direction !== \"vertical\" ? (percent / 100) : 1\n\t\t};\n\n\t// We are going to pass this effect to the size effect:\n\toptions.effect = \"size\";\n\toptions.queue = false;\n\toptions.complete = done;\n\n\t// Set default origin and restore for show/hide\n\tif ( mode !== \"effect\" ) {\n\t\toptions.origin = origin || [\"middle\",\"center\"];\n\t\toptions.restore = true;\n\t}\n\n\toptions.from = o.from || ( mode === \"show\" ? {\n\t\theight: 0,\n\t\twidth: 0,\n\t\touterHeight: 0,\n\t\touterWidth: 0\n\t} : original );\n\toptions.to = {\n\t\theight: original.height * factor.y,\n\t\twidth: original.width * factor.x,\n\t\touterHeight: original.outerHeight * factor.y,\n\t\touterWidth: original.outerWidth * factor.x\n\t};\n\n\t// Fade option to support puff\n\tif ( options.fade ) {\n\t\tif ( mode === \"show\" ) {\n\t\t\toptions.from.opacity = 0;\n\t\t\toptions.to.opacity = 1;\n\t\t}\n\t\tif ( mode === \"hide\" ) {\n\t\t\toptions.from.opacity = 1;\n\t\t\toptions.to.opacity = 0;\n\t\t}\n\t}\n\n\t// Animate\n\tel.effect( options );\n\n};\n\n$.effects.effect.size = function( o, done ) {\n\n\t// Create element\n\tvar original, baseline, factor,\n\t\tel = $( this ),\n\t\tprops0 = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"width\", \"height\", \"overflow\", \"opacity\" ],\n\n\t\t// Always restore\n\t\tprops1 = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"overflow\", \"opacity\" ],\n\n\t\t// Copy for children\n\t\tprops2 = [ \"width\", \"height\", \"overflow\" ],\n\t\tcProps = [ \"fontSize\" ],\n\t\tvProps = [ \"borderTopWidth\", \"borderBottomWidth\", \"paddingTop\", \"paddingBottom\" ],\n\t\thProps = [ \"borderLeftWidth\", \"borderRightWidth\", \"paddingLeft\", \"paddingRight\" ],\n\n\t\t// Set options\n\t\tmode = $.effects.setMode( el, o.mode || \"effect\" ),\n\t\trestore = o.restore || mode !== \"effect\",\n\t\tscale = o.scale || \"both\",\n\t\torigin = o.origin || [ \"middle\", \"center\" ],\n\t\tposition = el.css( \"position\" ),\n\t\tprops = restore ? props0 : props1,\n\t\tzero = {\n\t\t\theight: 0,\n\t\t\twidth: 0,\n\t\t\touterHeight: 0,\n\t\t\touterWidth: 0\n\t\t};\n\n\tif ( mode === \"show\" ) {\n\t\tel.show();\n\t}\n\toriginal = {\n\t\theight: el.height(),\n\t\twidth: el.width(),\n\t\touterHeight: el.outerHeight(),\n\t\touterWidth: el.outerWidth()\n\t};\n\n\tif ( o.mode === \"toggle\" && mode === \"show\" ) {\n\t\tel.from = o.to || zero;\n\t\tel.to = o.from || original;\n\t} else {\n\t\tel.from = o.from || ( mode === \"show\" ? zero : original );\n\t\tel.to = o.to || ( mode === \"hide\" ? zero : original );\n\t}\n\n\t// Set scaling factor\n\tfactor = {\n\t\tfrom: {\n\t\t\ty: el.from.height / original.height,\n\t\t\tx: el.from.width / original.width\n\t\t},\n\t\tto: {\n\t\t\ty: el.to.height / original.height,\n\t\t\tx: el.to.width / original.width\n\t\t}\n\t};\n\n\t// Scale the css box\n\tif ( scale === \"box\" || scale === \"both\" ) {\n\n\t\t// Vertical props scaling\n\t\tif ( factor.from.y !== factor.to.y ) {\n\t\t\tprops = props.concat( vProps );\n\t\t\tel.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );\n\t\t\tel.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );\n\t\t}\n\n\t\t// Horizontal props scaling\n\t\tif ( factor.from.x !== factor.to.x ) {\n\t\t\tprops = props.concat( hProps );\n\t\t\tel.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );\n\t\t\tel.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );\n\t\t}\n\t}\n\n\t// Scale the content\n\tif ( scale === \"content\" || scale === \"both\" ) {\n\n\t\t// Vertical props scaling\n\t\tif ( factor.from.y !== factor.to.y ) {\n\t\t\tprops = props.concat( cProps ).concat( props2 );\n\t\t\tel.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );\n\t\t\tel.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );\n\t\t}\n\t}\n\n\t$.effects.save( el, props );\n\tel.show();\n\t$.effects.createWrapper( el );\n\tel.css( \"overflow\", \"hidden\" ).css( el.from );\n\n\t// Adjust\n\tif (origin) { // Calculate baseline shifts\n\t\tbaseline = $.effects.getBaseline( origin, original );\n\t\tel.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;\n\t\tel.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;\n\t\tel.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;\n\t\tel.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;\n\t}\n\tel.css( el.from ); // set top & left\n\n\t// Animate\n\tif ( scale === \"content\" || scale === \"both\" ) { // Scale the children\n\n\t\t// Add margins/font-size\n\t\tvProps = vProps.concat([ \"marginTop\", \"marginBottom\" ]).concat(cProps);\n\t\thProps = hProps.concat([ \"marginLeft\", \"marginRight\" ]);\n\t\tprops2 = props0.concat(vProps).concat(hProps);\n\n\t\tel.find( \"*[width]\" ).each( function(){\n\t\t\tvar child = $( this ),\n\t\t\t\tc_original = {\n\t\t\t\t\theight: child.height(),\n\t\t\t\t\twidth: child.width(),\n\t\t\t\t\touterHeight: child.outerHeight(),\n\t\t\t\t\touterWidth: child.outerWidth()\n\t\t\t\t};\n\t\t\tif (restore) {\n\t\t\t\t$.effects.save(child, props2);\n\t\t\t}\n\n\t\t\tchild.from = {\n\t\t\t\theight: c_original.height * factor.from.y,\n\t\t\t\twidth: c_original.width * factor.from.x,\n\t\t\t\touterHeight: c_original.outerHeight * factor.from.y,\n\t\t\t\touterWidth: c_original.outerWidth * factor.from.x\n\t\t\t};\n\t\t\tchild.to = {\n\t\t\t\theight: c_original.height * factor.to.y,\n\t\t\t\twidth: c_original.width * factor.to.x,\n\t\t\t\touterHeight: c_original.height * factor.to.y,\n\t\t\t\touterWidth: c_original.width * factor.to.x\n\t\t\t};\n\n\t\t\t// Vertical props scaling\n\t\t\tif ( factor.from.y !== factor.to.y ) {\n\t\t\t\tchild.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );\n\t\t\t\tchild.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );\n\t\t\t}\n\n\t\t\t// Horizontal props scaling\n\t\t\tif ( factor.from.x !== factor.to.x ) {\n\t\t\t\tchild.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );\n\t\t\t\tchild.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );\n\t\t\t}\n\n\t\t\t// Animate children\n\t\t\tchild.css( child.from );\n\t\t\tchild.animate( child.to, o.duration, o.easing, function() {\n\n\t\t\t\t// Restore children\n\t\t\t\tif ( restore ) {\n\t\t\t\t\t$.effects.restore( child, props2 );\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t// Animate\n\tel.animate( el.to, {\n\t\tqueue: false,\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tcomplete: function() {\n\t\t\tif ( el.to.opacity === 0 ) {\n\t\t\t\tel.css( \"opacity\", el.from.opacity );\n\t\t\t}\n\t\t\tif( mode === \"hide\" ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\tif ( !restore ) {\n\n\t\t\t\t// we need to calculate our new positioning based on the scaling\n\t\t\t\tif ( position === \"static\" ) {\n\t\t\t\t\tel.css({\n\t\t\t\t\t\tposition: \"relative\",\n\t\t\t\t\t\ttop: el.to.top,\n\t\t\t\t\t\tleft: el.to.left\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t$.each([ \"top\", \"left\" ], function( idx, pos ) {\n\t\t\t\t\t\tel.css( pos, function( _, str ) {\n\t\t\t\t\t\t\tvar val = parseInt( str, 10 ),\n\t\t\t\t\t\t\t\ttoRef = idx ? el.to.left : el.to.top;\n\n\t\t\t\t\t\t\t// if original was \"auto\", recalculate the new value from wrapper\n\t\t\t\t\t\t\tif ( str === \"auto\" ) {\n\t\t\t\t\t\t\t\treturn toRef + \"px\";\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn val + toRef + \"px\";\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t}\n\t});\n\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.effects.effect.shake = function( o, done ) {\n\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"height\", \"width\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"effect\" ),\n\t\tdirection = o.direction || \"left\",\n\t\tdistance = o.distance || 20,\n\t\ttimes = o.times || 3,\n\t\tanims = times * 2 + 1,\n\t\tspeed = Math.round(o.duration/anims),\n\t\tref = (direction === \"up\" || direction === \"down\") ? \"top\" : \"left\",\n\t\tpositiveMotion = (direction === \"up\" || direction === \"left\"),\n\t\tanimation = {},\n\t\tanimation1 = {},\n\t\tanimation2 = {},\n\t\ti,\n\n\t\t// we will need to re-assemble the queue to stack our animations in place\n\t\tqueue = el.queue(),\n\t\tqueuelen = queue.length;\n\n\t$.effects.save( el, props );\n\tel.show();\n\t$.effects.createWrapper( el );\n\n\t// Animation\n\tanimation[ ref ] = ( positiveMotion ? \"-=\" : \"+=\" ) + distance;\n\tanimation1[ ref ] = ( positiveMotion ? \"+=\" : \"-=\" ) + distance * 2;\n\tanimation2[ ref ] = ( positiveMotion ? \"-=\" : \"+=\" ) + distance * 2;\n\n\t// Animate\n\tel.animate( animation, speed, o.easing );\n\n\t// Shakes\n\tfor ( i = 1; i < times; i++ ) {\n\t\tel.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );\n\t}\n\tel\n\t\t.animate( animation1, speed, o.easing )\n\t\t.animate( animation, speed / 2, o.easing )\n\t\t.queue(function() {\n\t\t\tif ( mode === \"hide\" ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t});\n\n\t// inject all the animations we just queued to be first in line (after \"inprogress\")\n\tif ( queuelen > 1) {\n\t\tqueue.splice.apply( queue,\n\t\t\t[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );\n\t}\n\tel.dequeue();\n\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.effects.effect.slide = function( o, done ) {\n\n\t// Create element\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"width\", \"height\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"show\" ),\n\t\tshow = mode === \"show\",\n\t\tdirection = o.direction || \"left\",\n\t\tref = (direction === \"up\" || direction === \"down\") ? \"top\" : \"left\",\n\t\tpositiveMotion = (direction === \"up\" || direction === \"left\"),\n\t\tdistance,\n\t\tanimation = {};\n\n\t// Adjust\n\t$.effects.save( el, props );\n\tel.show();\n\tdistance = o.distance || el[ ref === \"top\" ? \"outerHeight\" : \"outerWidth\" ]( true );\n\n\t$.effects.createWrapper( el ).css({\n\t\toverflow: \"hidden\"\n\t});\n\n\tif ( show ) {\n\t\tel.css( ref, positiveMotion ? (isNaN(distance) ? \"-\" + distance : -distance) : distance );\n\t}\n\n\t// Animation\n\tanimation[ ref ] = ( show ?\n\t\t( positiveMotion ? \"+=\" : \"-=\") :\n\t\t( positiveMotion ? \"-=\" : \"+=\")) +\n\t\tdistance;\n\n\t// Animate\n\tel.animate( animation, {\n\t\tqueue: false,\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tcomplete: function() {\n\t\t\tif ( mode === \"hide\" ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t}\n\t});\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.effects.effect.transfer = function( o, done ) {\n\tvar elem = $( this ),\n\t\ttarget = $( o.to ),\n\t\ttargetFixed = target.css( \"position\" ) === \"fixed\",\n\t\tbody = $(\"body\"),\n\t\tfixTop = targetFixed ? body.scrollTop() : 0,\n\t\tfixLeft = targetFixed ? body.scrollLeft() : 0,\n\t\tendPosition = target.offset(),\n\t\tanimation = {\n\t\t\ttop: endPosition.top - fixTop ,\n\t\t\tleft: endPosition.left - fixLeft ,\n\t\t\theight: target.innerHeight(),\n\t\t\twidth: target.innerWidth()\n\t\t},\n\t\tstartPosition = elem.offset(),\n\t\ttransfer = $( \"<div class='ui-effects-transfer'></div>\" )\n\t\t\t.appendTo( document.body )\n\t\t\t.addClass( o.className )\n\t\t\t.css({\n\t\t\t\ttop: startPosition.top - fixTop ,\n\t\t\t\tleft: startPosition.left - fixLeft ,\n\t\t\t\theight: elem.innerHeight(),\n\t\t\t\twidth: elem.innerWidth(),\n\t\t\t\tposition: targetFixed ? \"fixed\" : \"absolute\"\n\t\t\t})\n\t\t\t.animate( animation, o.duration, o.easing, function() {\n\t\t\t\ttransfer.remove();\n\t\t\t\tdone();\n\t\t\t});\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.widget( \"ui.menu\", {\n\tversion: \"1.10.3\",\n\tdefaultElement: \"<ul>\",\n\tdelay: 300,\n\toptions: {\n\t\ticons: {\n\t\t\tsubmenu: \"ui-icon-carat-1-e\"\n\t\t},\n\t\tmenus: \"ul\",\n\t\tposition: {\n\t\t\tmy: \"left top\",\n\t\t\tat: \"right top\"\n\t\t},\n\t\trole: \"menu\",\n\n\t\t// callbacks\n\t\tblur: null,\n\t\tfocus: null,\n\t\tselect: null\n\t},\n\n\t_create: function() {\n\t\tthis.activeMenu = this.element;\n\t\t// flag used to prevent firing of the click handler\n\t\t// as the event bubbles up through nested menus\n\t\tthis.mouseHandled = false;\n\t\tthis.element\n\t\t\t.uniqueId()\n\t\t\t.addClass( \"ui-menu ui-widget ui-widget-content ui-corner-all\" )\n\t\t\t.toggleClass( \"ui-menu-icons\", !!this.element.find( \".ui-icon\" ).length )\n\t\t\t.attr({\n\t\t\t\trole: this.options.role,\n\t\t\t\ttabIndex: 0\n\t\t\t})\n\t\t\t// need to catch all clicks on disabled menu\n\t\t\t// not possible through _on\n\t\t\t.bind( \"click\" + this.eventNamespace, $.proxy(function( event ) {\n\t\t\t\tif ( this.options.disabled ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}, this ));\n\n\t\tif ( this.options.disabled ) {\n\t\t\tthis.element\n\t\t\t\t.addClass( \"ui-state-disabled\" )\n\t\t\t\t.attr( \"aria-disabled\", \"true\" );\n\t\t}\n\n\t\tthis._on({\n\t\t\t// Prevent focus from sticking to links inside menu after clicking\n\t\t\t// them (focus should always stay on UL during navigation).\n\t\t\t\"mousedown .ui-menu-item > a\": function( event ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t},\n\t\t\t\"click .ui-state-disabled > a\": function( event ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t},\n\t\t\t\"click .ui-menu-item:has(a)\": function( event ) {\n\t\t\t\tvar target = $( event.target ).closest( \".ui-menu-item\" );\n\t\t\t\tif ( !this.mouseHandled && target.not( \".ui-state-disabled\" ).length ) {\n\t\t\t\t\tthis.mouseHandled = true;\n\n\t\t\t\t\tthis.select( event );\n\t\t\t\t\t// Open submenu on click\n\t\t\t\t\tif ( target.has( \".ui-menu\" ).length ) {\n\t\t\t\t\t\tthis.expand( event );\n\t\t\t\t\t} else if ( !this.element.is( \":focus\" ) ) {\n\t\t\t\t\t\t// Redirect focus to the menu\n\t\t\t\t\t\tthis.element.trigger( \"focus\", [ true ] );\n\n\t\t\t\t\t\t// If the active item is on the top level, let it stay active.\n\t\t\t\t\t\t// Otherwise, blur the active item since it is no longer visible.\n\t\t\t\t\t\tif ( this.active && this.active.parents( \".ui-menu\" ).length === 1 ) {\n\t\t\t\t\t\t\tclearTimeout( this.timer );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"mouseenter .ui-menu-item\": function( event ) {\n\t\t\t\tvar target = $( event.currentTarget );\n\t\t\t\t// Remove ui-state-active class from siblings of the newly focused menu item\n\t\t\t\t// to avoid a jump caused by adjacent elements both having a class with a border\n\t\t\t\ttarget.siblings().children( \".ui-state-active\" ).removeClass( \"ui-state-active\" );\n\t\t\t\tthis.focus( event, target );\n\t\t\t},\n\t\t\tmouseleave: \"collapseAll\",\n\t\t\t\"mouseleave .ui-menu\": \"collapseAll\",\n\t\t\tfocus: function( event, keepActiveItem ) {\n\t\t\t\t// If there's already an active item, keep it active\n\t\t\t\t// If not, activate the first item\n\t\t\t\tvar item = this.active || this.element.children( \".ui-menu-item\" ).eq( 0 );\n\n\t\t\t\tif ( !keepActiveItem ) {\n\t\t\t\t\tthis.focus( event, item );\n\t\t\t\t}\n\t\t\t},\n\t\t\tblur: function( event ) {\n\t\t\t\tthis._delay(function() {\n\t\t\t\t\tif ( !$.contains( this.element[0], this.document[0].activeElement ) ) {\n\t\t\t\t\t\tthis.collapseAll( event );\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\t\t\tkeydown: \"_keydown\"\n\t\t});\n\n\t\tthis.refresh();\n\n\t\t// Clicks outside of a menu collapse any open menus\n\t\tthis._on( this.document, {\n\t\t\tclick: function( event ) {\n\t\t\t\tif ( !$( event.target ).closest( \".ui-menu\" ).length ) {\n\t\t\t\t\tthis.collapseAll( event );\n\t\t\t\t}\n\n\t\t\t\t// Reset the mouseHandled flag\n\t\t\t\tthis.mouseHandled = false;\n\t\t\t}\n\t\t});\n\t},\n\n\t_destroy: function() {\n\t\t// Destroy (sub)menus\n\t\tthis.element\n\t\t\t.removeAttr( \"aria-activedescendant\" )\n\t\t\t.find( \".ui-menu\" ).addBack()\n\t\t\t\t.removeClass( \"ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons\" )\n\t\t\t\t.removeAttr( \"role\" )\n\t\t\t\t.removeAttr( \"tabIndex\" )\n\t\t\t\t.removeAttr( \"aria-labelledby\" )\n\t\t\t\t.removeAttr( \"aria-expanded\" )\n\t\t\t\t.removeAttr( \"aria-hidden\" )\n\t\t\t\t.removeAttr( \"aria-disabled\" )\n\t\t\t\t.removeUniqueId()\n\t\t\t\t.show();\n\n\t\t// Destroy menu items\n\t\tthis.element.find( \".ui-menu-item\" )\n\t\t\t.removeClass( \"ui-menu-item\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-disabled\" )\n\t\t\t.children( \"a\" )\n\t\t\t\t.removeUniqueId()\n\t\t\t\t.removeClass( \"ui-corner-all ui-state-hover\" )\n\t\t\t\t.removeAttr( \"tabIndex\" )\n\t\t\t\t.removeAttr( \"role\" )\n\t\t\t\t.removeAttr( \"aria-haspopup\" )\n\t\t\t\t.children().each( function() {\n\t\t\t\t\tvar elem = $( this );\n\t\t\t\t\tif ( elem.data( \"ui-menu-submenu-carat\" ) ) {\n\t\t\t\t\t\telem.remove();\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t// Destroy menu dividers\n\t\tthis.element.find( \".ui-menu-divider\" ).removeClass( \"ui-menu-divider ui-widget-content\" );\n\t},\n\n\t_keydown: function( event ) {\n\t\t/*jshint maxcomplexity:20*/\n\t\tvar match, prev, character, skip, regex,\n\t\t\tpreventDefault = true;\n\n\t\tfunction escape( value ) {\n\t\t\treturn value.replace( /[\\-\\[\\]{}()*+?.,\\\\\\^$|#\\s]/g, \"\\\\$&\" );\n\t\t}\n\n\t\tswitch ( event.keyCode ) {\n\t\tcase $.ui.keyCode.PAGE_UP:\n\t\t\tthis.previousPage( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.PAGE_DOWN:\n\t\t\tthis.nextPage( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.HOME:\n\t\t\tthis._move( \"first\", \"first\", event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.END:\n\t\t\tthis._move( \"last\", \"last\", event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.UP:\n\t\t\tthis.previous( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.DOWN:\n\t\t\tthis.next( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.LEFT:\n\t\t\tthis.collapse( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.RIGHT:\n\t\t\tif ( this.active && !this.active.is( \".ui-state-disabled\" ) ) {\n\t\t\t\tthis.expand( event );\n\t\t\t}\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.ENTER:\n\t\tcase $.ui.keyCode.SPACE:\n\t\t\tthis._activate( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.ESCAPE:\n\t\t\tthis.collapse( event );\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tpreventDefault = false;\n\t\t\tprev = this.previousFilter || \"\";\n\t\t\tcharacter = String.fromCharCode( event.keyCode );\n\t\t\tskip = false;\n\n\t\t\tclearTimeout( this.filterTimer );\n\n\t\t\tif ( character === prev ) {\n\t\t\t\tskip = true;\n\t\t\t} else {\n\t\t\t\tcharacter = prev + character;\n\t\t\t}\n\n\t\t\tregex = new RegExp( \"^\" + escape( character ), \"i\" );\n\t\t\tmatch = this.activeMenu.children( \".ui-menu-item\" ).filter(function() {\n\t\t\t\treturn regex.test( $( this ).children( \"a\" ).text() );\n\t\t\t});\n\t\t\tmatch = skip && match.index( this.active.next() ) !== -1 ?\n\t\t\t\tthis.active.nextAll( \".ui-menu-item\" ) :\n\t\t\t\tmatch;\n\n\t\t\t// If no matches on the current filter, reset to the last character pressed\n\t\t\t// to move down the menu to the first item that starts with that character\n\t\t\tif ( !match.length ) {\n\t\t\t\tcharacter = String.fromCharCode( event.keyCode );\n\t\t\t\tregex = new RegExp( \"^\" + escape( character ), \"i\" );\n\t\t\t\tmatch = this.activeMenu.children( \".ui-menu-item\" ).filter(function() {\n\t\t\t\t\treturn regex.test( $( this ).children( \"a\" ).text() );\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif ( match.length ) {\n\t\t\t\tthis.focus( event, match );\n\t\t\t\tif ( match.length > 1 ) {\n\t\t\t\t\tthis.previousFilter = character;\n\t\t\t\t\tthis.filterTimer = this._delay(function() {\n\t\t\t\t\t\tdelete this.previousFilter;\n\t\t\t\t\t}, 1000 );\n\t\t\t\t} else {\n\t\t\t\t\tdelete this.previousFilter;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdelete this.previousFilter;\n\t\t\t}\n\t\t}\n\n\t\tif ( preventDefault ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t},\n\n\t_activate: function( event ) {\n\t\tif ( !this.active.is( \".ui-state-disabled\" ) ) {\n\t\t\tif ( this.active.children( \"a[aria-haspopup='true']\" ).length ) {\n\t\t\t\tthis.expand( event );\n\t\t\t} else {\n\t\t\t\tthis.select( event );\n\t\t\t}\n\t\t}\n\t},\n\n\trefresh: function() {\n\t\tvar menus,\n\t\t\ticon = this.options.icons.submenu,\n\t\t\tsubmenus = this.element.find( this.options.menus );\n\n\t\t// Initialize nested menus\n\t\tsubmenus.filter( \":not(.ui-menu)\" )\n\t\t\t.addClass( \"ui-menu ui-widget ui-widget-content ui-corner-all\" )\n\t\t\t.hide()\n\t\t\t.attr({\n\t\t\t\trole: this.options.role,\n\t\t\t\t\"aria-hidden\": \"true\",\n\t\t\t\t\"aria-expanded\": \"false\"\n\t\t\t})\n\t\t\t.each(function() {\n\t\t\t\tvar menu = $( this ),\n\t\t\t\t\titem = menu.prev( \"a\" ),\n\t\t\t\t\tsubmenuCarat = $( \"<span>\" )\n\t\t\t\t\t\t.addClass( \"ui-menu-icon ui-icon \" + icon )\n\t\t\t\t\t\t.data( \"ui-menu-submenu-carat\", true );\n\n\t\t\t\titem\n\t\t\t\t\t.attr( \"aria-haspopup\", \"true\" )\n\t\t\t\t\t.prepend( submenuCarat );\n\t\t\t\tmenu.attr( \"aria-labelledby\", item.attr( \"id\" ) );\n\t\t\t});\n\n\t\tmenus = submenus.add( this.element );\n\n\t\t// Don't refresh list items that are already adapted\n\t\tmenus.children( \":not(.ui-menu-item):has(a)\" )\n\t\t\t.addClass( \"ui-menu-item\" )\n\t\t\t.attr( \"role\", \"presentation\" )\n\t\t\t.children( \"a\" )\n\t\t\t\t.uniqueId()\n\t\t\t\t.addClass( \"ui-corner-all\" )\n\t\t\t\t.attr({\n\t\t\t\t\ttabIndex: -1,\n\t\t\t\t\trole: this._itemRole()\n\t\t\t\t});\n\n\t\t// Initialize unlinked menu-items containing spaces and/or dashes only as dividers\n\t\tmenus.children( \":not(.ui-menu-item)\" ).each(function() {\n\t\t\tvar item = $( this );\n\t\t\t// hyphen, em dash, en dash\n\t\t\tif ( !/[^\\-\\u2014\\u2013\\s]/.test( item.text() ) ) {\n\t\t\t\titem.addClass( \"ui-widget-content ui-menu-divider\" );\n\t\t\t}\n\t\t});\n\n\t\t// Add aria-disabled attribute to any disabled menu item\n\t\tmenus.children( \".ui-state-disabled\" ).attr( \"aria-disabled\", \"true\" );\n\n\t\t// If the active item has been removed, blur the menu\n\t\tif ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {\n\t\t\tthis.blur();\n\t\t}\n\t},\n\n\t_itemRole: function() {\n\t\treturn {\n\t\t\tmenu: \"menuitem\",\n\t\t\tlistbox: \"option\"\n\t\t}[ this.options.role ];\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"icons\" ) {\n\t\t\tthis.element.find( \".ui-menu-icon\" )\n\t\t\t\t.removeClass( this.options.icons.submenu )\n\t\t\t\t.addClass( value.submenu );\n\t\t}\n\t\tthis._super( key, value );\n\t},\n\n\tfocus: function( event, item ) {\n\t\tvar nested, focused;\n\t\tthis.blur( event, event && event.type === \"focus\" );\n\n\t\tthis._scrollIntoView( item );\n\n\t\tthis.active = item.first();\n\t\tfocused = this.active.children( \"a\" ).addClass( \"ui-state-focus\" );\n\t\t// Only update aria-activedescendant if there's a role\n\t\t// otherwise we assume focus is managed elsewhere\n\t\tif ( this.options.role ) {\n\t\t\tthis.element.attr( \"aria-activedescendant\", focused.attr( \"id\" ) );\n\t\t}\n\n\t\t// Highlight active parent menu item, if any\n\t\tthis.active\n\t\t\t.parent()\n\t\t\t.closest( \".ui-menu-item\" )\n\t\t\t.children( \"a:first\" )\n\t\t\t.addClass( \"ui-state-active\" );\n\n\t\tif ( event && event.type === \"keydown\" ) {\n\t\t\tthis._close();\n\t\t} else {\n\t\t\tthis.timer = this._delay(function() {\n\t\t\t\tthis._close();\n\t\t\t}, this.delay );\n\t\t}\n\n\t\tnested = item.children( \".ui-menu\" );\n\t\tif ( nested.length && ( /^mouse/.test( event.type ) ) ) {\n\t\t\tthis._startOpening(nested);\n\t\t}\n\t\tthis.activeMenu = item.parent();\n\n\t\tthis._trigger( \"focus\", event, { item: item } );\n\t},\n\n\t_scrollIntoView: function( item ) {\n\t\tvar borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;\n\t\tif ( this._hasScroll() ) {\n\t\t\tborderTop = parseFloat( $.css( this.activeMenu[0], \"borderTopWidth\" ) ) || 0;\n\t\t\tpaddingTop = parseFloat( $.css( this.activeMenu[0], \"paddingTop\" ) ) || 0;\n\t\t\toffset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;\n\t\t\tscroll = this.activeMenu.scrollTop();\n\t\t\telementHeight = this.activeMenu.height();\n\t\t\titemHeight = item.height();\n\n\t\t\tif ( offset < 0 ) {\n\t\t\t\tthis.activeMenu.scrollTop( scroll + offset );\n\t\t\t} else if ( offset + itemHeight > elementHeight ) {\n\t\t\t\tthis.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );\n\t\t\t}\n\t\t}\n\t},\n\n\tblur: function( event, fromFocus ) {\n\t\tif ( !fromFocus ) {\n\t\t\tclearTimeout( this.timer );\n\t\t}\n\n\t\tif ( !this.active ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.active.children( \"a\" ).removeClass( \"ui-state-focus\" );\n\t\tthis.active = null;\n\n\t\tthis._trigger( \"blur\", event, { item: this.active } );\n\t},\n\n\t_startOpening: function( submenu ) {\n\t\tclearTimeout( this.timer );\n\n\t\t// Don't open if already open fixes a Firefox bug that caused a .5 pixel\n\t\t// shift in the submenu position when mousing over the carat icon\n\t\tif ( submenu.attr( \"aria-hidden\" ) !== \"true\" ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.timer = this._delay(function() {\n\t\t\tthis._close();\n\t\t\tthis._open( submenu );\n\t\t}, this.delay );\n\t},\n\n\t_open: function( submenu ) {\n\t\tvar position = $.extend({\n\t\t\tof: this.active\n\t\t}, this.options.position );\n\n\t\tclearTimeout( this.timer );\n\t\tthis.element.find( \".ui-menu\" ).not( submenu.parents( \".ui-menu\" ) )\n\t\t\t.hide()\n\t\t\t.attr( \"aria-hidden\", \"true\" );\n\n\t\tsubmenu\n\t\t\t.show()\n\t\t\t.removeAttr( \"aria-hidden\" )\n\t\t\t.attr( \"aria-expanded\", \"true\" )\n\t\t\t.position( position );\n\t},\n\n\tcollapseAll: function( event, all ) {\n\t\tclearTimeout( this.timer );\n\t\tthis.timer = this._delay(function() {\n\t\t\t// If we were passed an event, look for the submenu that contains the event\n\t\t\tvar currentMenu = all ? this.element :\n\t\t\t\t$( event && event.target ).closest( this.element.find( \".ui-menu\" ) );\n\n\t\t\t// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway\n\t\t\tif ( !currentMenu.length ) {\n\t\t\t\tcurrentMenu = this.element;\n\t\t\t}\n\n\t\t\tthis._close( currentMenu );\n\n\t\t\tthis.blur( event );\n\t\t\tthis.activeMenu = currentMenu;\n\t\t}, this.delay );\n\t},\n\n\t// With no arguments, closes the currently active menu - if nothing is active\n\t// it closes all menus.  If passed an argument, it will search for menus BELOW\n\t_close: function( startMenu ) {\n\t\tif ( !startMenu ) {\n\t\t\tstartMenu = this.active ? this.active.parent() : this.element;\n\t\t}\n\n\t\tstartMenu\n\t\t\t.find( \".ui-menu\" )\n\t\t\t\t.hide()\n\t\t\t\t.attr( \"aria-hidden\", \"true\" )\n\t\t\t\t.attr( \"aria-expanded\", \"false\" )\n\t\t\t.end()\n\t\t\t.find( \"a.ui-state-active\" )\n\t\t\t\t.removeClass( \"ui-state-active\" );\n\t},\n\n\tcollapse: function( event ) {\n\t\tvar newItem = this.active &&\n\t\t\tthis.active.parent().closest( \".ui-menu-item\", this.element );\n\t\tif ( newItem && newItem.length ) {\n\t\t\tthis._close();\n\t\t\tthis.focus( event, newItem );\n\t\t}\n\t},\n\n\texpand: function( event ) {\n\t\tvar newItem = this.active &&\n\t\t\tthis.active\n\t\t\t\t.children( \".ui-menu \" )\n\t\t\t\t.children( \".ui-menu-item\" )\n\t\t\t\t.first();\n\n\t\tif ( newItem && newItem.length ) {\n\t\t\tthis._open( newItem.parent() );\n\n\t\t\t// Delay so Firefox will not hide activedescendant change in expanding submenu from AT\n\t\t\tthis._delay(function() {\n\t\t\t\tthis.focus( event, newItem );\n\t\t\t});\n\t\t}\n\t},\n\n\tnext: function( event ) {\n\t\tthis._move( \"next\", \"first\", event );\n\t},\n\n\tprevious: function( event ) {\n\t\tthis._move( \"prev\", \"last\", event );\n\t},\n\n\tisFirstItem: function() {\n\t\treturn this.active && !this.active.prevAll( \".ui-menu-item\" ).length;\n\t},\n\n\tisLastItem: function() {\n\t\treturn this.active && !this.active.nextAll( \".ui-menu-item\" ).length;\n\t},\n\n\t_move: function( direction, filter, event ) {\n\t\tvar next;\n\t\tif ( this.active ) {\n\t\t\tif ( direction === \"first\" || direction === \"last\" ) {\n\t\t\t\tnext = this.active\n\t\t\t\t\t[ direction === \"first\" ? \"prevAll\" : \"nextAll\" ]( \".ui-menu-item\" )\n\t\t\t\t\t.eq( -1 );\n\t\t\t} else {\n\t\t\t\tnext = this.active\n\t\t\t\t\t[ direction + \"All\" ]( \".ui-menu-item\" )\n\t\t\t\t\t.eq( 0 );\n\t\t\t}\n\t\t}\n\t\tif ( !next || !next.length || !this.active ) {\n\t\t\tnext = this.activeMenu.children( \".ui-menu-item\" )[ filter ]();\n\t\t}\n\n\t\tthis.focus( event, next );\n\t},\n\n\tnextPage: function( event ) {\n\t\tvar item, base, height;\n\n\t\tif ( !this.active ) {\n\t\t\tthis.next( event );\n\t\t\treturn;\n\t\t}\n\t\tif ( this.isLastItem() ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( this._hasScroll() ) {\n\t\t\tbase = this.active.offset().top;\n\t\t\theight = this.element.height();\n\t\t\tthis.active.nextAll( \".ui-menu-item\" ).each(function() {\n\t\t\t\titem = $( this );\n\t\t\t\treturn item.offset().top - base - height < 0;\n\t\t\t});\n\n\t\t\tthis.focus( event, item );\n\t\t} else {\n\t\t\tthis.focus( event, this.activeMenu.children( \".ui-menu-item\" )\n\t\t\t\t[ !this.active ? \"first\" : \"last\" ]() );\n\t\t}\n\t},\n\n\tpreviousPage: function( event ) {\n\t\tvar item, base, height;\n\t\tif ( !this.active ) {\n\t\t\tthis.next( event );\n\t\t\treturn;\n\t\t}\n\t\tif ( this.isFirstItem() ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( this._hasScroll() ) {\n\t\t\tbase = this.active.offset().top;\n\t\t\theight = this.element.height();\n\t\t\tthis.active.prevAll( \".ui-menu-item\" ).each(function() {\n\t\t\t\titem = $( this );\n\t\t\t\treturn item.offset().top - base + height > 0;\n\t\t\t});\n\n\t\t\tthis.focus( event, item );\n\t\t} else {\n\t\t\tthis.focus( event, this.activeMenu.children( \".ui-menu-item\" ).first() );\n\t\t}\n\t},\n\n\t_hasScroll: function() {\n\t\treturn this.element.outerHeight() < this.element.prop( \"scrollHeight\" );\n\t},\n\n\tselect: function( event ) {\n\t\t// TODO: It should never be possible to not have an active item at this\n\t\t// point, but the tests don't trigger mouseenter before click.\n\t\tthis.active = this.active || $( event.target ).closest( \".ui-menu-item\" );\n\t\tvar ui = { item: this.active };\n\t\tif ( !this.active.has( \".ui-menu\" ).length ) {\n\t\t\tthis.collapseAll( event, true );\n\t\t}\n\t\tthis._trigger( \"select\", event, ui );\n\t}\n});\n\n}( jQuery ));\n\n(function( $, undefined ) {\n\n$.ui = $.ui || {};\n\nvar cachedScrollbarWidth,\n\tmax = Math.max,\n\tabs = Math.abs,\n\tround = Math.round,\n\trhorizontal = /left|center|right/,\n\trvertical = /top|center|bottom/,\n\troffset = /[\\+\\-]\\d+(\\.[\\d]+)?%?/,\n\trposition = /^\\w+/,\n\trpercent = /%$/,\n\t_position = $.fn.position;\n\nfunction getOffsets( offsets, width, height ) {\n\treturn [\n\t\tparseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),\n\t\tparseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )\n\t];\n}\n\nfunction parseCss( element, property ) {\n\treturn parseInt( $.css( element, property ), 10 ) || 0;\n}\n\nfunction getDimensions( elem ) {\n\tvar raw = elem[0];\n\tif ( raw.nodeType === 9 ) {\n\t\treturn {\n\t\t\twidth: elem.width(),\n\t\t\theight: elem.height(),\n\t\t\toffset: { top: 0, left: 0 }\n\t\t};\n\t}\n\tif ( $.isWindow( raw ) ) {\n\t\treturn {\n\t\t\twidth: elem.width(),\n\t\t\theight: elem.height(),\n\t\t\toffset: { top: elem.scrollTop(), left: elem.scrollLeft() }\n\t\t};\n\t}\n\tif ( raw.preventDefault ) {\n\t\treturn {\n\t\t\twidth: 0,\n\t\t\theight: 0,\n\t\t\toffset: { top: raw.pageY, left: raw.pageX }\n\t\t};\n\t}\n\treturn {\n\t\twidth: elem.outerWidth(),\n\t\theight: elem.outerHeight(),\n\t\toffset: elem.offset()\n\t};\n}\n\n$.position = {\n\tscrollbarWidth: function() {\n\t\tif ( cachedScrollbarWidth !== undefined ) {\n\t\t\treturn cachedScrollbarWidth;\n\t\t}\n\t\tvar w1, w2,\n\t\t\tdiv = $( \"<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>\" ),\n\t\t\tinnerDiv = div.children()[0];\n\n\t\t$( \"body\" ).append( div );\n\t\tw1 = innerDiv.offsetWidth;\n\t\tdiv.css( \"overflow\", \"scroll\" );\n\n\t\tw2 = innerDiv.offsetWidth;\n\n\t\tif ( w1 === w2 ) {\n\t\t\tw2 = div[0].clientWidth;\n\t\t}\n\n\t\tdiv.remove();\n\n\t\treturn (cachedScrollbarWidth = w1 - w2);\n\t},\n\tgetScrollInfo: function( within ) {\n\t\tvar overflowX = within.isWindow ? \"\" : within.element.css( \"overflow-x\" ),\n\t\t\toverflowY = within.isWindow ? \"\" : within.element.css( \"overflow-y\" ),\n\t\t\thasOverflowX = overflowX === \"scroll\" ||\n\t\t\t\t( overflowX === \"auto\" && within.width < within.element[0].scrollWidth ),\n\t\t\thasOverflowY = overflowY === \"scroll\" ||\n\t\t\t\t( overflowY === \"auto\" && within.height < within.element[0].scrollHeight );\n\t\treturn {\n\t\t\twidth: hasOverflowY ? $.position.scrollbarWidth() : 0,\n\t\t\theight: hasOverflowX ? $.position.scrollbarWidth() : 0\n\t\t};\n\t},\n\tgetWithinInfo: function( element ) {\n\t\tvar withinElement = $( element || window ),\n\t\t\tisWindow = $.isWindow( withinElement[0] );\n\t\treturn {\n\t\t\telement: withinElement,\n\t\t\tisWindow: isWindow,\n\t\t\toffset: withinElement.offset() || { left: 0, top: 0 },\n\t\t\tscrollLeft: withinElement.scrollLeft(),\n\t\t\tscrollTop: withinElement.scrollTop(),\n\t\t\twidth: isWindow ? withinElement.width() : withinElement.outerWidth(),\n\t\t\theight: isWindow ? withinElement.height() : withinElement.outerHeight()\n\t\t};\n\t}\n};\n\n$.fn.position = function( options ) {\n\tif ( !options || !options.of ) {\n\t\treturn _position.apply( this, arguments );\n\t}\n\n\t// make a copy, we don't want to modify arguments\n\toptions = $.extend( {}, options );\n\n\tvar atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,\n\t\ttarget = $( options.of ),\n\t\twithin = $.position.getWithinInfo( options.within ),\n\t\tscrollInfo = $.position.getScrollInfo( within ),\n\t\tcollision = ( options.collision || \"flip\" ).split( \" \" ),\n\t\toffsets = {};\n\n\tdimensions = getDimensions( target );\n\tif ( target[0].preventDefault ) {\n\t\t// force left top to allow flipping\n\t\toptions.at = \"left top\";\n\t}\n\ttargetWidth = dimensions.width;\n\ttargetHeight = dimensions.height;\n\ttargetOffset = dimensions.offset;\n\t// clone to reuse original targetOffset later\n\tbasePosition = $.extend( {}, targetOffset );\n\n\t// force my and at to have valid horizontal and vertical positions\n\t// if a value is missing or invalid, it will be converted to center\n\t$.each( [ \"my\", \"at\" ], function() {\n\t\tvar pos = ( options[ this ] || \"\" ).split( \" \" ),\n\t\t\thorizontalOffset,\n\t\t\tverticalOffset;\n\n\t\tif ( pos.length === 1) {\n\t\t\tpos = rhorizontal.test( pos[ 0 ] ) ?\n\t\t\t\tpos.concat( [ \"center\" ] ) :\n\t\t\t\trvertical.test( pos[ 0 ] ) ?\n\t\t\t\t\t[ \"center\" ].concat( pos ) :\n\t\t\t\t\t[ \"center\", \"center\" ];\n\t\t}\n\t\tpos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : \"center\";\n\t\tpos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : \"center\";\n\n\t\t// calculate offsets\n\t\thorizontalOffset = roffset.exec( pos[ 0 ] );\n\t\tverticalOffset = roffset.exec( pos[ 1 ] );\n\t\toffsets[ this ] = [\n\t\t\thorizontalOffset ? horizontalOffset[ 0 ] : 0,\n\t\t\tverticalOffset ? verticalOffset[ 0 ] : 0\n\t\t];\n\n\t\t// reduce to just the positions without the offsets\n\t\toptions[ this ] = [\n\t\t\trposition.exec( pos[ 0 ] )[ 0 ],\n\t\t\trposition.exec( pos[ 1 ] )[ 0 ]\n\t\t];\n\t});\n\n\t// normalize collision option\n\tif ( collision.length === 1 ) {\n\t\tcollision[ 1 ] = collision[ 0 ];\n\t}\n\n\tif ( options.at[ 0 ] === \"right\" ) {\n\t\tbasePosition.left += targetWidth;\n\t} else if ( options.at[ 0 ] === \"center\" ) {\n\t\tbasePosition.left += targetWidth / 2;\n\t}\n\n\tif ( options.at[ 1 ] === \"bottom\" ) {\n\t\tbasePosition.top += targetHeight;\n\t} else if ( options.at[ 1 ] === \"center\" ) {\n\t\tbasePosition.top += targetHeight / 2;\n\t}\n\n\tatOffset = getOffsets( offsets.at, targetWidth, targetHeight );\n\tbasePosition.left += atOffset[ 0 ];\n\tbasePosition.top += atOffset[ 1 ];\n\n\treturn this.each(function() {\n\t\tvar collisionPosition, using,\n\t\t\telem = $( this ),\n\t\t\telemWidth = elem.outerWidth(),\n\t\t\telemHeight = elem.outerHeight(),\n\t\t\tmarginLeft = parseCss( this, \"marginLeft\" ),\n\t\t\tmarginTop = parseCss( this, \"marginTop\" ),\n\t\t\tcollisionWidth = elemWidth + marginLeft + parseCss( this, \"marginRight\" ) + scrollInfo.width,\n\t\t\tcollisionHeight = elemHeight + marginTop + parseCss( this, \"marginBottom\" ) + scrollInfo.height,\n\t\t\tposition = $.extend( {}, basePosition ),\n\t\t\tmyOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );\n\n\t\tif ( options.my[ 0 ] === \"right\" ) {\n\t\t\tposition.left -= elemWidth;\n\t\t} else if ( options.my[ 0 ] === \"center\" ) {\n\t\t\tposition.left -= elemWidth / 2;\n\t\t}\n\n\t\tif ( options.my[ 1 ] === \"bottom\" ) {\n\t\t\tposition.top -= elemHeight;\n\t\t} else if ( options.my[ 1 ] === \"center\" ) {\n\t\t\tposition.top -= elemHeight / 2;\n\t\t}\n\n\t\tposition.left += myOffset[ 0 ];\n\t\tposition.top += myOffset[ 1 ];\n\n\t\t// if the browser doesn't support fractions, then round for consistent results\n\t\tif ( !$.support.offsetFractions ) {\n\t\t\tposition.left = round( position.left );\n\t\t\tposition.top = round( position.top );\n\t\t}\n\n\t\tcollisionPosition = {\n\t\t\tmarginLeft: marginLeft,\n\t\t\tmarginTop: marginTop\n\t\t};\n\n\t\t$.each( [ \"left\", \"top\" ], function( i, dir ) {\n\t\t\tif ( $.ui.position[ collision[ i ] ] ) {\n\t\t\t\t$.ui.position[ collision[ i ] ][ dir ]( position, {\n\t\t\t\t\ttargetWidth: targetWidth,\n\t\t\t\t\ttargetHeight: targetHeight,\n\t\t\t\t\telemWidth: elemWidth,\n\t\t\t\t\telemHeight: elemHeight,\n\t\t\t\t\tcollisionPosition: collisionPosition,\n\t\t\t\t\tcollisionWidth: collisionWidth,\n\t\t\t\t\tcollisionHeight: collisionHeight,\n\t\t\t\t\toffset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],\n\t\t\t\t\tmy: options.my,\n\t\t\t\t\tat: options.at,\n\t\t\t\t\twithin: within,\n\t\t\t\t\telem : elem\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\tif ( options.using ) {\n\t\t\t// adds feedback as second argument to using callback, if present\n\t\t\tusing = function( props ) {\n\t\t\t\tvar left = targetOffset.left - position.left,\n\t\t\t\t\tright = left + targetWidth - elemWidth,\n\t\t\t\t\ttop = targetOffset.top - position.top,\n\t\t\t\t\tbottom = top + targetHeight - elemHeight,\n\t\t\t\t\tfeedback = {\n\t\t\t\t\t\ttarget: {\n\t\t\t\t\t\t\telement: target,\n\t\t\t\t\t\t\tleft: targetOffset.left,\n\t\t\t\t\t\t\ttop: targetOffset.top,\n\t\t\t\t\t\t\twidth: targetWidth,\n\t\t\t\t\t\t\theight: targetHeight\n\t\t\t\t\t\t},\n\t\t\t\t\t\telement: {\n\t\t\t\t\t\t\telement: elem,\n\t\t\t\t\t\t\tleft: position.left,\n\t\t\t\t\t\t\ttop: position.top,\n\t\t\t\t\t\t\twidth: elemWidth,\n\t\t\t\t\t\t\theight: elemHeight\n\t\t\t\t\t\t},\n\t\t\t\t\t\thorizontal: right < 0 ? \"left\" : left > 0 ? \"right\" : \"center\",\n\t\t\t\t\t\tvertical: bottom < 0 ? \"top\" : top > 0 ? \"bottom\" : \"middle\"\n\t\t\t\t\t};\n\t\t\t\tif ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {\n\t\t\t\t\tfeedback.horizontal = \"center\";\n\t\t\t\t}\n\t\t\t\tif ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {\n\t\t\t\t\tfeedback.vertical = \"middle\";\n\t\t\t\t}\n\t\t\t\tif ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {\n\t\t\t\t\tfeedback.important = \"horizontal\";\n\t\t\t\t} else {\n\t\t\t\t\tfeedback.important = \"vertical\";\n\t\t\t\t}\n\t\t\t\toptions.using.call( this, props, feedback );\n\t\t\t};\n\t\t}\n\n\t\telem.offset( $.extend( position, { using: using } ) );\n\t});\n};\n\n$.ui.position = {\n\tfit: {\n\t\tleft: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.isWindow ? within.scrollLeft : within.offset.left,\n\t\t\t\touterWidth = within.width,\n\t\t\t\tcollisionPosLeft = position.left - data.collisionPosition.marginLeft,\n\t\t\t\toverLeft = withinOffset - collisionPosLeft,\n\t\t\t\toverRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,\n\t\t\t\tnewOverRight;\n\n\t\t\t// element is wider than within\n\t\t\tif ( data.collisionWidth > outerWidth ) {\n\t\t\t\t// element is initially over the left side of within\n\t\t\t\tif ( overLeft > 0 && overRight <= 0 ) {\n\t\t\t\t\tnewOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;\n\t\t\t\t\tposition.left += overLeft - newOverRight;\n\t\t\t\t// element is initially over right side of within\n\t\t\t\t} else if ( overRight > 0 && overLeft <= 0 ) {\n\t\t\t\t\tposition.left = withinOffset;\n\t\t\t\t// element is initially over both left and right sides of within\n\t\t\t\t} else {\n\t\t\t\t\tif ( overLeft > overRight ) {\n\t\t\t\t\t\tposition.left = withinOffset + outerWidth - data.collisionWidth;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tposition.left = withinOffset;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t// too far left -> align with left edge\n\t\t\t} else if ( overLeft > 0 ) {\n\t\t\t\tposition.left += overLeft;\n\t\t\t// too far right -> align with right edge\n\t\t\t} else if ( overRight > 0 ) {\n\t\t\t\tposition.left -= overRight;\n\t\t\t// adjust based on position and margin\n\t\t\t} else {\n\t\t\t\tposition.left = max( position.left - collisionPosLeft, position.left );\n\t\t\t}\n\t\t},\n\t\ttop: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.isWindow ? within.scrollTop : within.offset.top,\n\t\t\t\touterHeight = data.within.height,\n\t\t\t\tcollisionPosTop = position.top - data.collisionPosition.marginTop,\n\t\t\t\toverTop = withinOffset - collisionPosTop,\n\t\t\t\toverBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,\n\t\t\t\tnewOverBottom;\n\n\t\t\t// element is taller than within\n\t\t\tif ( data.collisionHeight > outerHeight ) {\n\t\t\t\t// element is initially over the top of within\n\t\t\t\tif ( overTop > 0 && overBottom <= 0 ) {\n\t\t\t\t\tnewOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;\n\t\t\t\t\tposition.top += overTop - newOverBottom;\n\t\t\t\t// element is initially over bottom of within\n\t\t\t\t} else if ( overBottom > 0 && overTop <= 0 ) {\n\t\t\t\t\tposition.top = withinOffset;\n\t\t\t\t// element is initially over both top and bottom of within\n\t\t\t\t} else {\n\t\t\t\t\tif ( overTop > overBottom ) {\n\t\t\t\t\t\tposition.top = withinOffset + outerHeight - data.collisionHeight;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tposition.top = withinOffset;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t// too far up -> align with top\n\t\t\t} else if ( overTop > 0 ) {\n\t\t\t\tposition.top += overTop;\n\t\t\t// too far down -> align with bottom edge\n\t\t\t} else if ( overBottom > 0 ) {\n\t\t\t\tposition.top -= overBottom;\n\t\t\t// adjust based on position and margin\n\t\t\t} else {\n\t\t\t\tposition.top = max( position.top - collisionPosTop, position.top );\n\t\t\t}\n\t\t}\n\t},\n\tflip: {\n\t\tleft: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.offset.left + within.scrollLeft,\n\t\t\t\touterWidth = within.width,\n\t\t\t\toffsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,\n\t\t\t\tcollisionPosLeft = position.left - data.collisionPosition.marginLeft,\n\t\t\t\toverLeft = collisionPosLeft - offsetLeft,\n\t\t\t\toverRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,\n\t\t\t\tmyOffset = data.my[ 0 ] === \"left\" ?\n\t\t\t\t\t-data.elemWidth :\n\t\t\t\t\tdata.my[ 0 ] === \"right\" ?\n\t\t\t\t\t\tdata.elemWidth :\n\t\t\t\t\t\t0,\n\t\t\t\tatOffset = data.at[ 0 ] === \"left\" ?\n\t\t\t\t\tdata.targetWidth :\n\t\t\t\t\tdata.at[ 0 ] === \"right\" ?\n\t\t\t\t\t\t-data.targetWidth :\n\t\t\t\t\t\t0,\n\t\t\t\toffset = -2 * data.offset[ 0 ],\n\t\t\t\tnewOverRight,\n\t\t\t\tnewOverLeft;\n\n\t\t\tif ( overLeft < 0 ) {\n\t\t\t\tnewOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;\n\t\t\t\tif ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {\n\t\t\t\t\tposition.left += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( overRight > 0 ) {\n\t\t\t\tnewOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;\n\t\t\t\tif ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {\n\t\t\t\t\tposition.left += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ttop: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.offset.top + within.scrollTop,\n\t\t\t\touterHeight = within.height,\n\t\t\t\toffsetTop = within.isWindow ? within.scrollTop : within.offset.top,\n\t\t\t\tcollisionPosTop = position.top - data.collisionPosition.marginTop,\n\t\t\t\toverTop = collisionPosTop - offsetTop,\n\t\t\t\toverBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,\n\t\t\t\ttop = data.my[ 1 ] === \"top\",\n\t\t\t\tmyOffset = top ?\n\t\t\t\t\t-data.elemHeight :\n\t\t\t\t\tdata.my[ 1 ] === \"bottom\" ?\n\t\t\t\t\t\tdata.elemHeight :\n\t\t\t\t\t\t0,\n\t\t\t\tatOffset = data.at[ 1 ] === \"top\" ?\n\t\t\t\t\tdata.targetHeight :\n\t\t\t\t\tdata.at[ 1 ] === \"bottom\" ?\n\t\t\t\t\t\t-data.targetHeight :\n\t\t\t\t\t\t0,\n\t\t\t\toffset = -2 * data.offset[ 1 ],\n\t\t\t\tnewOverTop,\n\t\t\t\tnewOverBottom;\n\t\t\tif ( overTop < 0 ) {\n\t\t\t\tnewOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;\n\t\t\t\tif ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {\n\t\t\t\t\tposition.top += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( overBottom > 0 ) {\n\t\t\t\tnewOverTop = position.top -  data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;\n\t\t\t\tif ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {\n\t\t\t\t\tposition.top += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\tflipfit: {\n\t\tleft: function() {\n\t\t\t$.ui.position.flip.left.apply( this, arguments );\n\t\t\t$.ui.position.fit.left.apply( this, arguments );\n\t\t},\n\t\ttop: function() {\n\t\t\t$.ui.position.flip.top.apply( this, arguments );\n\t\t\t$.ui.position.fit.top.apply( this, arguments );\n\t\t}\n\t}\n};\n\n// fraction support test\n(function () {\n\tvar testElement, testElementParent, testElementStyle, offsetLeft, i,\n\t\tbody = document.getElementsByTagName( \"body\" )[ 0 ],\n\t\tdiv = document.createElement( \"div\" );\n\n\t//Create a \"fake body\" for testing based on method used in jQuery.support\n\ttestElement = document.createElement( body ? \"div\" : \"body\" );\n\ttestElementStyle = {\n\t\tvisibility: \"hidden\",\n\t\twidth: 0,\n\t\theight: 0,\n\t\tborder: 0,\n\t\tmargin: 0,\n\t\tbackground: \"none\"\n\t};\n\tif ( body ) {\n\t\t$.extend( testElementStyle, {\n\t\t\tposition: \"absolute\",\n\t\t\tleft: \"-1000px\",\n\t\t\ttop: \"-1000px\"\n\t\t});\n\t}\n\tfor ( i in testElementStyle ) {\n\t\ttestElement.style[ i ] = testElementStyle[ i ];\n\t}\n\ttestElement.appendChild( div );\n\ttestElementParent = body || document.documentElement;\n\ttestElementParent.insertBefore( testElement, testElementParent.firstChild );\n\n\tdiv.style.cssText = \"position: absolute; left: 10.7432222px;\";\n\n\toffsetLeft = $( div ).offset().left;\n\t$.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;\n\n\ttestElement.innerHTML = \"\";\n\ttestElementParent.removeChild( testElement );\n})();\n\n}( jQuery ) );\n\n(function( $, undefined ) {\n\n$.widget( \"ui.progressbar\", {\n\tversion: \"1.10.3\",\n\toptions: {\n\t\tmax: 100,\n\t\tvalue: 0,\n\n\t\tchange: null,\n\t\tcomplete: null\n\t},\n\n\tmin: 0,\n\n\t_create: function() {\n\t\t// Constrain initial value\n\t\tthis.oldValue = this.options.value = this._constrainedValue();\n\n\t\tthis.element\n\t\t\t.addClass( \"ui-progressbar ui-widget ui-widget-content ui-corner-all\" )\n\t\t\t.attr({\n\t\t\t\t// Only set static values, aria-valuenow and aria-valuemax are\n\t\t\t\t// set inside _refreshValue()\n\t\t\t\trole: \"progressbar\",\n\t\t\t\t\"aria-valuemin\": this.min\n\t\t\t});\n\n\t\tthis.valueDiv = $( \"<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>\" )\n\t\t\t.appendTo( this.element );\n\n\t\tthis._refreshValue();\n\t},\n\n\t_destroy: function() {\n\t\tthis.element\n\t\t\t.removeClass( \"ui-progressbar ui-widget ui-widget-content ui-corner-all\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-valuemin\" )\n\t\t\t.removeAttr( \"aria-valuemax\" )\n\t\t\t.removeAttr( \"aria-valuenow\" );\n\n\t\tthis.valueDiv.remove();\n\t},\n\n\tvalue: function( newValue ) {\n\t\tif ( newValue === undefined ) {\n\t\t\treturn this.options.value;\n\t\t}\n\n\t\tthis.options.value = this._constrainedValue( newValue );\n\t\tthis._refreshValue();\n\t},\n\n\t_constrainedValue: function( newValue ) {\n\t\tif ( newValue === undefined ) {\n\t\t\tnewValue = this.options.value;\n\t\t}\n\n\t\tthis.indeterminate = newValue === false;\n\n\t\t// sanitize value\n\t\tif ( typeof newValue !== \"number\" ) {\n\t\t\tnewValue = 0;\n\t\t}\n\n\t\treturn this.indeterminate ? false :\n\t\t\tMath.min( this.options.max, Math.max( this.min, newValue ) );\n\t},\n\n\t_setOptions: function( options ) {\n\t\t// Ensure \"value\" option is set after other values (like max)\n\t\tvar value = options.value;\n\t\tdelete options.value;\n\n\t\tthis._super( options );\n\n\t\tthis.options.value = this._constrainedValue( value );\n\t\tthis._refreshValue();\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"max\" ) {\n\t\t\t// Don't allow a max less than min\n\t\t\tvalue = Math.max( this.min, value );\n\t\t}\n\n\t\tthis._super( key, value );\n\t},\n\n\t_percentage: function() {\n\t\treturn this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );\n\t},\n\n\t_refreshValue: function() {\n\t\tvar value = this.options.value,\n\t\t\tpercentage = this._percentage();\n\n\t\tthis.valueDiv\n\t\t\t.toggle( this.indeterminate || value > this.min )\n\t\t\t.toggleClass( \"ui-corner-right\", value === this.options.max )\n\t\t\t.width( percentage.toFixed(0) + \"%\" );\n\n\t\tthis.element.toggleClass( \"ui-progressbar-indeterminate\", this.indeterminate );\n\n\t\tif ( this.indeterminate ) {\n\t\t\tthis.element.removeAttr( \"aria-valuenow\" );\n\t\t\tif ( !this.overlayDiv ) {\n\t\t\t\tthis.overlayDiv = $( \"<div class='ui-progressbar-overlay'></div>\" ).appendTo( this.valueDiv );\n\t\t\t}\n\t\t} else {\n\t\t\tthis.element.attr({\n\t\t\t\t\"aria-valuemax\": this.options.max,\n\t\t\t\t\"aria-valuenow\": value\n\t\t\t});\n\t\t\tif ( this.overlayDiv ) {\n\t\t\t\tthis.overlayDiv.remove();\n\t\t\t\tthis.overlayDiv = null;\n\t\t\t}\n\t\t}\n\n\t\tif ( this.oldValue !== value ) {\n\t\t\tthis.oldValue = value;\n\t\t\tthis._trigger( \"change\" );\n\t\t}\n\t\tif ( value === this.options.max ) {\n\t\t\tthis._trigger( \"complete\" );\n\t\t}\n\t}\n});\n\n})( jQuery );\n\n(function( $, undefined ) {\n\n// number of pages in a slider\n// (how many times can you page up/down to go through the whole range)\nvar numPages = 5;\n\n$.widget( \"ui.slider\", $.ui.mouse, {\n\tversion: \"1.10.3\",\n\twidgetEventPrefix: \"slide\",\n\n\toptions: {\n\t\tanimate: false,\n\t\tdistance: 0,\n\t\tmax: 100,\n\t\tmin: 0,\n\t\torientation: \"horizontal\",\n\t\trange: false,\n\t\tstep: 1,\n\t\tvalue: 0,\n\t\tvalues: null,\n\n\t\t// callbacks\n\t\tchange: null,\n\t\tslide: null,\n\t\tstart: null,\n\t\tstop: null\n\t},\n\n\t_create: function() {\n\t\tthis._keySliding = false;\n\t\tthis._mouseSliding = false;\n\t\tthis._animateOff = true;\n\t\tthis._handleIndex = null;\n\t\tthis._detectOrientation();\n\t\tthis._mouseInit();\n\n\t\tthis.element\n\t\t\t.addClass( \"ui-slider\" +\n\t\t\t\t\" ui-slider-\" + this.orientation +\n\t\t\t\t\" ui-widget\" +\n\t\t\t\t\" ui-widget-content\" +\n\t\t\t\t\" ui-corner-all\");\n\n\t\tthis._refresh();\n\t\tthis._setOption( \"disabled\", this.options.disabled );\n\n\t\tthis._animateOff = false;\n\t},\n\n\t_refresh: function() {\n\t\tthis._createRange();\n\t\tthis._createHandles();\n\t\tthis._setupEvents();\n\t\tthis._refreshValue();\n\t},\n\n\t_createHandles: function() {\n\t\tvar i, handleCount,\n\t\t\toptions = this.options,\n\t\t\texistingHandles = this.element.find( \".ui-slider-handle\" ).addClass( \"ui-state-default ui-corner-all\" ),\n\t\t\thandle = \"<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>\",\n\t\t\thandles = [];\n\n\t\thandleCount = ( options.values && options.values.length ) || 1;\n\n\t\tif ( existingHandles.length > handleCount ) {\n\t\t\texistingHandles.slice( handleCount ).remove();\n\t\t\texistingHandles = existingHandles.slice( 0, handleCount );\n\t\t}\n\n\t\tfor ( i = existingHandles.length; i < handleCount; i++ ) {\n\t\t\thandles.push( handle );\n\t\t}\n\n\t\tthis.handles = existingHandles.add( $( handles.join( \"\" ) ).appendTo( this.element ) );\n\n\t\tthis.handle = this.handles.eq( 0 );\n\n\t\tthis.handles.each(function( i ) {\n\t\t\t$( this ).data( \"ui-slider-handle-index\", i );\n\t\t});\n\t},\n\n\t_createRange: function() {\n\t\tvar options = this.options,\n\t\t\tclasses = \"\";\n\n\t\tif ( options.range ) {\n\t\t\tif ( options.range === true ) {\n\t\t\t\tif ( !options.values ) {\n\t\t\t\t\toptions.values = [ this._valueMin(), this._valueMin() ];\n\t\t\t\t} else if ( options.values.length && options.values.length !== 2 ) {\n\t\t\t\t\toptions.values = [ options.values[0], options.values[0] ];\n\t\t\t\t} else if ( $.isArray( options.values ) ) {\n\t\t\t\t\toptions.values = options.values.slice(0);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( !this.range || !this.range.length ) {\n\t\t\t\tthis.range = $( \"<div></div>\" )\n\t\t\t\t\t.appendTo( this.element );\n\n\t\t\t\tclasses = \"ui-slider-range\" +\n\t\t\t\t// note: this isn't the most fittingly semantic framework class for this element,\n\t\t\t\t// but worked best visually with a variety of themes\n\t\t\t\t\" ui-widget-header ui-corner-all\";\n\t\t\t} else {\n\t\t\t\tthis.range.removeClass( \"ui-slider-range-min ui-slider-range-max\" )\n\t\t\t\t\t// Handle range switching from true to min/max\n\t\t\t\t\t.css({\n\t\t\t\t\t\t\"left\": \"\",\n\t\t\t\t\t\t\"bottom\": \"\"\n\t\t\t\t\t});\n\t\t\t}\n\n\t\t\tthis.range.addClass( classes +\n\t\t\t\t( ( options.range === \"min\" || options.range === \"max\" ) ? \" ui-slider-range-\" + options.range : \"\" ) );\n\t\t} else {\n\t\t\tthis.range = $([]);\n\t\t}\n\t},\n\n\t_setupEvents: function() {\n\t\tvar elements = this.handles.add( this.range ).filter( \"a\" );\n\t\tthis._off( elements );\n\t\tthis._on( elements, this._handleEvents );\n\t\tthis._hoverable( elements );\n\t\tthis._focusable( elements );\n\t},\n\n\t_destroy: function() {\n\t\tthis.handles.remove();\n\t\tthis.range.remove();\n\n\t\tthis.element\n\t\t\t.removeClass( \"ui-slider\" +\n\t\t\t\t\" ui-slider-horizontal\" +\n\t\t\t\t\" ui-slider-vertical\" +\n\t\t\t\t\" ui-widget\" +\n\t\t\t\t\" ui-widget-content\" +\n\t\t\t\t\" ui-corner-all\" );\n\n\t\tthis._mouseDestroy();\n\t},\n\n\t_mouseCapture: function( event ) {\n\t\tvar position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,\n\t\t\tthat = this,\n\t\t\to = this.options;\n\n\t\tif ( o.disabled ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.elementSize = {\n\t\t\twidth: this.element.outerWidth(),\n\t\t\theight: this.element.outerHeight()\n\t\t};\n\t\tthis.elementOffset = this.element.offset();\n\n\t\tposition = { x: event.pageX, y: event.pageY };\n\t\tnormValue = this._normValueFromMouse( position );\n\t\tdistance = this._valueMax() - this._valueMin() + 1;\n\t\tthis.handles.each(function( i ) {\n\t\t\tvar thisDistance = Math.abs( normValue - that.values(i) );\n\t\t\tif (( distance > thisDistance ) ||\n\t\t\t\t( distance === thisDistance &&\n\t\t\t\t\t(i === that._lastChangedValue || that.values(i) === o.min ))) {\n\t\t\t\tdistance = thisDistance;\n\t\t\t\tclosestHandle = $( this );\n\t\t\t\tindex = i;\n\t\t\t}\n\t\t});\n\n\t\tallowed = this._start( event, index );\n\t\tif ( allowed === false ) {\n\t\t\treturn false;\n\t\t}\n\t\tthis._mouseSliding = true;\n\n\t\tthis._handleIndex = index;\n\n\t\tclosestHandle\n\t\t\t.addClass( \"ui-state-active\" )\n\t\t\t.focus();\n\n\t\toffset = closestHandle.offset();\n\t\tmouseOverHandle = !$( event.target ).parents().addBack().is( \".ui-slider-handle\" );\n\t\tthis._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {\n\t\t\tleft: event.pageX - offset.left - ( closestHandle.width() / 2 ),\n\t\t\ttop: event.pageY - offset.top -\n\t\t\t\t( closestHandle.height() / 2 ) -\n\t\t\t\t( parseInt( closestHandle.css(\"borderTopWidth\"), 10 ) || 0 ) -\n\t\t\t\t( parseInt( closestHandle.css(\"borderBottomWidth\"), 10 ) || 0) +\n\t\t\t\t( parseInt( closestHandle.css(\"marginTop\"), 10 ) || 0)\n\t\t};\n\n\t\tif ( !this.handles.hasClass( \"ui-state-hover\" ) ) {\n\t\t\tthis._slide( event, index, normValue );\n\t\t}\n\t\tthis._animateOff = true;\n\t\treturn true;\n\t},\n\n\t_mouseStart: function() {\n\t\treturn true;\n\t},\n\n\t_mouseDrag: function( event ) {\n\t\tvar position = { x: event.pageX, y: event.pageY },\n\t\t\tnormValue = this._normValueFromMouse( position );\n\n\t\tthis._slide( event, this._handleIndex, normValue );\n\n\t\treturn false;\n\t},\n\n\t_mouseStop: function( event ) {\n\t\tthis.handles.removeClass( \"ui-state-active\" );\n\t\tthis._mouseSliding = false;\n\n\t\tthis._stop( event, this._handleIndex );\n\t\tthis._change( event, this._handleIndex );\n\n\t\tthis._handleIndex = null;\n\t\tthis._clickOffset = null;\n\t\tthis._animateOff = false;\n\n\t\treturn false;\n\t},\n\n\t_detectOrientation: function() {\n\t\tthis.orientation = ( this.options.orientation === \"vertical\" ) ? \"vertical\" : \"horizontal\";\n\t},\n\n\t_normValueFromMouse: function( position ) {\n\t\tvar pixelTotal,\n\t\t\tpixelMouse,\n\t\t\tpercentMouse,\n\t\t\tvalueTotal,\n\t\t\tvalueMouse;\n\n\t\tif ( this.orientation === \"horizontal\" ) {\n\t\t\tpixelTotal = this.elementSize.width;\n\t\t\tpixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );\n\t\t} else {\n\t\t\tpixelTotal = this.elementSize.height;\n\t\t\tpixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );\n\t\t}\n\n\t\tpercentMouse = ( pixelMouse / pixelTotal );\n\t\tif ( percentMouse > 1 ) {\n\t\t\tpercentMouse = 1;\n\t\t}\n\t\tif ( percentMouse < 0 ) {\n\t\t\tpercentMouse = 0;\n\t\t}\n\t\tif ( this.orientation === \"vertical\" ) {\n\t\t\tpercentMouse = 1 - percentMouse;\n\t\t}\n\n\t\tvalueTotal = this._valueMax() - this._valueMin();\n\t\tvalueMouse = this._valueMin() + percentMouse * valueTotal;\n\n\t\treturn this._trimAlignValue( valueMouse );\n\t},\n\n\t_start: function( event, index ) {\n\t\tvar uiHash = {\n\t\t\thandle: this.handles[ index ],\n\t\t\tvalue: this.value()\n\t\t};\n\t\tif ( this.options.values && this.options.values.length ) {\n\t\t\tuiHash.value = this.values( index );\n\t\t\tuiHash.values = this.values();\n\t\t}\n\t\treturn this._trigger( \"start\", event, uiHash );\n\t},\n\n\t_slide: function( event, index, newVal ) {\n\t\tvar otherVal,\n\t\t\tnewValues,\n\t\t\tallowed;\n\n\t\tif ( this.options.values && this.options.values.length ) {\n\t\t\totherVal = this.values( index ? 0 : 1 );\n\n\t\t\tif ( ( this.options.values.length === 2 && this.options.range === true ) &&\n\t\t\t\t\t( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )\n\t\t\t\t) {\n\t\t\t\tnewVal = otherVal;\n\t\t\t}\n\n\t\t\tif ( newVal !== this.values( index ) ) {\n\t\t\t\tnewValues = this.values();\n\t\t\t\tnewValues[ index ] = newVal;\n\t\t\t\t// A slide can be canceled by returning false from the slide callback\n\t\t\t\tallowed = this._trigger( \"slide\", event, {\n\t\t\t\t\thandle: this.handles[ index ],\n\t\t\t\t\tvalue: newVal,\n\t\t\t\t\tvalues: newValues\n\t\t\t\t} );\n\t\t\t\totherVal = this.values( index ? 0 : 1 );\n\t\t\t\tif ( allowed !== false ) {\n\t\t\t\t\tthis.values( index, newVal, true );\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif ( newVal !== this.value() ) {\n\t\t\t\t// A slide can be canceled by returning false from the slide callback\n\t\t\t\tallowed = this._trigger( \"slide\", event, {\n\t\t\t\t\thandle: this.handles[ index ],\n\t\t\t\t\tvalue: newVal\n\t\t\t\t} );\n\t\t\t\tif ( allowed !== false ) {\n\t\t\t\t\tthis.value( newVal );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t_stop: function( event, index ) {\n\t\tvar uiHash = {\n\t\t\thandle: this.handles[ index ],\n\t\t\tvalue: this.value()\n\t\t};\n\t\tif ( this.options.values && this.options.values.length ) {\n\t\t\tuiHash.value = this.values( index );\n\t\t\tuiHash.values = this.values();\n\t\t}\n\n\t\tthis._trigger( \"stop\", event, uiHash );\n\t},\n\n\t_change: function( event, index ) {\n\t\tif ( !this._keySliding && !this._mouseSliding ) {\n\t\t\tvar uiHash = {\n\t\t\t\thandle: this.handles[ index ],\n\t\t\t\tvalue: this.value()\n\t\t\t};\n\t\t\tif ( this.options.values && this.options.values.length ) {\n\t\t\t\tuiHash.value = this.values( index );\n\t\t\t\tuiHash.values = this.values();\n\t\t\t}\n\n\t\t\t//store the last changed value index for reference when handles overlap\n\t\t\tthis._lastChangedValue = index;\n\n\t\t\tthis._trigger( \"change\", event, uiHash );\n\t\t}\n\t},\n\n\tvalue: function( newValue ) {\n\t\tif ( arguments.length ) {\n\t\t\tthis.options.value = this._trimAlignValue( newValue );\n\t\t\tthis._refreshValue();\n\t\t\tthis._change( null, 0 );\n\t\t\treturn;\n\t\t}\n\n\t\treturn this._value();\n\t},\n\n\tvalues: function( index, newValue ) {\n\t\tvar vals,\n\t\t\tnewValues,\n\t\t\ti;\n\n\t\tif ( arguments.length > 1 ) {\n\t\t\tthis.options.values[ index ] = this._trimAlignValue( newValue );\n\t\t\tthis._refreshValue();\n\t\t\tthis._change( null, index );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( arguments.length ) {\n\t\t\tif ( $.isArray( arguments[ 0 ] ) ) {\n\t\t\t\tvals = this.options.values;\n\t\t\t\tnewValues = arguments[ 0 ];\n\t\t\t\tfor ( i = 0; i < vals.length; i += 1 ) {\n\t\t\t\t\tvals[ i ] = this._trimAlignValue( newValues[ i ] );\n\t\t\t\t\tthis._change( null, i );\n\t\t\t\t}\n\t\t\t\tthis._refreshValue();\n\t\t\t} else {\n\t\t\t\tif ( this.options.values && this.options.values.length ) {\n\t\t\t\t\treturn this._values( index );\n\t\t\t\t} else {\n\t\t\t\t\treturn this.value();\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\treturn this._values();\n\t\t}\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tvar i,\n\t\t\tvalsLength = 0;\n\n\t\tif ( key === \"range\" && this.options.range === true ) {\n\t\t\tif ( value === \"min\" ) {\n\t\t\t\tthis.options.value = this._values( 0 );\n\t\t\t\tthis.options.values = null;\n\t\t\t} else if ( value === \"max\" ) {\n\t\t\t\tthis.options.value = this._values( this.options.values.length-1 );\n\t\t\t\tthis.options.values = null;\n\t\t\t}\n\t\t}\n\n\t\tif ( $.isArray( this.options.values ) ) {\n\t\t\tvalsLength = this.options.values.length;\n\t\t}\n\n\t\t$.Widget.prototype._setOption.apply( this, arguments );\n\n\t\tswitch ( key ) {\n\t\t\tcase \"orientation\":\n\t\t\t\tthis._detectOrientation();\n\t\t\t\tthis.element\n\t\t\t\t\t.removeClass( \"ui-slider-horizontal ui-slider-vertical\" )\n\t\t\t\t\t.addClass( \"ui-slider-\" + this.orientation );\n\t\t\t\tthis._refreshValue();\n\t\t\t\tbreak;\n\t\t\tcase \"value\":\n\t\t\t\tthis._animateOff = true;\n\t\t\t\tthis._refreshValue();\n\t\t\t\tthis._change( null, 0 );\n\t\t\t\tthis._animateOff = false;\n\t\t\t\tbreak;\n\t\t\tcase \"values\":\n\t\t\t\tthis._animateOff = true;\n\t\t\t\tthis._refreshValue();\n\t\t\t\tfor ( i = 0; i < valsLength; i += 1 ) {\n\t\t\t\t\tthis._change( null, i );\n\t\t\t\t}\n\t\t\t\tthis._animateOff = false;\n\t\t\t\tbreak;\n\t\t\tcase \"min\":\n\t\t\tcase \"max\":\n\t\t\t\tthis._animateOff = true;\n\t\t\t\tthis._refreshValue();\n\t\t\t\tthis._animateOff = false;\n\t\t\t\tbreak;\n\t\t\tcase \"range\":\n\t\t\t\tthis._animateOff = true;\n\t\t\t\tthis._refresh();\n\t\t\t\tthis._animateOff = false;\n\t\t\t\tbreak;\n\t\t}\n\t},\n\n\t//internal value getter\n\t// _value() returns value trimmed by min and max, aligned by step\n\t_value: function() {\n\t\tvar val = this.options.value;\n\t\tval = this._trimAlignValue( val );\n\n\t\treturn val;\n\t},\n\n\t//internal values getter\n\t// _values() returns array of values trimmed by min and max, aligned by step\n\t// _values( index ) returns single value trimmed by min and max, aligned by step\n\t_values: function( index ) {\n\t\tvar val,\n\t\t\tvals,\n\t\t\ti;\n\n\t\tif ( arguments.length ) {\n\t\t\tval = this.options.values[ index ];\n\t\t\tval = this._trimAlignValue( val );\n\n\t\t\treturn val;\n\t\t} else if ( this.options.values && this.options.values.length ) {\n\t\t\t// .slice() creates a copy of the array\n\t\t\t// this copy gets trimmed by min and max and then returned\n\t\t\tvals = this.options.values.slice();\n\t\t\tfor ( i = 0; i < vals.length; i+= 1) {\n\t\t\t\tvals[ i ] = this._trimAlignValue( vals[ i ] );\n\t\t\t}\n\n\t\t\treturn vals;\n\t\t} else {\n\t\t\treturn [];\n\t\t}\n\t},\n\n\t// returns the step-aligned value that val is closest to, between (inclusive) min and max\n\t_trimAlignValue: function( val ) {\n\t\tif ( val <= this._valueMin() ) {\n\t\t\treturn this._valueMin();\n\t\t}\n\t\tif ( val >= this._valueMax() ) {\n\t\t\treturn this._valueMax();\n\t\t}\n\t\tvar step = ( this.options.step > 0 ) ? this.options.step : 1,\n\t\t\tvalModStep = (val - this._valueMin()) % step,\n\t\t\talignValue = val - valModStep;\n\n\t\tif ( Math.abs(valModStep) * 2 >= step ) {\n\t\t\talignValue += ( valModStep > 0 ) ? step : ( -step );\n\t\t}\n\n\t\t// Since JavaScript has problems with large floats, round\n\t\t// the final value to 5 digits after the decimal point (see #4124)\n\t\treturn parseFloat( alignValue.toFixed(5) );\n\t},\n\n\t_valueMin: function() {\n\t\treturn this.options.min;\n\t},\n\n\t_valueMax: function() {\n\t\treturn this.options.max;\n\t},\n\n\t_refreshValue: function() {\n\t\tvar lastValPercent, valPercent, value, valueMin, valueMax,\n\t\t\toRange = this.options.range,\n\t\t\to = this.options,\n\t\t\tthat = this,\n\t\t\tanimate = ( !this._animateOff ) ? o.animate : false,\n\t\t\t_set = {};\n\n\t\tif ( this.options.values && this.options.values.length ) {\n\t\t\tthis.handles.each(function( i ) {\n\t\t\t\tvalPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;\n\t\t\t\t_set[ that.orientation === \"horizontal\" ? \"left\" : \"bottom\" ] = valPercent + \"%\";\n\t\t\t\t$( this ).stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( _set, o.animate );\n\t\t\t\tif ( that.options.range === true ) {\n\t\t\t\t\tif ( that.orientation === \"horizontal\" ) {\n\t\t\t\t\t\tif ( i === 0 ) {\n\t\t\t\t\t\t\tthat.range.stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( { left: valPercent + \"%\" }, o.animate );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( i === 1 ) {\n\t\t\t\t\t\t\tthat.range[ animate ? \"animate\" : \"css\" ]( { width: ( valPercent - lastValPercent ) + \"%\" }, { queue: false, duration: o.animate } );\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ( i === 0 ) {\n\t\t\t\t\t\t\tthat.range.stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( { bottom: ( valPercent ) + \"%\" }, o.animate );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( i === 1 ) {\n\t\t\t\t\t\t\tthat.range[ animate ? \"animate\" : \"css\" ]( { height: ( valPercent - lastValPercent ) + \"%\" }, { queue: false, duration: o.animate } );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlastValPercent = valPercent;\n\t\t\t});\n\t\t} else {\n\t\t\tvalue = this.value();\n\t\t\tvalueMin = this._valueMin();\n\t\t\tvalueMax = this._valueMax();\n\t\t\tvalPercent = ( valueMax !== valueMin ) ?\n\t\t\t\t\t( value - valueMin ) / ( valueMax - valueMin ) * 100 :\n\t\t\t\t\t0;\n\t\t\t_set[ this.orientation === \"horizontal\" ? \"left\" : \"bottom\" ] = valPercent + \"%\";\n\t\t\tthis.handle.stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( _set, o.animate );\n\n\t\t\tif ( oRange === \"min\" && this.orientation === \"horizontal\" ) {\n\t\t\t\tthis.range.stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( { width: valPercent + \"%\" }, o.animate );\n\t\t\t}\n\t\t\tif ( oRange === \"max\" && this.orientation === \"horizontal\" ) {\n\t\t\t\tthis.range[ animate ? \"animate\" : \"css\" ]( { width: ( 100 - valPercent ) + \"%\" }, { queue: false, duration: o.animate } );\n\t\t\t}\n\t\t\tif ( oRange === \"min\" && this.orientation === \"vertical\" ) {\n\t\t\t\tthis.range.stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( { height: valPercent + \"%\" }, o.animate );\n\t\t\t}\n\t\t\tif ( oRange === \"max\" && this.orientation === \"vertical\" ) {\n\t\t\t\tthis.range[ animate ? \"animate\" : \"css\" ]( { height: ( 100 - valPercent ) + \"%\" }, { queue: false, duration: o.animate } );\n\t\t\t}\n\t\t}\n\t},\n\n\t_handleEvents: {\n\t\tkeydown: function( event ) {\n\t\t\t/*jshint maxcomplexity:25*/\n\t\t\tvar allowed, curVal, newVal, step,\n\t\t\t\tindex = $( event.target ).data( \"ui-slider-handle-index\" );\n\n\t\t\tswitch ( event.keyCode ) {\n\t\t\t\tcase $.ui.keyCode.HOME:\n\t\t\t\tcase $.ui.keyCode.END:\n\t\t\t\tcase $.ui.keyCode.PAGE_UP:\n\t\t\t\tcase $.ui.keyCode.PAGE_DOWN:\n\t\t\t\tcase $.ui.keyCode.UP:\n\t\t\t\tcase $.ui.keyCode.RIGHT:\n\t\t\t\tcase $.ui.keyCode.DOWN:\n\t\t\t\tcase $.ui.keyCode.LEFT:\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tif ( !this._keySliding ) {\n\t\t\t\t\t\tthis._keySliding = true;\n\t\t\t\t\t\t$( event.target ).addClass( \"ui-state-active\" );\n\t\t\t\t\t\tallowed = this._start( event, index );\n\t\t\t\t\t\tif ( allowed === false ) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tstep = this.options.step;\n\t\t\tif ( this.options.values && this.options.values.length ) {\n\t\t\t\tcurVal = newVal = this.values( index );\n\t\t\t} else {\n\t\t\t\tcurVal = newVal = this.value();\n\t\t\t}\n\n\t\t\tswitch ( event.keyCode ) {\n\t\t\t\tcase $.ui.keyCode.HOME:\n\t\t\t\t\tnewVal = this._valueMin();\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.END:\n\t\t\t\t\tnewVal = this._valueMax();\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.PAGE_UP:\n\t\t\t\t\tnewVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.PAGE_DOWN:\n\t\t\t\t\tnewVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.UP:\n\t\t\t\tcase $.ui.keyCode.RIGHT:\n\t\t\t\t\tif ( curVal === this._valueMax() ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tnewVal = this._trimAlignValue( curVal + step );\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.DOWN:\n\t\t\t\tcase $.ui.keyCode.LEFT:\n\t\t\t\t\tif ( curVal === this._valueMin() ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tnewVal = this._trimAlignValue( curVal - step );\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tthis._slide( event, index, newVal );\n\t\t},\n\t\tclick: function( event ) {\n\t\t\tevent.preventDefault();\n\t\t},\n\t\tkeyup: function( event ) {\n\t\t\tvar index = $( event.target ).data( \"ui-slider-handle-index\" );\n\n\t\t\tif ( this._keySliding ) {\n\t\t\t\tthis._keySliding = false;\n\t\t\t\tthis._stop( event, index );\n\t\t\t\tthis._change( event, index );\n\t\t\t\t$( event.target ).removeClass( \"ui-state-active\" );\n\t\t\t}\n\t\t}\n\t}\n\n});\n\n}(jQuery));\n\n(function( $ ) {\n\nfunction modifier( fn ) {\n\treturn function() {\n\t\tvar previous = this.element.val();\n\t\tfn.apply( this, arguments );\n\t\tthis._refresh();\n\t\tif ( previous !== this.element.val() ) {\n\t\t\tthis._trigger( \"change\" );\n\t\t}\n\t};\n}\n\n$.widget( \"ui.spinner\", {\n\tversion: \"1.10.3\",\n\tdefaultElement: \"<input>\",\n\twidgetEventPrefix: \"spin\",\n\toptions: {\n\t\tculture: null,\n\t\ticons: {\n\t\t\tdown: \"ui-icon-triangle-1-s\",\n\t\t\tup: \"ui-icon-triangle-1-n\"\n\t\t},\n\t\tincremental: true,\n\t\tmax: null,\n\t\tmin: null,\n\t\tnumberFormat: null,\n\t\tpage: 10,\n\t\tstep: 1,\n\n\t\tchange: null,\n\t\tspin: null,\n\t\tstart: null,\n\t\tstop: null\n\t},\n\n\t_create: function() {\n\t\t// handle string values that need to be parsed\n\t\tthis._setOption( \"max\", this.options.max );\n\t\tthis._setOption( \"min\", this.options.min );\n\t\tthis._setOption( \"step\", this.options.step );\n\n\t\t// format the value, but don't constrain\n\t\tthis._value( this.element.val(), true );\n\n\t\tthis._draw();\n\t\tthis._on( this._events );\n\t\tthis._refresh();\n\n\t\t// turning off autocomplete prevents the browser from remembering the\n\t\t// value when navigating through history, so we re-enable autocomplete\n\t\t// if the page is unloaded before the widget is destroyed. #7790\n\t\tthis._on( this.window, {\n\t\t\tbeforeunload: function() {\n\t\t\t\tthis.element.removeAttr( \"autocomplete\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_getCreateOptions: function() {\n\t\tvar options = {},\n\t\t\telement = this.element;\n\n\t\t$.each( [ \"min\", \"max\", \"step\" ], function( i, option ) {\n\t\t\tvar value = element.attr( option );\n\t\t\tif ( value !== undefined && value.length ) {\n\t\t\t\toptions[ option ] = value;\n\t\t\t}\n\t\t});\n\n\t\treturn options;\n\t},\n\n\t_events: {\n\t\tkeydown: function( event ) {\n\t\t\tif ( this._start( event ) && this._keydown( event ) ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t},\n\t\tkeyup: \"_stop\",\n\t\tfocus: function() {\n\t\t\tthis.previous = this.element.val();\n\t\t},\n\t\tblur: function( event ) {\n\t\t\tif ( this.cancelBlur ) {\n\t\t\t\tdelete this.cancelBlur;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._stop();\n\t\t\tthis._refresh();\n\t\t\tif ( this.previous !== this.element.val() ) {\n\t\t\t\tthis._trigger( \"change\", event );\n\t\t\t}\n\t\t},\n\t\tmousewheel: function( event, delta ) {\n\t\t\tif ( !delta ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif ( !this.spinning && !this._start( event ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tthis._spin( (delta > 0 ? 1 : -1) * this.options.step, event );\n\t\t\tclearTimeout( this.mousewheelTimer );\n\t\t\tthis.mousewheelTimer = this._delay(function() {\n\t\t\t\tif ( this.spinning ) {\n\t\t\t\t\tthis._stop( event );\n\t\t\t\t}\n\t\t\t}, 100 );\n\t\t\tevent.preventDefault();\n\t\t},\n\t\t\"mousedown .ui-spinner-button\": function( event ) {\n\t\t\tvar previous;\n\n\t\t\t// We never want the buttons to have focus; whenever the user is\n\t\t\t// interacting with the spinner, the focus should be on the input.\n\t\t\t// If the input is focused then this.previous is properly set from\n\t\t\t// when the input first received focus. If the input is not focused\n\t\t\t// then we need to set this.previous based on the value before spinning.\n\t\t\tprevious = this.element[0] === this.document[0].activeElement ?\n\t\t\t\tthis.previous : this.element.val();\n\t\t\tfunction checkFocus() {\n\t\t\t\tvar isActive = this.element[0] === this.document[0].activeElement;\n\t\t\t\tif ( !isActive ) {\n\t\t\t\t\tthis.element.focus();\n\t\t\t\t\tthis.previous = previous;\n\t\t\t\t\t// support: IE\n\t\t\t\t\t// IE sets focus asynchronously, so we need to check if focus\n\t\t\t\t\t// moved off of the input because the user clicked on the button.\n\t\t\t\t\tthis._delay(function() {\n\t\t\t\t\t\tthis.previous = previous;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// ensure focus is on (or stays on) the text field\n\t\t\tevent.preventDefault();\n\t\t\tcheckFocus.call( this );\n\n\t\t\t// support: IE\n\t\t\t// IE doesn't prevent moving focus even with event.preventDefault()\n\t\t\t// so we set a flag to know when we should ignore the blur event\n\t\t\t// and check (again) if focus moved off of the input.\n\t\t\tthis.cancelBlur = true;\n\t\t\tthis._delay(function() {\n\t\t\t\tdelete this.cancelBlur;\n\t\t\t\tcheckFocus.call( this );\n\t\t\t});\n\n\t\t\tif ( this._start( event ) === false ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._repeat( null, $( event.currentTarget ).hasClass( \"ui-spinner-up\" ) ? 1 : -1, event );\n\t\t},\n\t\t\"mouseup .ui-spinner-button\": \"_stop\",\n\t\t\"mouseenter .ui-spinner-button\": function( event ) {\n\t\t\t// button will add ui-state-active if mouse was down while mouseleave and kept down\n\t\t\tif ( !$( event.currentTarget ).hasClass( \"ui-state-active\" ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( this._start( event ) === false ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis._repeat( null, $( event.currentTarget ).hasClass( \"ui-spinner-up\" ) ? 1 : -1, event );\n\t\t},\n\t\t// TODO: do we really want to consider this a stop?\n\t\t// shouldn't we just stop the repeater and wait until mouseup before\n\t\t// we trigger the stop event?\n\t\t\"mouseleave .ui-spinner-button\": \"_stop\"\n\t},\n\n\t_draw: function() {\n\t\tvar uiSpinner = this.uiSpinner = this.element\n\t\t\t.addClass( \"ui-spinner-input\" )\n\t\t\t.attr( \"autocomplete\", \"off\" )\n\t\t\t.wrap( this._uiSpinnerHtml() )\n\t\t\t.parent()\n\t\t\t\t// add buttons\n\t\t\t\t.append( this._buttonHtml() );\n\n\t\tthis.element.attr( \"role\", \"spinbutton\" );\n\n\t\t// button bindings\n\t\tthis.buttons = uiSpinner.find( \".ui-spinner-button\" )\n\t\t\t.attr( \"tabIndex\", -1 )\n\t\t\t.button()\n\t\t\t.removeClass( \"ui-corner-all\" );\n\n\t\t// IE 6 doesn't understand height: 50% for the buttons\n\t\t// unless the wrapper has an explicit height\n\t\tif ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&\n\t\t\t\tuiSpinner.height() > 0 ) {\n\t\t\tuiSpinner.height( uiSpinner.height() );\n\t\t}\n\n\t\t// disable spinner if element was already disabled\n\t\tif ( this.options.disabled ) {\n\t\t\tthis.disable();\n\t\t}\n\t},\n\n\t_keydown: function( event ) {\n\t\tvar options = this.options,\n\t\t\tkeyCode = $.ui.keyCode;\n\n\t\tswitch ( event.keyCode ) {\n\t\tcase keyCode.UP:\n\t\t\tthis._repeat( null, 1, event );\n\t\t\treturn true;\n\t\tcase keyCode.DOWN:\n\t\t\tthis._repeat( null, -1, event );\n\t\t\treturn true;\n\t\tcase keyCode.PAGE_UP:\n\t\t\tthis._repeat( null, options.page, event );\n\t\t\treturn true;\n\t\tcase keyCode.PAGE_DOWN:\n\t\t\tthis._repeat( null, -options.page, event );\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t},\n\n\t_uiSpinnerHtml: function() {\n\t\treturn \"<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>\";\n\t},\n\n\t_buttonHtml: function() {\n\t\treturn \"\" +\n\t\t\t\"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>\" +\n\t\t\t\t\"<span class='ui-icon \" + this.options.icons.up + \"'>&#9650;</span>\" +\n\t\t\t\"</a>\" +\n\t\t\t\"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>\" +\n\t\t\t\t\"<span class='ui-icon \" + this.options.icons.down + \"'>&#9660;</span>\" +\n\t\t\t\"</a>\";\n\t},\n\n\t_start: function( event ) {\n\t\tif ( !this.spinning && this._trigger( \"start\", event ) === false ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( !this.counter ) {\n\t\t\tthis.counter = 1;\n\t\t}\n\t\tthis.spinning = true;\n\t\treturn true;\n\t},\n\n\t_repeat: function( i, steps, event ) {\n\t\ti = i || 500;\n\n\t\tclearTimeout( this.timer );\n\t\tthis.timer = this._delay(function() {\n\t\t\tthis._repeat( 40, steps, event );\n\t\t}, i );\n\n\t\tthis._spin( steps * this.options.step, event );\n\t},\n\n\t_spin: function( step, event ) {\n\t\tvar value = this.value() || 0;\n\n\t\tif ( !this.counter ) {\n\t\t\tthis.counter = 1;\n\t\t}\n\n\t\tvalue = this._adjustValue( value + step * this._increment( this.counter ) );\n\n\t\tif ( !this.spinning || this._trigger( \"spin\", event, { value: value } ) !== false) {\n\t\t\tthis._value( value );\n\t\t\tthis.counter++;\n\t\t}\n\t},\n\n\t_increment: function( i ) {\n\t\tvar incremental = this.options.incremental;\n\n\t\tif ( incremental ) {\n\t\t\treturn $.isFunction( incremental ) ?\n\t\t\t\tincremental( i ) :\n\t\t\t\tMath.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );\n\t\t}\n\n\t\treturn 1;\n\t},\n\n\t_precision: function() {\n\t\tvar precision = this._precisionOf( this.options.step );\n\t\tif ( this.options.min !== null ) {\n\t\t\tprecision = Math.max( precision, this._precisionOf( this.options.min ) );\n\t\t}\n\t\treturn precision;\n\t},\n\n\t_precisionOf: function( num ) {\n\t\tvar str = num.toString(),\n\t\t\tdecimal = str.indexOf( \".\" );\n\t\treturn decimal === -1 ? 0 : str.length - decimal - 1;\n\t},\n\n\t_adjustValue: function( value ) {\n\t\tvar base, aboveMin,\n\t\t\toptions = this.options;\n\n\t\t// make sure we're at a valid step\n\t\t// - find out where we are relative to the base (min or 0)\n\t\tbase = options.min !== null ? options.min : 0;\n\t\taboveMin = value - base;\n\t\t// - round to the nearest step\n\t\taboveMin = Math.round(aboveMin / options.step) * options.step;\n\t\t// - rounding is based on 0, so adjust back to our base\n\t\tvalue = base + aboveMin;\n\n\t\t// fix precision from bad JS floating point math\n\t\tvalue = parseFloat( value.toFixed( this._precision() ) );\n\n\t\t// clamp the value\n\t\tif ( options.max !== null && value > options.max) {\n\t\t\treturn options.max;\n\t\t}\n\t\tif ( options.min !== null && value < options.min ) {\n\t\t\treturn options.min;\n\t\t}\n\n\t\treturn value;\n\t},\n\n\t_stop: function( event ) {\n\t\tif ( !this.spinning ) {\n\t\t\treturn;\n\t\t}\n\n\t\tclearTimeout( this.timer );\n\t\tclearTimeout( this.mousewheelTimer );\n\t\tthis.counter = 0;\n\t\tthis.spinning = false;\n\t\tthis._trigger( \"stop\", event );\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"culture\" || key === \"numberFormat\" ) {\n\t\t\tvar prevValue = this._parse( this.element.val() );\n\t\t\tthis.options[ key ] = value;\n\t\t\tthis.element.val( this._format( prevValue ) );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key === \"max\" || key === \"min\" || key === \"step\" ) {\n\t\t\tif ( typeof value === \"string\" ) {\n\t\t\t\tvalue = this._parse( value );\n\t\t\t}\n\t\t}\n\t\tif ( key === \"icons\" ) {\n\t\t\tthis.buttons.first().find( \".ui-icon\" )\n\t\t\t\t.removeClass( this.options.icons.up )\n\t\t\t\t.addClass( value.up );\n\t\t\tthis.buttons.last().find( \".ui-icon\" )\n\t\t\t\t.removeClass( this.options.icons.down )\n\t\t\t\t.addClass( value.down );\n\t\t}\n\n\t\tthis._super( key, value );\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\tif ( value ) {\n\t\t\t\tthis.element.prop( \"disabled\", true );\n\t\t\t\tthis.buttons.button( \"disable\" );\n\t\t\t} else {\n\t\t\t\tthis.element.prop( \"disabled\", false );\n\t\t\t\tthis.buttons.button( \"enable\" );\n\t\t\t}\n\t\t}\n\t},\n\n\t_setOptions: modifier(function( options ) {\n\t\tthis._super( options );\n\t\tthis._value( this.element.val() );\n\t}),\n\n\t_parse: function( val ) {\n\t\tif ( typeof val === \"string\" && val !== \"\" ) {\n\t\t\tval = window.Globalize && this.options.numberFormat ?\n\t\t\t\tGlobalize.parseFloat( val, 10, this.options.culture ) : +val;\n\t\t}\n\t\treturn val === \"\" || isNaN( val ) ? null : val;\n\t},\n\n\t_format: function( value ) {\n\t\tif ( value === \"\" ) {\n\t\t\treturn \"\";\n\t\t}\n\t\treturn window.Globalize && this.options.numberFormat ?\n\t\t\tGlobalize.format( value, this.options.numberFormat, this.options.culture ) :\n\t\t\tvalue;\n\t},\n\n\t_refresh: function() {\n\t\tthis.element.attr({\n\t\t\t\"aria-valuemin\": this.options.min,\n\t\t\t\"aria-valuemax\": this.options.max,\n\t\t\t// TODO: what should we do with values that can't be parsed?\n\t\t\t\"aria-valuenow\": this._parse( this.element.val() )\n\t\t});\n\t},\n\n\t// update the value without triggering change\n\t_value: function( value, allowAny ) {\n\t\tvar parsed;\n\t\tif ( value !== \"\" ) {\n\t\t\tparsed = this._parse( value );\n\t\t\tif ( parsed !== null ) {\n\t\t\t\tif ( !allowAny ) {\n\t\t\t\t\tparsed = this._adjustValue( parsed );\n\t\t\t\t}\n\t\t\t\tvalue = this._format( parsed );\n\t\t\t}\n\t\t}\n\t\tthis.element.val( value );\n\t\tthis._refresh();\n\t},\n\n\t_destroy: function() {\n\t\tthis.element\n\t\t\t.removeClass( \"ui-spinner-input\" )\n\t\t\t.prop( \"disabled\", false )\n\t\t\t.removeAttr( \"autocomplete\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-valuemin\" )\n\t\t\t.removeAttr( \"aria-valuemax\" )\n\t\t\t.removeAttr( \"aria-valuenow\" );\n\t\tthis.uiSpinner.replaceWith( this.element );\n\t},\n\n\tstepUp: modifier(function( steps ) {\n\t\tthis._stepUp( steps );\n\t}),\n\t_stepUp: function( steps ) {\n\t\tif ( this._start() ) {\n\t\t\tthis._spin( (steps || 1) * this.options.step );\n\t\t\tthis._stop();\n\t\t}\n\t},\n\n\tstepDown: modifier(function( steps ) {\n\t\tthis._stepDown( steps );\n\t}),\n\t_stepDown: function( steps ) {\n\t\tif ( this._start() ) {\n\t\t\tthis._spin( (steps || 1) * -this.options.step );\n\t\t\tthis._stop();\n\t\t}\n\t},\n\n\tpageUp: modifier(function( pages ) {\n\t\tthis._stepUp( (pages || 1) * this.options.page );\n\t}),\n\n\tpageDown: modifier(function( pages ) {\n\t\tthis._stepDown( (pages || 1) * this.options.page );\n\t}),\n\n\tvalue: function( newVal ) {\n\t\tif ( !arguments.length ) {\n\t\t\treturn this._parse( this.element.val() );\n\t\t}\n\t\tmodifier( this._value ).call( this, newVal );\n\t},\n\n\twidget: function() {\n\t\treturn this.uiSpinner;\n\t}\n});\n\n}( jQuery ) );\n\n(function( $, undefined ) {\n\nvar tabId = 0,\n\trhash = /#.*$/;\n\nfunction getNextTabId() {\n\treturn ++tabId;\n}\n\nfunction isLocal( anchor ) {\n\treturn anchor.hash.length > 1 &&\n\t\tdecodeURIComponent( anchor.href.replace( rhash, \"\" ) ) ===\n\t\t\tdecodeURIComponent( location.href.replace( rhash, \"\" ) );\n}\n\n$.widget( \"ui.tabs\", {\n\tversion: \"1.10.3\",\n\tdelay: 300,\n\toptions: {\n\t\tactive: null,\n\t\tcollapsible: false,\n\t\tevent: \"click\",\n\t\theightStyle: \"content\",\n\t\thide: null,\n\t\tshow: null,\n\n\t\t// callbacks\n\t\tactivate: null,\n\t\tbeforeActivate: null,\n\t\tbeforeLoad: null,\n\t\tload: null\n\t},\n\n\t_create: function() {\n\t\tvar that = this,\n\t\t\toptions = this.options;\n\n\t\tthis.running = false;\n\n\t\tthis.element\n\t\t\t.addClass( \"ui-tabs ui-widget ui-widget-content ui-corner-all\" )\n\t\t\t.toggleClass( \"ui-tabs-collapsible\", options.collapsible )\n\t\t\t// Prevent users from focusing disabled tabs via click\n\t\t\t.delegate( \".ui-tabs-nav > li\", \"mousedown\" + this.eventNamespace, function( event ) {\n\t\t\t\tif ( $( this ).is( \".ui-state-disabled\" ) ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t})\n\t\t\t// support: IE <9\n\t\t\t// Preventing the default action in mousedown doesn't prevent IE\n\t\t\t// from focusing the element, so if the anchor gets focused, blur.\n\t\t\t// We don't have to worry about focusing the previously focused\n\t\t\t// element since clicking on a non-focusable element should focus\n\t\t\t// the body anyway.\n\t\t\t.delegate( \".ui-tabs-anchor\", \"focus\" + this.eventNamespace, function() {\n\t\t\t\tif ( $( this ).closest( \"li\" ).is( \".ui-state-disabled\" ) ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t}\n\t\t\t});\n\n\t\tthis._processTabs();\n\t\toptions.active = this._initialActive();\n\n\t\t// Take disabling tabs via class attribute from HTML\n\t\t// into account and update option properly.\n\t\tif ( $.isArray( options.disabled ) ) {\n\t\t\toptions.disabled = $.unique( options.disabled.concat(\n\t\t\t\t$.map( this.tabs.filter( \".ui-state-disabled\" ), function( li ) {\n\t\t\t\t\treturn that.tabs.index( li );\n\t\t\t\t})\n\t\t\t) ).sort();\n\t\t}\n\n\t\t// check for length avoids error when initializing empty list\n\t\tif ( this.options.active !== false && this.anchors.length ) {\n\t\t\tthis.active = this._findActive( options.active );\n\t\t} else {\n\t\t\tthis.active = $();\n\t\t}\n\n\t\tthis._refresh();\n\n\t\tif ( this.active.length ) {\n\t\t\tthis.load( options.active );\n\t\t}\n\t},\n\n\t_initialActive: function() {\n\t\tvar active = this.options.active,\n\t\t\tcollapsible = this.options.collapsible,\n\t\t\tlocationHash = location.hash.substring( 1 );\n\n\t\tif ( active === null ) {\n\t\t\t// check the fragment identifier in the URL\n\t\t\tif ( locationHash ) {\n\t\t\t\tthis.tabs.each(function( i, tab ) {\n\t\t\t\t\tif ( $( tab ).attr( \"aria-controls\" ) === locationHash ) {\n\t\t\t\t\t\tactive = i;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// check for a tab marked active via a class\n\t\t\tif ( active === null ) {\n\t\t\t\tactive = this.tabs.index( this.tabs.filter( \".ui-tabs-active\" ) );\n\t\t\t}\n\n\t\t\t// no active tab, set to false\n\t\t\tif ( active === null || active === -1 ) {\n\t\t\t\tactive = this.tabs.length ? 0 : false;\n\t\t\t}\n\t\t}\n\n\t\t// handle numbers: negative, out of range\n\t\tif ( active !== false ) {\n\t\t\tactive = this.tabs.index( this.tabs.eq( active ) );\n\t\t\tif ( active === -1 ) {\n\t\t\t\tactive = collapsible ? false : 0;\n\t\t\t}\n\t\t}\n\n\t\t// don't allow collapsible: false and active: false\n\t\tif ( !collapsible && active === false && this.anchors.length ) {\n\t\t\tactive = 0;\n\t\t}\n\n\t\treturn active;\n\t},\n\n\t_getCreateEventData: function() {\n\t\treturn {\n\t\t\ttab: this.active,\n\t\t\tpanel: !this.active.length ? $() : this._getPanelForTab( this.active )\n\t\t};\n\t},\n\n\t_tabKeydown: function( event ) {\n\t\t/*jshint maxcomplexity:15*/\n\t\tvar focusedTab = $( this.document[0].activeElement ).closest( \"li\" ),\n\t\t\tselectedIndex = this.tabs.index( focusedTab ),\n\t\t\tgoingForward = true;\n\n\t\tif ( this._handlePageNav( event ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tswitch ( event.keyCode ) {\n\t\t\tcase $.ui.keyCode.RIGHT:\n\t\t\tcase $.ui.keyCode.DOWN:\n\t\t\t\tselectedIndex++;\n\t\t\t\tbreak;\n\t\t\tcase $.ui.keyCode.UP:\n\t\t\tcase $.ui.keyCode.LEFT:\n\t\t\t\tgoingForward = false;\n\t\t\t\tselectedIndex--;\n\t\t\t\tbreak;\n\t\t\tcase $.ui.keyCode.END:\n\t\t\t\tselectedIndex = this.anchors.length - 1;\n\t\t\t\tbreak;\n\t\t\tcase $.ui.keyCode.HOME:\n\t\t\t\tselectedIndex = 0;\n\t\t\t\tbreak;\n\t\t\tcase $.ui.keyCode.SPACE:\n\t\t\t\t// Activate only, no collapsing\n\t\t\t\tevent.preventDefault();\n\t\t\t\tclearTimeout( this.activating );\n\t\t\t\tthis._activate( selectedIndex );\n\t\t\t\treturn;\n\t\t\tcase $.ui.keyCode.ENTER:\n\t\t\t\t// Toggle (cancel delayed activation, allow collapsing)\n\t\t\t\tevent.preventDefault();\n\t\t\t\tclearTimeout( this.activating );\n\t\t\t\t// Determine if we should collapse or activate\n\t\t\t\tthis._activate( selectedIndex === this.options.active ? false : selectedIndex );\n\t\t\t\treturn;\n\t\t\tdefault:\n\t\t\t\treturn;\n\t\t}\n\n\t\t// Focus the appropriate tab, based on which key was pressed\n\t\tevent.preventDefault();\n\t\tclearTimeout( this.activating );\n\t\tselectedIndex = this._focusNextTab( selectedIndex, goingForward );\n\n\t\t// Navigating with control key will prevent automatic activation\n\t\tif ( !event.ctrlKey ) {\n\t\t\t// Update aria-selected immediately so that AT think the tab is already selected.\n\t\t\t// Otherwise AT may confuse the user by stating that they need to activate the tab,\n\t\t\t// but the tab will already be activated by the time the announcement finishes.\n\t\t\tfocusedTab.attr( \"aria-selected\", \"false\" );\n\t\t\tthis.tabs.eq( selectedIndex ).attr( \"aria-selected\", \"true\" );\n\n\t\t\tthis.activating = this._delay(function() {\n\t\t\t\tthis.option( \"active\", selectedIndex );\n\t\t\t}, this.delay );\n\t\t}\n\t},\n\n\t_panelKeydown: function( event ) {\n\t\tif ( this._handlePageNav( event ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Ctrl+up moves focus to the current tab\n\t\tif ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {\n\t\t\tevent.preventDefault();\n\t\t\tthis.active.focus();\n\t\t}\n\t},\n\n\t// Alt+page up/down moves focus to the previous/next tab (and activates)\n\t_handlePageNav: function( event ) {\n\t\tif ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {\n\t\t\tthis._activate( this._focusNextTab( this.options.active - 1, false ) );\n\t\t\treturn true;\n\t\t}\n\t\tif ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {\n\t\t\tthis._activate( this._focusNextTab( this.options.active + 1, true ) );\n\t\t\treturn true;\n\t\t}\n\t},\n\n\t_findNextTab: function( index, goingForward ) {\n\t\tvar lastTabIndex = this.tabs.length - 1;\n\n\t\tfunction constrain() {\n\t\t\tif ( index > lastTabIndex ) {\n\t\t\t\tindex = 0;\n\t\t\t}\n\t\t\tif ( index < 0 ) {\n\t\t\t\tindex = lastTabIndex;\n\t\t\t}\n\t\t\treturn index;\n\t\t}\n\n\t\twhile ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {\n\t\t\tindex = goingForward ? index + 1 : index - 1;\n\t\t}\n\n\t\treturn index;\n\t},\n\n\t_focusNextTab: function( index, goingForward ) {\n\t\tindex = this._findNextTab( index, goingForward );\n\t\tthis.tabs.eq( index ).focus();\n\t\treturn index;\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"active\" ) {\n\t\t\t// _activate() will handle invalid values and update this.options\n\t\t\tthis._activate( value );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\t// don't use the widget factory's disabled handling\n\t\t\tthis._setupDisabled( value );\n\t\t\treturn;\n\t\t}\n\n\t\tthis._super( key, value);\n\n\t\tif ( key === \"collapsible\" ) {\n\t\t\tthis.element.toggleClass( \"ui-tabs-collapsible\", value );\n\t\t\t// Setting collapsible: false while collapsed; open first panel\n\t\t\tif ( !value && this.options.active === false ) {\n\t\t\t\tthis._activate( 0 );\n\t\t\t}\n\t\t}\n\n\t\tif ( key === \"event\" ) {\n\t\t\tthis._setupEvents( value );\n\t\t}\n\n\t\tif ( key === \"heightStyle\" ) {\n\t\t\tthis._setupHeightStyle( value );\n\t\t}\n\t},\n\n\t_tabId: function( tab ) {\n\t\treturn tab.attr( \"aria-controls\" ) || \"ui-tabs-\" + getNextTabId();\n\t},\n\n\t_sanitizeSelector: function( hash ) {\n\t\treturn hash ? hash.replace( /[!\"$%&'()*+,.\\/:;<=>?@\\[\\]\\^`{|}~]/g, \"\\\\$&\" ) : \"\";\n\t},\n\n\trefresh: function() {\n\t\tvar options = this.options,\n\t\t\tlis = this.tablist.children( \":has(a[href])\" );\n\n\t\t// get disabled tabs from class attribute from HTML\n\t\t// this will get converted to a boolean if needed in _refresh()\n\t\toptions.disabled = $.map( lis.filter( \".ui-state-disabled\" ), function( tab ) {\n\t\t\treturn lis.index( tab );\n\t\t});\n\n\t\tthis._processTabs();\n\n\t\t// was collapsed or no tabs\n\t\tif ( options.active === false || !this.anchors.length ) {\n\t\t\toptions.active = false;\n\t\t\tthis.active = $();\n\t\t// was active, but active tab is gone\n\t\t} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {\n\t\t\t// all remaining tabs are disabled\n\t\t\tif ( this.tabs.length === options.disabled.length ) {\n\t\t\t\toptions.active = false;\n\t\t\t\tthis.active = $();\n\t\t\t// activate previous tab\n\t\t\t} else {\n\t\t\t\tthis._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );\n\t\t\t}\n\t\t// was active, active tab still exists\n\t\t} else {\n\t\t\t// make sure active index is correct\n\t\t\toptions.active = this.tabs.index( this.active );\n\t\t}\n\n\t\tthis._refresh();\n\t},\n\n\t_refresh: function() {\n\t\tthis._setupDisabled( this.options.disabled );\n\t\tthis._setupEvents( this.options.event );\n\t\tthis._setupHeightStyle( this.options.heightStyle );\n\n\t\tthis.tabs.not( this.active ).attr({\n\t\t\t\"aria-selected\": \"false\",\n\t\t\ttabIndex: -1\n\t\t});\n\t\tthis.panels.not( this._getPanelForTab( this.active ) )\n\t\t\t.hide()\n\t\t\t.attr({\n\t\t\t\t\"aria-expanded\": \"false\",\n\t\t\t\t\"aria-hidden\": \"true\"\n\t\t\t});\n\n\t\t// Make sure one tab is in the tab order\n\t\tif ( !this.active.length ) {\n\t\t\tthis.tabs.eq( 0 ).attr( \"tabIndex\", 0 );\n\t\t} else {\n\t\t\tthis.active\n\t\t\t\t.addClass( \"ui-tabs-active ui-state-active\" )\n\t\t\t\t.attr({\n\t\t\t\t\t\"aria-selected\": \"true\",\n\t\t\t\t\ttabIndex: 0\n\t\t\t\t});\n\t\t\tthis._getPanelForTab( this.active )\n\t\t\t\t.show()\n\t\t\t\t.attr({\n\t\t\t\t\t\"aria-expanded\": \"true\",\n\t\t\t\t\t\"aria-hidden\": \"false\"\n\t\t\t\t});\n\t\t}\n\t},\n\n\t_processTabs: function() {\n\t\tvar that = this;\n\n\t\tthis.tablist = this._getList()\n\t\t\t.addClass( \"ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all\" )\n\t\t\t.attr( \"role\", \"tablist\" );\n\n\t\tthis.tabs = this.tablist.find( \"> li:has(a[href])\" )\n\t\t\t.addClass( \"ui-state-default ui-corner-top\" )\n\t\t\t.attr({\n\t\t\t\trole: \"tab\",\n\t\t\t\ttabIndex: -1\n\t\t\t});\n\n\t\tthis.anchors = this.tabs.map(function() {\n\t\t\t\treturn $( \"a\", this )[ 0 ];\n\t\t\t})\n\t\t\t.addClass( \"ui-tabs-anchor\" )\n\t\t\t.attr({\n\t\t\t\trole: \"presentation\",\n\t\t\t\ttabIndex: -1\n\t\t\t});\n\n\t\tthis.panels = $();\n\n\t\tthis.anchors.each(function( i, anchor ) {\n\t\t\tvar selector, panel, panelId,\n\t\t\t\tanchorId = $( anchor ).uniqueId().attr( \"id\" ),\n\t\t\t\ttab = $( anchor ).closest( \"li\" ),\n\t\t\t\toriginalAriaControls = tab.attr( \"aria-controls\" );\n\n\t\t\t// inline tab\n\t\t\tif ( isLocal( anchor ) ) {\n\t\t\t\tselector = anchor.hash;\n\t\t\t\tpanel = that.element.find( that._sanitizeSelector( selector ) );\n\t\t\t// remote tab\n\t\t\t} else {\n\t\t\t\tpanelId = that._tabId( tab );\n\t\t\t\tselector = \"#\" + panelId;\n\t\t\t\tpanel = that.element.find( selector );\n\t\t\t\tif ( !panel.length ) {\n\t\t\t\t\tpanel = that._createPanel( panelId );\n\t\t\t\t\tpanel.insertAfter( that.panels[ i - 1 ] || that.tablist );\n\t\t\t\t}\n\t\t\t\tpanel.attr( \"aria-live\", \"polite\" );\n\t\t\t}\n\n\t\t\tif ( panel.length) {\n\t\t\t\tthat.panels = that.panels.add( panel );\n\t\t\t}\n\t\t\tif ( originalAriaControls ) {\n\t\t\t\ttab.data( \"ui-tabs-aria-controls\", originalAriaControls );\n\t\t\t}\n\t\t\ttab.attr({\n\t\t\t\t\"aria-controls\": selector.substring( 1 ),\n\t\t\t\t\"aria-labelledby\": anchorId\n\t\t\t});\n\t\t\tpanel.attr( \"aria-labelledby\", anchorId );\n\t\t});\n\n\t\tthis.panels\n\t\t\t.addClass( \"ui-tabs-panel ui-widget-content ui-corner-bottom\" )\n\t\t\t.attr( \"role\", \"tabpanel\" );\n\t},\n\n\t// allow overriding how to find the list for rare usage scenarios (#7715)\n\t_getList: function() {\n\t\treturn this.element.find( \"ol,ul\" ).eq( 0 );\n\t},\n\n\t_createPanel: function( id ) {\n\t\treturn $( \"<div>\" )\n\t\t\t.attr( \"id\", id )\n\t\t\t.addClass( \"ui-tabs-panel ui-widget-content ui-corner-bottom\" )\n\t\t\t.data( \"ui-tabs-destroy\", true );\n\t},\n\n\t_setupDisabled: function( disabled ) {\n\t\tif ( $.isArray( disabled ) ) {\n\t\t\tif ( !disabled.length ) {\n\t\t\t\tdisabled = false;\n\t\t\t} else if ( disabled.length === this.anchors.length ) {\n\t\t\t\tdisabled = true;\n\t\t\t}\n\t\t}\n\n\t\t// disable tabs\n\t\tfor ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {\n\t\t\tif ( disabled === true || $.inArray( i, disabled ) !== -1 ) {\n\t\t\t\t$( li )\n\t\t\t\t\t.addClass( \"ui-state-disabled\" )\n\t\t\t\t\t.attr( \"aria-disabled\", \"true\" );\n\t\t\t} else {\n\t\t\t\t$( li )\n\t\t\t\t\t.removeClass( \"ui-state-disabled\" )\n\t\t\t\t\t.removeAttr( \"aria-disabled\" );\n\t\t\t}\n\t\t}\n\n\t\tthis.options.disabled = disabled;\n\t},\n\n\t_setupEvents: function( event ) {\n\t\tvar events = {\n\t\t\tclick: function( event ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t};\n\t\tif ( event ) {\n\t\t\t$.each( event.split(\" \"), function( index, eventName ) {\n\t\t\t\tevents[ eventName ] = \"_eventHandler\";\n\t\t\t});\n\t\t}\n\n\t\tthis._off( this.anchors.add( this.tabs ).add( this.panels ) );\n\t\tthis._on( this.anchors, events );\n\t\tthis._on( this.tabs, { keydown: \"_tabKeydown\" } );\n\t\tthis._on( this.panels, { keydown: \"_panelKeydown\" } );\n\n\t\tthis._focusable( this.tabs );\n\t\tthis._hoverable( this.tabs );\n\t},\n\n\t_setupHeightStyle: function( heightStyle ) {\n\t\tvar maxHeight,\n\t\t\tparent = this.element.parent();\n\n\t\tif ( heightStyle === \"fill\" ) {\n\t\t\tmaxHeight = parent.height();\n\t\t\tmaxHeight -= this.element.outerHeight() - this.element.height();\n\n\t\t\tthis.element.siblings( \":visible\" ).each(function() {\n\t\t\t\tvar elem = $( this ),\n\t\t\t\t\tposition = elem.css( \"position\" );\n\n\t\t\t\tif ( position === \"absolute\" || position === \"fixed\" ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tmaxHeight -= elem.outerHeight( true );\n\t\t\t});\n\n\t\t\tthis.element.children().not( this.panels ).each(function() {\n\t\t\t\tmaxHeight -= $( this ).outerHeight( true );\n\t\t\t});\n\n\t\t\tthis.panels.each(function() {\n\t\t\t\t$( this ).height( Math.max( 0, maxHeight -\n\t\t\t\t\t$( this ).innerHeight() + $( this ).height() ) );\n\t\t\t})\n\t\t\t.css( \"overflow\", \"auto\" );\n\t\t} else if ( heightStyle === \"auto\" ) {\n\t\t\tmaxHeight = 0;\n\t\t\tthis.panels.each(function() {\n\t\t\t\tmaxHeight = Math.max( maxHeight, $( this ).height( \"\" ).height() );\n\t\t\t}).height( maxHeight );\n\t\t}\n\t},\n\n\t_eventHandler: function( event ) {\n\t\tvar options = this.options,\n\t\t\tactive = this.active,\n\t\t\tanchor = $( event.currentTarget ),\n\t\t\ttab = anchor.closest( \"li\" ),\n\t\t\tclickedIsActive = tab[ 0 ] === active[ 0 ],\n\t\t\tcollapsing = clickedIsActive && options.collapsible,\n\t\t\ttoShow = collapsing ? $() : this._getPanelForTab( tab ),\n\t\t\ttoHide = !active.length ? $() : this._getPanelForTab( active ),\n\t\t\teventData = {\n\t\t\t\toldTab: active,\n\t\t\t\toldPanel: toHide,\n\t\t\t\tnewTab: collapsing ? $() : tab,\n\t\t\t\tnewPanel: toShow\n\t\t\t};\n\n\t\tevent.preventDefault();\n\n\t\tif ( tab.hasClass( \"ui-state-disabled\" ) ||\n\t\t\t\t// tab is already loading\n\t\t\t\ttab.hasClass( \"ui-tabs-loading\" ) ||\n\t\t\t\t// can't switch durning an animation\n\t\t\t\tthis.running ||\n\t\t\t\t// click on active header, but not collapsible\n\t\t\t\t( clickedIsActive && !options.collapsible ) ||\n\t\t\t\t// allow canceling activation\n\t\t\t\t( this._trigger( \"beforeActivate\", event, eventData ) === false ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\toptions.active = collapsing ? false : this.tabs.index( tab );\n\n\t\tthis.active = clickedIsActive ? $() : tab;\n\t\tif ( this.xhr ) {\n\t\t\tthis.xhr.abort();\n\t\t}\n\n\t\tif ( !toHide.length && !toShow.length ) {\n\t\t\t$.error( \"jQuery UI Tabs: Mismatching fragment identifier.\" );\n\t\t}\n\n\t\tif ( toShow.length ) {\n\t\t\tthis.load( this.tabs.index( tab ), event );\n\t\t}\n\t\tthis._toggle( event, eventData );\n\t},\n\n\t// handles show/hide for selecting tabs\n\t_toggle: function( event, eventData ) {\n\t\tvar that = this,\n\t\t\ttoShow = eventData.newPanel,\n\t\t\ttoHide = eventData.oldPanel;\n\n\t\tthis.running = true;\n\n\t\tfunction complete() {\n\t\t\tthat.running = false;\n\t\t\tthat._trigger( \"activate\", event, eventData );\n\t\t}\n\n\t\tfunction show() {\n\t\t\teventData.newTab.closest( \"li\" ).addClass( \"ui-tabs-active ui-state-active\" );\n\n\t\t\tif ( toShow.length && that.options.show ) {\n\t\t\t\tthat._show( toShow, that.options.show, complete );\n\t\t\t} else {\n\t\t\t\ttoShow.show();\n\t\t\t\tcomplete();\n\t\t\t}\n\t\t}\n\n\t\t// start out by hiding, then showing, then completing\n\t\tif ( toHide.length && this.options.hide ) {\n\t\t\tthis._hide( toHide, this.options.hide, function() {\n\t\t\t\teventData.oldTab.closest( \"li\" ).removeClass( \"ui-tabs-active ui-state-active\" );\n\t\t\t\tshow();\n\t\t\t});\n\t\t} else {\n\t\t\teventData.oldTab.closest( \"li\" ).removeClass( \"ui-tabs-active ui-state-active\" );\n\t\t\ttoHide.hide();\n\t\t\tshow();\n\t\t}\n\n\t\ttoHide.attr({\n\t\t\t\"aria-expanded\": \"false\",\n\t\t\t\"aria-hidden\": \"true\"\n\t\t});\n\t\teventData.oldTab.attr( \"aria-selected\", \"false\" );\n\t\t// If we're switching tabs, remove the old tab from the tab order.\n\t\t// If we're opening from collapsed state, remove the previous tab from the tab order.\n\t\t// If we're collapsing, then keep the collapsing tab in the tab order.\n\t\tif ( toShow.length && toHide.length ) {\n\t\t\teventData.oldTab.attr( \"tabIndex\", -1 );\n\t\t} else if ( toShow.length ) {\n\t\t\tthis.tabs.filter(function() {\n\t\t\t\treturn $( this ).attr( \"tabIndex\" ) === 0;\n\t\t\t})\n\t\t\t.attr( \"tabIndex\", -1 );\n\t\t}\n\n\t\ttoShow.attr({\n\t\t\t\"aria-expanded\": \"true\",\n\t\t\t\"aria-hidden\": \"false\"\n\t\t});\n\t\teventData.newTab.attr({\n\t\t\t\"aria-selected\": \"true\",\n\t\t\ttabIndex: 0\n\t\t});\n\t},\n\n\t_activate: function( index ) {\n\t\tvar anchor,\n\t\t\tactive = this._findActive( index );\n\n\t\t// trying to activate the already active panel\n\t\tif ( active[ 0 ] === this.active[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// trying to collapse, simulate a click on the current active header\n\t\tif ( !active.length ) {\n\t\t\tactive = this.active;\n\t\t}\n\n\t\tanchor = active.find( \".ui-tabs-anchor\" )[ 0 ];\n\t\tthis._eventHandler({\n\t\t\ttarget: anchor,\n\t\t\tcurrentTarget: anchor,\n\t\t\tpreventDefault: $.noop\n\t\t});\n\t},\n\n\t_findActive: function( index ) {\n\t\treturn index === false ? $() : this.tabs.eq( index );\n\t},\n\n\t_getIndex: function( index ) {\n\t\t// meta-function to give users option to provide a href string instead of a numerical index.\n\t\tif ( typeof index === \"string\" ) {\n\t\t\tindex = this.anchors.index( this.anchors.filter( \"[href$='\" + index + \"']\" ) );\n\t\t}\n\n\t\treturn index;\n\t},\n\n\t_destroy: function() {\n\t\tif ( this.xhr ) {\n\t\t\tthis.xhr.abort();\n\t\t}\n\n\t\tthis.element.removeClass( \"ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible\" );\n\n\t\tthis.tablist\n\t\t\t.removeClass( \"ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all\" )\n\t\t\t.removeAttr( \"role\" );\n\n\t\tthis.anchors\n\t\t\t.removeClass( \"ui-tabs-anchor\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"tabIndex\" )\n\t\t\t.removeUniqueId();\n\n\t\tthis.tabs.add( this.panels ).each(function() {\n\t\t\tif ( $.data( this, \"ui-tabs-destroy\" ) ) {\n\t\t\t\t$( this ).remove();\n\t\t\t} else {\n\t\t\t\t$( this )\n\t\t\t\t\t.removeClass( \"ui-state-default ui-state-active ui-state-disabled \" +\n\t\t\t\t\t\t\"ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel\" )\n\t\t\t\t\t.removeAttr( \"tabIndex\" )\n\t\t\t\t\t.removeAttr( \"aria-live\" )\n\t\t\t\t\t.removeAttr( \"aria-busy\" )\n\t\t\t\t\t.removeAttr( \"aria-selected\" )\n\t\t\t\t\t.removeAttr( \"aria-labelledby\" )\n\t\t\t\t\t.removeAttr( \"aria-hidden\" )\n\t\t\t\t\t.removeAttr( \"aria-expanded\" )\n\t\t\t\t\t.removeAttr( \"role\" );\n\t\t\t}\n\t\t});\n\n\t\tthis.tabs.each(function() {\n\t\t\tvar li = $( this ),\n\t\t\t\tprev = li.data( \"ui-tabs-aria-controls\" );\n\t\t\tif ( prev ) {\n\t\t\t\tli\n\t\t\t\t\t.attr( \"aria-controls\", prev )\n\t\t\t\t\t.removeData( \"ui-tabs-aria-controls\" );\n\t\t\t} else {\n\t\t\t\tli.removeAttr( \"aria-controls\" );\n\t\t\t}\n\t\t});\n\n\t\tthis.panels.show();\n\n\t\tif ( this.options.heightStyle !== \"content\" ) {\n\t\t\tthis.panels.css( \"height\", \"\" );\n\t\t}\n\t},\n\n\tenable: function( index ) {\n\t\tvar disabled = this.options.disabled;\n\t\tif ( disabled === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( index === undefined ) {\n\t\t\tdisabled = false;\n\t\t} else {\n\t\t\tindex = this._getIndex( index );\n\t\t\tif ( $.isArray( disabled ) ) {\n\t\t\t\tdisabled = $.map( disabled, function( num ) {\n\t\t\t\t\treturn num !== index ? num : null;\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tdisabled = $.map( this.tabs, function( li, num ) {\n\t\t\t\t\treturn num !== index ? num : null;\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tthis._setupDisabled( disabled );\n\t},\n\n\tdisable: function( index ) {\n\t\tvar disabled = this.options.disabled;\n\t\tif ( disabled === true ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( index === undefined ) {\n\t\t\tdisabled = true;\n\t\t} else {\n\t\t\tindex = this._getIndex( index );\n\t\t\tif ( $.inArray( index, disabled ) !== -1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif ( $.isArray( disabled ) ) {\n\t\t\t\tdisabled = $.merge( [ index ], disabled ).sort();\n\t\t\t} else {\n\t\t\t\tdisabled = [ index ];\n\t\t\t}\n\t\t}\n\t\tthis._setupDisabled( disabled );\n\t},\n\n\tload: function( index, event ) {\n\t\tindex = this._getIndex( index );\n\t\tvar that = this,\n\t\t\ttab = this.tabs.eq( index ),\n\t\t\tanchor = tab.find( \".ui-tabs-anchor\" ),\n\t\t\tpanel = this._getPanelForTab( tab ),\n\t\t\teventData = {\n\t\t\t\ttab: tab,\n\t\t\t\tpanel: panel\n\t\t\t};\n\n\t\t// not remote\n\t\tif ( isLocal( anchor[ 0 ] ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );\n\n\t\t// support: jQuery <1.8\n\t\t// jQuery <1.8 returns false if the request is canceled in beforeSend,\n\t\t// but as of 1.8, $.ajax() always returns a jqXHR object.\n\t\tif ( this.xhr && this.xhr.statusText !== \"canceled\" ) {\n\t\t\ttab.addClass( \"ui-tabs-loading\" );\n\t\t\tpanel.attr( \"aria-busy\", \"true\" );\n\n\t\t\tthis.xhr\n\t\t\t\t.success(function( response ) {\n\t\t\t\t\t// support: jQuery <1.8\n\t\t\t\t\t// http://bugs.jquery.com/ticket/11778\n\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\tpanel.html( response );\n\t\t\t\t\t\tthat._trigger( \"load\", event, eventData );\n\t\t\t\t\t}, 1 );\n\t\t\t\t})\n\t\t\t\t.complete(function( jqXHR, status ) {\n\t\t\t\t\t// support: jQuery <1.8\n\t\t\t\t\t// http://bugs.jquery.com/ticket/11778\n\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\tif ( status === \"abort\" ) {\n\t\t\t\t\t\t\tthat.panels.stop( false, true );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttab.removeClass( \"ui-tabs-loading\" );\n\t\t\t\t\t\tpanel.removeAttr( \"aria-busy\" );\n\n\t\t\t\t\t\tif ( jqXHR === that.xhr ) {\n\t\t\t\t\t\t\tdelete that.xhr;\n\t\t\t\t\t\t}\n\t\t\t\t\t}, 1 );\n\t\t\t\t});\n\t\t}\n\t},\n\n\t_ajaxSettings: function( anchor, event, eventData ) {\n\t\tvar that = this;\n\t\treturn {\n\t\t\turl: anchor.attr( \"href\" ),\n\t\t\tbeforeSend: function( jqXHR, settings ) {\n\t\t\t\treturn that._trigger( \"beforeLoad\", event,\n\t\t\t\t\t$.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );\n\t\t\t}\n\t\t};\n\t},\n\n\t_getPanelForTab: function( tab ) {\n\t\tvar id = $( tab ).attr( \"aria-controls\" );\n\t\treturn this.element.find( this._sanitizeSelector( \"#\" + id ) );\n\t}\n});\n\n})( jQuery );\n\n(function( $ ) {\n\nvar increments = 0;\n\nfunction addDescribedBy( elem, id ) {\n\tvar describedby = (elem.attr( \"aria-describedby\" ) || \"\").split( /\\s+/ );\n\tdescribedby.push( id );\n\telem\n\t\t.data( \"ui-tooltip-id\", id )\n\t\t.attr( \"aria-describedby\", $.trim( describedby.join( \" \" ) ) );\n}\n\nfunction removeDescribedBy( elem ) {\n\tvar id = elem.data( \"ui-tooltip-id\" ),\n\t\tdescribedby = (elem.attr( \"aria-describedby\" ) || \"\").split( /\\s+/ ),\n\t\tindex = $.inArray( id, describedby );\n\tif ( index !== -1 ) {\n\t\tdescribedby.splice( index, 1 );\n\t}\n\n\telem.removeData( \"ui-tooltip-id\" );\n\tdescribedby = $.trim( describedby.join( \" \" ) );\n\tif ( describedby ) {\n\t\telem.attr( \"aria-describedby\", describedby );\n\t} else {\n\t\telem.removeAttr( \"aria-describedby\" );\n\t}\n}\n\n$.widget( \"ui.tooltip\", {\n\tversion: \"1.10.3\",\n\toptions: {\n\t\tcontent: function() {\n\t\t\t// support: IE<9, Opera in jQuery <1.7\n\t\t\t// .text() can't accept undefined, so coerce to a string\n\t\t\tvar title = $( this ).attr( \"title\" ) || \"\";\n\t\t\t// Escape title, since we're going from an attribute to raw HTML\n\t\t\treturn $( \"<a>\" ).text( title ).html();\n\t\t},\n\t\thide: true,\n\t\t// Disabled elements have inconsistent behavior across browsers (#8661)\n\t\titems: \"[title]:not([disabled])\",\n\t\tposition: {\n\t\t\tmy: \"left top+15\",\n\t\t\tat: \"left bottom\",\n\t\t\tcollision: \"flipfit flip\"\n\t\t},\n\t\tshow: true,\n\t\ttooltipClass: null,\n\t\ttrack: false,\n\n\t\t// callbacks\n\t\tclose: null,\n\t\topen: null\n\t},\n\n\t_create: function() {\n\t\tthis._on({\n\t\t\tmouseover: \"open\",\n\t\t\tfocusin: \"open\"\n\t\t});\n\n\t\t// IDs of generated tooltips, needed for destroy\n\t\tthis.tooltips = {};\n\t\t// IDs of parent tooltips where we removed the title attribute\n\t\tthis.parents = {};\n\n\t\tif ( this.options.disabled ) {\n\t\t\tthis._disable();\n\t\t}\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tvar that = this;\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis[ value ? \"_disable\" : \"_enable\" ]();\n\t\t\tthis.options[ key ] = value;\n\t\t\t// disable element style changes\n\t\t\treturn;\n\t\t}\n\n\t\tthis._super( key, value );\n\n\t\tif ( key === \"content\" ) {\n\t\t\t$.each( this.tooltips, function( id, element ) {\n\t\t\t\tthat._updateContent( element );\n\t\t\t});\n\t\t}\n\t},\n\n\t_disable: function() {\n\t\tvar that = this;\n\n\t\t// close open tooltips\n\t\t$.each( this.tooltips, function( id, element ) {\n\t\t\tvar event = $.Event( \"blur\" );\n\t\t\tevent.target = event.currentTarget = element[0];\n\t\t\tthat.close( event, true );\n\t\t});\n\n\t\t// remove title attributes to prevent native tooltips\n\t\tthis.element.find( this.options.items ).addBack().each(function() {\n\t\t\tvar element = $( this );\n\t\t\tif ( element.is( \"[title]\" ) ) {\n\t\t\t\telement\n\t\t\t\t\t.data( \"ui-tooltip-title\", element.attr( \"title\" ) )\n\t\t\t\t\t.attr( \"title\", \"\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_enable: function() {\n\t\t// restore title attributes\n\t\tthis.element.find( this.options.items ).addBack().each(function() {\n\t\t\tvar element = $( this );\n\t\t\tif ( element.data( \"ui-tooltip-title\" ) ) {\n\t\t\t\telement.attr( \"title\", element.data( \"ui-tooltip-title\" ) );\n\t\t\t}\n\t\t});\n\t},\n\n\topen: function( event ) {\n\t\tvar that = this,\n\t\t\ttarget = $( event ? event.target : this.element )\n\t\t\t\t// we need closest here due to mouseover bubbling,\n\t\t\t\t// but always pointing at the same event target\n\t\t\t\t.closest( this.options.items );\n\n\t\t// No element to show a tooltip for or the tooltip is already open\n\t\tif ( !target.length || target.data( \"ui-tooltip-id\" ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( target.attr( \"title\" ) ) {\n\t\t\ttarget.data( \"ui-tooltip-title\", target.attr( \"title\" ) );\n\t\t}\n\n\t\ttarget.data( \"ui-tooltip-open\", true );\n\n\t\t// kill parent tooltips, custom or native, for hover\n\t\tif ( event && event.type === \"mouseover\" ) {\n\t\t\ttarget.parents().each(function() {\n\t\t\t\tvar parent = $( this ),\n\t\t\t\t\tblurEvent;\n\t\t\t\tif ( parent.data( \"ui-tooltip-open\" ) ) {\n\t\t\t\t\tblurEvent = $.Event( \"blur\" );\n\t\t\t\t\tblurEvent.target = blurEvent.currentTarget = this;\n\t\t\t\t\tthat.close( blurEvent, true );\n\t\t\t\t}\n\t\t\t\tif ( parent.attr( \"title\" ) ) {\n\t\t\t\t\tparent.uniqueId();\n\t\t\t\t\tthat.parents[ this.id ] = {\n\t\t\t\t\t\telement: this,\n\t\t\t\t\t\ttitle: parent.attr( \"title\" )\n\t\t\t\t\t};\n\t\t\t\t\tparent.attr( \"title\", \"\" );\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tthis._updateContent( target, event );\n\t},\n\n\t_updateContent: function( target, event ) {\n\t\tvar content,\n\t\t\tcontentOption = this.options.content,\n\t\t\tthat = this,\n\t\t\teventType = event ? event.type : null;\n\n\t\tif ( typeof contentOption === \"string\" ) {\n\t\t\treturn this._open( event, target, contentOption );\n\t\t}\n\n\t\tcontent = contentOption.call( target[0], function( response ) {\n\t\t\t// ignore async response if tooltip was closed already\n\t\t\tif ( !target.data( \"ui-tooltip-open\" ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// IE may instantly serve a cached response for ajax requests\n\t\t\t// delay this call to _open so the other call to _open runs first\n\t\t\tthat._delay(function() {\n\t\t\t\t// jQuery creates a special event for focusin when it doesn't\n\t\t\t\t// exist natively. To improve performance, the native event\n\t\t\t\t// object is reused and the type is changed. Therefore, we can't\n\t\t\t\t// rely on the type being correct after the event finished\n\t\t\t\t// bubbling, so we set it back to the previous value. (#8740)\n\t\t\t\tif ( event ) {\n\t\t\t\t\tevent.type = eventType;\n\t\t\t\t}\n\t\t\t\tthis._open( event, target, response );\n\t\t\t});\n\t\t});\n\t\tif ( content ) {\n\t\t\tthis._open( event, target, content );\n\t\t}\n\t},\n\n\t_open: function( event, target, content ) {\n\t\tvar tooltip, events, delayedShow,\n\t\t\tpositionOption = $.extend( {}, this.options.position );\n\n\t\tif ( !content ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Content can be updated multiple times. If the tooltip already\n\t\t// exists, then just update the content and bail.\n\t\ttooltip = this._find( target );\n\t\tif ( tooltip.length ) {\n\t\t\ttooltip.find( \".ui-tooltip-content\" ).html( content );\n\t\t\treturn;\n\t\t}\n\n\t\t// if we have a title, clear it to prevent the native tooltip\n\t\t// we have to check first to avoid defining a title if none exists\n\t\t// (we don't want to cause an element to start matching [title])\n\t\t//\n\t\t// We use removeAttr only for key events, to allow IE to export the correct\n\t\t// accessible attributes. For mouse events, set to empty string to avoid\n\t\t// native tooltip showing up (happens only when removing inside mouseover).\n\t\tif ( target.is( \"[title]\" ) ) {\n\t\t\tif ( event && event.type === \"mouseover\" ) {\n\t\t\t\ttarget.attr( \"title\", \"\" );\n\t\t\t} else {\n\t\t\t\ttarget.removeAttr( \"title\" );\n\t\t\t}\n\t\t}\n\n\t\ttooltip = this._tooltip( target );\n\t\taddDescribedBy( target, tooltip.attr( \"id\" ) );\n\t\ttooltip.find( \".ui-tooltip-content\" ).html( content );\n\n\t\tfunction position( event ) {\n\t\t\tpositionOption.of = event;\n\t\t\tif ( tooltip.is( \":hidden\" ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttooltip.position( positionOption );\n\t\t}\n\t\tif ( this.options.track && event && /^mouse/.test( event.type ) ) {\n\t\t\tthis._on( this.document, {\n\t\t\t\tmousemove: position\n\t\t\t});\n\t\t\t// trigger once to override element-relative positioning\n\t\t\tposition( event );\n\t\t} else {\n\t\t\ttooltip.position( $.extend({\n\t\t\t\tof: target\n\t\t\t}, this.options.position ) );\n\t\t}\n\n\t\ttooltip.hide();\n\n\t\tthis._show( tooltip, this.options.show );\n\t\t// Handle tracking tooltips that are shown with a delay (#8644). As soon\n\t\t// as the tooltip is visible, position the tooltip using the most recent\n\t\t// event.\n\t\tif ( this.options.show && this.options.show.delay ) {\n\t\t\tdelayedShow = this.delayedShow = setInterval(function() {\n\t\t\t\tif ( tooltip.is( \":visible\" ) ) {\n\t\t\t\t\tposition( positionOption.of );\n\t\t\t\t\tclearInterval( delayedShow );\n\t\t\t\t}\n\t\t\t}, $.fx.interval );\n\t\t}\n\n\t\tthis._trigger( \"open\", event, { tooltip: tooltip } );\n\n\t\tevents = {\n\t\t\tkeyup: function( event ) {\n\t\t\t\tif ( event.keyCode === $.ui.keyCode.ESCAPE ) {\n\t\t\t\t\tvar fakeEvent = $.Event(event);\n\t\t\t\t\tfakeEvent.currentTarget = target[0];\n\t\t\t\t\tthis.close( fakeEvent, true );\n\t\t\t\t}\n\t\t\t},\n\t\t\tremove: function() {\n\t\t\t\tthis._removeTooltip( tooltip );\n\t\t\t}\n\t\t};\n\t\tif ( !event || event.type === \"mouseover\" ) {\n\t\t\tevents.mouseleave = \"close\";\n\t\t}\n\t\tif ( !event || event.type === \"focusin\" ) {\n\t\t\tevents.focusout = \"close\";\n\t\t}\n\t\tthis._on( true, target, events );\n\t},\n\n\tclose: function( event ) {\n\t\tvar that = this,\n\t\t\ttarget = $( event ? event.currentTarget : this.element ),\n\t\t\ttooltip = this._find( target );\n\n\t\t// disabling closes the tooltip, so we need to track when we're closing\n\t\t// to avoid an infinite loop in case the tooltip becomes disabled on close\n\t\tif ( this.closing ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Clear the interval for delayed tracking tooltips\n\t\tclearInterval( this.delayedShow );\n\n\t\t// only set title if we had one before (see comment in _open())\n\t\tif ( target.data( \"ui-tooltip-title\" ) ) {\n\t\t\ttarget.attr( \"title\", target.data( \"ui-tooltip-title\" ) );\n\t\t}\n\n\t\tremoveDescribedBy( target );\n\n\t\ttooltip.stop( true );\n\t\tthis._hide( tooltip, this.options.hide, function() {\n\t\t\tthat._removeTooltip( $( this ) );\n\t\t});\n\n\t\ttarget.removeData( \"ui-tooltip-open\" );\n\t\tthis._off( target, \"mouseleave focusout keyup\" );\n\t\t// Remove 'remove' binding only on delegated targets\n\t\tif ( target[0] !== this.element[0] ) {\n\t\t\tthis._off( target, \"remove\" );\n\t\t}\n\t\tthis._off( this.document, \"mousemove\" );\n\n\t\tif ( event && event.type === \"mouseleave\" ) {\n\t\t\t$.each( this.parents, function( id, parent ) {\n\t\t\t\t$( parent.element ).attr( \"title\", parent.title );\n\t\t\t\tdelete that.parents[ id ];\n\t\t\t});\n\t\t}\n\n\t\tthis.closing = true;\n\t\tthis._trigger( \"close\", event, { tooltip: tooltip } );\n\t\tthis.closing = false;\n\t},\n\n\t_tooltip: function( element ) {\n\t\tvar id = \"ui-tooltip-\" + increments++,\n\t\t\ttooltip = $( \"<div>\" )\n\t\t\t\t.attr({\n\t\t\t\t\tid: id,\n\t\t\t\t\trole: \"tooltip\"\n\t\t\t\t})\n\t\t\t\t.addClass( \"ui-tooltip ui-widget ui-corner-all ui-widget-content \" +\n\t\t\t\t\t( this.options.tooltipClass || \"\" ) );\n\t\t$( \"<div>\" )\n\t\t\t.addClass( \"ui-tooltip-content\" )\n\t\t\t.appendTo( tooltip );\n\t\ttooltip.appendTo( this.document[0].body );\n\t\tthis.tooltips[ id ] = element;\n\t\treturn tooltip;\n\t},\n\n\t_find: function( target ) {\n\t\tvar id = target.data( \"ui-tooltip-id\" );\n\t\treturn id ? $( \"#\" + id ) : $();\n\t},\n\n\t_removeTooltip: function( tooltip ) {\n\t\ttooltip.remove();\n\t\tdelete this.tooltips[ tooltip.attr( \"id\" ) ];\n\t},\n\n\t_destroy: function() {\n\t\tvar that = this;\n\n\t\t// close open tooltips\n\t\t$.each( this.tooltips, function( id, element ) {\n\t\t\t// Delegate to close method to handle common cleanup\n\t\t\tvar event = $.Event( \"blur\" );\n\t\t\tevent.target = event.currentTarget = element[0];\n\t\t\tthat.close( event, true );\n\n\t\t\t// Remove immediately; destroying an open tooltip doesn't use the\n\t\t\t// hide animation\n\t\t\t$( \"#\" + id ).remove();\n\n\t\t\t// Restore the title\n\t\t\tif ( element.data( \"ui-tooltip-title\" ) ) {\n\t\t\t\telement.attr( \"title\", element.data( \"ui-tooltip-title\" ) );\n\t\t\t\telement.removeData( \"ui-tooltip-title\" );\n\t\t\t}\n\t\t});\n\t}\n});\n\n}( jQuery ) );\n"
  },
  {
    "path": "static/template/js/uncompressed/bootstrap-wysihtml5.js",
    "content": "!function($, wysi) {\n    \"use strict\";\n\n    var tpl = {\n        \"font-styles\": function(locale, options) {\n            var size = (options && options.size) ? ' btn-'+options.size : '';\n            return \"<li class='dropdown'>\" +\n              \"<a class='btn btn-default dropdown-toggle\" + size + \"' data-toggle='dropdown' href='#'>\" +\n              \"<i class='fa fa-font'></i>&nbsp;<span class='current-font'>\" + locale.font_styles.normal + \"</span>&nbsp;<b class='caret'></b>\" +\n              \"</a>\" +\n              \"<ul class='dropdown-menu'>\" +\n                \"<li><a data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='div' tabindex='-1'>\" + locale.font_styles.normal + \"</a></li>\" +\n                \"<li><a data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='h1' tabindex='-1'>\" + locale.font_styles.h1 + \"</a></li>\" +\n                \"<li><a data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='h2' tabindex='-1'>\" + locale.font_styles.h2 + \"</a></li>\" +\n                \"<li><a data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='h3' tabindex='-1'>\" + locale.font_styles.h3 + \"</a></li>\" +\n                \"<li><a data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='h4'>\" + locale.font_styles.h4 + \"</a></li>\" +\n                \"<li><a data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='h5'>\" + locale.font_styles.h5 + \"</a></li>\" +\n                \"<li><a data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='h6'>\" + locale.font_styles.h6 + \"</a></li>\" +\n              \"</ul>\" +\n            \"</li>\";\n        },\n\n        \"emphasis\": function(locale, options) {\n            var size = (options && options.size) ? ' btn-'+options.size : '';\n            return \"<li>\" +\n              \"<div class='btn-group'>\" +\n                \"<a class='btn btn-default\" + size + \"' data-wysihtml5-command='bold' title='CTRL+B' tabindex='-1'>\" + locale.emphasis.bold + \"<i class='fa fa-bold'></i></a>\" +\n                \"<a class='btn btn-default\" + size + \"' data-wysihtml5-command='italic' title='CTRL+I' tabindex='-1'>\" + locale.emphasis.italic + \"<i class='fa fa-italic'></i></a>\" +\n                \"<a class='btn btn-default\" + size + \"' data-wysihtml5-command='underline' title='CTRL+U' tabindex='-1'>\" + locale.emphasis.underline + \"<i class='fa fa-underline'></i></a>\" +\n              \"</div>\" +\n            \"</li>\";\n        },\n\n        \"lists\": function(locale, options) {\n            var size = (options && options.size) ? ' btn-'+options.size : '';\n            return \"<li>\" +\n              \"<div class='btn-group'>\" +\n                \"<a class='btn btn-default\" + size + \"' data-wysihtml5-command='insertUnorderedList' title='\" + locale.lists.unordered + \"' tabindex='-1'><i class='fa fa-list'></i></a>\" +\n                \"<a class='btn btn-default\" + size + \"' data-wysihtml5-command='insertOrderedList' title='\" + locale.lists.ordered + \"' tabindex='-1'><i class='fa fa-th-list'></i></a>\" +\n                \"<a class='btn btn-default\" + size + \"' data-wysihtml5-command='Outdent' title='\" + locale.lists.outdent + \"' tabindex='-1'><i class='fa fa-indent'></i></a>\" +\n                \"<a class='btn btn-default\" + size + \"' data-wysihtml5-command='Indent' title='\" + locale.lists.indent + \"' tabindex='-1'><i class='fa fa-outdent'></i></a>\" +\n              \"</div>\" +\n            \"</li>\";\n        },\n\n        \"link\": function(locale, options) {\n            var size = (options && options.size) ? ' btn-'+options.size : '';\n            return \"<li>\" +\n              \"<div class='bootstrap-wysihtml5-insert-link-modal modal fade'>\" +\n\t\t\t\t\"<div class='modal-dialog'>\" +\n\t\t\t\t\t\"<div class='modal-content'>\" +\n\t\t\t\t\t\t\"<div class='modal-header'>\" +\n\t\t\t\t\t\t  \"<a class='close' data-dismiss='modal'>&times;</a>\" +\n\t\t\t\t\t\t  \"<h3>\" + locale.link.insert + \"</h3>\" +\n\t\t\t\t\t\t\"</div>\" +\n\t\t\t\t\t\t\"<div class='modal-body'>\" +\n\t\t\t\t\t\t  \"<input class='form-control bootstrap-wysihtml5-insert-link-url input-xlarge' value='http://'>\" +\n\t\t\t\t\t\t  \"<label class='label-checkbox'>\" +\n\t\t\t\t\t\t\t\t\"<input type='checkbox' class='bootstrap-wysihtml5-insert-link-target' checked>\" +\n\t\t\t\t\t\t\t\t\"<span class='custom-checkbox'></span>\" +\n\t\t\t\t\t\t\t\tlocale.link.target +\n\t\t\t\t\t\t  \"</label>\" + \n\t\t\t\t\t\t\"</div>\" +\n\t\t\t\t\t\t\"<div class='modal-footer'>\" +\n\t\t\t\t\t\t  \"<a href='#' class='btn btn-default' data-dismiss='modal'>\" + locale.link.cancel + \"</a>\" +\n\t\t\t\t\t\t  \"<a href='#' class='btn btn-primary' data-dismiss='modal'>\" + locale.link.insert + \"</a>\" +\n\t\t\t\t\t\t\"</div>\" +\n\t\t\t\t\t\"</div>\" +\n\t\t\t\t\"</div>\" +\n              \"</div>\" +\n              \"<a class='btn btn-default\" + size + \"' data-wysihtml5-command='createLink' title='\" + locale.link.insert + \"' tabindex='-1'><i class='fa fa-share'></i></a>\" +\n            \"</li>\";\n        },\n\n        \"image\": function(locale, options) {\n            var size = (options && options.size) ? ' btn-'+options.size : '';\n            return \"<li>\" +\n              \"<div class='bootstrap-wysihtml5-insert-image-modal modal fade'>\" +\n\t\t\t\t\"<div class='modal-dialog'>\" +\n\t\t\t\t\t\"<div class='modal-content'>\" +\n\t\t\t\t\t\t\"<div class='modal-header'>\" +\n\t\t\t\t\t\t  \"<a class='close' data-dismiss='modal'>&times;</a>\" +\n\t\t\t\t\t\t  \"<h3>\" + locale.image.insert + \"</h3>\" +\n\t\t\t\t\t\t\"</div>\" +\n\t\t\t\t\t\t\"<div class='modal-body'>\" +\n\t\t\t\t\t\t  \"<input class='form-control bootstrap-wysihtml5-insert-image-url input-xlarge' value='http://'>\" +\n\t\t\t\t\t\t\"</div>\" +\n\t\t\t\t\t\t\"<div class='modal-footer'>\" +\n\t\t\t\t\t\t  \"<a href='#' class='btn btn-default' data-dismiss='modal'>\" + locale.image.cancel + \"</a>\" +\n\t\t\t\t\t\t  \"<a href='#' class='btn btn-primary' data-dismiss='modal'>\" + locale.image.insert + \"</a>\" +\n\t\t\t\t\t\t\"</div>\" +\n\t\t\t\t\t\"</div>\" +\n\t\t\t\t\"</div>\" +\n              \"</div>\" +\n              \"<a class='btn btn-default\" + size + \"' data-wysihtml5-command='insertImage' title='\" + locale.image.insert + \"' tabindex='-1'><i class='fa fa-picture-o'></i></a>\" +\n            \"</li>\";\n        },\n\n        \"html\": function(locale, options) {\n            var size = (options && options.size) ? ' btn-'+options.size : '';\n            return \"<li>\" +\n              \"<div class='btn-group'>\" +\n                \"<a class='btn btn-default\" + size + \"' data-wysihtml5-action='change_view' title='\" + locale.html.edit + \"' tabindex='-1'><i class='fa fa-pencil'></i></a>\" +\n              \"</div>\" +\n            \"</li>\";\n        },\n\n        \"color\": function(locale, options) {\n            var size = (options && options.size) ? ' btn-'+options.size : '';\n            return \"<li class='dropdown'>\" +\n              \"<a class='btn btn-default dropdown-toggle\" + size + \"' data-toggle='dropdown' href='#' tabindex='-1'>\" +\n                \"<span class='current-color'>\" + locale.colours.black + \"</span>&nbsp;<b class='caret'></b>\" +\n              \"</a>\" +\n              \"<ul class='dropdown-menu'>\" +\n                \"<li><div class='wysihtml5-colors' data-wysihtml5-command-value='black'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='black'>\" + locale.colours.black + \"</a></li>\" +\n                \"<li><div class='wysihtml5-colors' data-wysihtml5-command-value='silver'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='silver'>\" + locale.colours.silver + \"</a></li>\" +\n                \"<li><div class='wysihtml5-colors' data-wysihtml5-command-value='gray'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='gray'>\" + locale.colours.gray + \"</a></li>\" +\n                \"<li><div class='wysihtml5-colors' data-wysihtml5-command-value='maroon'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='maroon'>\" + locale.colours.maroon + \"</a></li>\" +\n                \"<li><div class='wysihtml5-colors' data-wysihtml5-command-value='red'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='red'>\" + locale.colours.red + \"</a></li>\" +\n                \"<li><div class='wysihtml5-colors' data-wysihtml5-command-value='purple'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='purple'>\" + locale.colours.purple + \"</a></li>\" +\n                \"<li><div class='wysihtml5-colors' data-wysihtml5-command-value='green'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='green'>\" + locale.colours.green + \"</a></li>\" +\n                \"<li><div class='wysihtml5-colors' data-wysihtml5-command-value='olive'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='olive'>\" + locale.colours.olive + \"</a></li>\" +\n                \"<li><div class='wysihtml5-colors' data-wysihtml5-command-value='navy'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='navy'>\" + locale.colours.navy + \"</a></li>\" +\n                \"<li><div class='wysihtml5-colors' data-wysihtml5-command-value='blue'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='blue'>\" + locale.colours.blue + \"</a></li>\" +\n                \"<li><div class='wysihtml5-colors' data-wysihtml5-command-value='orange'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='orange'>\" + locale.colours.orange + \"</a></li>\" +\n              \"</ul>\" +\n            \"</li>\";\n        }\n    };\n\n    var templates = function(key, locale, options) {\n        return tpl[key](locale, options);\n    };\n\n\n    var Wysihtml5 = function(el, options) {\n        this.el = el;\n        var toolbarOpts = options || defaultOptions;\n        for(var t in toolbarOpts.customTemplates) {\n          tpl[t] = toolbarOpts.customTemplates[t];\n        }\n        this.toolbar = this.createToolbar(el, toolbarOpts);\n        this.editor =  this.createEditor(options);\n\n        window.editor = this.editor;\n\n        $('iframe.wysihtml5-sandbox').each(function(i, el){\n            $(el.contentWindow).off('focus.wysihtml5').on({\n                'focus.wysihtml5' : function(){\n                    $('li.dropdown').removeClass('open');\n                }\n            });\n        });\n    };\n\n    Wysihtml5.prototype = {\n\n        constructor: Wysihtml5,\n\n        createEditor: function(options) {\n            options = options || {};\n            \n            // Add the toolbar to a clone of the options object so multiple instances\n            // of the WYISYWG don't break because \"toolbar\" is already defined\n            options = $.extend(true, {}, options);\n            options.toolbar = this.toolbar[0];\n\n            var editor = new wysi.Editor(this.el[0], options);\n\n            if(options && options.events) {\n                for(var eventName in options.events) {\n                    editor.on(eventName, options.events[eventName]);\n                }\n            }\n            return editor;\n        },\n\n        createToolbar: function(el, options) {\n            var self = this;\n            var toolbar = $(\"<ul/>\", {\n                'class' : \"wysihtml5-toolbar\",\n                'style': \"display:none\"\n            });\n            var culture = options.locale || defaultOptions.locale || \"en\";\n            for(var key in defaultOptions) {\n                var value = false;\n\n                if(options[key] !== undefined) {\n                    if(options[key] === true) {\n                        value = true;\n                    }\n                } else {\n                    value = defaultOptions[key];\n                }\n\n                if(value === true) {\n                    toolbar.append(templates(key, locale[culture], options));\n\n                    if(key === \"html\") {\n                        this.initHtml(toolbar);\n                    }\n\n                    if(key === \"link\") {\n                        this.initInsertLink(toolbar);\n                    }\n\n                    if(key === \"image\") {\n                        this.initInsertImage(toolbar);\n                    }\n                }\n            }\n\n            if(options.toolbar) {\n                for(key in options.toolbar) {\n                    toolbar.append(options.toolbar[key]);\n                }\n            }\n\n            toolbar.find(\"a[data-wysihtml5-command='formatBlock']\").click(function(e) {\n                var target = e.target || e.srcElement;\n                var el = $(target);\n                self.toolbar.find('.current-font').text(el.html());\n            });\n\n            toolbar.find(\"a[data-wysihtml5-command='foreColor']\").click(function(e) {\n                var target = e.target || e.srcElement;\n                var el = $(target);\n                self.toolbar.find('.current-color').text(el.html());\n            });\n\n            this.el.before(toolbar);\n\n            return toolbar;\n        },\n\n        initHtml: function(toolbar) {\n            var changeViewSelector = \"a[data-wysihtml5-action='change_view']\";\n            toolbar.find(changeViewSelector).click(function(e) {\n                toolbar.find('a.btn').not(changeViewSelector).toggleClass('disabled');\n            });\n        },\n\n        initInsertImage: function(toolbar) {\n            var self = this;\n            var insertImageModal = toolbar.find('.bootstrap-wysihtml5-insert-image-modal');\n            var urlInput = insertImageModal.find('.bootstrap-wysihtml5-insert-image-url');\n            var insertButton = insertImageModal.find('a.btn-primary');\n            var initialValue = urlInput.val();\n            var caretBookmark;\n\n            var insertImage = function() {\n                var url = urlInput.val();\n                urlInput.val(initialValue);\n                self.editor.currentView.element.focus();\n                if (caretBookmark) {\n                  self.editor.composer.selection.setBookmark(caretBookmark);\n                  caretBookmark = null;\n                }\n                self.editor.composer.commands.exec(\"insertImage\", url);\n            };\n\n            urlInput.keypress(function(e) {\n                if(e.which == 13) {\n                    insertImage();\n                    insertImageModal.modal('hide');\n                }\n            });\n\n            insertButton.click(insertImage);\n\n            insertImageModal.on('shown', function() {\n                urlInput.focus();\n            });\n\n            insertImageModal.on('hide', function() {\n                self.editor.currentView.element.focus();\n            });\n\n            toolbar.find('a[data-wysihtml5-command=insertImage]').click(function() {\n                var activeButton = $(this).hasClass(\"wysihtml5-command-active\");\n\n                if (!activeButton) {\n                    self.editor.currentView.element.focus(false);\n                    caretBookmark = self.editor.composer.selection.getBookmark();\n                    insertImageModal.appendTo('body').modal('show');\n                    insertImageModal.on('click.dismiss.modal', '[data-dismiss=\"modal\"]', function(e) {\n                        e.stopPropagation();\n                    });\n                    return false;\n                }\n                else {\n                    return true;\n                }\n            });\n        },\n\n        initInsertLink: function(toolbar) {\n            var self = this;\n            var insertLinkModal = toolbar.find('.bootstrap-wysihtml5-insert-link-modal');\n            var urlInput = insertLinkModal.find('.bootstrap-wysihtml5-insert-link-url');\n            var targetInput = insertLinkModal.find('.bootstrap-wysihtml5-insert-link-target');\n            var insertButton = insertLinkModal.find('a.btn-primary');\n            var initialValue = urlInput.val();\n            var caretBookmark;\n\n            var insertLink = function() {\n                var url = urlInput.val();\n                urlInput.val(initialValue);\n                self.editor.currentView.element.focus();\n                if (caretBookmark) {\n                  self.editor.composer.selection.setBookmark(caretBookmark);\n                  caretBookmark = null;\n                }\n\n                var newWindow = targetInput.prop(\"checked\");\n                self.editor.composer.commands.exec(\"createLink\", {\n                    'href' : url,\n                    'target' : (newWindow ? '_blank' : '_self'),\n                    'rel' : (newWindow ? 'nofollow' : '')\n                });\n            };\n            var pressedEnter = false;\n\n            urlInput.keypress(function(e) {\n                if(e.which == 13) {\n                    insertLink();\n                    insertLinkModal.modal('hide');\n                }\n            });\n\n            insertButton.click(insertLink);\n\n            insertLinkModal.on('shown', function() {\n                urlInput.focus();\n            });\n\n            insertLinkModal.on('hide', function() {\n                self.editor.currentView.element.focus();\n            });\n\n            toolbar.find('a[data-wysihtml5-command=createLink]').click(function() {\n                var activeButton = $(this).hasClass(\"wysihtml5-command-active\");\n\n                if (!activeButton) {\n                    self.editor.currentView.element.focus(false);\n                    caretBookmark = self.editor.composer.selection.getBookmark();\n                    insertLinkModal.appendTo('body').modal('show');\n                    insertLinkModal.on('click.dismiss.modal', '[data-dismiss=\"modal\"]', function(e) {\n                        e.stopPropagation();\n                    });\n                    return false;\n                }\n                else {\n                    return true;\n                }\n            });\n        }\n    };\n\n    // these define our public api\n    var methods = {\n        resetDefaults: function() {\n            $.fn.wysihtml5.defaultOptions = $.extend(true, {}, $.fn.wysihtml5.defaultOptionsCache);\n        },\n        bypassDefaults: function(options) {\n            return this.each(function () {\n                var $this = $(this);\n                $this.data('wysihtml5', new Wysihtml5($this, options));\n            });\n        },\n        shallowExtend: function (options) {\n            var settings = $.extend({}, $.fn.wysihtml5.defaultOptions, options || {}, $(this).data());\n            var that = this;\n            return methods.bypassDefaults.apply(that, [settings]);\n        },\n        deepExtend: function(options) {\n            var settings = $.extend(true, {}, $.fn.wysihtml5.defaultOptions, options || {});\n            var that = this;\n            return methods.bypassDefaults.apply(that, [settings]);\n        },\n        init: function(options) {\n            var that = this;\n            return methods.shallowExtend.apply(that, [options]);\n        }\n    };\n\n    $.fn.wysihtml5 = function ( method ) {\n        if ( methods[method] ) {\n            return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));\n        } else if ( typeof method === 'object' || ! method ) {\n            return methods.init.apply( this, arguments );\n        } else {\n            $.error( 'Method ' +  method + ' does not exist on jQuery.wysihtml5' );\n        }    \n    };\n\n    $.fn.wysihtml5.Constructor = Wysihtml5;\n\n    var defaultOptions = $.fn.wysihtml5.defaultOptions = {\n        \"font-styles\": true,\n        \"color\": false,\n        \"emphasis\": true,\n        \"lists\": true,\n        \"html\": false,\n        \"link\": true,\n        \"image\": true,\n        events: {},\n        parserRules: {\n            classes: {\n                // (path_to_project/lib/css/wysiwyg-color.css)\n                \"wysiwyg-color-silver\" : 1,\n                \"wysiwyg-color-gray\" : 1,\n                \"wysiwyg-color-white\" : 1,\n                \"wysiwyg-color-maroon\" : 1,\n                \"wysiwyg-color-red\" : 1,\n                \"wysiwyg-color-purple\" : 1,\n                \"wysiwyg-color-fuchsia\" : 1,\n                \"wysiwyg-color-green\" : 1,\n                \"wysiwyg-color-lime\" : 1,\n                \"wysiwyg-color-olive\" : 1,\n                \"wysiwyg-color-yellow\" : 1,\n                \"wysiwyg-color-navy\" : 1,\n                \"wysiwyg-color-blue\" : 1,\n                \"wysiwyg-color-teal\" : 1,\n                \"wysiwyg-color-aqua\" : 1,\n                \"wysiwyg-color-orange\" : 1\n            },\n            tags: {\n                \"b\":  {},\n                \"i\":  {},\n                \"br\": {},\n                \"ol\": {},\n                \"ul\": {},\n                \"li\": {},\n                \"h1\": {},\n                \"h2\": {},\n                \"h3\": {},\n                \"h4\": {},\n                \"h5\": {},\n                \"h6\": {},\n                \"blockquote\": {},\n                \"u\": 1,\n                \"img\": {\n                    \"check_attributes\": {\n                        \"width\": \"numbers\",\n                        \"alt\": \"alt\",\n                        \"src\": \"url\",\n                        \"height\": \"numbers\"\n                    }\n                },\n                \"a\":  {\n                    check_attributes: {\n                        'href': \"url\", // important to avoid XSS\n                        'target': 'alt',\n                        'rel': 'alt'\n                    }\n                },\n                \"span\": 1,\n                \"div\": 1,\n                // to allow save and edit files with code tag hacks\n                \"code\": 1,\n                \"pre\": 1\n            }\n        },\n        stylesheets: [\"css/wysiwyg-color.css\"], // (path_to_project/lib/css/wysiwyg-color.css)\n        locale: \"en\"\n    };\n\n    if (typeof $.fn.wysihtml5.defaultOptionsCache === 'undefined') {\n        $.fn.wysihtml5.defaultOptionsCache = $.extend(true, {}, $.fn.wysihtml5.defaultOptions);\n    }\n\n    var locale = $.fn.wysihtml5.locale = {\n        en: {\n            font_styles: {\n                normal: \"Normal text\",\n                h1: \"Heading 1\",\n                h2: \"Heading 2\",\n                h3: \"Heading 3\",\n                h4: \"Heading 4\",\n                h5: \"Heading 5\",\n                h6: \"Heading 6\"\n            },\n            emphasis: {\n                bold: \"\",\n                italic: \"\",\n                underline: \"\"\n            },\n            lists: {\n                unordered: \"Unordered list\",\n                ordered: \"Ordered list\",\n                outdent: \"Outdent\",\n                indent: \"Indent\"\n            },\n            link: {\n                insert: \"Insert link\",\n                cancel: \"Cancel\",\n                target: \"Open link in new window\"\n            },\n            image: {\n                insert: \"Insert image\",\n                cancel: \"Cancel\"\n            },\n            html: {\n                edit: \"Edit HTML\"\n            },\n            colours: {\n                black: \"Black\",\n                silver: \"Silver\",\n                gray: \"Grey\",\n                maroon: \"Maroon\",\n                red: \"Red\",\n                purple: \"Purple\",\n                green: \"Green\",\n                olive: \"Olive\",\n                navy: \"Navy\",\n                blue: \"Blue\",\n                orange: \"Orange\"\n            }\n        }\n    };\n\n}(window.jQuery, window.wysihtml5);\n"
  },
  {
    "path": "static/template/js/uncompressed/holder.js",
    "content": "/*\n\nHolder - 2.2 - client side image placeholders\n(c) 2012-2013 Ivan Malopinsky / http://imsky.co\n\nProvided under the MIT License.\nCommercial use requires attribution.\n\n*/\n\nvar Holder = Holder || {};\n(function (app, win) {\n\nvar preempted = false,\nfallback = false,\ncanvas = document.createElement('canvas');\nvar dpr = 1, bsr = 1;\nvar resizable_images = [];\n\nif (!canvas.getContext) {\n\tfallback = true;\n} else {\n\tif (canvas.toDataURL(\"image/png\")\n\t\t.indexOf(\"data:image/png\") < 0) {\n\t\t//Android doesn't support data URI\n\t\tfallback = true;\n\t} else {\n\t\tvar ctx = canvas.getContext(\"2d\");\n\t}\n}\n\nif(!fallback){\n    dpr = window.devicePixelRatio || 1,\n    bsr = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1;\n}\n\nvar ratio = dpr / bsr;\n\nvar settings = {\n\tdomain: \"holder.js\",\n\timages: \"img\",\n\tbgnodes: \".holderjs\",\n\tthemes: {\n\t\t\"gray\": {\n\t\t\tbackground: \"#eee\",\n\t\t\tforeground: \"#aaa\",\n\t\t\tsize: 12\n\t\t},\n\t\t\"social\": {\n\t\t\tbackground: \"#3a5a97\",\n\t\t\tforeground: \"#fff\",\n\t\t\tsize: 12\n\t\t},\n\t\t\"industrial\": {\n\t\t\tbackground: \"#434A52\",\n\t\t\tforeground: \"#C2F200\",\n\t\t\tsize: 12\n\t\t},\n\t\t\"sky\": {\n\t\t\tbackground: \"#0D8FDB\",\n\t\t\tforeground: \"#fff\",\n\t\t\tsize: 12\n\t\t},\n\t\t\"vine\": {\n\t\t\tbackground: \"#39DBAC\",\n\t\t\tforeground: \"#1E292C\",\n\t\t\tsize: 12\n\t\t},\n\t\t\"lava\": {\n\t\t\tbackground: \"#F8591A\",\n\t\t\tforeground: \"#1C2846\",\n\t\t\tsize: 12\n\t\t}\n\t},\n\tstylesheet: \"\"\n};\napp.flags = {\n\tdimensions: {\n\t\tregex: /^(\\d+)x(\\d+)$/,\n\t\toutput: function (val) {\n\t\t\tvar exec = this.regex.exec(val);\n\t\t\treturn {\n\t\t\t\twidth: +exec[1],\n\t\t\t\theight: +exec[2]\n\t\t\t}\n\t\t}\n\t},\n\tfluid: {\n\t\tregex: /^([0-9%]+)x([0-9%]+)$/,\n\t\toutput: function (val) {\n\t\t\tvar exec = this.regex.exec(val);\n\t\t\treturn {\n\t\t\t\twidth: exec[1],\n\t\t\t\theight: exec[2]\n\t\t\t}\n\t\t}\n\t},\n\tcolors: {\n\t\tregex: /#([0-9a-f]{3,})\\:#([0-9a-f]{3,})/i,\n\t\toutput: function (val) {\n\t\t\tvar exec = this.regex.exec(val);\n\t\t\treturn {\n\t\t\t\tsize: settings.themes.gray.size,\n\t\t\t\tforeground: \"#\" + exec[2],\n\t\t\t\tbackground: \"#\" + exec[1]\n\t\t\t}\n\t\t}\n\t},\n\ttext: {\n\t\tregex: /text\\:(.*)/,\n\t\toutput: function (val) {\n\t\t\treturn this.regex.exec(val)[1];\n\t\t}\n\t},\n\tfont: {\n\t\tregex: /font\\:(.*)/,\n\t\toutput: function (val) {\n\t\t\treturn this.regex.exec(val)[1];\n\t\t}\n\t},\n\tauto: {\n\t\tregex: /^auto$/\n\t},\n\ttextmode: {\n\t\tregex: /textmode\\:(.*)/,\n\t\toutput: function(val){\n\t\t\treturn this.regex.exec(val)[1];\n\t\t}\n\t}\n}\n\n//getElementsByClassName polyfill\ndocument.getElementsByClassName||(document.getElementsByClassName=function(e){var t=document,n,r,i,s=[];if(t.querySelectorAll)return t.querySelectorAll(\".\"+e);if(t.evaluate){r=\".//*[contains(concat(' ', @class, ' '), ' \"+e+\" ')]\",n=t.evaluate(r,t,null,0,null);while(i=n.iterateNext())s.push(i)}else{n=t.getElementsByTagName(\"*\"),r=new RegExp(\"(^|\\\\s)\"+e+\"(\\\\s|$)\");for(i=0;i<n.length;i++)r.test(n[i].className)&&s.push(n[i])}return s})\n\n//getComputedStyle polyfill\nwindow.getComputedStyle||(window.getComputedStyle=function(e){return this.el=e,this.getPropertyValue=function(t){var n=/(\\-([a-z]){1})/g;return t==\"float\"&&(t=\"styleFloat\"),n.test(t)&&(t=t.replace(n,function(){return arguments[2].toUpperCase()})),e.currentStyle[t]?e.currentStyle[t]:null},this})\n\n//http://javascript.nwbox.com/ContentLoaded by Diego Perini with modifications\nfunction contentLoaded(n,t){var l=\"complete\",s=\"readystatechange\",u=!1,h=u,c=!0,i=n.document,a=i.documentElement,e=i.addEventListener?\"addEventListener\":\"attachEvent\",v=i.addEventListener?\"removeEventListener\":\"detachEvent\",f=i.addEventListener?\"\":\"on\",r=function(e){(e.type!=s||i.readyState==l)&&((e.type==\"load\"?n:i)[v](f+e.type,r,u),!h&&(h=!0)&&t.call(n,null))},o=function(){try{a.doScroll(\"left\")}catch(n){setTimeout(o,50);return}r(\"poll\")};if(i.readyState==l)t.call(n,\"lazy\");else{if(i.createEventObject&&a.doScroll){try{c=!n.frameElement}catch(y){}c&&o()}i[e](f+\"DOMContentLoaded\",r,u),i[e](f+s,r,u),n[e](f+\"load\",r,u)}}\n\n//https://gist.github.com/991057 by Jed Schmidt with modifications\nfunction selector(a){\n\ta=a.match(/^(\\W)?(.*)/);var b=document[\"getElement\"+(a[1]?a[1]==\"#\"?\"ById\":\"sByClassName\":\"sByTagName\")](a[2]);\n\tvar ret=[];\tb!==null&&(b.length?ret=b:b.length===0?ret=b:ret=[b]);\treturn ret;\n}\n\n//shallow object property extend\nfunction extend(a,b){\n\tvar c={};\n\tfor(var i in a){\n\t\tif(a.hasOwnProperty(i)){\n\t\t\tc[i]=a[i];\n\t\t}\n\t}\n\tfor(var i in b){\n\t\tif(b.hasOwnProperty(i)){\n\t\t\tc[i]=b[i];\n\t\t}\n\t}\n\treturn c\n}\n\n//hasOwnProperty polyfill\nif (!Object.prototype.hasOwnProperty)\n    /*jshint -W001, -W103 */\n    Object.prototype.hasOwnProperty = function(prop) {\n\t\tvar proto = this.__proto__ || this.constructor.prototype;\n\t\treturn (prop in this) && (!(prop in proto) || proto[prop] !== this[prop]);\n\t}\n    /*jshint +W001, +W103 */\n\nfunction text_size(width, height, template) {\n\theight = parseInt(height, 10);\n\twidth = parseInt(width, 10);\n\tvar bigSide = Math.max(height, width)\n\tvar smallSide = Math.min(height, width)\n\tvar scale = 1 / 12;\n\tvar newHeight = Math.min(smallSide * 0.75, 0.75 * bigSide * scale);\n\treturn {\n\t\theight: Math.round(Math.max(template.size, newHeight))\n\t}\n}\n\nfunction draw(args) {\n\tvar ctx = args.ctx;\n\tvar dimensions = args.dimensions;\n\tvar template = args.template;\n\tvar ratio = args.ratio;\n\tvar holder = args.holder;\n\tvar literal = holder.textmode == \"literal\";\n\tvar exact = holder.textmode == \"exact\";\n\n\tvar ts = text_size(dimensions.width, dimensions.height, template);\n\tvar text_height = ts.height;\n\tvar width = dimensions.width * ratio,\n\t\theight = dimensions.height * ratio;\n\tvar font = template.font ? template.font : \"sans-serif\";\n\tcanvas.width = width;\n\tcanvas.height = height;\n\tctx.textAlign = \"center\";\n\tctx.textBaseline = \"middle\";\n\tctx.fillStyle = template.background;\n\tctx.fillRect(0, 0, width, height);\n\tctx.fillStyle = template.foreground;\n\tctx.font = \"bold \" + text_height + \"px \" + font;\n\tvar text = template.text ? template.text : (Math.floor(dimensions.width) + \"x\" + Math.floor(dimensions.height));\n\tif (literal) {\n\t\tvar dimensions = holder.dimensions;\n\t\ttext = dimensions.width + \"x\" + dimensions.height;\n\t}\n\telse if(exact && holder.exact_dimensions){\n\t\tvar dimensions = holder.exact_dimensions;\n\t\ttext = (Math.floor(dimensions.width) + \"x\" + Math.floor(dimensions.height));\n\t}\n\tvar text_width = ctx.measureText(text).width;\n\tif (text_width / width >= 0.75) {\n\t\ttext_height = Math.floor(text_height * 0.75 * (width / text_width));\n\t}\n\t//Resetting font size if necessary\n\tctx.font = \"bold \" + (text_height * ratio) + \"px \" + font;\n\tctx.fillText(text, (width / 2), (height / 2), width);\n\treturn canvas.toDataURL(\"image/png\");\n}\n\nfunction render(mode, el, holder, src) {\n\t\n\tvar dimensions = holder.dimensions,\n\t\ttheme = holder.theme,\n\t\ttext = holder.text ? decodeURIComponent(holder.text) : holder.text;\n\tvar dimensions_caption = dimensions.width + \"x\" + dimensions.height;\n\ttheme = (text ? extend(theme, {\n\t\ttext: text\n\t}) : theme);\n\ttheme = (holder.font ? extend(theme, {\n\t\tfont: holder.font\n\t}) : theme);\n\tel.setAttribute(\"data-src\", src);\n\tholder.theme = theme;\n\tel.holder_data = holder;\n\t\n\tif (mode == \"image\") {\n\t\tel.setAttribute(\"alt\", text ? text : theme.text ? theme.text + \" [\" + dimensions_caption + \"]\" : dimensions_caption);\n\t\tif (fallback || !holder.auto) {\n\t\t\tel.style.width = dimensions.width + \"px\";\n\t\t\tel.style.height = dimensions.height + \"px\";\n\t\t}\n\t\tif (fallback) {\n\t\t\tel.style.backgroundColor = theme.background;\n\t\t} else {\n\t\t\tel.setAttribute(\"src\", draw({ctx: ctx, dimensions: dimensions, template: theme, ratio:ratio, holder: holder}));\n\t\t\t\n\t\t\tif(holder.textmode && holder.textmode == \"exact\"){\n\t\t\t\tresizable_images.push(el);\n\t\t\t\tresizable_update(el);\n\t\t\t}\n\t\t\t\n\t\t}\n\t} else if (mode == \"background\") {\n\t\tif (!fallback) {\n\t\t\tel.style.backgroundImage = \"url(\" + draw({ctx:ctx, dimensions: dimensions, template: theme, ratio: ratio, holder: holder}) + \")\";\n\t\t\tel.style.backgroundSize = dimensions.width + \"px \" + dimensions.height + \"px\";\n\t\t}\n\t} else if (mode == \"fluid\") {\n\t\tel.setAttribute(\"alt\", text ? text : theme.text ? theme.text + \" [\" + dimensions_caption + \"]\" : dimensions_caption);\n\t\tif (dimensions.height.slice(-1) == \"%\") {\n\t\t\tel.style.height = dimensions.height\n\t\t} else {\n\t\t\tel.style.height = dimensions.height + \"px\"\n\t\t}\n\t\tif (dimensions.width.slice(-1) == \"%\") {\n\t\t\tel.style.width = dimensions.width\n\t\t} else {\n\t\t\tel.style.width = dimensions.width + \"px\"\n\t\t}\n\t\tif (el.style.display == \"inline\" || el.style.display === \"\" || el.style.display == \"none\") {\n\t\t\tel.style.display = \"block\";\n\t\t}\n\t\tif (fallback) {\n\t\t\tel.style.backgroundColor = theme.background;\n\t\t} else {\n\t\t\tresizable_images.push(el);\n\t\t\tresizable_update(el);\n\t\t}\n\t}\n}\n\nfunction dimension_check(el, callback) {\n\tvar dimensions = {\n\t\theight: el.clientHeight,\n\t\twidth: el.clientWidth\n\t};\n\tif (!dimensions.height && !dimensions.width) {\n\t\tif (el.hasAttribute(\"data-holder-invisible\")) {\n\t\t\tthrow new Error(\"Holder: placeholder is not visible\");\n\t\t} else {\n\t\t\tel.setAttribute(\"data-holder-invisible\", true)\n\t\t\tsetTimeout(function () {\n\t\t\t\tcallback.call(this, el)\n\t\t\t}, 1)\n\t\t\treturn null;\n\t\t}\n\t} else {\n\t\tel.removeAttribute(\"data-holder-invisible\")\n\t}\n\treturn dimensions;\n}\n\nfunction resizable_update(element) {\n\tvar images;\n\tif (element.nodeType == null) {\n\t\timages = resizable_images;\n\t} else {\n\t\timages = [element]\n\t}\n\tfor (var i in images) {\n\t\tif (!images.hasOwnProperty(i)) {\n\t\t\tcontinue;\n\t\t}\n\t\tvar el = images[i]\n\t\tif (el.holder_data) {\n\t\t\tvar holder = el.holder_data;\n\t\t\tvar dimensions = dimension_check(el, resizable_update)\n\t\t\tif(dimensions){\n\t\t\t\tif(holder.fluid){\n\t\t\t\t\tel.setAttribute(\"src\", draw({\n\t\t\t\t\t\tctx: ctx,\n\t\t\t\t\t\tdimensions: dimensions,\n\t\t\t\t\t\ttemplate: holder.theme,\n\t\t\t\t\t\tratio: ratio,\n\t\t\t\t\t\tholder: holder\n\t\t\t\t\t}))\n\t\t\t\t}\n\t\t\t\tif(holder.textmode && holder.textmode == \"exact\"){\n\t\t\t\t\tholder.exact_dimensions = dimensions;\n\t\t\t\t\tel.setAttribute(\"src\", draw({\n\t\t\t\t\t\tctx: ctx,\n\t\t\t\t\t\tdimensions: holder.dimensions,\n\t\t\t\t\t\ttemplate: holder.theme,\n\t\t\t\t\t\tratio: ratio,\n\t\t\t\t\t\tholder: holder\n\t\t\t\t\t}))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction parse_flags(flags, options) {\n\tvar ret = {\n\t\ttheme: extend(settings.themes.gray, {})\n\t};\n\tvar render = false;\n\tfor (sl = flags.length, j = 0; j < sl; j++) {\n\t\tvar flag = flags[j];\n\t\tif (app.flags.dimensions.match(flag)) {\n\t\t\trender = true;\n\t\t\tret.dimensions = app.flags.dimensions.output(flag);\n\t\t} else if (app.flags.fluid.match(flag)) {\n\t\t\trender = true;\n\t\t\tret.dimensions = app.flags.fluid.output(flag);\n\t\t\tret.fluid = true;\n\t\t} else if (app.flags.textmode.match(flag)) {\n\t\t\tret.textmode = app.flags.textmode.output(flag)\n\t\t} else if (app.flags.colors.match(flag)) {\n\t\t\tret.theme = app.flags.colors.output(flag);\n\t\t} else if (options.themes[flag]) {\n\t\t\t//If a theme is specified, it will override custom colors\n\t\t\tif(options.themes.hasOwnProperty(flag)){\n\t\t\t\tret.theme = extend(options.themes[flag], {});\n\t\t\t}\n\t\t} else if (app.flags.font.match(flag)) {\n\t\t\tret.font = app.flags.font.output(flag);\n\t\t} else if (app.flags.auto.match(flag)) {\n\t\t\tret.auto = true;\n\t\t} else if (app.flags.text.match(flag)) {\n\t\t\tret.text = app.flags.text.output(flag);\n\t\t}\n\t}\n\treturn render ? ret : false;\n}\n\nfor (var flag in app.flags) {\n\tif (!app.flags.hasOwnProperty(flag)) continue;\n\tapp.flags[flag].match = function (val) {\n\t\treturn val.match(this.regex)\n\t}\n}\napp.add_theme = function (name, theme) {\n\tname != null && theme != null && (settings.themes[name] = theme);\n\treturn app;\n};\napp.add_image = function (src, el) {\n\tvar node = selector(el);\n\tif (node.length) {\n\t\tfor (var i = 0, l = node.length; i < l; i++) {\n\t\t\tvar img = document.createElement(\"img\")\n\t\t\timg.setAttribute(\"data-src\", src);\n\t\t\tnode[i].appendChild(img);\n\t\t}\n\t}\n\treturn app;\n};\napp.run = function (o) {\n\tpreempted = true;\n\t\n\tvar options = extend(settings, o),\n\t\timages = [],\n\t\timageNodes = [],\n\t\tbgnodes = [];\n\tif (typeof (options.images) == \"string\") {\n\t\timageNodes = selector(options.images);\n\t} else if (window.NodeList && options.images instanceof window.NodeList) {\n\t\timageNodes = options.images;\n\t} else if (window.Node && options.images instanceof window.Node) {\n\t\timageNodes = [options.images];\n\t}\n\t\n\tif (typeof (options.bgnodes) == \"string\") {\n\t\tbgnodes = selector(options.bgnodes);\n\t} else if (window.NodeList && options.elements instanceof window.NodeList) {\n\t\tbgnodes = options.bgnodes;\n\t} else if (window.Node && options.bgnodes instanceof window.Node) {\n\t\tbgnodes = [options.bgnodes];\n\t}\n\tfor (i = 0, l = imageNodes.length; i < l; i++) images.push(imageNodes[i]);\n\tvar holdercss = document.getElementById(\"holderjs-style\");\n\tif (!holdercss) {\n\t\tholdercss = document.createElement(\"style\");\n\t\tholdercss.setAttribute(\"id\", \"holderjs-style\");\n\t\tholdercss.type = \"text/css\";\n\t\tdocument.getElementsByTagName(\"head\")[0].appendChild(holdercss);\n\t}\n\tif (!options.nocss) {\n\t\tif (holdercss.styleSheet) {\n\t\t\tholdercss.styleSheet.cssText += options.stylesheet;\n\t\t} else {\n\t\t\tholdercss.appendChild(document.createTextNode(options.stylesheet));\n\t\t}\n\t}\n\tvar cssregex = new RegExp(options.domain + \"\\/(.*?)\\\"?\\\\)\");\n\tfor (var l = bgnodes.length, i = 0; i < l; i++) {\n\t\tvar src = window.getComputedStyle(bgnodes[i], null)\n\t\t\t.getPropertyValue(\"background-image\");\n\t\tvar flags = src.match(cssregex);\n\t\tvar bgsrc = bgnodes[i].getAttribute(\"data-background-src\");\n\t\tif (flags) {\n\t\t\tvar holder = parse_flags(flags[1].split(\"/\"), options);\n\t\t\tif (holder) {\n\t\t\t\trender(\"background\", bgnodes[i], holder, src);\n\t\t\t}\n\t\t} else if (bgsrc != null) {\n\t\t\tvar holder = parse_flags(bgsrc.substr(bgsrc.lastIndexOf(options.domain) + options.domain.length + 1)\n\t\t\t\t.split(\"/\"), options);\n\t\t\tif (holder) {\n\t\t\t\trender(\"background\", bgnodes[i], holder, src);\n\t\t\t}\n\t\t}\n\t}\n\tfor (l = images.length, i = 0; i < l; i++) {\n\t\tvar attr_data_src, attr_src;\n\t\tattr_src = attr_data_src = src = null;\n\t\ttry {\n\t\t\tattr_src = images[i].getAttribute(\"src\");\n\t\t\tattr_datasrc = images[i].getAttribute(\"data-src\");\n\t\t} catch (e) {}\n\t\tif (attr_datasrc == null && !! attr_src && attr_src.indexOf(options.domain) >= 0) {\n\t\t\tsrc = attr_src;\n\t\t} else if ( !! attr_datasrc && attr_datasrc.indexOf(options.domain) >= 0) {\n\t\t\tsrc = attr_datasrc;\n\t\t}\n\t\tif (src) {\n\t\t\tvar holder = parse_flags(src.substr(src.lastIndexOf(options.domain) + options.domain.length + 1)\n\t\t\t\t.split(\"/\"), options);\n\t\t\tif (holder) {\n\t\t\t\tif (holder.fluid) {\n\t\t\t\t\trender(\"fluid\", images[i], holder, src)\n\t\t\t\t} else {\n\t\t\t\t\trender(\"image\", images[i], holder, src);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn app;\n};\ncontentLoaded(win, function () {\n\tif (window.addEventListener) {\n\t\twindow.addEventListener(\"resize\", resizable_update, false);\n\t\twindow.addEventListener(\"orientationchange\", resizable_update, false);\n\t} else {\n\t\twindow.attachEvent(\"onresize\", resizable_update)\n\t}\n\tpreempted || app.run();\n});\nif (typeof define === \"function\" && define.amd) {\n\tdefine([], function () {\n\t\treturn app;\n\t});\n}\n\n})(Holder, window);\n"
  },
  {
    "path": "static/template/js/uncompressed/pace.js",
    "content": "(function() {\n  var AjaxMonitor, Bar, DocumentMonitor, ElementMonitor, ElementTracker, EventLagMonitor, Evented, Events, NoTargetError, RequestIntercept, SOURCE_KEYS, Scaler, SocketRequestTracker, XHRRequestTracker, animation, avgAmplitude, bar, cancelAnimation, cancelAnimationFrame, defaultOptions, extend, extendNative, getFromDOM, getIntercept, handlePushState, ignoreStack, init, now, options, requestAnimationFrame, result, runAnimation, scalers, shouldTrack, source, sources, uniScaler, _WebSocket, _XDomainRequest, _XMLHttpRequest, _i, _intercept, _len, _pushState, _ref, _ref1, _replaceState,\n    __slice = [].slice,\n    __hasProp = {}.hasOwnProperty,\n    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },\n    __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };\n\n  defaultOptions = {\n    catchupTime: 500,\n    initialRate: .03,\n    minTime: 500,\n    ghostTime: 500,\n    maxProgressPerFrame: 10,\n    easeFactor: 1.25,\n    startOnPageLoad: true,\n    restartOnPushState: true,\n    restartOnRequestAfter: 500,\n    target: 'body',\n    elements: {\n      checkInterval: 100,\n      selectors: ['body']\n    },\n    eventLag: {\n      minSamples: 10,\n      sampleCount: 3,\n      lagThreshold: 3\n    },\n    ajax: {\n      trackMethods: ['GET'],\n      trackWebSockets: false\n    }\n  };\n\n  now = function() {\n    var _ref;\n    return (_ref = typeof performance !== \"undefined\" && performance !== null ? typeof performance.now === \"function\" ? performance.now() : void 0 : void 0) != null ? _ref : +(new Date);\n  };\n\n  requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;\n\n  cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame;\n\n  if (requestAnimationFrame == null) {\n    requestAnimationFrame = function(fn) {\n      return setTimeout(fn, 50);\n    };\n    cancelAnimationFrame = function(id) {\n      return clearTimeout(id);\n    };\n  }\n\n  runAnimation = function(fn) {\n    var last, tick;\n    last = now();\n    tick = function() {\n      var diff;\n      diff = now() - last;\n      if (diff >= 33) {\n        last = now();\n        return fn(diff, function() {\n          return requestAnimationFrame(tick);\n        });\n      } else {\n        return setTimeout(tick, 33 - diff);\n      }\n    };\n    return tick();\n  };\n\n  result = function() {\n    var args, key, obj;\n    obj = arguments[0], key = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : [];\n    if (typeof obj[key] === 'function') {\n      return obj[key].apply(obj, args);\n    } else {\n      return obj[key];\n    }\n  };\n\n  extend = function() {\n    var key, out, source, sources, val, _i, _len;\n    out = arguments[0], sources = 2 <= arguments.length ? __slice.call(arguments, 1) : [];\n    for (_i = 0, _len = sources.length; _i < _len; _i++) {\n      source = sources[_i];\n      if (source) {\n        for (key in source) {\n          if (!__hasProp.call(source, key)) continue;\n          val = source[key];\n          if ((out[key] != null) && typeof out[key] === 'object' && (val != null) && typeof val === 'object') {\n            extend(out[key], val);\n          } else {\n            out[key] = val;\n          }\n        }\n      }\n    }\n    return out;\n  };\n\n  avgAmplitude = function(arr) {\n    var count, sum, v, _i, _len;\n    sum = count = 0;\n    for (_i = 0, _len = arr.length; _i < _len; _i++) {\n      v = arr[_i];\n      sum += Math.abs(v);\n      count++;\n    }\n    return sum / count;\n  };\n\n  getFromDOM = function(key, json) {\n    var data, e, el;\n    if (key == null) {\n      key = 'options';\n    }\n    if (json == null) {\n      json = true;\n    }\n    el = document.querySelector(\"[data-pace-\" + key + \"]\");\n    if (!el) {\n      return;\n    }\n    data = el.getAttribute(\"data-pace-\" + key);\n    if (!json) {\n      return data;\n    }\n    try {\n      return JSON.parse(data);\n    } catch (_error) {\n      e = _error;\n      return typeof console !== \"undefined\" && console !== null ? console.error(\"Error parsing inline pace options\", e) : void 0;\n    }\n  };\n\n  Evented = (function() {\n    function Evented() {}\n\n    Evented.prototype.on = function(event, handler, ctx, once) {\n      var _base;\n      if (once == null) {\n        once = false;\n      }\n      if (this.bindings == null) {\n        this.bindings = {};\n      }\n      if ((_base = this.bindings)[event] == null) {\n        _base[event] = [];\n      }\n      return this.bindings[event].push({\n        handler: handler,\n        ctx: ctx,\n        once: once\n      });\n    };\n\n    Evented.prototype.once = function(event, handler, ctx) {\n      return this.on(event, handler, ctx, true);\n    };\n\n    Evented.prototype.off = function(event, handler) {\n      var i, _ref, _results;\n      if (((_ref = this.bindings) != null ? _ref[event] : void 0) == null) {\n        return;\n      }\n      if (handler == null) {\n        return delete this.bindings[event];\n      } else {\n        i = 0;\n        _results = [];\n        while (i < this.bindings[event].length) {\n          if (this.bindings[event][i].handler === handler) {\n            _results.push(this.bindings[event].splice(i, 1));\n          } else {\n            _results.push(i++);\n          }\n        }\n        return _results;\n      }\n    };\n\n    Evented.prototype.trigger = function() {\n      var args, ctx, event, handler, i, once, _ref, _ref1, _results;\n      event = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];\n      if ((_ref = this.bindings) != null ? _ref[event] : void 0) {\n        i = 0;\n        _results = [];\n        while (i < this.bindings[event].length) {\n          _ref1 = this.bindings[event][i], handler = _ref1.handler, ctx = _ref1.ctx, once = _ref1.once;\n          handler.apply(ctx != null ? ctx : this, args);\n          if (once) {\n            _results.push(this.bindings[event].splice(i, 1));\n          } else {\n            _results.push(i++);\n          }\n        }\n        return _results;\n      }\n    };\n\n    return Evented;\n\n  })();\n\n  if (window.Pace == null) {\n    window.Pace = {};\n  }\n\n  extend(Pace, Evented.prototype);\n\n  options = Pace.options = extend({}, defaultOptions, window.paceOptions, getFromDOM());\n\n  _ref = ['ajax', 'document', 'eventLag', 'elements'];\n  for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n    source = _ref[_i];\n    if (options[source] === true) {\n      options[source] = defaultOptions[source];\n    }\n  }\n\n  NoTargetError = (function(_super) {\n    __extends(NoTargetError, _super);\n\n    function NoTargetError() {\n      _ref1 = NoTargetError.__super__.constructor.apply(this, arguments);\n      return _ref1;\n    }\n\n    return NoTargetError;\n\n  })(Error);\n\n  Bar = (function() {\n    function Bar() {\n      this.progress = 0;\n    }\n\n    Bar.prototype.getElement = function() {\n      var targetElement;\n      if (this.el == null) {\n        targetElement = document.querySelector(options.target);\n        if (!targetElement) {\n          throw new NoTargetError;\n        }\n        this.el = document.createElement('div');\n        this.el.className = \"pace pace-active\";\n        document.body.className = document.body.className.replace('pace-done', '');\n        document.body.className += ' pace-running';\n        this.el.innerHTML = '<div class=\"pace-progress\">\\n  <div class=\"pace-progress-inner\"></div>\\n</div>\\n<div class=\"pace-activity\"></div>';\n        if (targetElement.firstChild != null) {\n          targetElement.insertBefore(this.el, targetElement.firstChild);\n        } else {\n          targetElement.appendChild(this.el);\n        }\n      }\n      return this.el;\n    };\n\n    Bar.prototype.finish = function() {\n      var el;\n      el = this.getElement();\n      el.className = el.className.replace('pace-active', '');\n      el.className += ' pace-inactive';\n      document.body.className = document.body.className.replace('pace-running', '');\n      return document.body.className += ' pace-done';\n    };\n\n    Bar.prototype.update = function(prog) {\n      this.progress = prog;\n      return this.render();\n    };\n\n    Bar.prototype.destroy = function() {\n      try {\n        this.getElement().parentNode.removeChild(this.getElement());\n      } catch (_error) {\n        NoTargetError = _error;\n      }\n      return this.el = void 0;\n    };\n\n    Bar.prototype.render = function() {\n      var el, progressStr;\n      if (document.querySelector(options.target) == null) {\n        return false;\n      }\n      el = this.getElement();\n      el.children[0].style.width = \"\" + this.progress + \"%\";\n      if (!this.lastRenderedProgress || this.lastRenderedProgress | 0 !== this.progress | 0) {\n        el.children[0].setAttribute('data-progress-text', \"\" + (this.progress | 0) + \"%\");\n        if (this.progress >= 100) {\n          progressStr = '99';\n        } else {\n          progressStr = this.progress < 10 ? \"0\" : \"\";\n          progressStr += this.progress | 0;\n        }\n        el.children[0].setAttribute('data-progress', \"\" + progressStr);\n      }\n      return this.lastRenderedProgress = this.progress;\n    };\n\n    Bar.prototype.done = function() {\n      return this.progress >= 100;\n    };\n\n    return Bar;\n\n  })();\n\n  Events = (function() {\n    function Events() {\n      this.bindings = {};\n    }\n\n    Events.prototype.trigger = function(name, val) {\n      var binding, _j, _len1, _ref2, _results;\n      if (this.bindings[name] != null) {\n        _ref2 = this.bindings[name];\n        _results = [];\n        for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {\n          binding = _ref2[_j];\n          _results.push(binding.call(this, val));\n        }\n        return _results;\n      }\n    };\n\n    Events.prototype.on = function(name, fn) {\n      var _base;\n      if ((_base = this.bindings)[name] == null) {\n        _base[name] = [];\n      }\n      return this.bindings[name].push(fn);\n    };\n\n    return Events;\n\n  })();\n\n  _XMLHttpRequest = window.XMLHttpRequest;\n\n  _XDomainRequest = window.XDomainRequest;\n\n  _WebSocket = window.WebSocket;\n\n  extendNative = function(to, from) {\n    var e, key, val, _results;\n    _results = [];\n    for (key in from.prototype) {\n      try {\n        val = from.prototype[key];\n        if ((to[key] == null) && typeof val !== 'function') {\n          _results.push(to[key] = val);\n        } else {\n          _results.push(void 0);\n        }\n      } catch (_error) {\n        e = _error;\n      }\n    }\n    return _results;\n  };\n\n  ignoreStack = [];\n\n  Pace.ignore = function() {\n    var args, fn, ret;\n    fn = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];\n    ignoreStack.unshift('ignore');\n    ret = fn.apply(null, args);\n    ignoreStack.shift();\n    return ret;\n  };\n\n  Pace.track = function() {\n    var args, fn, ret;\n    fn = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];\n    ignoreStack.unshift('track');\n    ret = fn.apply(null, args);\n    ignoreStack.shift();\n    return ret;\n  };\n\n  shouldTrack = function(method) {\n    var _ref2;\n    if (method == null) {\n      method = 'GET';\n    }\n    if (ignoreStack[0] === 'track') {\n      return 'force';\n    }\n    if (!ignoreStack.length && options.ajax) {\n      if (method === 'socket' && options.ajax.trackWebSockets) {\n        return true;\n      } else if (_ref2 = method.toUpperCase(), __indexOf.call(options.ajax.trackMethods, _ref2) >= 0) {\n        return true;\n      }\n    }\n    return false;\n  };\n\n  RequestIntercept = (function(_super) {\n    __extends(RequestIntercept, _super);\n\n    function RequestIntercept() {\n      var monitorXHR,\n        _this = this;\n      RequestIntercept.__super__.constructor.apply(this, arguments);\n      monitorXHR = function(req) {\n        var _open;\n        _open = req.open;\n        return req.open = function(type, url, async) {\n          if (shouldTrack(type)) {\n            _this.trigger('request', {\n              type: type,\n              url: url,\n              request: req\n            });\n          }\n          return _open.apply(req, arguments);\n        };\n      };\n      window.XMLHttpRequest = function(flags) {\n        var req;\n        req = new _XMLHttpRequest(flags);\n        monitorXHR(req);\n        return req;\n      };\n      extendNative(window.XMLHttpRequest, _XMLHttpRequest);\n      if (_XDomainRequest != null) {\n        window.XDomainRequest = function() {\n          var req;\n          req = new _XDomainRequest;\n          monitorXHR(req);\n          return req;\n        };\n        extendNative(window.XDomainRequest, _XDomainRequest);\n      }\n      if ((_WebSocket != null) && options.ajax.trackWebSockets) {\n        window.WebSocket = function(url, protocols) {\n          var req;\n          req = new _WebSocket(url, protocols);\n          if (shouldTrack('socket')) {\n            _this.trigger('request', {\n              type: 'socket',\n              url: url,\n              protocols: protocols,\n              request: req\n            });\n          }\n          return req;\n        };\n        extendNative(window.WebSocket, _WebSocket);\n      }\n    }\n\n    return RequestIntercept;\n\n  })(Events);\n\n  _intercept = null;\n\n  getIntercept = function() {\n    if (_intercept == null) {\n      _intercept = new RequestIntercept;\n    }\n    return _intercept;\n  };\n\n  getIntercept().on('request', function(_arg) {\n    var after, args, request, type;\n    type = _arg.type, request = _arg.request;\n    if (!Pace.running && (options.restartOnRequestAfter !== false || shouldTrack(type) === 'force')) {\n      args = arguments;\n      after = options.restartOnRequestAfter || 0;\n      if (typeof after === 'boolean') {\n        after = 0;\n      }\n      return setTimeout(function() {\n        var stillActive, _j, _len1, _ref2, _ref3, _results;\n        if (type === 'socket') {\n          stillActive = request.readyState < 2;\n        } else {\n          stillActive = (0 < (_ref2 = request.readyState) && _ref2 < 4);\n        }\n        if (stillActive) {\n          Pace.restart();\n          _ref3 = Pace.sources;\n          _results = [];\n          for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {\n            source = _ref3[_j];\n            if (source instanceof AjaxMonitor) {\n              source.watch.apply(source, args);\n              break;\n            } else {\n              _results.push(void 0);\n            }\n          }\n          return _results;\n        }\n      }, after);\n    }\n  });\n\n  AjaxMonitor = (function() {\n    function AjaxMonitor() {\n      var _this = this;\n      this.elements = [];\n      getIntercept().on('request', function() {\n        return _this.watch.apply(_this, arguments);\n      });\n    }\n\n    AjaxMonitor.prototype.watch = function(_arg) {\n      var request, tracker, type;\n      type = _arg.type, request = _arg.request;\n      if (type === 'socket') {\n        tracker = new SocketRequestTracker(request);\n      } else {\n        tracker = new XHRRequestTracker(request);\n      }\n      return this.elements.push(tracker);\n    };\n\n    return AjaxMonitor;\n\n  })();\n\n  XHRRequestTracker = (function() {\n    function XHRRequestTracker(request) {\n      var event, size, _j, _len1, _onreadystatechange, _ref2,\n        _this = this;\n      this.progress = 0;\n      if (window.ProgressEvent != null) {\n        size = null;\n        request.addEventListener('progress', function(evt) {\n          if (evt.lengthComputable) {\n            return _this.progress = 100 * evt.loaded / evt.total;\n          } else {\n            return _this.progress = _this.progress + (100 - _this.progress) / 2;\n          }\n        });\n        _ref2 = ['load', 'abort', 'timeout', 'error'];\n        for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {\n          event = _ref2[_j];\n          request.addEventListener(event, function() {\n            return _this.progress = 100;\n          });\n        }\n      } else {\n        _onreadystatechange = request.onreadystatechange;\n        request.onreadystatechange = function() {\n          var _ref3;\n          if ((_ref3 = request.readyState) === 0 || _ref3 === 4) {\n            _this.progress = 100;\n          } else if (request.readyState === 3) {\n            _this.progress = 50;\n          }\n          return typeof _onreadystatechange === \"function\" ? _onreadystatechange.apply(null, arguments) : void 0;\n        };\n      }\n    }\n\n    return XHRRequestTracker;\n\n  })();\n\n  SocketRequestTracker = (function() {\n    function SocketRequestTracker(request) {\n      var event, _j, _len1, _ref2,\n        _this = this;\n      this.progress = 0;\n      _ref2 = ['error', 'open'];\n      for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {\n        event = _ref2[_j];\n        request.addEventListener(event, function() {\n          return _this.progress = 100;\n        });\n      }\n    }\n\n    return SocketRequestTracker;\n\n  })();\n\n  ElementMonitor = (function() {\n    function ElementMonitor(options) {\n      var selector, _j, _len1, _ref2;\n      if (options == null) {\n        options = {};\n      }\n      this.elements = [];\n      if (options.selectors == null) {\n        options.selectors = [];\n      }\n      _ref2 = options.selectors;\n      for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {\n        selector = _ref2[_j];\n        this.elements.push(new ElementTracker(selector));\n      }\n    }\n\n    return ElementMonitor;\n\n  })();\n\n  ElementTracker = (function() {\n    function ElementTracker(selector) {\n      this.selector = selector;\n      this.progress = 0;\n      this.check();\n    }\n\n    ElementTracker.prototype.check = function() {\n      var _this = this;\n      if (document.querySelector(this.selector)) {\n        return this.done();\n      } else {\n        return setTimeout((function() {\n          return _this.check();\n        }), options.elements.checkInterval);\n      }\n    };\n\n    ElementTracker.prototype.done = function() {\n      return this.progress = 100;\n    };\n\n    return ElementTracker;\n\n  })();\n\n  DocumentMonitor = (function() {\n    DocumentMonitor.prototype.states = {\n      loading: 0,\n      interactive: 50,\n      complete: 100\n    };\n\n    function DocumentMonitor() {\n      var _onreadystatechange, _ref2,\n        _this = this;\n      this.progress = (_ref2 = this.states[document.readyState]) != null ? _ref2 : 100;\n      _onreadystatechange = document.onreadystatechange;\n      document.onreadystatechange = function() {\n        if (_this.states[document.readyState] != null) {\n          _this.progress = _this.states[document.readyState];\n        }\n        return typeof _onreadystatechange === \"function\" ? _onreadystatechange.apply(null, arguments) : void 0;\n      };\n    }\n\n    return DocumentMonitor;\n\n  })();\n\n  EventLagMonitor = (function() {\n    function EventLagMonitor() {\n      var avg, interval, last, points, samples,\n        _this = this;\n      this.progress = 0;\n      avg = 0;\n      samples = [];\n      points = 0;\n      last = now();\n      interval = setInterval(function() {\n        var diff;\n        diff = now() - last - 50;\n        last = now();\n        samples.push(diff);\n        if (samples.length > options.eventLag.sampleCount) {\n          samples.shift();\n        }\n        avg = avgAmplitude(samples);\n        if (++points >= options.eventLag.minSamples && avg < options.eventLag.lagThreshold) {\n          _this.progress = 100;\n          return clearInterval(interval);\n        } else {\n          return _this.progress = 100 * (3 / (avg + 3));\n        }\n      }, 50);\n    }\n\n    return EventLagMonitor;\n\n  })();\n\n  Scaler = (function() {\n    function Scaler(source) {\n      this.source = source;\n      this.last = this.sinceLastUpdate = 0;\n      this.rate = options.initialRate;\n      this.catchup = 0;\n      this.progress = this.lastProgress = 0;\n      if (this.source != null) {\n        this.progress = result(this.source, 'progress');\n      }\n    }\n\n    Scaler.prototype.tick = function(frameTime, val) {\n      var scaling;\n      if (val == null) {\n        val = result(this.source, 'progress');\n      }\n      if (val >= 100) {\n        this.done = true;\n      }\n      if (val === this.last) {\n        this.sinceLastUpdate += frameTime;\n      } else {\n        if (this.sinceLastUpdate) {\n          this.rate = (val - this.last) / this.sinceLastUpdate;\n        }\n        this.catchup = (val - this.progress) / options.catchupTime;\n        this.sinceLastUpdate = 0;\n        this.last = val;\n      }\n      if (val > this.progress) {\n        this.progress += this.catchup * frameTime;\n      }\n      scaling = 1 - Math.pow(this.progress / 100, options.easeFactor);\n      this.progress += scaling * this.rate * frameTime;\n      this.progress = Math.min(this.lastProgress + options.maxProgressPerFrame, this.progress);\n      this.progress = Math.max(0, this.progress);\n      this.progress = Math.min(100, this.progress);\n      this.lastProgress = this.progress;\n      return this.progress;\n    };\n\n    return Scaler;\n\n  })();\n\n  sources = null;\n\n  scalers = null;\n\n  bar = null;\n\n  uniScaler = null;\n\n  animation = null;\n\n  cancelAnimation = null;\n\n  Pace.running = false;\n\n  handlePushState = function() {\n    if (options.restartOnPushState) {\n      return Pace.restart();\n    }\n  };\n\n  if (window.history.pushState != null) {\n    _pushState = window.history.pushState;\n    window.history.pushState = function() {\n      handlePushState();\n      return _pushState.apply(window.history, arguments);\n    };\n  }\n\n  if (window.history.replaceState != null) {\n    _replaceState = window.history.replaceState;\n    window.history.replaceState = function() {\n      handlePushState();\n      return _replaceState.apply(window.history, arguments);\n    };\n  }\n\n  SOURCE_KEYS = {\n    ajax: AjaxMonitor,\n    elements: ElementMonitor,\n    document: DocumentMonitor,\n    eventLag: EventLagMonitor\n  };\n\n  (init = function() {\n    var type, _j, _k, _len1, _len2, _ref2, _ref3, _ref4;\n    Pace.sources = sources = [];\n    _ref2 = ['ajax', 'elements', 'document', 'eventLag'];\n    for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {\n      type = _ref2[_j];\n      if (options[type] !== false) {\n        sources.push(new SOURCE_KEYS[type](options[type]));\n      }\n    }\n    _ref4 = (_ref3 = options.extraSources) != null ? _ref3 : [];\n    for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) {\n      source = _ref4[_k];\n      sources.push(new source(options));\n    }\n    Pace.bar = bar = new Bar;\n    scalers = [];\n    return uniScaler = new Scaler;\n  })();\n\n  Pace.stop = function() {\n    Pace.trigger('stop');\n    Pace.running = false;\n    bar.destroy();\n    cancelAnimation = true;\n    if (animation != null) {\n      if (typeof cancelAnimationFrame === \"function\") {\n        cancelAnimationFrame(animation);\n      }\n      animation = null;\n    }\n    return init();\n  };\n\n  Pace.restart = function() {\n    Pace.trigger('restart');\n    Pace.stop();\n    return Pace.start();\n  };\n\n  Pace.go = function() {\n    Pace.running = true;\n    bar.render();\n    cancelAnimation = false;\n    return animation = runAnimation(function(frameTime, enqueueNextFrame) {\n      var avg, count, done, element, elements, i, j, remaining, scaler, scalerList, start, sum, _j, _k, _len1, _len2, _ref2;\n      remaining = 100 - bar.progress;\n      count = sum = 0;\n      done = true;\n      for (i = _j = 0, _len1 = sources.length; _j < _len1; i = ++_j) {\n        source = sources[i];\n        scalerList = scalers[i] != null ? scalers[i] : scalers[i] = [];\n        elements = (_ref2 = source.elements) != null ? _ref2 : [source];\n        for (j = _k = 0, _len2 = elements.length; _k < _len2; j = ++_k) {\n          element = elements[j];\n          scaler = scalerList[j] != null ? scalerList[j] : scalerList[j] = new Scaler(element);\n          done &= scaler.done;\n          if (scaler.done) {\n            continue;\n          }\n          count++;\n          sum += scaler.tick(frameTime);\n        }\n      }\n      avg = sum / count;\n      bar.update(uniScaler.tick(frameTime, avg));\n      start = now();\n      if (bar.done() || done || cancelAnimation) {\n        bar.update(100);\n        Pace.trigger('done');\n        return setTimeout(function() {\n          bar.finish();\n          Pace.running = false;\n          return Pace.trigger('hide');\n        }, Math.max(options.ghostTime, Math.min(options.minTime, now() - start)));\n      } else {\n        return enqueueNextFrame();\n      }\n    });\n  };\n\n  Pace.start = function(_options) {\n    extend(options, _options);\n    Pace.running = true;\n    try {\n      bar.render();\n    } catch (_error) {\n      NoTargetError = _error;\n    }\n    if (!document.querySelector('.pace')) {\n      return setTimeout(Pace.start, 50);\n    } else {\n      Pace.trigger('start');\n      return Pace.go();\n    }\n  };\n\n  if (typeof define === 'function' && define.amd) {\n    define(function() {\n      return Pace;\n    });\n  } else if (typeof exports === 'object') {\n    module.exports = Pace;\n  } else {\n    if (options.startOnPageLoad) {\n      Pace.start();\n    }\n  }\n\n}).call(this);\n"
  },
  {
    "path": "static/template/js/uncompressed/run_prettify.js",
    "content": "// Copyright (C) 2013 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n\n// Looks at query parameters to decide which language handlers and style-sheets\n// to load.\n\n// Query Parameter     Format           Effect                        Default\n// +------------------+---------------+------------------------------+--------+\n// | autorun=         | true | false  | If true then prettyPrint()   | \"true\" |\n// |                  |               | is called on page load.      |        |\n// +------------------+---------------+------------------------------+--------+\n// | lang=            | language name | Loads the language handler   | Can    |\n// |                  |               | named \"lang-<NAME>.js\".      | appear |\n// |                  |               | See available handlers at    | many   |\n// |                  |               | http://code.google.com/p/    | times. |\n// |                  |               | google-code-prettify/source/ |        |\n// |                  |               | browse/trunk/src             |        |\n// +------------------+---------------+------------------------------+--------+\n// | skin=            | skin name     | Loads the skin stylesheet    | none.  |\n// |                  |               | named \"<NAME>.css\".          |        |\n// |                  |               | http://code.google.com/p/    |        |\n// |                  |               | google-code-prettify/source/ |        |\n// |                  |               | browse/trunk/styles          |        |\n// +------------------+---------------+------------------------------+--------+\n// | callback=        | JS identifier | When \"prettyPrint\" finishes  | none   |\n// |                  |               | window.exports[js_ident] is  |        |\n// |                  |               | called.                      |        |\n// |                  |               | The callback must be under   |        |\n// |                  |               | exports to reduce the risk   |        |\n// |                  |               | of XSS via query parameter   |        |\n// |                  |               | injection.                   |        |\n// +------------------+---------------+------------------------------+--------+\n\n// Exmaples\n// .../prettify.js?lang=css&skin=sunburst\n//   1. Loads the CSS language handler which can be used to prettify CSS\n//      stylesheets, HTML <style> element bodies and style=\"...\" attributes\n//      values.\n//   2. Loads the sunburst.css stylesheet instead of the default prettify.css\n//      stylesheet.\n//      A gallery of stylesheets is available at\n//      https://google-code-prettify.googlecode.com/svn/trunk/styles/index.html\n//   3. Since autorun=false is not specified, calls prettyPrint() on page load.\n\n\n/** @define {boolean} */\nvar IN_GLOBAL_SCOPE = false;\n\n(function () {\n  \"use strict\";\n\n  var win = window;\n  var setTimeout = win.setTimeout;\n  var doc = document;\n  var root = doc.documentElement;\n  var head = doc['head'] || doc.getElementsByTagName(\"head\")[0] || root;\n\n  // From http://javascript.nwbox.com/ContentLoaded/contentloaded.js\n  // Author: Diego Perini (diego.perini at gmail.com)\n  // Summary: cross-browser wrapper for DOMContentLoaded\n  // Updated: 20101020\n  // License: MIT\n  // Version: 1.2\n  function contentLoaded(callback) {\n    var addEventListener = doc['addEventListener'];\n    var done = false, top = true,\n        add = addEventListener ? 'addEventListener' : 'attachEvent',\n        rem = addEventListener ? 'removeEventListener' : 'detachEvent',\n        pre = addEventListener ? '' : 'on',\n\n        init = function(e) {\n          if (e.type == 'readystatechange' && doc.readyState != 'complete') {\n            return;\n          }\n          (e.type == 'load' ? win : doc)[rem](pre + e.type, init, false);\n          if (!done && (done = true)) { callback.call(win, e.type || e); }\n        },\n\n        poll = function() {\n          try {\n            root.doScroll('left');\n          } catch(e) {\n            setTimeout(poll, 50);\n            return;\n          }\n          init('poll');\n        };\n\n    if (doc.readyState == 'complete') {\n      callback.call(win, 'lazy');\n    } else {\n      if (doc.createEventObject && root.doScroll) {\n        try { top = !win.frameElement; } catch(e) { }\n        if (top) { poll(); }\n      }\n      doc[add](pre + 'DOMContentLoaded', init, false);\n      doc[add](pre + 'readystatechange', init, false);\n      win[add](pre + 'load', init, false);\n    }\n  }\n\n  // Given a list of URLs to stylesheets, loads the first that loads without\n  // triggering an error event.\n  function loadStylesheetsFallingBack(stylesheets) {\n    var n = stylesheets.length;\n    function load(i) {\n      if (i === n) { return; }\n      var link = doc.createElement('link');\n      link.rel = 'stylesheet';\n      link.type = 'text/css';\n      if (i + 1 < n) {\n        // http://pieisgood.org/test/script-link-events/ indicates that many\n        // versions of IE do not support onerror on <link>s, though\n        // http://msdn.microsoft.com/en-us/library/ie/ms535848(v=vs.85).aspx\n        // indicates that recent IEs do support error.\n        link.error = link.onerror = function () { load(i + 1); };\n      }\n      link.href = stylesheets[i];\n      head.appendChild(link);\n    }\n    load(0);\n  }\n\n  var scriptQuery = '';\n  // Look for the <script> node that loads this script to get its parameters.\n  // This starts looking at the end instead of just considering the last\n  // because deferred and async scripts run out of order.\n  // If the script is loaded twice, then this will run in reverse order.\n  for (var scripts = doc.scripts, i = scripts.length; --i >= 0;) {\n    var script = scripts[i];\n    var match = script.src.match(\n        /^[^?#]*\\/run_prettify\\.js(\\?[^#]*)?(?:#.*)?$/);\n    if (match) {\n      scriptQuery = match[1] || '';\n      // Remove the script from the DOM so that multiple runs at least run\n      // multiple times even if parameter sets are interpreted in reverse\n      // order.\n      script.parentNode.removeChild(script);\n      break;\n    }\n  }\n\n  // Pull parameters into local variables.\n  var autorun = true;\n  var langs = [];\n  var skins = [];\n  var callbacks = [];\n  scriptQuery.replace(\n      /[?&]([^&=]+)=([^&]+)/g,\n      function (_, name, value) {\n        value = decodeURIComponent(value);\n        name = decodeURIComponent(name);\n        if (name == 'autorun')   { autorun = !/^[0fn]/i.test(value); } else\n        if (name == 'lang')      { langs.push(value);                } else\n        if (name == 'skin')      { skins.push(value);                } else\n        if (name == 'callback')  { callbacks.push(value);            }\n      });\n\n  // Use https to avoid mixed content warnings in client pages and to\n  // prevent a MITM from rewrite prettify mid-flight.\n  // This only works if this script is loaded via https : something\n  // over which we exercise no control.\n  var LOADER_BASE_URL =\n     'https://google-code-prettify.googlecode.com/svn/loader';\n\n  for (var i = 0, n = langs.length; i < n; ++i) (function (lang) {\n    var script = doc.createElement(\"script\");\n\n    // Excerpted from jQuery.ajaxTransport(\"script\") to fire events when\n    // a script is finished loading.\n    // Attach handlers for each script\n    script.onload = script.onerror = script.onreadystatechange = function () {\n      if (script && (\n            !script.readyState || /loaded|complete/.test(script.readyState))) {\n        // Handle memory leak in IE\n        script.onerror = script.onload = script.onreadystatechange = null;\n\n        --pendingLanguages;\n        checkPendingLanguages();\n\n        // Remove the script\n        if (script.parentNode) {\n          script.parentNode.removeChild(script);\n        }\n\n        script = null;\n      }\n    };\n\n    script.type = 'text/javascript';\n    script.src = LOADER_BASE_URL\n      + '/lang-' + encodeURIComponent(langs[i]) + '.js';\n\n    // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending\n    head.insertBefore(script, head.firstChild);\n  })(langs[i]);\n\n  var pendingLanguages = langs.length;\n  function checkPendingLanguages() {\n    if (!pendingLanguages) {\n      setTimeout(onLangsLoaded, 0);\n    }\n  }\n\n  var skinUrls = [];\n  for (var i = 0, n = skins.length; i < n; ++i) {\n    skinUrls.push(LOADER_BASE_URL\n        + '/skins/' + encodeURIComponent(skins[i]) + '.css');\n  }\n  skinUrls.push(LOADER_BASE_URL + '/prettify.css');\n  loadStylesheetsFallingBack(skinUrls);\n\n  var prettyPrint = (function () {\n    // Copyright (C) 2006 Google Inc.\n    //\n    // Licensed under the Apache License, Version 2.0 (the \"License\");\n    // you may not use this file except in compliance with the License.\n    // You may obtain a copy of the License at\n    //\n    //      http://www.apache.org/licenses/LICENSE-2.0\n    //\n    // Unless required by applicable law or agreed to in writing, software\n    // distributed under the License is distributed on an \"AS IS\" BASIS,\n    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    // See the License for the specific language governing permissions and\n    // limitations under the License.\n    \n    \n    /**\n     * @fileoverview\n     * some functions for browser-side pretty printing of code contained in html.\n     *\n     * <p>\n     * For a fairly comprehensive set of languages see the\n     * <a href=\"http://google-code-prettify.googlecode.com/svn/trunk/README.html#langs\">README</a>\n     * file that came with this source.  At a minimum, the lexer should work on a\n     * number of languages including C and friends, Java, Python, Bash, SQL, HTML,\n     * XML, CSS, Javascript, and Makefiles.  It works passably on Ruby, PHP and Awk\n     * and a subset of Perl, but, because of commenting conventions, doesn't work on\n     * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class.\n     * <p>\n     * Usage: <ol>\n     * <li> include this source file in an html page via\n     *   {@code <script type=\"text/javascript\" src=\"/path/to/prettify.js\"></script>}\n     * <li> define style rules.  See the example page for examples.\n     * <li> mark the {@code <pre>} and {@code <code>} tags in your source with\n     *    {@code class=prettyprint.}\n     *    You can also use the (html deprecated) {@code <xmp>} tag, but the pretty\n     *    printer needs to do more substantial DOM manipulations to support that, so\n     *    some css styles may not be preserved.\n     * </ol>\n     * That's it.  I wanted to keep the API as simple as possible, so there's no\n     * need to specify which language the code is in, but if you wish, you can add\n     * another class to the {@code <pre>} or {@code <code>} element to specify the\n     * language, as in {@code <pre class=\"prettyprint lang-java\">}.  Any class that\n     * starts with \"lang-\" followed by a file extension, specifies the file type.\n     * See the \"lang-*.js\" files in this directory for code that implements\n     * per-language file handlers.\n     * <p>\n     * Change log:<br>\n     * cbeust, 2006/08/22\n     * <blockquote>\n     *   Java annotations (start with \"@\") are now captured as literals (\"lit\")\n     * </blockquote>\n     * @requires console\n     */\n    \n    // JSLint declarations\n    /*global console, document, navigator, setTimeout, window, define */\n    \n    /**\n     * Split {@code prettyPrint} into multiple timeouts so as not to interfere with\n     * UI events.\n     * If set to {@code false}, {@code prettyPrint()} is synchronous.\n     */\n    window['PR_SHOULD_USE_CONTINUATION'] = true;\n    \n    /**\n     * Pretty print a chunk of code.\n     * @param {string} sourceCodeHtml The HTML to pretty print.\n     * @param {string} opt_langExtension The language name to use.\n     *     Typically, a filename extension like 'cpp' or 'java'.\n     * @param {number|boolean} opt_numberLines True to number lines,\n     *     or the 1-indexed number of the first line in sourceCodeHtml.\n     * @return {string} code as html, but prettier\n     */\n    var prettyPrintOne;\n    /**\n     * Find all the {@code <pre>} and {@code <code>} tags in the DOM with\n     * {@code class=prettyprint} and prettify them.\n     *\n     * @param {Function} opt_whenDone called when prettifying is done.\n     * @param {HTMLElement|HTMLDocument} opt_root an element or document\n     *   containing all the elements to pretty print.\n     *   Defaults to {@code document.body}.\n     */\n    var prettyPrint;\n    \n    \n    (function () {\n      var win = window;\n      // Keyword lists for various languages.\n      // We use things that coerce to strings to make them compact when minified\n      // and to defeat aggressive optimizers that fold large string constants.\n      var FLOW_CONTROL_KEYWORDS = [\"break,continue,do,else,for,if,return,while\"];\n      var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,\"auto,case,char,const,default,\" + \n          \"double,enum,extern,float,goto,inline,int,long,register,short,signed,\" +\n          \"sizeof,static,struct,switch,typedef,union,unsigned,void,volatile\"];\n      var COMMON_KEYWORDS = [C_KEYWORDS,\"catch,class,delete,false,import,\" +\n          \"new,operator,private,protected,public,this,throw,true,try,typeof\"];\n      var CPP_KEYWORDS = [COMMON_KEYWORDS,\"alignof,align_union,asm,axiom,bool,\" +\n          \"concept,concept_map,const_cast,constexpr,decltype,delegate,\" +\n          \"dynamic_cast,explicit,export,friend,generic,late_check,\" +\n          \"mutable,namespace,nullptr,property,reinterpret_cast,static_assert,\" +\n          \"static_cast,template,typeid,typename,using,virtual,where\"];\n      var JAVA_KEYWORDS = [COMMON_KEYWORDS,\n          \"abstract,assert,boolean,byte,extends,final,finally,implements,import,\" +\n          \"instanceof,interface,null,native,package,strictfp,super,synchronized,\" +\n          \"throws,transient\"];\n      var CSHARP_KEYWORDS = [JAVA_KEYWORDS,\n          \"as,base,by,checked,decimal,delegate,descending,dynamic,event,\" +\n          \"fixed,foreach,from,group,implicit,in,internal,into,is,let,\" +\n          \"lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,\" +\n          \"sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,\" +\n          \"var,virtual,where\"];\n      var COFFEE_KEYWORDS = \"all,and,by,catch,class,else,extends,false,finally,\" +\n          \"for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,\" +\n          \"throw,true,try,unless,until,when,while,yes\";\n      var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS,\n          \"debugger,eval,export,function,get,null,set,undefined,var,with,\" +\n          \"Infinity,NaN\"];\n      var PERL_KEYWORDS = \"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,\" +\n          \"goto,if,import,last,local,my,next,no,our,print,package,redo,require,\" +\n          \"sub,undef,unless,until,use,wantarray,while,BEGIN,END\";\n      var PYTHON_KEYWORDS = [FLOW_CONTROL_KEYWORDS, \"and,as,assert,class,def,del,\" +\n          \"elif,except,exec,finally,from,global,import,in,is,lambda,\" +\n          \"nonlocal,not,or,pass,print,raise,try,with,yield,\" +\n          \"False,True,None\"];\n      var RUBY_KEYWORDS = [FLOW_CONTROL_KEYWORDS, \"alias,and,begin,case,class,\" +\n          \"def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,\" +\n          \"rescue,retry,self,super,then,true,undef,unless,until,when,yield,\" +\n          \"BEGIN,END\"];\n       var RUST_KEYWORDS = [FLOW_CONTROL_KEYWORDS, \"as,assert,const,copy,drop,\" +\n          \"enum,extern,fail,false,fn,impl,let,log,loop,match,mod,move,mut,priv,\" +\n          \"pub,pure,ref,self,static,struct,true,trait,type,unsafe,use\"];\n      var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, \"case,done,elif,esac,eval,fi,\" +\n          \"function,in,local,set,then,until\"];\n      var ALL_KEYWORDS = [\n          CPP_KEYWORDS, CSHARP_KEYWORDS, JSCRIPT_KEYWORDS, PERL_KEYWORDS,\n          PYTHON_KEYWORDS, RUBY_KEYWORDS, SH_KEYWORDS];\n      var C_TYPES = /^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\\d*)\\b/;\n    \n      // token style names.  correspond to css classes\n      /**\n       * token style for a string literal\n       * @const\n       */\n      var PR_STRING = 'str';\n      /**\n       * token style for a keyword\n       * @const\n       */\n      var PR_KEYWORD = 'kwd';\n      /**\n       * token style for a comment\n       * @const\n       */\n      var PR_COMMENT = 'com';\n      /**\n       * token style for a type\n       * @const\n       */\n      var PR_TYPE = 'typ';\n      /**\n       * token style for a literal value.  e.g. 1, null, true.\n       * @const\n       */\n      var PR_LITERAL = 'lit';\n      /**\n       * token style for a punctuation string.\n       * @const\n       */\n      var PR_PUNCTUATION = 'pun';\n      /**\n       * token style for plain text.\n       * @const\n       */\n      var PR_PLAIN = 'pln';\n    \n      /**\n       * token style for an sgml tag.\n       * @const\n       */\n      var PR_TAG = 'tag';\n      /**\n       * token style for a markup declaration such as a DOCTYPE.\n       * @const\n       */\n      var PR_DECLARATION = 'dec';\n      /**\n       * token style for embedded source.\n       * @const\n       */\n      var PR_SOURCE = 'src';\n      /**\n       * token style for an sgml attribute name.\n       * @const\n       */\n      var PR_ATTRIB_NAME = 'atn';\n      /**\n       * token style for an sgml attribute value.\n       * @const\n       */\n      var PR_ATTRIB_VALUE = 'atv';\n    \n      /**\n       * A class that indicates a section of markup that is not code, e.g. to allow\n       * embedding of line numbers within code listings.\n       * @const\n       */\n      var PR_NOCODE = 'nocode';\n    \n      \n      \n      /**\n       * A set of tokens that can precede a regular expression literal in\n       * javascript\n       * http://web.archive.org/web/20070717142515/http://www.mozilla.org/js/language/js20/rationale/syntax.html\n       * has the full list, but I've removed ones that might be problematic when\n       * seen in languages that don't support regular expression literals.\n       *\n       * <p>Specifically, I've removed any keywords that can't precede a regexp\n       * literal in a syntactically legal javascript program, and I've removed the\n       * \"in\" keyword since it's not a keyword in many languages, and might be used\n       * as a count of inches.\n       *\n       * <p>The link above does not accurately describe EcmaScript rules since\n       * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works\n       * very well in practice.\n       *\n       * @private\n       * @const\n       */\n      var REGEXP_PRECEDER_PATTERN = '(?:^^\\\\.?|[+-]|[!=]=?=?|\\\\#|%=?|&&?=?|\\\\(|\\\\*=?|[+\\\\-]=|->|\\\\/=?|::?|<<?=?|>>?>?=?|,|;|\\\\?|@|\\\\[|~|{|\\\\^\\\\^?=?|\\\\|\\\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\\\s*';\n      \n      // CAVEAT: this does not properly handle the case where a regular\n      // expression immediately follows another since a regular expression may\n      // have flags for case-sensitivity and the like.  Having regexp tokens\n      // adjacent is not valid in any language I'm aware of, so I'm punting.\n      // TODO: maybe style special characters inside a regexp as punctuation.\n    \n      /**\n       * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally\n       * matches the union of the sets of strings matched by the input RegExp.\n       * Since it matches globally, if the input strings have a start-of-input\n       * anchor (/^.../), it is ignored for the purposes of unioning.\n       * @param {Array.<RegExp>} regexs non multiline, non-global regexs.\n       * @return {RegExp} a global regex.\n       */\n      function combinePrefixPatterns(regexs) {\n        var capturedGroupIndex = 0;\n      \n        var needToFoldCase = false;\n        var ignoreCase = false;\n        for (var i = 0, n = regexs.length; i < n; ++i) {\n          var regex = regexs[i];\n          if (regex.ignoreCase) {\n            ignoreCase = true;\n          } else if (/[a-z]/i.test(regex.source.replace(\n                         /\\\\u[0-9a-f]{4}|\\\\x[0-9a-f]{2}|\\\\[^ux]/gi, ''))) {\n            needToFoldCase = true;\n            ignoreCase = false;\n            break;\n          }\n        }\n      \n        var escapeCharToCodeUnit = {\n          'b': 8,\n          't': 9,\n          'n': 0xa,\n          'v': 0xb,\n          'f': 0xc,\n          'r': 0xd\n        };\n      \n        function decodeEscape(charsetPart) {\n          var cc0 = charsetPart.charCodeAt(0);\n          if (cc0 !== 92 /* \\\\ */) {\n            return cc0;\n          }\n          var c1 = charsetPart.charAt(1);\n          cc0 = escapeCharToCodeUnit[c1];\n          if (cc0) {\n            return cc0;\n          } else if ('0' <= c1 && c1 <= '7') {\n            return parseInt(charsetPart.substring(1), 8);\n          } else if (c1 === 'u' || c1 === 'x') {\n            return parseInt(charsetPart.substring(2), 16);\n          } else {\n            return charsetPart.charCodeAt(1);\n          }\n        }\n      \n        function encodeEscape(charCode) {\n          if (charCode < 0x20) {\n            return (charCode < 0x10 ? '\\\\x0' : '\\\\x') + charCode.toString(16);\n          }\n          var ch = String.fromCharCode(charCode);\n          return (ch === '\\\\' || ch === '-' || ch === ']' || ch === '^')\n              ? \"\\\\\" + ch : ch;\n        }\n      \n        function caseFoldCharset(charSet) {\n          var charsetParts = charSet.substring(1, charSet.length - 1).match(\n              new RegExp(\n                  '\\\\\\\\u[0-9A-Fa-f]{4}'\n                  + '|\\\\\\\\x[0-9A-Fa-f]{2}'\n                  + '|\\\\\\\\[0-3][0-7]{0,2}'\n                  + '|\\\\\\\\[0-7]{1,2}'\n                  + '|\\\\\\\\[\\\\s\\\\S]'\n                  + '|-'\n                  + '|[^-\\\\\\\\]',\n                  'g'));\n          var ranges = [];\n          var inverse = charsetParts[0] === '^';\n      \n          var out = ['['];\n          if (inverse) { out.push('^'); }\n      \n          for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {\n            var p = charsetParts[i];\n            if (/\\\\[bdsw]/i.test(p)) {  // Don't muck with named groups.\n              out.push(p);\n            } else {\n              var start = decodeEscape(p);\n              var end;\n              if (i + 2 < n && '-' === charsetParts[i + 1]) {\n                end = decodeEscape(charsetParts[i + 2]);\n                i += 2;\n              } else {\n                end = start;\n              }\n              ranges.push([start, end]);\n              // If the range might intersect letters, then expand it.\n              // This case handling is too simplistic.\n              // It does not deal with non-latin case folding.\n              // It works for latin source code identifiers though.\n              if (!(end < 65 || start > 122)) {\n                if (!(end < 65 || start > 90)) {\n                  ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);\n                }\n                if (!(end < 97 || start > 122)) {\n                  ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);\n                }\n              }\n            }\n          }\n      \n          // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]\n          // -> [[1, 12], [14, 14], [16, 17]]\n          ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1]  - a[1]); });\n          var consolidatedRanges = [];\n          var lastRange = [];\n          for (var i = 0; i < ranges.length; ++i) {\n            var range = ranges[i];\n            if (range[0] <= lastRange[1] + 1) {\n              lastRange[1] = Math.max(lastRange[1], range[1]);\n            } else {\n              consolidatedRanges.push(lastRange = range);\n            }\n          }\n      \n          for (var i = 0; i < consolidatedRanges.length; ++i) {\n            var range = consolidatedRanges[i];\n            out.push(encodeEscape(range[0]));\n            if (range[1] > range[0]) {\n              if (range[1] + 1 > range[0]) { out.push('-'); }\n              out.push(encodeEscape(range[1]));\n            }\n          }\n          out.push(']');\n          return out.join('');\n        }\n      \n        function allowAnywhereFoldCaseAndRenumberGroups(regex) {\n          // Split into character sets, escape sequences, punctuation strings\n          // like ('(', '(?:', ')', '^'), and runs of characters that do not\n          // include any of the above.\n          var parts = regex.source.match(\n              new RegExp(\n                  '(?:'\n                  + '\\\\[(?:[^\\\\x5C\\\\x5D]|\\\\\\\\[\\\\s\\\\S])*\\\\]'  // a character set\n                  + '|\\\\\\\\u[A-Fa-f0-9]{4}'  // a unicode escape\n                  + '|\\\\\\\\x[A-Fa-f0-9]{2}'  // a hex escape\n                  + '|\\\\\\\\[0-9]+'  // a back-reference or octal escape\n                  + '|\\\\\\\\[^ux0-9]'  // other escape sequence\n                  + '|\\\\(\\\\?[:!=]'  // start of a non-capturing group\n                  + '|[\\\\(\\\\)\\\\^]'  // start/end of a group, or line start\n                  + '|[^\\\\x5B\\\\x5C\\\\(\\\\)\\\\^]+'  // run of other characters\n                  + ')',\n                  'g'));\n          var n = parts.length;\n      \n          // Maps captured group numbers to the number they will occupy in\n          // the output or to -1 if that has not been determined, or to\n          // undefined if they need not be capturing in the output.\n          var capturedGroups = [];\n      \n          // Walk over and identify back references to build the capturedGroups\n          // mapping.\n          for (var i = 0, groupIndex = 0; i < n; ++i) {\n            var p = parts[i];\n            if (p === '(') {\n              // groups are 1-indexed, so max group index is count of '('\n              ++groupIndex;\n            } else if ('\\\\' === p.charAt(0)) {\n              var decimalValue = +p.substring(1);\n              if (decimalValue) {\n                if (decimalValue <= groupIndex) {\n                  capturedGroups[decimalValue] = -1;\n                } else {\n                  // Replace with an unambiguous escape sequence so that\n                  // an octal escape sequence does not turn into a backreference\n                  // to a capturing group from an earlier regex.\n                  parts[i] = encodeEscape(decimalValue);\n                }\n              }\n            }\n          }\n      \n          // Renumber groups and reduce capturing groups to non-capturing groups\n          // where possible.\n          for (var i = 1; i < capturedGroups.length; ++i) {\n            if (-1 === capturedGroups[i]) {\n              capturedGroups[i] = ++capturedGroupIndex;\n            }\n          }\n          for (var i = 0, groupIndex = 0; i < n; ++i) {\n            var p = parts[i];\n            if (p === '(') {\n              ++groupIndex;\n              if (!capturedGroups[groupIndex]) {\n                parts[i] = '(?:';\n              }\n            } else if ('\\\\' === p.charAt(0)) {\n              var decimalValue = +p.substring(1);\n              if (decimalValue && decimalValue <= groupIndex) {\n                parts[i] = '\\\\' + capturedGroups[decimalValue];\n              }\n            }\n          }\n      \n          // Remove any prefix anchors so that the output will match anywhere.\n          // ^^ really does mean an anchored match though.\n          for (var i = 0; i < n; ++i) {\n            if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }\n          }\n      \n          // Expand letters to groups to handle mixing of case-sensitive and\n          // case-insensitive patterns if necessary.\n          if (regex.ignoreCase && needToFoldCase) {\n            for (var i = 0; i < n; ++i) {\n              var p = parts[i];\n              var ch0 = p.charAt(0);\n              if (p.length >= 2 && ch0 === '[') {\n                parts[i] = caseFoldCharset(p);\n              } else if (ch0 !== '\\\\') {\n                // TODO: handle letters in numeric escapes.\n                parts[i] = p.replace(\n                    /[a-zA-Z]/g,\n                    function (ch) {\n                      var cc = ch.charCodeAt(0);\n                      return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';\n                    });\n              }\n            }\n          }\n      \n          return parts.join('');\n        }\n      \n        var rewritten = [];\n        for (var i = 0, n = regexs.length; i < n; ++i) {\n          var regex = regexs[i];\n          if (regex.global || regex.multiline) { throw new Error('' + regex); }\n          rewritten.push(\n              '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');\n        }\n      \n        return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');\n      }\n    \n      /**\n       * Split markup into a string of source code and an array mapping ranges in\n       * that string to the text nodes in which they appear.\n       *\n       * <p>\n       * The HTML DOM structure:</p>\n       * <pre>\n       * (Element   \"p\"\n       *   (Element \"b\"\n       *     (Text  \"print \"))       ; #1\n       *   (Text    \"'Hello '\")      ; #2\n       *   (Element \"br\")            ; #3\n       *   (Text    \"  + 'World';\")) ; #4\n       * </pre>\n       * <p>\n       * corresponds to the HTML\n       * {@code <p><b>print </b>'Hello '<br>  + 'World';</p>}.</p>\n       *\n       * <p>\n       * It will produce the output:</p>\n       * <pre>\n       * {\n       *   sourceCode: \"print 'Hello '\\n  + 'World';\",\n       *   //                     1          2\n       *   //           012345678901234 5678901234567\n       *   spans: [0, #1, 6, #2, 14, #3, 15, #4]\n       * }\n       * </pre>\n       * <p>\n       * where #1 is a reference to the {@code \"print \"} text node above, and so\n       * on for the other text nodes.\n       * </p>\n       *\n       * <p>\n       * The {@code} spans array is an array of pairs.  Even elements are the start\n       * indices of substrings, and odd elements are the text nodes (or BR elements)\n       * that contain the text for those substrings.\n       * Substrings continue until the next index or the end of the source.\n       * </p>\n       *\n       * @param {Node} node an HTML DOM subtree containing source-code.\n       * @param {boolean} isPreformatted true if white-space in text nodes should\n       *    be considered significant.\n       * @return {Object} source code and the text nodes in which they occur.\n       */\n      function extractSourceSpans(node, isPreformatted) {\n        var nocode = /(?:^|\\s)nocode(?:\\s|$)/;\n      \n        var chunks = [];\n        var length = 0;\n        var spans = [];\n        var k = 0;\n      \n        function walk(node) {\n          var type = node.nodeType;\n          if (type == 1) {  // Element\n            if (nocode.test(node.className)) { return; }\n            for (var child = node.firstChild; child; child = child.nextSibling) {\n              walk(child);\n            }\n            var nodeName = node.nodeName.toLowerCase();\n            if ('br' === nodeName || 'li' === nodeName) {\n              chunks[k] = '\\n';\n              spans[k << 1] = length++;\n              spans[(k++ << 1) | 1] = node;\n            }\n          } else if (type == 3 || type == 4) {  // Text\n            var text = node.nodeValue;\n            if (text.length) {\n              if (!isPreformatted) {\n                text = text.replace(/[ \\t\\r\\n]+/g, ' ');\n              } else {\n                text = text.replace(/\\r\\n?/g, '\\n');  // Normalize newlines.\n              }\n              // TODO: handle tabs here?\n              chunks[k] = text;\n              spans[k << 1] = length;\n              length += text.length;\n              spans[(k++ << 1) | 1] = node;\n            }\n          }\n        }\n      \n        walk(node);\n      \n        return {\n          sourceCode: chunks.join('').replace(/\\n$/, ''),\n          spans: spans\n        };\n      }\n    \n      /**\n       * Apply the given language handler to sourceCode and add the resulting\n       * decorations to out.\n       * @param {number} basePos the index of sourceCode within the chunk of source\n       *    whose decorations are already present on out.\n       */\n      function appendDecorations(basePos, sourceCode, langHandler, out) {\n        if (!sourceCode) { return; }\n        var job = {\n          sourceCode: sourceCode,\n          basePos: basePos\n        };\n        langHandler(job);\n        out.push.apply(out, job.decorations);\n      }\n    \n      var notWs = /\\S/;\n    \n      /**\n       * Given an element, if it contains only one child element and any text nodes\n       * it contains contain only space characters, return the sole child element.\n       * Otherwise returns undefined.\n       * <p>\n       * This is meant to return the CODE element in {@code <pre><code ...>} when\n       * there is a single child element that contains all the non-space textual\n       * content, but not to return anything where there are multiple child elements\n       * as in {@code <pre><code>...</code><code>...</code></pre>} or when there\n       * is textual content.\n       */\n      function childContentWrapper(element) {\n        var wrapper = undefined;\n        for (var c = element.firstChild; c; c = c.nextSibling) {\n          var type = c.nodeType;\n          wrapper = (type === 1)  // Element Node\n              ? (wrapper ? element : c)\n              : (type === 3)  // Text Node\n              ? (notWs.test(c.nodeValue) ? element : wrapper)\n              : wrapper;\n        }\n        return wrapper === element ? undefined : wrapper;\n      }\n    \n      /** Given triples of [style, pattern, context] returns a lexing function,\n        * The lexing function interprets the patterns to find token boundaries and\n        * returns a decoration list of the form\n        * [index_0, style_0, index_1, style_1, ..., index_n, style_n]\n        * where index_n is an index into the sourceCode, and style_n is a style\n        * constant like PR_PLAIN.  index_n-1 <= index_n, and style_n-1 applies to\n        * all characters in sourceCode[index_n-1:index_n].\n        *\n        * The stylePatterns is a list whose elements have the form\n        * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].\n        *\n        * Style is a style constant like PR_PLAIN, or can be a string of the\n        * form 'lang-FOO', where FOO is a language extension describing the\n        * language of the portion of the token in $1 after pattern executes.\n        * E.g., if style is 'lang-lisp', and group 1 contains the text\n        * '(hello (world))', then that portion of the token will be passed to the\n        * registered lisp handler for formatting.\n        * The text before and after group 1 will be restyled using this decorator\n        * so decorators should take care that this doesn't result in infinite\n        * recursion.  For example, the HTML lexer rule for SCRIPT elements looks\n        * something like ['lang-js', /<[s]cript>(.+?)<\\/script>/].  This may match\n        * '<script>foo()<\\/script>', which would cause the current decorator to\n        * be called with '<script>' which would not match the same rule since\n        * group 1 must not be empty, so it would be instead styled as PR_TAG by\n        * the generic tag rule.  The handler registered for the 'js' extension would\n        * then be called with 'foo()', and finally, the current decorator would\n        * be called with '<\\/script>' which would not match the original rule and\n        * so the generic tag rule would identify it as a tag.\n        *\n        * Pattern must only match prefixes, and if it matches a prefix, then that\n        * match is considered a token with the same style.\n        *\n        * Context is applied to the last non-whitespace, non-comment token\n        * recognized.\n        *\n        * Shortcut is an optional string of characters, any of which, if the first\n        * character, gurantee that this pattern and only this pattern matches.\n        *\n        * @param {Array} shortcutStylePatterns patterns that always start with\n        *   a known character.  Must have a shortcut string.\n        * @param {Array} fallthroughStylePatterns patterns that will be tried in\n        *   order if the shortcut ones fail.  May have shortcuts.\n        *\n        * @return {function (Object)} a\n        *   function that takes source code and returns a list of decorations.\n        */\n      function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {\n        var shortcuts = {};\n        var tokenizer;\n        (function () {\n          var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);\n          var allRegexs = [];\n          var regexKeys = {};\n          for (var i = 0, n = allPatterns.length; i < n; ++i) {\n            var patternParts = allPatterns[i];\n            var shortcutChars = patternParts[3];\n            if (shortcutChars) {\n              for (var c = shortcutChars.length; --c >= 0;) {\n                shortcuts[shortcutChars.charAt(c)] = patternParts;\n              }\n            }\n            var regex = patternParts[1];\n            var k = '' + regex;\n            if (!regexKeys.hasOwnProperty(k)) {\n              allRegexs.push(regex);\n              regexKeys[k] = null;\n            }\n          }\n          allRegexs.push(/[\\0-\\uffff]/);\n          tokenizer = combinePrefixPatterns(allRegexs);\n        })();\n    \n        var nPatterns = fallthroughStylePatterns.length;\n    \n        /**\n         * Lexes job.sourceCode and produces an output array job.decorations of\n         * style classes preceded by the position at which they start in\n         * job.sourceCode in order.\n         *\n         * @param {Object} job an object like <pre>{\n         *    sourceCode: {string} sourceText plain text,\n         *    basePos: {int} position of job.sourceCode in the larger chunk of\n         *        sourceCode.\n         * }</pre>\n         */\n        var decorate = function (job) {\n          var sourceCode = job.sourceCode, basePos = job.basePos;\n          /** Even entries are positions in source in ascending order.  Odd enties\n            * are style markers (e.g., PR_COMMENT) that run from that position until\n            * the end.\n            * @type {Array.<number|string>}\n            */\n          var decorations = [basePos, PR_PLAIN];\n          var pos = 0;  // index into sourceCode\n          var tokens = sourceCode.match(tokenizer) || [];\n          var styleCache = {};\n    \n          for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {\n            var token = tokens[ti];\n            var style = styleCache[token];\n            var match = void 0;\n    \n            var isEmbedded;\n            if (typeof style === 'string') {\n              isEmbedded = false;\n            } else {\n              var patternParts = shortcuts[token.charAt(0)];\n              if (patternParts) {\n                match = token.match(patternParts[1]);\n                style = patternParts[0];\n              } else {\n                for (var i = 0; i < nPatterns; ++i) {\n                  patternParts = fallthroughStylePatterns[i];\n                  match = token.match(patternParts[1]);\n                  if (match) {\n                    style = patternParts[0];\n                    break;\n                  }\n                }\n    \n                if (!match) {  // make sure that we make progress\n                  style = PR_PLAIN;\n                }\n              }\n    \n              isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);\n              if (isEmbedded && !(match && typeof match[1] === 'string')) {\n                isEmbedded = false;\n                style = PR_SOURCE;\n              }\n    \n              if (!isEmbedded) { styleCache[token] = style; }\n            }\n    \n            var tokenStart = pos;\n            pos += token.length;\n    \n            if (!isEmbedded) {\n              decorations.push(basePos + tokenStart, style);\n            } else {  // Treat group 1 as an embedded block of source code.\n              var embeddedSource = match[1];\n              var embeddedSourceStart = token.indexOf(embeddedSource);\n              var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;\n              if (match[2]) {\n                // If embeddedSource can be blank, then it would match at the\n                // beginning which would cause us to infinitely recurse on the\n                // entire token, so we catch the right context in match[2].\n                embeddedSourceEnd = token.length - match[2].length;\n                embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;\n              }\n              var lang = style.substring(5);\n              // Decorate the left of the embedded source\n              appendDecorations(\n                  basePos + tokenStart,\n                  token.substring(0, embeddedSourceStart),\n                  decorate, decorations);\n              // Decorate the embedded source\n              appendDecorations(\n                  basePos + tokenStart + embeddedSourceStart,\n                  embeddedSource,\n                  langHandlerForExtension(lang, embeddedSource),\n                  decorations);\n              // Decorate the right of the embedded section\n              appendDecorations(\n                  basePos + tokenStart + embeddedSourceEnd,\n                  token.substring(embeddedSourceEnd),\n                  decorate, decorations);\n            }\n          }\n          job.decorations = decorations;\n        };\n        return decorate;\n      }\n    \n      /** returns a function that produces a list of decorations from source text.\n        *\n        * This code treats \", ', and ` as string delimiters, and \\ as a string\n        * escape.  It does not recognize perl's qq() style strings.\n        * It has no special handling for double delimiter escapes as in basic, or\n        * the tripled delimiters used in python, but should work on those regardless\n        * although in those cases a single string literal may be broken up into\n        * multiple adjacent string literals.\n        *\n        * It recognizes C, C++, and shell style comments.\n        *\n        * @param {Object} options a set of optional parameters.\n        * @return {function (Object)} a function that examines the source code\n        *     in the input job and builds the decoration list.\n        */\n      function sourceDecorator(options) {\n        var shortcutStylePatterns = [], fallthroughStylePatterns = [];\n        if (options['tripleQuotedStrings']) {\n          // '''multi-line-string''', 'single-line-string', and double-quoted\n          shortcutStylePatterns.push(\n              [PR_STRING,  /^(?:\\'\\'\\'(?:[^\\'\\\\]|\\\\[\\s\\S]|\\'{1,2}(?=[^\\']))*(?:\\'\\'\\'|$)|\\\"\\\"\\\"(?:[^\\\"\\\\]|\\\\[\\s\\S]|\\\"{1,2}(?=[^\\\"]))*(?:\\\"\\\"\\\"|$)|\\'(?:[^\\\\\\']|\\\\[\\s\\S])*(?:\\'|$)|\\\"(?:[^\\\\\\\"]|\\\\[\\s\\S])*(?:\\\"|$))/,\n               null, '\\'\"']);\n        } else if (options['multiLineStrings']) {\n          // 'multi-line-string', \"multi-line-string\"\n          shortcutStylePatterns.push(\n              [PR_STRING,  /^(?:\\'(?:[^\\\\\\']|\\\\[\\s\\S])*(?:\\'|$)|\\\"(?:[^\\\\\\\"]|\\\\[\\s\\S])*(?:\\\"|$)|\\`(?:[^\\\\\\`]|\\\\[\\s\\S])*(?:\\`|$))/,\n               null, '\\'\"`']);\n        } else {\n          // 'single-line-string', \"single-line-string\"\n          shortcutStylePatterns.push(\n              [PR_STRING,\n               /^(?:\\'(?:[^\\\\\\'\\r\\n]|\\\\.)*(?:\\'|$)|\\\"(?:[^\\\\\\\"\\r\\n]|\\\\.)*(?:\\\"|$))/,\n               null, '\"\\'']);\n        }\n        if (options['verbatimStrings']) {\n          // verbatim-string-literal production from the C# grammar.  See issue 93.\n          fallthroughStylePatterns.push(\n              [PR_STRING, /^@\\\"(?:[^\\\"]|\\\"\\\")*(?:\\\"|$)/, null]);\n        }\n        var hc = options['hashComments'];\n        if (hc) {\n          if (options['cStyleComments']) {\n            if (hc > 1) {  // multiline hash comments\n              shortcutStylePatterns.push(\n                  [PR_COMMENT, /^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/, null, '#']);\n            } else {\n              // Stop C preprocessor declarations at an unclosed open comment\n              shortcutStylePatterns.push(\n                  [PR_COMMENT, /^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\\b|[^\\r\\n]*)/,\n                   null, '#']);\n            }\n            // #include <stdio.h>\n            fallthroughStylePatterns.push(\n                [PR_STRING,\n                 /^<(?:(?:(?:\\.\\.\\/)*|\\/?)(?:[\\w-]+(?:\\/[\\w-]+)+)?[\\w-]+\\.h(?:h|pp|\\+\\+)?|[a-z]\\w*)>/,\n                 null]);\n          } else {\n            shortcutStylePatterns.push([PR_COMMENT, /^#[^\\r\\n]*/, null, '#']);\n          }\n        }\n        if (options['cStyleComments']) {\n          fallthroughStylePatterns.push([PR_COMMENT, /^\\/\\/[^\\r\\n]*/, null]);\n          fallthroughStylePatterns.push(\n              [PR_COMMENT, /^\\/\\*[\\s\\S]*?(?:\\*\\/|$)/, null]);\n        }\n        var regexLiterals = options['regexLiterals'];\n        if (regexLiterals) {\n          /**\n           * @const\n           */\n          var regexExcls = regexLiterals > 1\n            ? ''  // Multiline regex literals\n            : '\\n\\r';\n          /**\n           * @const\n           */\n          var regexAny = regexExcls ? '.' : '[\\\\S\\\\s]';\n          /**\n           * @const\n           */\n          var REGEX_LITERAL = (\n              // A regular expression literal starts with a slash that is\n              // not followed by * or / so that it is not confused with\n              // comments.\n              '/(?=[^/*' + regexExcls + '])'\n              // and then contains any number of raw characters,\n              + '(?:[^/\\\\x5B\\\\x5C' + regexExcls + ']'\n              // escape sequences (\\x5C),\n              +    '|\\\\x5C' + regexAny\n              // or non-nesting character sets (\\x5B\\x5D);\n              +    '|\\\\x5B(?:[^\\\\x5C\\\\x5D' + regexExcls + ']'\n              +             '|\\\\x5C' + regexAny + ')*(?:\\\\x5D|$))+'\n              // finally closed by a /.\n              + '/');\n          fallthroughStylePatterns.push(\n              ['lang-regex',\n               RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')\n               ]);\n        }\n    \n        var types = options['types'];\n        if (types) {\n          fallthroughStylePatterns.push([PR_TYPE, types]);\n        }\n    \n        var keywords = (\"\" + options['keywords']).replace(/^ | $/g, '');\n        if (keywords.length) {\n          fallthroughStylePatterns.push(\n              [PR_KEYWORD,\n               new RegExp('^(?:' + keywords.replace(/[\\s,]+/g, '|') + ')\\\\b'),\n               null]);\n        }\n    \n        shortcutStylePatterns.push([PR_PLAIN,       /^\\s+/, null, ' \\r\\n\\t\\xA0']);\n    \n        var punctuation =\n          // The Bash man page says\n    \n          // A word is a sequence of characters considered as a single\n          // unit by GRUB. Words are separated by metacharacters,\n          // which are the following plus space, tab, and newline: { }\n          // | & $ ; < >\n          // ...\n          \n          // A word beginning with # causes that word and all remaining\n          // characters on that line to be ignored.\n    \n          // which means that only a '#' after /(?:^|[{}|&$;<>\\s])/ starts a\n          // comment but empirically\n          // $ echo {#}\n          // {#}\n          // $ echo \\$#\n          // $#\n          // $ echo }#\n          // }#\n    \n          // so /(?:^|[|&;<>\\s])/ is more appropriate.\n    \n          // http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC3\n          // suggests that this definition is compatible with a\n          // default mode that tries to use a single token definition\n          // to recognize both bash/python style comments and C\n          // preprocessor directives.\n    \n          // This definition of punctuation does not include # in the list of\n          // follow-on exclusions, so # will not be broken before if preceeded\n          // by a punctuation character.  We could try to exclude # after\n          // [|&;<>] but that doesn't seem to cause many major problems.\n          // If that does turn out to be a problem, we should change the below\n          // when hc is truthy to include # in the run of punctuation characters\n          // only when not followint [|&;<>].\n          '^.[^\\\\s\\\\w.$@\\'\"`/\\\\\\\\]*';\n        if (options['regexLiterals']) {\n          punctuation += '(?!\\s*\\/)';\n        }\n    \n        fallthroughStylePatterns.push(\n            // TODO(mikesamuel): recognize non-latin letters and numerals in idents\n            [PR_LITERAL,     /^@[a-z_$][a-z_$@0-9]*/i, null],\n            [PR_TYPE,        /^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\\w+_t\\b)/, null],\n            [PR_PLAIN,       /^[a-z_$][a-z_$@0-9]*/i, null],\n            [PR_LITERAL,\n             new RegExp(\n                 '^(?:'\n                 // A hex number\n                 + '0x[a-f0-9]+'\n                 // or an octal or decimal number,\n                 + '|(?:\\\\d(?:_\\\\d+)*\\\\d*(?:\\\\.\\\\d*)?|\\\\.\\\\d\\\\+)'\n                 // possibly in scientific notation\n                 + '(?:e[+\\\\-]?\\\\d+)?'\n                 + ')'\n                 // with an optional modifier like UL for unsigned long\n                 + '[a-z]*', 'i'),\n             null, '0123456789'],\n            // Don't treat escaped quotes in bash as starting strings.\n            // See issue 144.\n            [PR_PLAIN,       /^\\\\[\\s\\S]?/, null],\n            [PR_PUNCTUATION, new RegExp(punctuation), null]);\n    \n        return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);\n      }\n    \n      var decorateSource = sourceDecorator({\n            'keywords': ALL_KEYWORDS,\n            'hashComments': true,\n            'cStyleComments': true,\n            'multiLineStrings': true,\n            'regexLiterals': true\n          });\n    \n      /**\n       * Given a DOM subtree, wraps it in a list, and puts each line into its own\n       * list item.\n       *\n       * @param {Node} node modified in place.  Its content is pulled into an\n       *     HTMLOListElement, and each line is moved into a separate list item.\n       *     This requires cloning elements, so the input might not have unique\n       *     IDs after numbering.\n       * @param {boolean} isPreformatted true iff white-space in text nodes should\n       *     be treated as significant.\n       */\n      function numberLines(node, opt_startLineNum, isPreformatted) {\n        var nocode = /(?:^|\\s)nocode(?:\\s|$)/;\n        var lineBreak = /\\r\\n?|\\n/;\n      \n        var document = node.ownerDocument;\n      \n        var li = document.createElement('li');\n        while (node.firstChild) {\n          li.appendChild(node.firstChild);\n        }\n        // An array of lines.  We split below, so this is initialized to one\n        // un-split line.\n        var listItems = [li];\n      \n        function walk(node) {\n          var type = node.nodeType;\n          if (type == 1 && !nocode.test(node.className)) {  // Element\n            if ('br' === node.nodeName) {\n              breakAfter(node);\n              // Discard the <BR> since it is now flush against a </LI>.\n              if (node.parentNode) {\n                node.parentNode.removeChild(node);\n              }\n            } else {\n              for (var child = node.firstChild; child; child = child.nextSibling) {\n                walk(child);\n              }\n            }\n          } else if ((type == 3 || type == 4) && isPreformatted) {  // Text\n            var text = node.nodeValue;\n            var match = text.match(lineBreak);\n            if (match) {\n              var firstLine = text.substring(0, match.index);\n              node.nodeValue = firstLine;\n              var tail = text.substring(match.index + match[0].length);\n              if (tail) {\n                var parent = node.parentNode;\n                parent.insertBefore(\n                  document.createTextNode(tail), node.nextSibling);\n              }\n              breakAfter(node);\n              if (!firstLine) {\n                // Don't leave blank text nodes in the DOM.\n                node.parentNode.removeChild(node);\n              }\n            }\n          }\n        }\n      \n        // Split a line after the given node.\n        function breakAfter(lineEndNode) {\n          // If there's nothing to the right, then we can skip ending the line\n          // here, and move root-wards since splitting just before an end-tag\n          // would require us to create a bunch of empty copies.\n          while (!lineEndNode.nextSibling) {\n            lineEndNode = lineEndNode.parentNode;\n            if (!lineEndNode) { return; }\n          }\n      \n          function breakLeftOf(limit, copy) {\n            // Clone shallowly if this node needs to be on both sides of the break.\n            var rightSide = copy ? limit.cloneNode(false) : limit;\n            var parent = limit.parentNode;\n            if (parent) {\n              // We clone the parent chain.\n              // This helps us resurrect important styling elements that cross lines.\n              // E.g. in <i>Foo<br>Bar</i>\n              // should be rewritten to <li><i>Foo</i></li><li><i>Bar</i></li>.\n              var parentClone = breakLeftOf(parent, 1);\n              // Move the clone and everything to the right of the original\n              // onto the cloned parent.\n              var next = limit.nextSibling;\n              parentClone.appendChild(rightSide);\n              for (var sibling = next; sibling; sibling = next) {\n                next = sibling.nextSibling;\n                parentClone.appendChild(sibling);\n              }\n            }\n            return rightSide;\n          }\n      \n          var copiedListItem = breakLeftOf(lineEndNode.nextSibling, 0);\n      \n          // Walk the parent chain until we reach an unattached LI.\n          for (var parent;\n               // Check nodeType since IE invents document fragments.\n               (parent = copiedListItem.parentNode) && parent.nodeType === 1;) {\n            copiedListItem = parent;\n          }\n          // Put it on the list of lines for later processing.\n          listItems.push(copiedListItem);\n        }\n      \n        // Split lines while there are lines left to split.\n        for (var i = 0;  // Number of lines that have been split so far.\n             i < listItems.length;  // length updated by breakAfter calls.\n             ++i) {\n          walk(listItems[i]);\n        }\n      \n        // Make sure numeric indices show correctly.\n        if (opt_startLineNum === (opt_startLineNum|0)) {\n          listItems[0].setAttribute('value', opt_startLineNum);\n        }\n      \n        var ol = document.createElement('ol');\n        ol.className = 'linenums';\n        var offset = Math.max(0, ((opt_startLineNum - 1 /* zero index */)) | 0) || 0;\n        for (var i = 0, n = listItems.length; i < n; ++i) {\n          li = listItems[i];\n          // Stick a class on the LIs so that stylesheets can\n          // color odd/even rows, or any other row pattern that\n          // is co-prime with 10.\n          li.className = 'L' + ((i + offset) % 10);\n          if (!li.firstChild) {\n            li.appendChild(document.createTextNode('\\xA0'));\n          }\n          ol.appendChild(li);\n        }\n      \n        node.appendChild(ol);\n      }    \n      /**\n       * Breaks {@code job.sourceCode} around style boundaries in\n       * {@code job.decorations} and modifies {@code job.sourceNode} in place.\n       * @param {Object} job like <pre>{\n       *    sourceCode: {string} source as plain text,\n       *    sourceNode: {HTMLElement} the element containing the source,\n       *    spans: {Array.<number|Node>} alternating span start indices into source\n       *       and the text node or element (e.g. {@code <BR>}) corresponding to that\n       *       span.\n       *    decorations: {Array.<number|string} an array of style classes preceded\n       *       by the position at which they start in job.sourceCode in order\n       * }</pre>\n       * @private\n       */\n      function recombineTagsAndDecorations(job) {\n        var isIE8OrEarlier = /\\bMSIE\\s(\\d+)/.exec(navigator.userAgent);\n        isIE8OrEarlier = isIE8OrEarlier && +isIE8OrEarlier[1] <= 8;\n        var newlineRe = /\\n/g;\n      \n        var source = job.sourceCode;\n        var sourceLength = source.length;\n        // Index into source after the last code-unit recombined.\n        var sourceIndex = 0;\n      \n        var spans = job.spans;\n        var nSpans = spans.length;\n        // Index into spans after the last span which ends at or before sourceIndex.\n        var spanIndex = 0;\n      \n        var decorations = job.decorations;\n        var nDecorations = decorations.length;\n        // Index into decorations after the last decoration which ends at or before\n        // sourceIndex.\n        var decorationIndex = 0;\n      \n        // Remove all zero-length decorations.\n        decorations[nDecorations] = sourceLength;\n        var decPos, i;\n        for (i = decPos = 0; i < nDecorations;) {\n          if (decorations[i] !== decorations[i + 2]) {\n            decorations[decPos++] = decorations[i++];\n            decorations[decPos++] = decorations[i++];\n          } else {\n            i += 2;\n          }\n        }\n        nDecorations = decPos;\n      \n        // Simplify decorations.\n        for (i = decPos = 0; i < nDecorations;) {\n          var startPos = decorations[i];\n          // Conflate all adjacent decorations that use the same style.\n          var startDec = decorations[i + 1];\n          var end = i + 2;\n          while (end + 2 <= nDecorations && decorations[end + 1] === startDec) {\n            end += 2;\n          }\n          decorations[decPos++] = startPos;\n          decorations[decPos++] = startDec;\n          i = end;\n        }\n      \n        nDecorations = decorations.length = decPos;\n      \n        var sourceNode = job.sourceNode;\n        var oldDisplay;\n        if (sourceNode) {\n          oldDisplay = sourceNode.style.display;\n          sourceNode.style.display = 'none';\n        }\n        try {\n          var decoration = null;\n          while (spanIndex < nSpans) {\n            var spanStart = spans[spanIndex];\n            var spanEnd = spans[spanIndex + 2] || sourceLength;\n      \n            var decEnd = decorations[decorationIndex + 2] || sourceLength;\n      \n            var end = Math.min(spanEnd, decEnd);\n      \n            var textNode = spans[spanIndex + 1];\n            var styledText;\n            if (textNode.nodeType !== 1  // Don't muck with <BR>s or <LI>s\n                // Don't introduce spans around empty text nodes.\n                && (styledText = source.substring(sourceIndex, end))) {\n              // This may seem bizarre, and it is.  Emitting LF on IE causes the\n              // code to display with spaces instead of line breaks.\n              // Emitting Windows standard issue linebreaks (CRLF) causes a blank\n              // space to appear at the beginning of every line but the first.\n              // Emitting an old Mac OS 9 line separator makes everything spiffy.\n              if (isIE8OrEarlier) {\n                styledText = styledText.replace(newlineRe, '\\r');\n              }\n              textNode.nodeValue = styledText;\n              var document = textNode.ownerDocument;\n              var span = document.createElement('span');\n              span.className = decorations[decorationIndex + 1];\n              var parentNode = textNode.parentNode;\n              parentNode.replaceChild(span, textNode);\n              span.appendChild(textNode);\n              if (sourceIndex < spanEnd) {  // Split off a text node.\n                spans[spanIndex + 1] = textNode\n                    // TODO: Possibly optimize by using '' if there's no flicker.\n                    = document.createTextNode(source.substring(end, spanEnd));\n                parentNode.insertBefore(textNode, span.nextSibling);\n              }\n            }\n      \n            sourceIndex = end;\n      \n            if (sourceIndex >= spanEnd) {\n              spanIndex += 2;\n            }\n            if (sourceIndex >= decEnd) {\n              decorationIndex += 2;\n            }\n          }\n        } finally {\n          if (sourceNode) {\n            sourceNode.style.display = oldDisplay;\n          }\n        }\n      }\n    \n      /** Maps language-specific file extensions to handlers. */\n      var langHandlerRegistry = {};\n      /** Register a language handler for the given file extensions.\n        * @param {function (Object)} handler a function from source code to a list\n        *      of decorations.  Takes a single argument job which describes the\n        *      state of the computation.   The single parameter has the form\n        *      {@code {\n        *        sourceCode: {string} as plain text.\n        *        decorations: {Array.<number|string>} an array of style classes\n        *                     preceded by the position at which they start in\n        *                     job.sourceCode in order.\n        *                     The language handler should assigned this field.\n        *        basePos: {int} the position of source in the larger source chunk.\n        *                 All positions in the output decorations array are relative\n        *                 to the larger source chunk.\n        *      } }\n        * @param {Array.<string>} fileExtensions\n        */\n      function registerLangHandler(handler, fileExtensions) {\n        for (var i = fileExtensions.length; --i >= 0;) {\n          var ext = fileExtensions[i];\n          if (!langHandlerRegistry.hasOwnProperty(ext)) {\n            langHandlerRegistry[ext] = handler;\n          } else if (win['console']) {\n            console['warn']('cannot override language handler %s', ext);\n          }\n        }\n      }\n      function langHandlerForExtension(extension, source) {\n        if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {\n          // Treat it as markup if the first non whitespace character is a < and\n          // the last non-whitespace character is a >.\n          extension = /^\\s*</.test(source)\n              ? 'default-markup'\n              : 'default-code';\n        }\n        return langHandlerRegistry[extension];\n      }\n      registerLangHandler(decorateSource, ['default-code']);\n      registerLangHandler(\n          createSimpleLexer(\n              [],\n              [\n               [PR_PLAIN,       /^[^<?]+/],\n               [PR_DECLARATION, /^<!\\w[^>]*(?:>|$)/],\n               [PR_COMMENT,     /^<\\!--[\\s\\S]*?(?:-\\->|$)/],\n               // Unescaped content in an unknown language\n               ['lang-',        /^<\\?([\\s\\S]+?)(?:\\?>|$)/],\n               ['lang-',        /^<%([\\s\\S]+?)(?:%>|$)/],\n               [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],\n               ['lang-',        /^<xmp\\b[^>]*>([\\s\\S]+?)<\\/xmp\\b[^>]*>/i],\n               // Unescaped content in javascript.  (Or possibly vbscript).\n               ['lang-js',      /^<script\\b[^>]*>([\\s\\S]*?)(<\\/script\\b[^>]*>)/i],\n               // Contains unescaped stylesheet content\n               ['lang-css',     /^<style\\b[^>]*>([\\s\\S]*?)(<\\/style\\b[^>]*>)/i],\n               ['lang-in.tag',  /^(<\\/?[a-z][^<>]*>)/i]\n              ]),\n          ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);\n      registerLangHandler(\n          createSimpleLexer(\n              [\n               [PR_PLAIN,        /^[\\s]+/, null, ' \\t\\r\\n'],\n               [PR_ATTRIB_VALUE, /^(?:\\\"[^\\\"]*\\\"?|\\'[^\\']*\\'?)/, null, '\\\"\\'']\n               ],\n              [\n               [PR_TAG,          /^^<\\/?[a-z](?:[\\w.:-]*\\w)?|\\/?>$/i],\n               [PR_ATTRIB_NAME,  /^(?!style[\\s=]|on)[a-z](?:[\\w:-]*\\w)?/i],\n               ['lang-uq.val',   /^=\\s*([^>\\'\\\"\\s]*(?:[^>\\'\\\"\\s\\/]|\\/(?=\\s)))/],\n               [PR_PUNCTUATION,  /^[=<>\\/]+/],\n               ['lang-js',       /^on\\w+\\s*=\\s*\\\"([^\\\"]+)\\\"/i],\n               ['lang-js',       /^on\\w+\\s*=\\s*\\'([^\\']+)\\'/i],\n               ['lang-js',       /^on\\w+\\s*=\\s*([^\\\"\\'>\\s]+)/i],\n               ['lang-css',      /^style\\s*=\\s*\\\"([^\\\"]+)\\\"/i],\n               ['lang-css',      /^style\\s*=\\s*\\'([^\\']+)\\'/i],\n               ['lang-css',      /^style\\s*=\\s*([^\\\"\\'>\\s]+)/i]\n               ]),\n          ['in.tag']);\n      registerLangHandler(\n          createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\\s\\S]+/]]), ['uq.val']);\n      registerLangHandler(sourceDecorator({\n              'keywords': CPP_KEYWORDS,\n              'hashComments': true,\n              'cStyleComments': true,\n              'types': C_TYPES\n            }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);\n      registerLangHandler(sourceDecorator({\n              'keywords': 'null,true,false'\n            }), ['json']);\n      registerLangHandler(sourceDecorator({\n              'keywords': CSHARP_KEYWORDS,\n              'hashComments': true,\n              'cStyleComments': true,\n              'verbatimStrings': true,\n              'types': C_TYPES\n            }), ['cs']);\n      registerLangHandler(sourceDecorator({\n              'keywords': JAVA_KEYWORDS,\n              'cStyleComments': true\n            }), ['java']);\n      registerLangHandler(sourceDecorator({\n              'keywords': SH_KEYWORDS,\n              'hashComments': true,\n              'multiLineStrings': true\n            }), ['bash', 'bsh', 'csh', 'sh']);\n      registerLangHandler(sourceDecorator({\n              'keywords': PYTHON_KEYWORDS,\n              'hashComments': true,\n              'multiLineStrings': true,\n              'tripleQuotedStrings': true\n            }), ['cv', 'py', 'python']);\n      registerLangHandler(sourceDecorator({\n              'keywords': PERL_KEYWORDS,\n              'hashComments': true,\n              'multiLineStrings': true,\n              'regexLiterals': 2  // multiline regex literals\n            }), ['perl', 'pl', 'pm']);\n      registerLangHandler(sourceDecorator({\n              'keywords': RUBY_KEYWORDS,\n              'hashComments': true,\n              'multiLineStrings': true,\n              'regexLiterals': true\n            }), ['rb', 'ruby']);\n      registerLangHandler(sourceDecorator({\n              'keywords': JSCRIPT_KEYWORDS,\n              'cStyleComments': true,\n              'regexLiterals': true\n            }), ['javascript', 'js']);\n      registerLangHandler(sourceDecorator({\n              'keywords': COFFEE_KEYWORDS,\n              'hashComments': 3,  // ### style block comments\n              'cStyleComments': true,\n              'multilineStrings': true,\n              'tripleQuotedStrings': true,\n              'regexLiterals': true\n            }), ['coffee']);\n      registerLangHandler(sourceDecorator({\n              'keywords': RUST_KEYWORDS,\n              'cStyleComments': true,\n              'multilineStrings': true\n            }), ['rc', 'rs', 'rust']);\n      registerLangHandler(\n          createSimpleLexer([], [[PR_STRING, /^[\\s\\S]+/]]), ['regex']);\n    \n      function applyDecorator(job) {\n        var opt_langExtension = job.langExtension;\n    \n        try {\n          // Extract tags, and convert the source code to plain text.\n          var sourceAndSpans = extractSourceSpans(job.sourceNode, job.pre);\n          /** Plain text. @type {string} */\n          var source = sourceAndSpans.sourceCode;\n          job.sourceCode = source;\n          job.spans = sourceAndSpans.spans;\n          job.basePos = 0;\n    \n          // Apply the appropriate language handler\n          langHandlerForExtension(opt_langExtension, source)(job);\n    \n          // Integrate the decorations and tags back into the source code,\n          // modifying the sourceNode in place.\n          recombineTagsAndDecorations(job);\n        } catch (e) {\n          if (win['console']) {\n            console['log'](e && e['stack'] || e);\n          }\n        }\n      }\n    \n      /**\n       * Pretty print a chunk of code.\n       * @param sourceCodeHtml {string} The HTML to pretty print.\n       * @param opt_langExtension {string} The language name to use.\n       *     Typically, a filename extension like 'cpp' or 'java'.\n       * @param opt_numberLines {number|boolean} True to number lines,\n       *     or the 1-indexed number of the first line in sourceCodeHtml.\n       */\n      function $prettyPrintOne(sourceCodeHtml, opt_langExtension, opt_numberLines) {\n        var container = document.createElement('div');\n        // This could cause images to load and onload listeners to fire.\n        // E.g. <img onerror=\"alert(1337)\" src=\"nosuchimage.png\">.\n        // We assume that the inner HTML is from a trusted source.\n        // The pre-tag is required for IE8 which strips newlines from innerHTML\n        // when it is injected into a <pre> tag.\n        // http://stackoverflow.com/questions/451486/pre-tag-loses-line-breaks-when-setting-innerhtml-in-ie\n        // http://stackoverflow.com/questions/195363/inserting-a-newline-into-a-pre-tag-ie-javascript\n        container.innerHTML = '<pre>' + sourceCodeHtml + '</pre>';\n        container = container.firstChild;\n        if (opt_numberLines) {\n          numberLines(container, opt_numberLines, true);\n        }\n    \n        var job = {\n          langExtension: opt_langExtension,\n          numberLines: opt_numberLines,\n          sourceNode: container,\n          pre: 1\n        };\n        applyDecorator(job);\n        return container.innerHTML;\n      }\n    \n       /**\n        * Find all the {@code <pre>} and {@code <code>} tags in the DOM with\n        * {@code class=prettyprint} and prettify them.\n        *\n        * @param {Function} opt_whenDone called when prettifying is done.\n        * @param {HTMLElement|HTMLDocument} opt_root an element or document\n        *   containing all the elements to pretty print.\n        *   Defaults to {@code document.body}.\n        */\n      function $prettyPrint(opt_whenDone, opt_root) {\n        var root = opt_root || document.body;\n        var doc = root.ownerDocument || document;\n        function byTagName(tn) { return root.getElementsByTagName(tn); }\n        // fetch a list of nodes to rewrite\n        var codeSegments = [byTagName('pre'), byTagName('code'), byTagName('xmp')];\n        var elements = [];\n        for (var i = 0; i < codeSegments.length; ++i) {\n          for (var j = 0, n = codeSegments[i].length; j < n; ++j) {\n            elements.push(codeSegments[i][j]);\n          }\n        }\n        codeSegments = null;\n    \n        var clock = Date;\n        if (!clock['now']) {\n          clock = { 'now': function () { return +(new Date); } };\n        }\n    \n        // The loop is broken into a series of continuations to make sure that we\n        // don't make the browser unresponsive when rewriting a large page.\n        var k = 0;\n        var prettyPrintingJob;\n    \n        var langExtensionRe = /\\blang(?:uage)?-([\\w.]+)(?!\\S)/;\n        var prettyPrintRe = /\\bprettyprint\\b/;\n        var prettyPrintedRe = /\\bprettyprinted\\b/;\n        var preformattedTagNameRe = /pre|xmp/i;\n        var codeRe = /^code$/i;\n        var preCodeXmpRe = /^(?:pre|code|xmp)$/i;\n        var EMPTY = {};\n    \n        function doWork() {\n          var endTime = (win['PR_SHOULD_USE_CONTINUATION'] ?\n                         clock['now']() + 250 /* ms */ :\n                         Infinity);\n          for (; k < elements.length && clock['now']() < endTime; k++) {\n            var cs = elements[k];\n    \n            // Look for a preceding comment like\n            // <?prettify lang=\"...\" linenums=\"...\"?>\n            var attrs = EMPTY;\n            {\n              for (var preceder = cs; (preceder = preceder.previousSibling);) {\n                var nt = preceder.nodeType;\n                // <?foo?> is parsed by HTML 5 to a comment node (8)\n                // like <!--?foo?-->, but in XML is a processing instruction\n                var value = (nt === 7 || nt === 8) && preceder.nodeValue;\n                if (value\n                    ? !/^\\??prettify\\b/.test(value)\n                    : (nt !== 3 || /\\S/.test(preceder.nodeValue))) {\n                  // Skip over white-space text nodes but not others.\n                  break;\n                }\n                if (value) {\n                  attrs = {};\n                  value.replace(\n                      /\\b(\\w+)=([\\w:.%+-]+)/g,\n                    function (_, name, value) { attrs[name] = value; });\n                  break;\n                }\n              }\n            }\n    \n            var className = cs.className;\n            if ((attrs !== EMPTY || prettyPrintRe.test(className))\n                // Don't redo this if we've already done it.\n                // This allows recalling pretty print to just prettyprint elements\n                // that have been added to the page since last call.\n                && !prettyPrintedRe.test(className)) {\n    \n              // make sure this is not nested in an already prettified element\n              var nested = false;\n              for (var p = cs.parentNode; p; p = p.parentNode) {\n                var tn = p.tagName;\n                if (preCodeXmpRe.test(tn)\n                    && p.className && prettyPrintRe.test(p.className)) {\n                  nested = true;\n                  break;\n                }\n              }\n              if (!nested) {\n                // Mark done.  If we fail to prettyprint for whatever reason,\n                // we shouldn't try again.\n                cs.className += ' prettyprinted';\n    \n                // If the classes includes a language extensions, use it.\n                // Language extensions can be specified like\n                //     <pre class=\"prettyprint lang-cpp\">\n                // the language extension \"cpp\" is used to find a language handler\n                // as passed to PR.registerLangHandler.\n                // HTML5 recommends that a language be specified using \"language-\"\n                // as the prefix instead.  Google Code Prettify supports both.\n                // http://dev.w3.org/html5/spec-author-view/the-code-element.html\n                var langExtension = attrs['lang'];\n                if (!langExtension) {\n                  langExtension = className.match(langExtensionRe);\n                  // Support <pre class=\"prettyprint\"><code class=\"language-c\">\n                  var wrapper;\n                  if (!langExtension && (wrapper = childContentWrapper(cs))\n                      && codeRe.test(wrapper.tagName)) {\n                    langExtension = wrapper.className.match(langExtensionRe);\n                  }\n    \n                  if (langExtension) { langExtension = langExtension[1]; }\n                }\n    \n                var preformatted;\n                if (preformattedTagNameRe.test(cs.tagName)) {\n                  preformatted = 1;\n                } else {\n                  var currentStyle = cs['currentStyle'];\n                  var defaultView = doc.defaultView;\n                  var whitespace = (\n                      currentStyle\n                      ? currentStyle['whiteSpace']\n                      : (defaultView\n                         && defaultView.getComputedStyle)\n                      ? defaultView.getComputedStyle(cs, null)\n                      .getPropertyValue('white-space')\n                      : 0);\n                  preformatted = whitespace\n                      && 'pre' === whitespace.substring(0, 3);\n                }\n    \n                // Look for a class like linenums or linenums:<n> where <n> is the\n                // 1-indexed number of the first line.\n                var lineNums = attrs['linenums'];\n                if (!(lineNums = lineNums === 'true' || +lineNums)) {\n                  lineNums = className.match(/\\blinenums\\b(?::(\\d+))?/);\n                  lineNums =\n                    lineNums\n                    ? lineNums[1] && lineNums[1].length\n                      ? +lineNums[1] : true\n                    : false;\n                }\n                if (lineNums) { numberLines(cs, lineNums, preformatted); }\n    \n                // do the pretty printing\n                prettyPrintingJob = {\n                  langExtension: langExtension,\n                  sourceNode: cs,\n                  numberLines: lineNums,\n                  pre: preformatted\n                };\n                applyDecorator(prettyPrintingJob);\n              }\n            }\n          }\n          if (k < elements.length) {\n            // finish up in a continuation\n            setTimeout(doWork, 250);\n          } else if ('function' === typeof opt_whenDone) {\n            opt_whenDone();\n          }\n        }\n    \n        doWork();\n      }\n    \n      /**\n       * Contains functions for creating and registering new language handlers.\n       * @type {Object}\n       */\n      var PR = win['PR'] = {\n            'createSimpleLexer': createSimpleLexer,\n            'registerLangHandler': registerLangHandler,\n            'sourceDecorator': sourceDecorator,\n            'PR_ATTRIB_NAME': PR_ATTRIB_NAME,\n            'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,\n            'PR_COMMENT': PR_COMMENT,\n            'PR_DECLARATION': PR_DECLARATION,\n            'PR_KEYWORD': PR_KEYWORD,\n            'PR_LITERAL': PR_LITERAL,\n            'PR_NOCODE': PR_NOCODE,\n            'PR_PLAIN': PR_PLAIN,\n            'PR_PUNCTUATION': PR_PUNCTUATION,\n            'PR_SOURCE': PR_SOURCE,\n            'PR_STRING': PR_STRING,\n            'PR_TAG': PR_TAG,\n            'PR_TYPE': PR_TYPE,\n            'prettyPrintOne':\n               IN_GLOBAL_SCOPE\n                 ? (win['prettyPrintOne'] = $prettyPrintOne)\n                 : (prettyPrintOne = $prettyPrintOne),\n            'prettyPrint': prettyPrint =\n               IN_GLOBAL_SCOPE\n                 ? (win['prettyPrint'] = $prettyPrint)\n                 : (prettyPrint = $prettyPrint)\n          };\n    \n      // Make PR available via the Asynchronous Module Definition (AMD) API.\n      // Per https://github.com/amdjs/amdjs-api/wiki/AMD:\n      // The Asynchronous Module Definition (AMD) API specifies a\n      // mechanism for defining modules such that the module and its\n      // dependencies can be asynchronously loaded.\n      // ...\n      // To allow a clear indicator that a global define function (as\n      // needed for script src browser loading) conforms to the AMD API,\n      // any global define function SHOULD have a property called \"amd\"\n      // whose value is an object. This helps avoid conflict with any\n      // other existing JavaScript code that could have defined a define()\n      // function that does not conform to the AMD API.\n      if (typeof define === \"function\" && define['amd']) {\n        define(\"google-code-prettify\", [], function () {\n          return PR; \n        });\n      }\n    })();\n    return prettyPrint;\n  })();\n\n  // If this script is deferred or async and the document is already\n  // loaded we need to wait for language handlers to load before performing\n  // any autorun.\n  function onLangsLoaded() {\n    if (autorun) {\n      contentLoaded(\n        function () {\n          var n = callbacks.length;\n          var callback = n ? function () {\n            for (var i = 0; i < n; ++i) {\n              (function (i) {\n                 setTimeout(\n                   function () {\n                     win['exports'][callbacks[i]].apply(win, arguments);\n                   }, 0);\n               })(i);\n            }\n          } : void 0;\n          prettyPrint(callback);\n        });\n    }\n  }\n  checkPendingLanguages();\n\n}());\n"
  },
  {
    "path": "supervisord/FirstBlood_dev.conf",
    "content": "; Sample supervisor config file.\n;\n; For more information on the config file, please see:\n; http://supervisord.org/configuration.html\n;\n; Note: shell expansion (\"~\" or \"$HOME\") is not supported.  Environment\n; variables can be expanded using this syntax: \"%(ENV_HOME)s\".\n\n[unix_http_server]\nfile=/tmp/supervisor.sock   ; (the path to the socket file)\n;chmod=0700                 ; socket file mode (default 0700)\n;chown=nobody:nogroup       ; socket file uid:gid owner\n;username=user              ; (default is no username (open server))\n;password=123               ; (default is no password (open server))\n\n;[inet_http_server]         ; inet (TCP) server disabled by default\n;port=127.0.0.1:9001        ; (ip_address:port specifier, *:port for all iface)\n;username=user              ; (default is no username (open server))\n;password=123               ; (default is no password (open server))\n\n[supervisord]\nlogfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)\nlogfile_maxbytes=50MB        ; (max main logfile bytes b4 rotation;default 50MB)\nlogfile_backups=10           ; (num of main logfile rotation backups;default 10)\nloglevel=info                ; (log level;default info; others: debug,warn,trace)\npidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)\nnodaemon=false               ; (start in foreground if true;default false)\nminfds=1024                  ; (min. avail startup file descriptors;default 1024)\nminprocs=200                 ; (min. avail process descriptors;default 200)\n;umask=022                   ; (process file creation umask;default 022)\n;user=chrism                 ; (default is current user, required if root)\n;identifier=supervisor       ; (supervisord identifier, default is 'supervisor')\n;directory=/tmp              ; (default is not to cd during start)\n;nocleanup=true              ; (don't clean up tempfiles at start;default false)\n;childlogdir=/tmp            ; ('AUTO' child log dir, default $TEMP)\n;environment=KEY=\"value\"     ; (key value pairs to add to environment)\n;strip_ansi=false            ; (strip ansi escape codes in logs; def. false)\n\n; the below section must remain in the config file for RPC\n; (supervisorctl/web interface) to work, additional interfaces may be\n; added by defining them in separate rpcinterface: sections\n[rpcinterface:supervisor]\nsupervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface\n\n[supervisorctl]\nserverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket\n;serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket\n;username=chris              ; should be same as http_username if set\n;password=123                ; should be same as http_password if set\n;prompt=mysupervisor         ; cmd line prompt (default \"supervisor\")\n;history_file=~/.sc_history  ; use readline history if available\n\n; The below sample program section shows all possible program subsection values,\n; create one or more 'real' program: sections to be able to control them under\n; supervisor.\n\n;[program:theprogramname]\n;command=/bin/cat              ; the program (relative uses PATH, can take args)\n;process_name=%(program_name)s ; process_name expr (default %(program_name)s)\n;numprocs=1                    ; number of processes copies to start (def 1)\n;directory=/tmp                ; directory to cwd to before exec (def no cwd)\n;umask=022                     ; umask for process (default None)\n;priority=999                  ; the relative start priority (default 999)\n;autostart=true                ; start at supervisord start (default: true)\n;autorestart=unexpected        ; whether/when to restart (default: unexpected)\n;startsecs=1                   ; number of secs prog must stay running (def. 1)\n;startretries=3                ; max # of serial start failures (default 3)\n;exitcodes=0,2                 ; 'expected' exit codes for process (default 0,2)\n;stopsignal=QUIT               ; signal used to kill process (default TERM)\n;stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)\n;stopasgroup=false             ; send stop signal to the UNIX process group (default false)\n;killasgroup=false             ; SIGKILL the UNIX process group (def false)\n;user=chrism                   ; setuid to this UNIX account to run the program\n;redirect_stderr=true          ; redirect proc stderr to stdout (default false)\n;stdout_logfile=/a/path        ; stdout log path, NONE for none; default AUTO\n;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)\n;stdout_logfile_backups=10     ; # of stdout logfile backups (default 10)\n;stdout_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)\n;stdout_events_enabled=false   ; emit events on stdout writes (default false)\n;stderr_logfile=/a/path        ; stderr log path, NONE for none; default AUTO\n;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)\n;stderr_logfile_backups=10     ; # of stderr logfile backups (default 10)\n;stderr_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)\n;stderr_events_enabled=false   ; emit events on stderr writes (default false)\n;environment=A=\"1\",B=\"2\"       ; process environment additions (def no adds)\n;serverurl=AUTO                ; override serverurl computation (childutils)\n\n; The below sample eventlistener section shows all possible\n; eventlistener subsection values, create one or more 'real'\n; eventlistener: sections to be able to handle event notifications\n; sent by supervisor.\n\n;[eventlistener:theeventlistenername]\n;command=/bin/eventlistener    ; the program (relative uses PATH, can take args)\n;process_name=%(program_name)s ; process_name expr (default %(program_name)s)\n;numprocs=1                    ; number of processes copies to start (def 1)\n;events=EVENT                  ; event notif. types to subscribe to (req'd)\n;buffer_size=10                ; event buffer queue size (default 10)\n;directory=/tmp                ; directory to cwd to before exec (def no cwd)\n;umask=022                     ; umask for process (default None)\n;priority=-1                   ; the relative start priority (default -1)\n;autostart=true                ; start at supervisord start (default: true)\n;autorestart=unexpected        ; whether/when to restart (default: unexpected)\n;startsecs=1                   ; number of secs prog must stay running (def. 1)\n;startretries=3                ; max # of serial start failures (default 3)\n;exitcodes=0,2                 ; 'expected' exit codes for process (default 0,2)\n;stopsignal=QUIT               ; signal used to kill process (default TERM)\n;stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)\n;stopasgroup=false             ; send stop signal to the UNIX process group (default false)\n;killasgroup=false             ; SIGKILL the UNIX process group (def false)\n;user=chrism                   ; setuid to this UNIX account to run the program\n;redirect_stderr=true          ; redirect proc stderr to stdout (default false)\n;stdout_logfile=/a/path        ; stdout log path, NONE for none; default AUTO\n;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)\n;stdout_logfile_backups=10     ; # of stdout logfile backups (default 10)\n;stdout_events_enabled=false   ; emit events on stdout writes (default false)\n;stderr_logfile=/a/path        ; stderr log path, NONE for none; default AUTO\n;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)\n;stderr_logfile_backups        ; # of stderr logfile backups (default 10)\n;stderr_events_enabled=false   ; emit events on stderr writes (default false)\n;environment=A=\"1\",B=\"2\"       ; process environment additions\n;serverurl=AUTO                ; override serverurl computation (childutils)\n\n; The below sample group section shows all possible group values,\n; create one or more 'real' group: sections to create \"heterogeneous\"\n; process groups.\n\n;[group:thegroupname]\n;programs=progname1,progname2  ; each refers to 'x' in [program:x] definitions\n;priority=999                  ; the relative start priority (default 999)\n\n; The [include] section can just contain the \"files\" setting.  This\n; setting can list multiple files (separated by whitespace or\n; newlines).  It can also contain wildcards.  The filenames are\n; interpreted as relative to this file.  Included files *cannot*\n; include files themselves.\n\n;[include]\n;files = relative/directory/*.ini\n\n\n;[program:djangoproject.celeryd]\n;command=/usr/bin/python /data/application/picha/manage.py celeryd --concurrency=1\n;user=root\n;numprocs=1\n;directory=/data/application/picha\n;stdout_logfile=/var/log/celery_worker.log\n;stderr_logfile=/var/log/celery_worker.log\n;autostart=true\n;autorestart=true\n;startsecs=10\n;stopwaitsecs = 120\n;priority=998\n \n;[program:djangoproject.celerybeat]\n;command=/usr/bin/python /data/application/picha/manage.py celery beat --schedule=/tmp/celerybeat-schedule ;--pidfile=/tmp/django_celerybeat.pid --loglevel=INFO\n;user=root\n;numprocs=1\n;directory=/data/application/picha\n;stdout_logfile=/var/log/celery_beat.log\n;stderr_logfile=/var/log/celery_beat.log\n;autostart=true\n;autorestart=true\n;startsecs=10\n;stopwaitsecs = 120\n;priority=998\n \n;[program:djangoproject.celerycam]\n;command=/usr/bin/python /data/application/picha/manage.py celerycam --frequency=10.0\n;user=root\n;numprocs=1\n;directory=/data/application/picha\n;stdout_logfile=/var/log/celerycam.log\n;stderr_logfile=/var/log/celerycam.log\n;autostart=true\n;autorestart=true\n;startsecs=10\n;stopwaitsecs = 120\n;priority=998\n\n;[group:picha]\n;programs:djangoproject.celeryd,djangoproject.celerybeat,djangoproject.celerycam\n\n[program:fb.celeryd]\n#command=/usr/bin/python /data/application/FirstBlood/manage.py celeryd --concurrency=3\ncommand=/usr/bin/python /data/application/FirstBlood/manage.py celeryd\nuser=root\nnumprocs=1\ndirectory=/data/application/FirstBlood\nstdout_logfile=/tmp/fbcelery_worker.log\nstderr_logfile=/tmp/fbcelery_worker.log\nautostart=true\nautorestart=true\nstartsecs=10\nstopwaitsecs = 120\npriority=998\n\n[program:fb.celerybeat]\ncommand=/usr/bin/python /data/application/FirstBlood/manage.py celery beat --schedule=/tmp/fbcelerybeat-schedule --pidfile=/tmp/django_fbcelerybeat.pid --loglevel=INFO\nuser=root\nnumprocs=1\ndirectory=/data/application/FirstBlood\nstdout_logfile=/tmp/fbcelery_beat.log\nstderr_logfile=/tmp/fbcelery_beat.log\nautostart=true\nautorestart=true\nstartsecs=10\nstopwaitsecs = 120\npriority=998\n\n[program:fb.celerycam]\ncommand=/usr/bin/python /data/application/FirstBlood/manage.py celerycam --frequency=1.0\nuser=root\nnumprocs=1\ndirectory=/data/application/FirstBlood\nstdout_logfile=/tmp/fbcelerycam.log\nstderr_logfile=/tmp/fbcelerycam.log\nautostart=true\nautorestart=true\nstartsecs=10\nstopwaitsecs = 120\npriority=998\n\n\n[program:fb.websockted]\ncommand=/data/application/FirstBlood/websockted/websocketd --port=8080 /usr/bin/python /data/application/FirstBlood/websockted/datax_web_job_instance.py\nuser=root\nnumprocs=1\ndirectory=/data/application/FirstBlood\nstdout_logfile=/tmp/fb_websockted.log\nstderr_logfile=/tmp/fb_websockted.log\nautostart=true\nautorestart=true\nstartsecs=10\nstopwaitsecs = 120\npriority=998\n\n[group:fb]\nprograms:fb.celeryd,fb.celerybeat,fb.celerycam,fb.websockted"
  },
  {
    "path": "supervisord/FirstBlood_pro.conf",
    "content": "; Sample supervisor config file.\n;\n; For more information on the config file, please see:\n; http://supervisord.org/configuration.html\n;\n; Note: shell expansion (\"~\" or \"$HOME\") is not supported.  Environment\n; variables can be expanded using this syntax: \"%(ENV_HOME)s\".\n\n[unix_http_server]\nfile=/tmp/supervisor.sock   ; (the path to the socket file)\n;chmod=0700                 ; socket file mode (default 0700)\n;chown=nobody:nogroup       ; socket file uid:gid owner\n;username=user              ; (default is no username (open server))\n;password=123               ; (default is no password (open server))\n\n;[inet_http_server]         ; inet (TCP) server disabled by default\n;port=127.0.0.1:9001        ; (ip_address:port specifier, *:port for all iface)\n;username=user              ; (default is no username (open server))\n;password=123               ; (default is no password (open server))\n\n[supervisord]\nlogfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)\nlogfile_maxbytes=50MB        ; (max main logfile bytes b4 rotation;default 50MB)\nlogfile_backups=10           ; (num of main logfile rotation backups;default 10)\nloglevel=info                ; (log level;default info; others: debug,warn,trace)\npidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)\nnodaemon=false               ; (start in foreground if true;default false)\nminfds=1024                  ; (min. avail startup file descriptors;default 1024)\nminprocs=200                 ; (min. avail process descriptors;default 200)\n;umask=022                   ; (process file creation umask;default 022)\n;user=chrism                 ; (default is current user, required if root)\n;identifier=supervisor       ; (supervisord identifier, default is 'supervisor')\n;directory=/tmp              ; (default is not to cd during start)\n;nocleanup=true              ; (don't clean up tempfiles at start;default false)\n;childlogdir=/tmp            ; ('AUTO' child log dir, default $TEMP)\n;environment=KEY=\"value\"     ; (key value pairs to add to environment)\n;strip_ansi=false            ; (strip ansi escape codes in logs; def. false)\n\n; the below section must remain in the config file for RPC\n; (supervisorctl/web interface) to work, additional interfaces may be\n; added by defining them in separate rpcinterface: sections\n[rpcinterface:supervisor]\nsupervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface\n\n[supervisorctl]\nserverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket\n;serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket\n;username=chris              ; should be same as http_username if set\n;password=123                ; should be same as http_password if set\n;prompt=mysupervisor         ; cmd line prompt (default \"supervisor\")\n;history_file=~/.sc_history  ; use readline history if available\n\n; The below sample program section shows all possible program subsection values,\n; create one or more 'real' program: sections to be able to control them under\n; supervisor.\n\n;[program:theprogramname]\n;command=/bin/cat              ; the program (relative uses PATH, can take args)\n;process_name=%(program_name)s ; process_name expr (default %(program_name)s)\n;numprocs=1                    ; number of processes copies to start (def 1)\n;directory=/tmp                ; directory to cwd to before exec (def no cwd)\n;umask=022                     ; umask for process (default None)\n;priority=999                  ; the relative start priority (default 999)\n;autostart=true                ; start at supervisord start (default: true)\n;autorestart=unexpected        ; whether/when to restart (default: unexpected)\n;startsecs=1                   ; number of secs prog must stay running (def. 1)\n;startretries=3                ; max # of serial start failures (default 3)\n;exitcodes=0,2                 ; 'expected' exit codes for process (default 0,2)\n;stopsignal=QUIT               ; signal used to kill process (default TERM)\n;stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)\n;stopasgroup=false             ; send stop signal to the UNIX process group (default false)\n;killasgroup=false             ; SIGKILL the UNIX process group (def false)\n;user=chrism                   ; setuid to this UNIX account to run the program\n;redirect_stderr=true          ; redirect proc stderr to stdout (default false)\n;stdout_logfile=/a/path        ; stdout log path, NONE for none; default AUTO\n;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)\n;stdout_logfile_backups=10     ; # of stdout logfile backups (default 10)\n;stdout_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)\n;stdout_events_enabled=false   ; emit events on stdout writes (default false)\n;stderr_logfile=/a/path        ; stderr log path, NONE for none; default AUTO\n;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)\n;stderr_logfile_backups=10     ; # of stderr logfile backups (default 10)\n;stderr_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)\n;stderr_events_enabled=false   ; emit events on stderr writes (default false)\n;environment=A=\"1\",B=\"2\"       ; process environment additions (def no adds)\n;serverurl=AUTO                ; override serverurl computation (childutils)\n\n; The below sample eventlistener section shows all possible\n; eventlistener subsection values, create one or more 'real'\n; eventlistener: sections to be able to handle event notifications\n; sent by supervisor.\n\n;[eventlistener:theeventlistenername]\n;command=/bin/eventlistener    ; the program (relative uses PATH, can take args)\n;process_name=%(program_name)s ; process_name expr (default %(program_name)s)\n;numprocs=1                    ; number of processes copies to start (def 1)\n;events=EVENT                  ; event notif. types to subscribe to (req'd)\n;buffer_size=10                ; event buffer queue size (default 10)\n;directory=/tmp                ; directory to cwd to before exec (def no cwd)\n;umask=022                     ; umask for process (default None)\n;priority=-1                   ; the relative start priority (default -1)\n;autostart=true                ; start at supervisord start (default: true)\n;autorestart=unexpected        ; whether/when to restart (default: unexpected)\n;startsecs=1                   ; number of secs prog must stay running (def. 1)\n;startretries=3                ; max # of serial start failures (default 3)\n;exitcodes=0,2                 ; 'expected' exit codes for process (default 0,2)\n;stopsignal=QUIT               ; signal used to kill process (default TERM)\n;stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)\n;stopasgroup=false             ; send stop signal to the UNIX process group (default false)\n;killasgroup=false             ; SIGKILL the UNIX process group (def false)\n;user=chrism                   ; setuid to this UNIX account to run the program\n;redirect_stderr=true          ; redirect proc stderr to stdout (default false)\n;stdout_logfile=/a/path        ; stdout log path, NONE for none; default AUTO\n;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)\n;stdout_logfile_backups=10     ; # of stdout logfile backups (default 10)\n;stdout_events_enabled=false   ; emit events on stdout writes (default false)\n;stderr_logfile=/a/path        ; stderr log path, NONE for none; default AUTO\n;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)\n;stderr_logfile_backups        ; # of stderr logfile backups (default 10)\n;stderr_events_enabled=false   ; emit events on stderr writes (default false)\n;environment=A=\"1\",B=\"2\"       ; process environment additions\n;serverurl=AUTO                ; override serverurl computation (childutils)\n\n; The below sample group section shows all possible group values,\n; create one or more 'real' group: sections to create \"heterogeneous\"\n; process groups.\n\n;[group:thegroupname]\n;programs=progname1,progname2  ; each refers to 'x' in [program:x] definitions\n;priority=999                  ; the relative start priority (default 999)\n\n; The [include] section can just contain the \"files\" setting.  This\n; setting can list multiple files (separated by whitespace or\n; newlines).  It can also contain wildcards.  The filenames are\n; interpreted as relative to this file.  Included files *cannot*\n; include files themselves.\n\n;[include]\n;files = relative/directory/*.ini\n\n\n;[program:djangoproject.celeryd]\n;command=/usr/bin/python /data/service/project/picha/manage.py celeryd --concurrency=1\n;user=root\n;numprocs=1\n;directory=/data/service/project/picha\n;stdout_logfile=/var/log/celery_worker.log\n;stderr_logfile=/var/log/celery_worker.log\n;autostart=true\n;autorestart=true\n;startsecs=10\n;stopwaitsecs = 120\n;priority=998\n \n;[program:djangoproject.celerybeat]\n;command=/usr/bin/python /data/service/project/picha/manage.py celery beat --schedule=/tmp/celerybeat-schedule ;--pidfile=/tmp/django_celerybeat.pid --loglevel=INFO\n;user=root\n;numprocs=1\n;directory=/data/service/project/picha\n;stdout_logfile=/var/log/celery_beat.log\n;stderr_logfile=/var/log/celery_beat.log\n;autostart=true\n;autorestart=true\n;startsecs=10\n;stopwaitsecs = 120\n;priority=998\n \n;[program:djangoproject.celerycam]\n;command=/usr/bin/python /data/service/project/picha/manage.py celerycam --frequency=10.0\n;user=root\n;numprocs=1\n;directory=/data/service/project/picha\n;stdout_logfile=/var/log/celerycam.log\n;stderr_logfile=/var/log/celerycam.log\n;autostart=true\n;autorestart=true\n;startsecs=10\n;stopwaitsecs = 120\n;priority=998\n\n;[group:picha]\n;programs:djangoproject.celeryd,djangoproject.celerybeat,djangoproject.celerycam\n\n[program:fb.celeryd]\n#command=/usr/bin/python /data/service/project/FirstBlood/manage.py celeryd --concurrency=10\ncommand=/usr/bin/python /data/service/project/FirstBlood/manage.py celeryd\nuser=huangxiaoxue\nnumprocs=1\ndirectory=/data/service/project/FirstBlood\nstdout_logfile=/tmp/fbcelery_worker.log\nstderr_logfile=/tmp/fbcelery_worker.log\nautostart=true\nautorestart=true\nstartsecs=10\nstopwaitsecs = 120\npriority=998\n\n[program:fb.celerybeat]\ncommand=/usr/bin/python /data/service/project/FirstBlood/manage.py celery beat --schedule=/tmp/fbcelerybeat-schedule --pidfile=/tmp/django_fbcelerybeat.pid --loglevel=INFO\nuser=huangxiaoxue\nnumprocs=1\ndirectory=/data/service/project/FirstBlood\nstdout_logfile=/tmp/fbcelery_beat.log\nstderr_logfile=/tmp/fbcelery_beat.log\nautostart=true\nautorestart=true\nstartsecs=10\nstopwaitsecs = 120\npriority=998\n\n[program:fb.celerycam]\ncommand=/usr/bin/python /data/service/project/FirstBlood/manage.py celerycam --frequency=1.0\nuser=huangxiaoxue\nnumprocs=1\ndirectory=/data/service/project/FirstBlood\nstdout_logfile=/tmp/fbcelerycam.log\nstderr_logfile=/tmp/fbcelerycam.log\nautostart=true\nautorestart=true\nstartsecs=10\nstopwaitsecs = 120\npriority=998\n\n\n[program:fb.websockted]\ncommand=/data/service/project/FirstBlood/websockted/websocketd --port=8080 /usr/bin/python /data/service/project/FirstBlood/websockted/datax_web_job_instance.py\nuser=huangxiaoxue\nnumprocs=1\ndirectory=/data/service/project/FirstBlood\nstdout_logfile=/tmp/fb_websockted.log\nstderr_logfile=/tmp/fb_websockted.log\nautostart=true\nautorestart=true\nstartsecs=10\nstopwaitsecs = 120\npriority=998\n\n[group:fb]\nprograms:fb.celeryd,fb.celerybeat,fb.celerycam,fb.websockted"
  },
  {
    "path": "templates/403.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <title>Endless Admin</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n\n    <!-- Bootstrap core CSS -->\n    <link href=\"/static/template/bootstrap/css/bootstrap.min.css\" rel=\"stylesheet\">\n\t\n\t<!-- Font Awesome -->\n\t<link href=\"/static/template/css/font-awesome.min.css\" rel=\"stylesheet\">\n\n\t<!-- Endless -->\n\t<link href=\"/static/template/css/endless.min.css\" rel=\"stylesheet\">\n\t<link href=\"/static/template/css/endless-skin.css\" rel=\"stylesheet\">\n\t\n  </head>\n\n  <body>\n\t<div id=\"wrapper\">\n\t\t<div class=\"padding-md\" style=\"margin-top:50px;\">\n\t\t\t<div class=\"row\">\n\t\t\t\t<div class=\"col-md-4 col-md-offset-4 col-sm-6 col-sm-offset-3 text-center\">\n\t\t\t\t\t<div class=\"h5\">sorry, 你没有权限查看此页面!</div>\n\t\t\t\t\t<h1 class=\"m-top-none error-heading\">403</h1>\n\t\t\t\t\t\n\t\t\t\t\t<h4>Search Our Website</h4>\n\t\t\t\t\t<div>Can't find what you need?</div>\n\t\t\t\t\t<div class=\"m-bottom-md\">Try searching for the page here</div>\n\t\t\t\t\t<div class=\"input-group m-bottom-md\">\n\t\t\t\t\t\t<input type=\"text\" class=\"form-control input-sm\" placeholder=\"search here...\">\n\t\t\t\t\t\t<span class=\"input-group-btn\">\n\t\t\t\t\t\t\t<button class=\"btn btn-default btn-sm\" type=\"button\"><i class=\"fa fa-search\"></i></button>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</div><!-- /input-group -->\n\t\t\t\t\t<a class=\"btn btn-success m-bottom-sm\" href=\"/index/\"><i class=\"fa fa-home\"></i> Back to Dashboard</a>\n\t\t\t\t\t<a class=\"btn btn-success m-bottom-sm\" href=\"/index/\"><i class=\"fa fa-envelope\"></i> Contact Us</a>\n\t\t\t\t</div><!-- /.col -->\n\t\t\t</div><!-- /.row -->\n\t\t</div><!-- /.padding-md -->\n\t</div><!-- /wrapper -->\n\n    <!-- Le javascript\n    ================================================== -->\n    <!-- Placed at the end of the document so the pages load faster -->\n\t\n\t<!-- Jquery -->\n\t<script src=\"/static/template/js/jquery-1.10.2.min.js\"></script>\n\t\n\t<!-- Bootstrap -->\n    <script src=\"/static/template/bootstrap/js/bootstrap.min.js\"></script>\n    \n\t<!-- Modernizr -->\n\t<script src='/static/template/js/modernizr.min.js'></script>\n\t\n\t<!-- Pace -->\n\t<script src='/static/template/js/pace.min.js'></script>\n\t\n\t<!-- Popup Overlay -->\n\t<script src='/static/template/js/jquery.popupoverlay.min.js'></script>\n\t\n\t<!-- Slimscroll -->\n\t<script src='/static/template/js/jquery.slimscroll.min.js'></script>\n\t\n\t<!-- Cookie -->\n\t<script src='/static/template/js/jquery.cookie.min.js'></script>\n\n\t<!-- Endless -->\n\t<script src=\"/static/template/js/endless/endless.js\"></script>\n\t\n  </body>\n</html>\n"
  },
  {
    "path": "templates/404.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <title>Endless Admin</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n\n    <!-- Bootstrap core CSS -->\n    <link href=\"/static/template/bootstrap/css/bootstrap.min.css\" rel=\"stylesheet\">\n\t\n\t<!-- Font Awesome -->\n\t<link href=\"/static/template/css/font-awesome.min.css\" rel=\"stylesheet\">\n\n\t<!-- Endless -->\n\t<link href=\"/static/template/css/endless.min.css\" rel=\"stylesheet\">\n\t<link href=\"/static/template/css/endless-skin.css\" rel=\"stylesheet\">\n\t\n  </head>\n\n  <body>\n\t<div id=\"wrapper\">\n\t\t<div class=\"padding-md\" style=\"margin-top:50px;\">\n\t\t\t<div class=\"row\">\n\t\t\t\t<div class=\"col-md-4 col-md-offset-4 col-sm-6 col-sm-offset-3 text-center\">\n\t\t\t\t\t<div class=\"h5\">Oops, This Page Could Not Be Found!</div>\n\t\t\t\t\t<h1 class=\"m-top-none error-heading\">404</h1>\n\t\t\t\t\t\n\t\t\t\t\t<h4>Search Our Website</h4>\n\t\t\t\t\t<div>Can't find what you need?</div>\n\t\t\t\t\t<div class=\"m-bottom-md\">Try searching for the page here</div>\n\t\t\t\t\t<div class=\"input-group m-bottom-md\">\n\t\t\t\t\t\t<input type=\"text\" class=\"form-control input-sm\" placeholder=\"search here...\">\n\t\t\t\t\t\t<span class=\"input-group-btn\">\n\t\t\t\t\t\t\t<button class=\"btn btn-default btn-sm\" type=\"button\"><i class=\"fa fa-search\"></i></button>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</div><!-- /input-group -->\n\t\t\t\t\t<a class=\"btn btn-success m-bottom-sm\" href=\"index.html\"><i class=\"fa fa-home\"></i> Back to Dashboard</a>\n\t\t\t\t\t<a class=\"btn btn-success m-bottom-sm\" href=\"contact.html\"><i class=\"fa fa-envelope\"></i> Contact Us</a>\n\t\t\t\t</div><!-- /.col -->\n\t\t\t</div><!-- /.row -->\n\t\t</div><!-- /.padding-md -->\n\t</div><!-- /wrapper -->\n\n    <!-- Le javascript\n    ================================================== -->\n    <!-- Placed at the end of the document so the pages load faster -->\n\t\n\t<!-- Jquery -->\n\t<script src=\"/static/template/js/jquery-1.10.2.min.js\"></script>\n\t\n\t<!-- Bootstrap -->\n    <script src=\"/static/template/bootstrap/js/bootstrap.min.js\"></script>\n    \n\t<!-- Modernizr -->\n\t<script src='/static/template/js/modernizr.min.js'></script>\n\t\n\t<!-- Pace -->\n\t<script src='/static/template/js/pace.min.js'></script>\n\t\n\t<!-- Popup Overlay -->\n\t<script src='/static/template/js/jquery.popupoverlay.min.js'></script>\n\t\n\t<!-- Slimscroll -->\n\t<script src='/static/template/js/jquery.slimscroll.min.js'></script>\n\t\n\t<!-- Cookie -->\n\t<script src='/static/template/js/jquery.cookie.min.js'></script>\n\n\t<!-- Endless -->\n\t<script src=\"/static/template/js/endless/endless.js\"></script>\n\t\n  </body>\n</html>\n"
  },
  {
    "path": "templates/base.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <title>First Blood</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n\n    <!-- Bootstrap core CSS -->\n    <link href=\"/static/template/bootstrap/css/bootstrap.css\" rel=\"stylesheet\">\n\n\t<!-- Chosen -->\n\t<link href=\"/static/template/css/chosen/chosen.min.css\" rel=\"stylesheet\"/>\n\n\t<!-- Font Awesome -->\n\t<link href=\"/static/template/css/font-awesome.min.css\" rel=\"stylesheet\">\n\n\t<!-- Pace -->\n\t<link href=\"/static/template/css/pace.css\" rel=\"stylesheet\">\n\t\n\t<!-- Endless -->\n\t<link href=\"/static/template/css/endless.css\" rel=\"stylesheet\">\n\t<link href=\"/static/template/css/endless-skin.css\" rel=\"stylesheet\">\n\n\t<!-- Datatable -->\n\t<link href=\"/static/plugins/datatables/css/jquery.dataTables_themeroller.css\" rel=\"stylesheet\">\n\n\t<!-- bootstrap-table -->\n\t<link href=\"/static/plugins/bootstarp-table/bootstrap-table.min.css\" rel=\"stylesheet\">\n\n\t{# 其他HEAD内容，子模板请覆盖此处 #}\n\t{% block header_content %}{% endblock %}\n    {# 其他HEAD结束 #}\n\n    <style>\n        /* 取消bootstrap模板 Endless Admin 对bootstrap-table表格中的checkbox按钮样式的修改 */\n        div[title='列'] > ul > li > label > input,\n        .table input {\n          opacity: 1;\n          position: relative;\n        }\n    </style>\n  </head>\n\n  <body class=\"overflow-hidden\">\n\t<!-- Overlay Div -->\n\t<div id=\"overlay\" class=\"transparent\"></div>\n\n\t<a href=\"\" id=\"theme-setting-icon\"><i class=\"fa fa-cog fa-lg\"></i></a>\n\t<div id=\"theme-setting\">\n\t\t<div class=\"title\">\n\t\t\t<strong class=\"no-margin\">Skin Color</strong>\n\t\t</div>\n\t\t<div class=\"theme-box\">\n\t\t\t<a class=\"theme-color\" style=\"background:#323447\" id=\"default\"></a>\n\t\t\t<a class=\"theme-color\" style=\"background:#efefef\" id=\"skin-1\"></a>\n\t\t\t<a class=\"theme-color\" style=\"background:#a93922\" id=\"skin-2\"></a>\n\t\t\t<a class=\"theme-color\" style=\"background:#3e6b96\" id=\"skin-3\"></a>\n\t\t\t<a class=\"theme-color\" style=\"background:#635247\" id=\"skin-4\"></a>\n\t\t\t<a class=\"theme-color\" style=\"background:#3a3a3a\" id=\"skin-5\"></a>\n\t\t\t<a class=\"theme-color\" style=\"background:#495B6C\" id=\"skin-6\"></a>\n\t\t</div>\n\t\t<div class=\"title\">\n\t\t\t<strong class=\"no-margin\">Sidebar Menu</strong>\n\t\t</div>\n\t\t<div class=\"theme-box\">\n\t\t\t<label class=\"label-checkbox\">\n\t\t\t\t<input type=\"checkbox\" checked id=\"fixedSidebar\">\n\t\t\t\t<span class=\"custom-checkbox\"></span>\n\t\t\t\tFixed Sidebar\n\t\t\t</label>\n\t\t</div>\n\t</div><!-- /theme-setting -->\n\t\n\t<div id=\"wrapper\" class=\"preload\">\n\t\t<div id=\"top-nav\" class=\"skin-6 fixed\">\n\t\t\t<div class=\"brand\">\n\t\t\t\t<span>First</span>\n\t\t\t\t<span class=\"text-toggle\"> Blood</span>\n\t\t\t</div><!-- /brand -->\n\t\t\t<button type=\"button\" class=\"navbar-toggle pull-left\" id=\"sidebarToggle\">\n\t\t\t\t<span class=\"icon-bar\"></span>\n\t\t\t\t<span class=\"icon-bar\"></span>\n\t\t\t\t<span class=\"icon-bar\"></span>\n\t\t\t</button>\n\t\t\t<button type=\"button\" class=\"navbar-toggle pull-left hide-menu\" id=\"menuToggle\">\n\t\t\t\t<span class=\"icon-bar\"></span>\n\t\t\t\t<span class=\"icon-bar\"></span>\n\t\t\t\t<span class=\"icon-bar\"></span>\n\t\t\t</button>\n\t\t\t<ul class=\"nav-notification clearfix\">\n\t\t\t\t<li class=\"profile dropdown\">\n\t\t\t\t\t<a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n\t\t\t\t\t\t<strong></strong>\n\t\t\t\t\t\t<span><i class=\"fa fa-chevron-down\"></i></span>\n\t\t\t\t\t</a>\n\t\t\t\t\t<ul class=\"dropdown-menu\">\n\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t<a class=\"clearfix\" href=\"#\">\n\t\t\t\t\t\t\t\t<img src=\"/static/template/img/user.jpg\" alt=\"User Avatar\">\n\t\t\t\t\t\t\t\t<div class=\"detail\">\n\t\t\t\t\t\t\t\t\t<strong></strong>\n\t\t\t\t\t\t\t\t\t<!-- <p class=\"grey\">John_Doe@email.com</p>  -->\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n                        <li>\n                            <a tabindex=\"-1\" href=\"{% url 'django.contrib.auth.views.password_change' %}\" class=\"main-link\">\n                                <i class=\"fa fa-edit fa-lg\"></i> password change</a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li><a tabindex=\"-1\" class=\"main-link logoutConfirm_open\" href=\"#logoutConfirm\"><i class=\"fa fa-lock fa-lg\"></i> Log out</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</li>\n\t\t\t</ul>\n\t\t</div><!-- /top-nav-->\n\t\t\n\t\t<aside class=\"fixed skin-3\">\t\n\t\t\t<div class=\"sidebar-inner scrollable-sidebar\">\n\t\t\t\t<div class=\"size-toggle\">\n\t\t\t\t\t<a class=\"btn btn-sm\" id=\"sizeToggle\">\n\t\t\t\t\t\t<span class=\"icon-bar\"></span>\n\t\t\t\t\t\t<span class=\"icon-bar\"></span>\n\t\t\t\t\t\t<span class=\"icon-bar\"></span>\n\t\t\t\t\t</a>\n\t\t\t\t\t<a class=\"btn btn-sm pull-right logoutConfirm_open\"  href=\"#logoutConfirm\">\n\t\t\t\t\t\t<i class=\"fa fa-power-off\"></i>\n\t\t\t\t\t</a>\n\t\t\t\t</div><!-- /size-toggle -->\t\n\t\t\t\t<div class=\"user-block clearfix\">\n\t\t\t\t\t<img src=\"/static/template/img/user.jpg\" alt=\"User Avatar\">\n\t\t\t\t\t<div class=\"detail\">\n\t\t\t\t\t\t<strong>{{nowuser.username}}</strong>\n\t\t\t\t\t</div>\n\t\t\t\t</div><!-- /user-block -->\n\t\t\t\t<div class=\"main-menu\">\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t{% block users %}\n\t\t\t\t\t\t<li class=\"\">\n\t\t\t\t\t\t\t<a href=\"/\">\n\t\t\t\t\t\t\t\t<span class=\"menu-icon\">\n\t\t\t\t\t\t\t\t\t<i class=\"fa fa-desktop fa-lg\"></i>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span class=\"text\">\n\t\t\t\t\t\t\t\t\tDashboard\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span class=\"menu-hover\"></span>\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n                        <li id=\"scheduled_tasks\" class=\"openable\">\n\t\t\t\t\t\t\t<a href=\"#\">\n\t\t\t\t\t\t\t\t<span class=\"menu-icon\">\n\t\t\t\t\t\t\t\t\t<i class=\"fa fa-tasks fa-lg\"></i>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span class=\"text\">\n\t\t\t\t\t\t\t\t\t数据同步\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span class=\"badge badge-success bounceIn animation-delay5\">2</span>\n\t\t\t\t\t\t\t\t<span class=\"menu-hover\"></span>\n\t\t\t\t\t\t\t</a>\n                            <ul class=\"submenu\">\n\t\t\t\t\t\t\t\t<li><a href=\"/datax_web/index/\"><span class=\"submenu-label\">作业</span></a></li>\n\t\t\t\t\t\t\t</ul>\n                            <ul class=\"submenu\">\n\t\t\t\t\t\t\t\t<li><a href=\"/datax_web/monitor_job/\" target=\"_black\"><span class=\"submenu-label\">执行历史</span></a></li>\n\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t</li>\n                        <li id=\"SQL\" class=\"openable\">\n\t\t\t\t\t\t\t<a href=\"#\">\n\t\t\t\t\t\t\t\t<span class=\"menu-icon\">\n\t\t\t\t\t\t\t\t\t<i class=\"fa fa-asterisk fa-lg\"></i>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span class=\"text\">\n\t\t\t\t\t\t\t\t\tSQL脚本\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span class=\"badge badge-success bounceIn animation-delay5\">2</span>\n\t\t\t\t\t\t\t\t<span class=\"menu-hover\"></span>\n\t\t\t\t\t\t\t</a>\n                            <ul class=\"submenu\">\n\t\t\t\t\t\t\t\t<li><a href=\"#\"><span class=\"submenu-label\">列表</span></a></li>\n\t\t\t\t\t\t\t</ul>\n                            <ul class=\"submenu\">\n\t\t\t\t\t\t\t\t<li><a href=\"#\" target=\"_black\"><span class=\"submenu-label\">执行历史</span></a></li>\n\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t</li>\n                        <li id=\"batch_job\" class=\"openable\">\n\t\t\t\t\t\t\t<a href=\"#\">\n\t\t\t\t\t\t\t\t<span class=\"menu-icon\">\n\t\t\t\t\t\t\t\t\t<i class=\"fa fa-tag fa-lg\"></i>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span class=\"text\">\n\t\t\t\t\t\t\t\t\t批处理作业\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span class=\"badge badge-success bounceIn animation-delay5\">3</span>\n\t\t\t\t\t\t\t\t<span class=\"menu-hover\"></span>\n\t\t\t\t\t\t\t</a>\n                            <ul class=\"submenu\">\n\t\t\t\t\t\t\t\t<li><a href=\"/batch_job/index/\"><span class=\"submenu-label\">作业列表</span></a></li>\n\t\t\t\t\t\t\t</ul>\n                            <ul class=\"submenu\">\n\t\t\t\t\t\t\t\t<li><a href=\"/batch_job/batch_job_instance/\" target=\"_black\"><span class=\"submenu-label\">执行历史</span></a></li>\n\t\t\t\t\t\t\t</ul>\n                            <ul class=\"submenu\">\n\t\t\t\t\t\t\t\t<li><a href=\"/batch_job/crontabs/\"><span class=\"submenu-label\">Crontabs</span></a></li>\n\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t</li>\n                        <li id=\"dtmt\" class=\"openable\">\n\t\t\t\t\t\t\t<a href=\"#\">\n\t\t\t\t\t\t\t\t<span class=\"menu-icon\">\n\t\t\t\t\t\t\t\t\t<i class=\"fa fa-wrench fa-lg\"></i>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span class=\"text\">\n\t\t\t\t\t\t\t\t\t数据库管理工具\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span class=\"badge badge-success bounceIn animation-delay5\">2</span>\n\t\t\t\t\t\t\t\t<span class=\"menu-hover\"></span>\n\t\t\t\t\t\t\t</a>\n                            <ul class=\"submenu\">\n\t\t\t\t\t\t\t\t<li><a href=\"#\"><span class=\"submenu-label\">查询</span></a></li>\n\t\t\t\t\t\t\t</ul>\n                            <ul class=\"submenu\">\n\t\t\t\t\t\t\t\t<li><a href=\"#\"><span class=\"submenu-label\">生产库</span></a></li>\n\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t\t{% endblock %}\n\t\t\t\t\t</ul>\n\t\t\t\t</div><!-- /main-menu -->\n\t\t\t</div><!-- /sidebar-inner -->\n\t\t</aside>\n\n\t\t{# 主体，子模板请覆盖此处 #}\n\t\t{% block container %}{% endblock %}\n        {# 主体结束 #}\n\n\t</div><!-- /wrapper -->\n\n\t<a href=\"\" id=\"scroll-to-top\" class=\"hidden-print\"><i class=\"fa fa-chevron-up\"></i></a>\n\t\n\t<!-- Logout confirmation -->\n\t<div class=\"custom-popup width-100\" id=\"logoutConfirm\">\n\t\t<div class=\"padding-md\">\n\t\t\t<h4 class=\"m-top-none\"> Do you want to logout?</h4>\n\t\t</div>\n\n\t\t<div class=\"text-center\">\n\t\t\t<a class=\"btn btn-success m-right-sm\" href=\"{% url 'django.contrib.auth.views.logout'%}?next=/\">Logout</a>\n\t\t\t<a class=\"btn btn-danger logoutConfirm_close\">Cancel</a>\n\t\t</div>\n\t</div>\n\t\n    <!-- Le javascript\n    ================================================== -->\n    <!-- Placed at the end of the document so the pages load faster -->\n\t\n\n\n\t<!-- Jquery -->\n\t<script src=\"/static/template/js/jquery-1.10.2.min.js\"></script>\n\n\t<!-- Bootstrap -->\n    <script src=\"/static/template/bootstrap/js/bootstrap.min.js\"></script>\n\n    <!-- Chosen -->\n\t<script src='/static/template/js/chosen.jquery.min.js'></script>\n\n\t<!-- Modernizr -->\n\t<script src='/static/template/js/modernizr.min.js'></script>\n   \n    <!-- Pace -->\n\t<script src='/static/template/js/pace.min.js'></script>\n\t\n\t<!-- Popup Overlay -->\n\t<script src='/static/template/js/jquery.popupoverlay.min.js'></script>\n   \n    <!-- Slimscroll -->\n\t<script src='/static/template/js/jquery.slimscroll.min.js'></script>\n    \n\t<!-- Cookie -->\n\t<script src='/static/template/js/jquery.cookie.min.js'></script>\n\n\t<!-- Endless -->\n\t<script src=\"/static/template/js/endless/endless.js\"></script>\n\n\t<!-- 加载csrf.js，实现ajax post方式提交数据时可以跨过django的跨站请求伪造保护 -->\n\t<script src=\"/static/js/csrf.js\"></script>\n\n\t<script src=\"/static/plugins/layer/layer.js\"></script> {# 加载layer控件，实现弹出框 #}\n\n\t<!-- Datatable -->\n{#\t<script src='/static/plugins/datatables/js/jquery.dataTables.min.js'></script>#}\n\n    <!-- bootstrap-table -->\n    <script src='/static/plugins/bootstarp-table/bootstrap-table.min.js'></script>\n    <!-- bootstrap-table-zh -->\n\t<script src='/static/plugins/bootstarp-table/bootstrap-table-zh-CN.js'></script>\n\n\n<script>\n$(document).ready(function(){\n  // 设置菜单选中\n    var url = window.location.href;\n    var data = url.split('/');\n    $('#'+ data[3]).attr('class','active openable open');\n    $('#'+ data[3]).find(\"a[href*=\"+ data[4] +\"]\").parent().attr('class','active');\n\n    get_username();\n});\n\n\n/*\n*获取当前用户名\n*/\nfunction get_username() {\n    var url = '/get_username/';\n    $.post(url, function (data) {\n        var username =  $.parseJSON(data);\n        $('.profile').find('strong').text(username);\n    })\n}\n</script>\n{# 结束内容，子模板请覆盖此处 #}\n{% block footer_content %}{% endblock %}\n   {# 主体结束 #}\n\n\n  </body>\n</html>\n"
  },
  {
    "path": "templates/batch_job/add_batch_job.html",
    "content": "{% extends 'base.html' %}\n\n{% block header_content %}\n<style>\n.center {\n width: auto;\n display: table;\n margin-left: auto;\n margin-right: auto;\n}\n.text-center > table > tbody > tr > th,\n.text-center > table > thead > tr > th {\n text-align: center;\n}\n\n.table-responsive {\nwidth: 100%;\nmargin-bottom: 15px;\noverflow-x: scroll;\noverflow-y: hidden;\nborder: 1px solid #dddddd;\n-ms-overflow-style: -ms-autohiding-scrollbar;\n-webkit-overflow-scrolling: touch;\n}\n.table-responsive > .table {\nmargin-bottom: 0;\n}\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 {\nwhite-space: nowrap;\n}\n\n.NoNewline\n{\nword-break: keep-all;/*必须*/\nwhite-space: nowrap;\n}\n\n/* 设置chosen菜单向上弹出 css样式 */\n.chosen-container .chosen-drop {\n    border-bottom: 0;\n    border-top: 1px solid #aaa;\n    top: auto;\n    bottom: 40px;\n}\n</style>\n\t<!-- Datepicker -->\n    <link href=\"/static/template/css/bootstrap-datepicker.min.css\" rel=\"stylesheet\"/>\n    <!-- Gritter -->\n\t<link href=\"/static/template/css/gritter/jquery.gritter.css\" rel=\"stylesheet\">\n{% endblock %}\n\n\n{% block container %}\n<div id=\"main-container\">\n\t<div class=\"main-header clearfix\">\n\t\t<div class=\"page-title\">\n\t\t\t<h3 class=\"no-margin\">新建批处理作业</h3>\n\t\t</div><!-- /page-title -->\n\t</div><!-- /main-header -->\n\n\n\t<div class=\"padding-md\">\n        <div class=\"row\">\n            <div class=\"col-md-12\">\n                <div class=\"panel panel-default\">\n                    <form class=\"form-horizontal form-border no-margin\" id=\"basic-constraint\" data-validate=\"parsley\" novalidate>\n                        <div class=\"panel-heading\">\n                            Add Batch Job\n                        </div>\n                        <div class=\"panel-body\">\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">任务名称</label>\n                                <div class=\"col-lg-4\">\n                                    <input type=\"text\" id=\"name\" class=\"form-control input-sm\" data-required=\"true\" placeholder=\"请输入英文\">\n                                </div><!-- /.col -->\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">描述</label>\n                                <div class=\"col-lg-4\">\n                                    <textarea id=\"description\" spellcheck=\"false\" class=\"form-control\" placeholder=\"describe the specific job\" rows=\"6\" data-required=\"true\"></textarea>\n                                </div><!-- /.col -->\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">任务模板</label>\n                                <div class=\"col-lg-3\">\n                                    <select id=\"task_template\" class=\"form-control\"></select>\n                                </div><!-- /.col -->\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">是否启用</label>\n                                <div class=\"col-lg-9\">\n                                    <div class=\"seperator\"></div>\n                                    <label class=\"label-checkbox inline\">\n                                        <input id=\"is_enable\" type=\"checkbox\" data-required=\"true\" name=\"chk-demo\" checked=\"checked\">\n                                        <span class=\"custom-checkbox\"></span>\n                                    </label>\n                                </div><!-- /.col -->\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">执行时间</label>\n                                <div class=\"col-lg-4\">\n                                    <select id=\"crontab\" class=\"form-control\">\n                                        <option>请选择</option>\n                                    </select>\n                                </div><!-- /.col -->\n                                <div class=\"col-lg-1\">\n                                    <a href=\"#crontabModal\" data-toggle=\"modal\" type=\"button\" class=\"btn btn-default\"><i class=\"fa fa-plus\"></i></a>\n                                </div>\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">作业详情</label>\n                                <div class=\"col-lg-9\">\n                                     <table class=\"table table-hover table-bordered NoNewline\" id=\"table\"></table>\n                                </div><!-- /.col -->\n                                <div class=\"col-lg-1\">\n                                    <button id=\"batch_job_delete_btn\" type=\"button\" class=\"btn btn-default\"><i class=\"fa fa-minus\"></i></button>\n                                </div>\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\"><span class=\"label label-info\">选择作业列表</span></label>\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">数据同步</label>\n                                <div class=\"col-lg-4\">\n                                    <select id=\"datax_job\" class=\"form-control chzn-select\">\n                                        <option value=\"-1\">请选择</option>\n                                    </select>\n                                </div><!-- /.col -->\n                                <div class=\"col-lg-1\">\n                                    <button data-toggle=\"modal\" type=\"button\" class=\"btn btn-default\"><i class=\"fa fa-plus\"></i></button>\n                                </div>\n                            </div><!-- /form-group -->\n                        </div>\n\n                        <div class=\"panel-footer\">\n                            <button id=\"save_job\" type=\"button\" class=\"btn btn-success\">Save</button>\n                        </div>\n                    </form>\n                    <div class=\"modal fade\" id=\"crontabModal\">\n                        <div class=\"modal-dialog\">\n                            <div class=\"modal-content\">\n                                <div class=\"modal-header\">\n                                    <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">&times;</button>\n                                    <h4>Add crontab</h4>\n                                </div>\n                                <div class=\"modal-body\">\n                                    <form class=\"form-horizontal form-border no-margin\" id=\"basic-constraint\" data-validate=\"parsley\" novalidate>\n                                        <div class=\"panel-body\">\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">minute</label>\n                                                <div class=\"col-lg-9\">\n                                                    <input name=\"minute\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">hour</label>\n                                                <div class=\"col-lg-9\">\n                                                    <input name=\"hour\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">day_of_week</label>\n                                                <div class=\"col-lg-9\">\n                                                    <input name=\"day_of_week\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">day_of_month</label>\n                                                <div class=\"col-lg-9\">\n                                                    <input name=\"day_of_month\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">month_of_year</label>\n                                                <div class=\"col-lg-9\">\n                                                    <input name=\"month_of_year\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                        </div>\n                                    </form>\n                                </div>\n                                <div class=\"modal-footer\">\n                                    <button class=\"btn btn-success btn-sm\" data-dismiss=\"modal\" aria-hidden=\"true\">Close</button>\n                                    <a id=\"save_crontab\" type=\"button\" class=\"btn btn-danger btn-sm\">Save</a>\n                                </div>\n                            </div><!-- /.modal-content -->\n                        </div><!-- /.modal-dialog -->\n                    </div><!-- /.modal -->\n                </div><!-- /panel -->\n            </div><!-- /.col-->\n        </div><!-- /.row -->\n\t</div><!-- /padding-md -->\n</div><!-- /main-container -->\n{% endblock %}\n\n{% block footer_content %}\n\n\n<!-- Datepicker -->\n<script src='/static/template/js/bootstrap-datepicker.js'></script>\n<script src='/static/template/js/bootstrap-datepicker.zh-CN.min.js'></script>\n<script src=\"/static/template/js/jquery.gritter.min.js\"></script>\n<!-- Modernizr -->\n{#<script src='/static/template/js/modernizr.min.js'></script>#}\n<script>\n$(document).ready(function(){\n    let index = layer.load();\n    Initialization_task_template();\n    Initialization_datax_job();\n    Initialization_crontab();\n    layer.close(index);\n});\n\n\n/*\n*初始化任务模板\n*/\nfunction Initialization_task_template() {\n    var url = '/batch_job/get_task_template/';\n    var para = {};\n    $.post(url, para, function (jdata) {\n        var data = $.parseJSON(jdata);\n        $.each(data, function (k, v) {\n            var _option = \"<option value='\"+ v +\"'>\"+ v +\"</option>\";\n            $(\"#task_template\").append(_option);\n        });\n    })\n}\n\n\n/*\n*初始化 数据同步选择按钮select内容\n*/\nfunction Initialization_datax_job() {\n    let url = '/datax_web/get_job_data/';\n    let para = {};\n    $.post(url, para, function (jdata) {\n        let data = $.parseJSON(jdata);\n        $.each(data, function (k, v) {\n            let _option = \"<option value='\"+ v.id +\"'>\"+ v.name + \" \" + v.description +\"</option>\";\n            $(\"#datax_job\").append(_option);\n        });\n        $(\".chzn-select\").chosen();\n    })\n}\n\n\n/*\n*初始化crontab 时间\n*/\nfunction Initialization_crontab() {\n    var url = '/batch_job/get_crontab/';\n    var para = {};\n    $.post(url, para, function (jdata) {\n        var _data = $.parseJSON(jdata);\n        $(\"#crontab\").empty();\n        $.each(_data, function (k, v) {\n            var _cont = [v.minute, v.hour, v.day_of_week, v.day_of_month, v.month_of_year];\n            var _option = \"<option value='\"+ v.id +\"'>\"+ _cont.join(' ')+ \" (分/时/周/日/月)\" +\"</option>\";\n            $(\"#crontab\").append(_option);\n        });\n    })\n}\n\n\n/*\n*初始化表格\n*/\n$('#table').bootstrapTable({\n    url: '#',\n    pagination: true,                   //是否显示分页（*）\n    sortable: false,                     //是否启用排序\n    sortOrder: \"asc\",                   //排序方式\n    showColumns: true,\n    queryParams: queryParams,           //传递参数（*）\n    sidePagination: \"client\",           //分页方式：client客户端分页，server服务端分页（*）\n    pageNumber: 1,                       //初始化加载第一页，默认第一页\n    pageSize: 10,                       //每页的记录行数（*）\n    pageList: [10, 25, 50, 100],        //可供选择的每页的行数（*）\n    search: true,                  //是否显示搜索 --前端搜索\n    columns:get_columns()\n});\n\n\n/*\n*得到查询的参数\n*/\nfunction queryParams(params) {\n    return {   //这里的键的名字和控制器的变量名必须一直，这边改动，控制器也需要改成一样的\n        limit: params.limit,   //页面大小\n        offset: params.offset,  //页码\n        name: $('#name').val(),\n        description: $('#description').val(),\n        reader_databaseinfo_host: $('#reader_databaseinfo_host').val(),\n        writer_databaseinfo_host: $('#writer_databaseinfo_host').val(),\n        status: $('#status').val(),\n        writer_table: $('#writer_table').val(),\n        result: $('#result').val(),\n        trigger_mode: $('#trigger_mode').val(),\n    };\n}\n\n\n/*\n*获取bootstraptable 的列columns\n*/\nfunction get_columns() {\n    return [{\n            field: 'checkbox',\n            checkbox: true,\n        },{\n            title: '序号',//标题  可不加\n            formatter: function (value, row, index) {\n                return index+1;\n                }\n        }, {\n            field: 'subjob_id',\n            title: 'ID',\n            visible: false\n        }, {\n            field: 'name',\n            title: '任务名称',\n            formatter: subjectFormatter\n        }, {\n            field: 'description',\n            title: '描述 '\n        }, {\n            field: 'type',\n            title: '类型',\n            formatter: typeFormatter\n    }];\n}\n\n\n/*\n*添加 crontab 时间\n*/\n$(\"#save_crontab\").click(function () {\n    var url = '/batch_job/add_crontab/';\n    var para = {};\n    $(\"#crontabModal\").find('input').each(function () {\n        para[$(this).prop('name')] = $(this).val();\n    });\n    var jpara = JSON.stringify(para);\n    $.post(url, {'data': jpara}, function () {\n        Initialization_crontab();\n        $('#crontabModal').modal('hide');\n        $.gritter.add({\n            title: \"<i class='fa fa-check-circle'></i> Success\",\n            text: ' 可选择新添加的crontab时间.',\n            sticky: false,\n            time: '',\n            class_name: 'gritter-success'\n        });\n        return false;\n    })\n});\n\n\n/*\n* 添加数据同步\n*/\n$('#datax_job').parent().next().click(function () {\n    let val = $(\"#datax_job\").val();\n    let text = $(\"#datax_job\").find(\"option:selected\").text();\n    let name = text.split(' ')[0];\n    let description = text.split(' ')[1];\n\n    if (val > 0){\n        let is_selected = false;\n        let selectedData = $(\"#table\").bootstrapTable('getData');\n        $.each(selectedData, function (k, v) {\n            if (v.subjob_id == val){\n                is_selected = true;\n                layer.msg(v.description + ' 已添加');\n           }\n        });\n        if (!is_selected){\n            let row = {'subjob_id': val, 'name':name, 'description': description, 'type': 1};\n            $(\"#table\").bootstrapTable('append', [row]);\n        }\n    }\n});\n\n\n/*\n*删除批处理作业详情\n*/\n$(\"#batch_job_delete_btn\").click(function () {\n    let selectedData = $(\"#table\").bootstrapTable('getSelections');\n    let ids = $.map(selectedData, function (row) {\n        return row.subjob_id\n    });\n    $('#table').bootstrapTable('remove', {field: 'subjob_id', values: ids});\n});\n\n\n/*\n*保存任务 save job\n*/\n$(\"#save_job\").click(function () {\n    let para = get_para();\n    let jpara = JSON.stringify(para);\n    let url = '/batch_job/add_batch_job_data/';\n    let index = layer.load();\n    $.post(url, {'data': jpara}, function (res) {\n        let _data = $.parseJSON(res);\n        layer.close(index);\n        // 成功则跳转列表页面，失败则提示错误信息继续修改。\n        if (_data.status == 0) {\n            let url =\"/batch_job/index/\";\n            ajax_callback2(_data.msg, url)\n        }\n        else{\n            ajax_callback1(_data.msg);\n        }\n    });\n});\n\n\n/*\n*获取提交的信息\n*/\nfunction get_para() {\n    let name = $(\"#name\").val().trim();\n    let description = $(\"#description\").val().trim();\n    let task_template = $(\"#task_template\").val().trim();\n    let is_enable = $(\"#is_enable\").is(\":checked\");\n    let crontab = $(\"#crontab\").val().trim();\n    let batch_job_details = $('#table').bootstrapTable('getData');\n\n    return {\n        'operation_type': 1,\n        'name': name,\n        'description': description,\n        'task_template': task_template,\n        'is_enable': is_enable,\n        'crontab': crontab,\n        'batch_job_details': batch_job_details,\n    }\n}\n\n\n/*\n*超链接显示邮件标题\n*/\nfunction subjectFormatter(value, row, index) {\n    let url = \"/datax_web/update_job/\" + row.subjob_id;\n    return [\n        '<div><a target=\"_black\" class=\"mod\" href='+ url +'>',\n        value,\n        '</a></div>'\n    ].join('');\n}\n\n\n/*\n*格式化执行结果\n*/\nfunction typeFormatter(value, row, index) {\n    let resultF = null;\n    let className = null;\n    switch (Number(value)){\n        case 1:\n            resultF = '数据同步';\n            className = '';\n            break;\n        case 2:\n            resultF = 'SQL脚本';\n            className = 'label-danger';\n            break;\n        case 3:\n            resultF = '备份';\n            className = 'label-info';\n            break;\n    }\n    return '<span class=\"label ' + className + '\">' + resultF + '</span>'\n}\n\n\n/*\n*格式化执行状态\n*/\nfunction statusFormatter(value, row, index) {\n    let resultF = null;\n    let className = null;\n    switch (Number(value)){\n        case 0:\n            resultF = '正在执行';\n            className = '';\n            break;\n        case 1:\n            resultF = '执行完成';\n            className = '';\n            break;\n    }\n    return '<span class=\"label ' + className + '\">' + resultF + '</span>'\n}\n\n\n/*\n*格式化触发模式\n*/\nfunction triggerModeFormatter(value, row, index) {\n    let resultF = null;\n    let className = null;\n    switch (Number(value)){\n        case 1:\n            resultF = '自动';\n            className = '';\n            break;\n        case 2:\n            resultF = '手动';\n            className = '';\n            break;\n    }\n    return '<span class=\"label ' + className + '\">' + resultF + '</span>'\n}\n\n\n/*\n*ajax get callback\n*/\nfunction ajax_callback1(msg){\n    var index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n       layer.close(index)\n    });\n}\n\n\n/*\n*ajax get callback2\n*/\nfunction ajax_callback2(msg, url){\n    var index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n        layer.close(index);\n        window.location=url;\n    });\n}\n</script>\n{% endblock %}"
  },
  {
    "path": "templates/batch_job/add_crontabs.html",
    "content": "{% extends 'base.html' %}\n{% load ygol_filter_tag %}\n\n{% block header_content %}\n<style>\n.center {\n width: auto;\n display: table;\n margin-left: auto;\n margin-right: auto;\n}\n.text-center > table > tbody > tr > th,\n.text-center > table > thead > tr > th {\n text-align: center;\n}\n\n.table-responsive {\nwidth: 100%;\nmargin-bottom: 15px;\noverflow-x: scroll;\noverflow-y: hidden;\nborder: 1px solid #dddddd;\n-ms-overflow-style: -ms-autohiding-scrollbar;\n-webkit-overflow-scrolling: touch;\n}\n.table-responsive > .table {\nmargin-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 {\nwhite-space: nowrap;\n}\n\n.NoNewline\n{\nword-break: keep-all;/*必须*/\nwhite-space: nowrap;\n}\n</style>\n\t<!-- Datepicker -->\n    <link href=\"/static/template/css/bootstrap-datepicker.min.css\" rel=\"stylesheet\"/>\n    <!-- Gritter -->\n\t<link href=\"/static/template/css/gritter/jquery.gritter.css\" rel=\"stylesheet\">\n{% endblock %}\n\n\n{% block container %}\n<div id=\"main-container\">\n\t<div class=\"main-header clearfix\">\n\t\t<div class=\"page-title\">\n\t\t\t<h3 class=\"no-margin\">Add crontab</h3>\n\t\t</div><!-- /page-title -->\n\t</div><!-- /main-header -->\n\n\n\t<div class=\"padding-md\">\n        <div class=\"row\">\n            <div class=\"col-md-12\">\n\t\t\t\t\t\t<div class=\"panel panel-default\">\n\t\t\t\t\t\t\t<form class=\"form-horizontal form-border no-margin\" id=\"basic-constraint\" data-validate=\"parsley\" novalidate>\n\t\t\t\t\t\t\t\t<div class=\"panel-heading\">\n\t\t\t\t\t\t\t\t\t请按照crontab格式修改，修改后请重新指定定时任务的执行时间\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div class=\"panel-body\">\n                                    <form class=\"form-horizontal form-border no-margin\" data-validate=\"parsley\" novalidate>\n                                        <div class=\"panel-body\" id=\"crontabModal\">\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">minute</label>\n                                                <div class=\"col-lg-5\">\n                                                    <input name=\"minute\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">hour</label>\n                                                <div class=\"col-lg-5\">\n                                                    <input name=\"hour\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">day_of_week</label>\n                                                <div class=\"col-lg-5\">\n                                                    <input name=\"day_of_week\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">day_of_month</label>\n                                                <div class=\"col-lg-5\">\n                                                    <input name=\"day_of_month\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">month_of_year</label>\n                                                <div class=\"col-lg-5\">\n                                                    <input name=\"month_of_year\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                        </div>\n                                    </form>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div class=\"panel-footer\">\n\t\t\t\t\t\t\t\t\t<button id=\"save_crontab\" type=\"button\" class=\"btn btn-success\">Save</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</form>\n\t\t\t\t\t\t</div><!-- /panel -->\n\t\t\t\t\t</div><!-- /.col-->\n        </div><!-- /.row -->\n\t</div><!-- /padding-md -->\n</div><!-- /main-container -->\n{% endblock %}\n\n{% block footer_content %}\n\n\n<!-- Datepicker -->\n<script src='/static/template/js/bootstrap-datepicker.js'></script>\n<script src='/static/template/js/bootstrap-datepicker.zh-CN.min.js'></script>\n<script src=\"/static/template/js/jquery.gritter.min.js\"></script>\n<!-- Modernizr -->\n{#<script src='/static/template/js/modernizr.min.js'></script>#}\n<script>\n/*\n*添加 crontab 时间\n*/\n$(\"#save_crontab\").click(function () {\n    var url = '/scheduled_tasks/add_crontab/';\n    var para = {};\n    $(\"#crontabModal\").find('input').each(function () {\n        para[$(this).prop('name')] = $(this).val();\n    });\n    var jpara = JSON.stringify(para);\n    $.post(url, {'data': jpara}, function () {\n        var url =\"/scheduled_tasks/crontabs/\";\n        ajax_callback2('操作成功', url)\n    })\n});\n\n\n/*\n*ajax get callback2\n*/\nfunction ajax_callback2(msg, url){\n    var index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n        layer.close(index);\n        window.location=url;\n    });\n}\n</script>\n{% endblock %}"
  },
  {
    "path": "templates/batch_job/batch_job_instance.html",
    "content": "{% extends 'base.html' %}\n\n{% block header_content %}\n<style>\n.center {\n width: auto;\n display: table;\n margin-left: auto;\n margin-right: auto;\n}\n.text-center > table > tbody > tr > th,\n.text-center > table > thead > tr > th {\n text-align: center;\n}\n\n.table-responsive {\nwidth: 100%;\nmargin-bottom: 15px;\noverflow-x: scroll;\noverflow-y: hidden;\nborder: 1px solid #dddddd;\n-ms-overflow-style: -ms-autohiding-scrollbar;\n-webkit-overflow-scrolling: touch;\n}\n.table-responsive > .table {\nmargin-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 {\nwhite-space: nowrap;\n}\n\n.NoNewline\n{\nword-break: keep-all;/*必须*/\nwhite-space: nowrap;\n}\n\n.text-overflow{\nwidth:100px;\noverflow:hidden;;/* 内容超出宽度时隐藏超出部分的内容 */\ntext-overflow:ellipsis;;/* 当对象内文本溢出时显示省略标记(...) ；需与overflow:hidden;一起使用。*/\nwhite-space:nowrap;/* 不换行 */\n}\n</style>\n\t<!-- Datepicker -->\n    <link href=\"/static/template/css/bootstrap-datepicker.min.css\" rel=\"stylesheet\"/>\n{% endblock %}\n\n\n{% block container %}\n<div id=\"main-container\">\n\t<div class=\"main-header clearfix\">\n\t\t<div class=\"page-title\">\n\t\t\t<h3 class=\"no-margin\">批处理作业 - 执行历史</h3>\n\t\t</div><!-- /page-title -->\n\t</div><!-- /main-header -->\n\n\t<div class=\"padding-md\">\n\t\t<div class=\"panel panel-default table-responsive\">\n            <div class=\"panel-body\">\n                <table class=\"table-condensed\" id=\"search_tb\">\n                    <tr>\n                        <td><label>任务名称</label></td>\n                        <td><input type=\"text\" id=\"name\" name=\"store\" class=\"form-control input-sm\"></td>\n                        <td><label>描述</label></td>\n                        <td><input type=\"text\" id=\"description\" name=\"account_manager\" class=\"form-control input-sm\"></td>\n\n                        <td><label>执行状态</label></td>\n                        <td>\n    \t\t\t\t\t\t<select id=\"status\" name=\"status\" class=\"form-control\">\n                                <option value=\"\">请选择</option>\n                                <option value=\"0\">正在执行</option>\n                                <option value=\"1\">执行完成</option>\n                            </select>\n                        </td>\n                    </tr>\n                    <tr>\n                        <td><label>执行结果</label></td>\n                        <td>\n    \t\t\t\t\t\t<select id=\"result\" name=\"result\" class=\"form-control\">\n                                <option value=\"\">请选择</option>\n                                <option value=\"0\">成功</option>\n                                <option value=\"1\">失败</option>\n                                <option value=\"2\">未知</option>\n                            </select>\n                        </td>\n                        <td><label>触发模式</label></td>\n                        <td>\n    \t\t\t\t\t\t<select id=\"trigger_mode\" name=\"status\" class=\"form-control\">\n                                <option value=\"\">请选择</option>\n                                <option value=\"1\">自动</option>\n                                <option value=\"2\">手动</option>\n                            </select>\n                        </td>\n                    </tr>\n\n                </table>\n            </div>\n            <div class=\"form-inline\">\n\n            </div>\n            <div class=\"table-responsive\">\n\t\t\t\t<table class=\"table table-hover table-bordered NoNewline\" id=\"table\"></table>\n\t\t\t</div><!-- /.padding-md -->\n\t\t</div><!-- /panel -->\n\t</div><!-- /padding-md -->\n</div><!-- /main-container -->\n{% endblock %}\n\n{% block footer_content %}\n\n\n<!-- Datepicker -->\n<script src='/static/template/js/bootstrap-datepicker.js'></script>\n<script src='/static/template/js/bootstrap-datepicker.zh-CN.min.js'></script>\n<script>\n$(document).ready(function(){\n    $('body').on('mouseover', '.text-overflow', function() {\n        var _cont = $(this).children().text();\n        layer.tips(_cont.split('\\n').join('<br>'), $(this), {\n        tips: [1, '#0FA6D8'],\n        time: 0\n        });\n    });\n    $('body').on('mouseout', '.text-overflow', function() {\n        layer.closeAll('tips'); //关闭所有的tips层\n    });\n\n    Initialization_Database();\n});\n\n\n/*\n*初始化表格\n*/\n$('#table').bootstrapTable({\n    url: '/batch_job/get_batch_job_instance/',\n    pagination: true,                   //是否显示分页（*）\n    sortable: false,                     //是否启用排序\n    sortOrder: \"asc\",                   //排序方式\n    showColumns: true,\n    showRefresh: true,\n    queryParams: queryParams,           //传递参数（*）\n    sidePagination: \"server\",           //分页方式：client客户端分页，server服务端分页（*）\n    pageNumber: 1,                       //初始化加载第一页，默认第一页\n    pageSize: 10,                       //每页的记录行数（*）\n    pageList: [10, 25, 50, 100],        //可供选择的每页的行数（*）\n    search: false,                  //是否显示搜索 --前端搜索\n    columns:get_columns()\n});\n\n\n/*\n*得到查询的参数\n*/\nfunction queryParams(params) {\n    return {   //这里的键的名字和控制器的变量名必须一直，这边改动，控制器也需要改成一样的\n        limit: params.limit,   //页面大小\n        offset: params.offset,  //页码\n        name: $('#name').val(),\n        description: $('#description').val(),\n        status: $('#status').val(),\n        result: $('#result').val(),\n        trigger_mode: $('#trigger_mode').val(),\n    };\n}\n\n\n/*\n*获取bootstraptable 的列columns\n*/\nfunction get_columns() {\n    return [{\n        title: '序号',//标题  可不加\n        formatter: function (value, row, index) {\n            return index+1;\n            }\n    }, {\n        field: 'id',\n        title: 'ID',\n        visible: false\n    }, {\n        field: 'name',\n        title: '任务名称',\n        formatter: subjectFormatter\n    }, {\n        field: 'description',\n        title: '描述 '\n    }, {\n        field: 'trigger_mode',\n        title: '触发模式',\n        formatter: triggerModeFormatter\n    }, {\n        field: 'status',\n        title: '执行状态',\n        formatter: statusFormatter\n    }, {\n        field: 'result',\n        title: '执行结果 ',\n        formatter: resultFormatter\n    }, {\n        field: 'start_time',\n        title: '开始时间 '\n    }, {\n        field: 'end_time',\n        title: '结束时间 '\n    }];\n}\n\n\n/*\n*超链接显示收件人\n*/\nfunction receiversFormatter(value, row, index) {\n    return [\n        '<div class=\"text-overflow\"><a href=\"#\">',\n        value,\n        '</a></div>'\n    ].join('');\n}\n\n\n/*\n*超链接显示邮件标题\n*/\nfunction subjectFormatter(value, row, index) {\n    var url = \"/batch_job/batch_job_instance_details/\" + row.instance_id;\n    return [\n        '<div><a class=\"mod\" href='+ url +'>',\n        value,\n        '</a></div>'\n    ].join('');\n}\n\n\n/*\n*格式化执行结果\n*/\nfunction resultFormatter(value, row, index) {\n    switch (Number(value)){\n        case 0:\n            var resultF = '成功';\n            var className = 'label-success';\n            break;\n        case 1:\n            var resultF = '失败';\n            className = 'label-danger';\n            break;\n        case 2:\n            resultF = '';\n            className = 'label-info';\n            break;\n    }\n    return '<span class=\"label ' + className + '\">' + resultF + '</span>'\n}\n\n\n/*\n*格式化执行状态\n*/\nfunction statusFormatter(value, row, index) {\n    switch (Number(value)){\n        case 0:\n            var resultF = '正在执行';\n            var className = '';\n            break;\n        case 1:\n            var resultF = '执行完成';\n            className = '';\n            break;\n    }\n    return '<span class=\"label ' + className + '\">' + resultF + '</span>'\n}\n\n\n/*\n*格式化触发模式\n*/\nfunction triggerModeFormatter(value, row, index) {\n    switch (Number(value)){\n        case 1:\n            var resultF = '自动';\n            var className = '';\n            break;\n        case 2:\n            var resultF = '手动';\n            className = '';\n            break;\n    }\n    return '<span class=\"label ' + className + '\">' + resultF + '</span>'\n}\n\n\n/*\n*初始化数据库\n*/\nfunction Initialization_Database() {\n    var url = '/datax_web/get_database/';\n    var para = {};\n    $.post(url, para, function (jdata) {\n        var _data = $.parseJSON(jdata);\n        $.each(_data, function (k, v) {\n            var _option = \"<option ip='\"+ v.host +\"' value='\"+ v.id +\"'>\"+ v.description + \" \" + v.host.substr(0, 15) + \"</option>\";\n            $(\"#reader_databaseinfo_host\").append(_option);\n            $(\"#writer_databaseinfo_host\").append(_option);\n        });\n    })\n}\n\n\n/*\n*ajax get callback\n*/\nfunction ajax_callback1(msg){\n    var index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n       layer.close(index)\n    });\n}\n\n</script>\n{% endblock %}"
  },
  {
    "path": "templates/batch_job/batch_job_instance_details.html",
    "content": "{% extends 'base.html' %}\n\n{% block header_content %}\n<style>\n.center {\n width: auto;\n display: table;\n margin-left: auto;\n margin-right: auto;\n}\n.text-center > table > tbody > tr > th,\n.text-center > table > thead > tr > th {\n text-align: center;\n}\n\n.table-responsive {\nwidth: 100%;\nmargin-bottom: 15px;\noverflow-x: scroll;\noverflow-y: hidden;\nborder: 1px solid #dddddd;\n-ms-overflow-style: -ms-autohiding-scrollbar;\n-webkit-overflow-scrolling: touch;\n}\n.table-responsive > .table {\nmargin-bottom: 0;\n}\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 {\nwhite-space: nowrap;\n}\n\n.NoNewline\n{\nword-break: keep-all;/*必须*/\nwhite-space: nowrap;\n}\n\n/* 设置chosen菜单向上弹出 css样式 */\n.chosen-container .chosen-drop {\n    border-bottom: 0;\n    border-top: 1px solid #aaa;\n    top: auto;\n    bottom: 40px;\n}\n</style>\n\t<!-- Datepicker -->\n    <link href=\"/static/template/css/bootstrap-datepicker.min.css\" rel=\"stylesheet\"/>\n    <!-- Gritter -->\n\t<link href=\"/static/template/css/gritter/jquery.gritter.css\" rel=\"stylesheet\">\n{% endblock %}\n\n\n{% block container %}\n<div id=\"main-container\">\n\t<div class=\"main-header clearfix\">\n\t\t<div class=\"page-title\">\n\t\t\t<h3 class=\"no-margin\">批处理作业详情 - 执行历史</h3>\n\t\t</div><!-- /page-title -->\n\t</div><!-- /main-header -->\n\n\n\t<div class=\"padding-md\">\n        <div class=\"row\">\n            <div class=\"col-md-12\">\n                <div class=\"panel panel-default\">\n                    <form class=\"form-horizontal form-border no-margin\" id=\"basic-constraint\" data-validate=\"parsley\" novalidate>\n                        <div class=\"panel-heading\">\n                            Update Batch Job\n                        </div>\n                        <div class=\"panel-body\">\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">任务名称</label>\n                                <div class=\"col-lg-4\">\n\t\t\t\t\t\t\t\t\t<p id=\"name\" class=\"form-control-static\"></p>\n\t\t\t\t\t\t\t\t</div>\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">描述</label>\n                                <div class=\"col-lg-4\">\n\t\t\t\t\t\t\t\t\t<p id=\"description\" class=\"form-control-static\"></p>\n\t\t\t\t\t\t\t\t</div>\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">触发模式</label>\n                                <div class=\"col-lg-4\">\n\t\t\t\t\t\t\t\t\t<p id=\"trigger_mode\" class=\"form-control-static\"></p>\n\t\t\t\t\t\t\t\t</div>\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">执行状态</label>\n                                <div class=\"col-lg-4\">\n\t\t\t\t\t\t\t\t\t<p id=\"status\" class=\"form-control-static\"></p>\n\t\t\t\t\t\t\t\t</div>\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">执行结果</label>\n                                <div class=\"col-lg-4\">\n                                    <span id=\"result\" class=\"control-label label label-success col-lg-1\" style=\"margin-top: 5px;\"></span>\n\t\t\t\t\t\t\t\t</div>\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">开始时间</label>\n                                <div class=\"col-lg-4\">\n\t\t\t\t\t\t\t\t\t<p id=\"start_time\" class=\"form-control-static\"></p>\n\t\t\t\t\t\t\t\t</div>\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">结束时间</label>\n                                <div class=\"col-lg-4\">\n\t\t\t\t\t\t\t\t\t<p id=\"end_time\" class=\"form-control-static\"></p>\n\t\t\t\t\t\t\t\t</div>\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">作业详情</label>\n                                <div class=\"col-lg-10\">\n                                     <table class=\"table table-hover table-bordered NoNewline\" id=\"table\"></table>\n                                </div><!-- /.col -->\n                            </div><!-- /form-group -->\n                        </div>\n                    </form>\n                </div><!-- /panel -->\n            </div><!-- /.col-->\n        </div><!-- /.row -->\n\t</div><!-- /padding-md -->\n</div><!-- /main-container -->\n{% endblock %}\n\n{% block footer_content %}\n\n\n<!-- Datepicker -->\n<script src='/static/template/js/bootstrap-datepicker.js'></script>\n<script src='/static/template/js/bootstrap-datepicker.zh-CN.min.js'></script>\n<script src=\"/static/template/js/jquery.gritter.min.js\"></script>\n<!-- Modernizr -->\n{#<script src='/static/template/js/modernizr.min.js'></script>#}\n<script>\n$(document).ready(function(){\n    let index = layer.load();\n    InitBatchJobInstanceData();\n    InitSubJob();\n    layer.close(index);\n});\n\n\n/**\n * 初始化批处理作业数据\n */\nfunction InitBatchJobInstanceData(){\n    let url = '/batch_job/get_batch_job_instance_data_by_id/';\n    let instance_id = getId();\n    let para = {'instance_id': instance_id};\n    $.ajax({\n\t\ttype : \"post\",\n\t\turl : url,\n\t\tdata : para,\n\t\tsuccess : function (jdata) {\n\t\t\tlet data = $.parseJSON(jdata);\n\t\t\t$(\"#name\").text(data.name);\n\t\t\t$(\"#description\").text(data.description);\n\t\t\t$(\"#trigger_mode\").text(TriggerModeFormatter(data.trigger_mode));\n\t\t\t$(\"#status\").text(StatusFormatter(data.status));\n\n\t\t\tlet result = ResultFormatter(data.result);\n\t\t\t$(\"#result\").text(result.resultF);\n\t\t\t$(\"#result\").addClass(result.className);\n\n\t\t\t$(\"#start_time\").text(data.start_time);\n\t\t\t$(\"#end_time\").text(data.end_time);\n\n\t\t}\n  \t});\n}\n\n/**\n * 初始化触发模式\n */\nfunction TriggerModeFormatter(value) {\n    let resultF = null;\n    switch (Number(value)){\n        case 1:\n            resultF = '自动';\n            break;\n        case 2:\n            resultF = '手动';\n            break;\n    }\n    return resultF\n}\n\n\n/**\n * 初始化状态\n */\nfunction StatusFormatter(value) {\n    let resultF = null;\n    switch (Number(value)){\n        case 0:\n            resultF = '正在执行';\n            break;\n        case 1:\n            resultF = '执行完成';\n            break;\n    }\n    return resultF\n}\n\n\n/**\n * 初始化结果\n */\nfunction ResultFormatter(value) {\n    let resultF = null;\n    let className = null;\n    switch (Number(value)){\n        case 0:\n            resultF = '成功';\n            className = 'label-success';\n            break;\n        case 1:\n            resultF = '失败';\n            className = 'label-danger';\n            break;\n        case 2:\n            resultF = '未知';\n            className = 'label-info';\n            break;\n    }\n    return {'resultF': resultF, 'className': className}\n}\n\n\n/**\n * 初始化子作业\n */\nfunction InitSubJob() {\n    let url = '/batch_job/get_batch_job_sub_job_by_id/';\n    let _id = getId();\n    let para = {'_id': _id};\n    $.ajax({\n\t\ttype : \"post\",\n\t\turl : url,\n\t\tdata : para,\n\t\tsuccess : function (jdata) {\n\t\t\tlet data = $.parseJSON(jdata);\n            $(\"#table\").bootstrapTable('append', data);\n\t\t}\n  \t});\n}\n\n\n/*\n*初始化批处理作业详情表格\n*/\n$('#table').bootstrapTable({\n    url: '/batch_job/get_batch_job_sub_job_instance_data_by_id/',\n    pagination: true,                   //是否显示分页（*）\n    sortable: false,                     //是否启用排序\n    sortOrder: \"asc\",                   //排序方式\n    showColumns: true,\n    showRefresh: true,\n    queryParams: queryParams,           //传递参数（*）\n    sidePagination: \"client\",           //分页方式：client客户端分页，server服务端分页（*）\n    pageNumber: 1,                       //初始化加载第一页，默认第一页\n    pageSize: 10,                       //每页的记录行数（*）\n    pageList: [10, 25, 50, 100],        //可供选择的每页的行数（*）\n    search: true,                  //是否显示搜索 --前端搜索\n    columns:get_columns()\n});\n\n\n/*\n*得到查询的参数\n*/\nfunction queryParams(params) {\n    return {   //这里的键的名字和控制器的变量名必须一直，这边改动，控制器也需要改成一样的\n        limit: params.limit,   //页面大小\n        offset: params.offset,  //页码\n        instance_id: getId(),\n        name: $('#name').val(),\n        description: $('#description').val(),\n        result: $('#result').val(),\n        trigger_mode: $('#trigger_mode').val(),\n    };\n}\n\n\n/*\n*获取bootstraptable 的列columns\n*/\nfunction get_columns() {\n    return [{\n            field: 'checkbox',\n            checkbox: true,\n        },{\n            title: '序号',//标题  可不加\n            formatter: function (value, row, index) {\n                return index+1;\n                }\n        }, {\n            field: 'subjob_id',\n            title: 'ID',\n            visible: false\n        }, {\n            field: 'name',\n            title: '任务名称',\n            formatter: subjectFormatter\n        }, {\n            field: 'description',\n            title: '描述 '\n        }, {\n            field: 'type',\n            title: '类型',\n            formatter: typeFormatter\n        }, {\n            field: 'trigger_mode',\n            title: '触发模式',\n            formatter: triggerModeFormatter\n        }, {\n            field: 'status',\n            title: '执行状态',\n            formatter: statusFormatter\n        }, {\n            field: 'result',\n            title: '执行结果',\n            formatter: resultFormatter\n        }, {\n            field: 'start_time',\n            title: '开始时间',\n        }, {\n            field: 'end_time',\n            title: '结束时间',\n    }];\n}\n\n\n/*\n* 超链接显示\n* 子作业扩展后，需要根据子作业类型生成url\n*/\nfunction subjectFormatter(value, row, index) {\n    let url = \"/datax_web/monitor_job_detail/\" + row.subjob_instance_id;\n    return [\n        '<div><a target=\"_black\" class=\"mod\" href='+ url +'>',\n        value,\n        '</a></div>'\n    ].join('');\n}\n\n\n/*\n*格式化执行结果\n*/\nfunction typeFormatter(value, row, index) {\n    let resultF = null;\n    let className = null;\n    switch (Number(value)){\n        case 1:\n            resultF = '数据同步';\n            className = '';\n            break;\n        case 2:\n            resultF = 'SQL脚本';\n            className = 'label-danger';\n            break;\n        case 3:\n            resultF = '备份';\n            className = 'label-info';\n            break;\n    }\n    return '<span class=\"label ' + className + '\">' + resultF + '</span>'\n}\n\n\n/*\n*格式化执行结果\n*/\nfunction resultFormatter(value, row, index) {\n    switch (Number(value)){\n        case 0:\n            var resultF = '成功';\n            var className = 'label-success';\n            break;\n        case 1:\n            var resultF = '失败';\n            className = 'label-danger';\n            break;\n        case 2:\n            resultF = '';\n            className = 'label-info';\n            break;\n    }\n    return '<span class=\"label ' + className + '\">' + resultF + '</span>'\n}\n\n\n/*\n*格式化执行状态\n*/\nfunction statusFormatter(value, row, index) {\n    switch (Number(value)){\n        case 0:\n            var resultF = '正在执行';\n            var className = '';\n            break;\n        case 1:\n            var resultF = '执行完成';\n            className = '';\n            break;\n    }\n    return '<span class=\"label ' + className + '\">' + resultF + '</span>'\n}\n\n\n/*\n*格式化触发模式\n*/\nfunction triggerModeFormatter(value, row, index) {\n    switch (Number(value)){\n        case 1:\n            var resultF = '自动';\n            var className = '';\n            break;\n        case 2:\n            var resultF = '手动';\n            className = '';\n            break;\n    }\n    return '<span class=\"label ' + className + '\">' + resultF + '</span>'\n}\n\n\n/**\n * 获取URL后面的ID\n * return: _id\n */\nfunction getId() {\n    let str=location.href;\n    let args = str.split('/');\n    return args[args.length-2];\n}\n\n/*\n*ajax get callback\n*/\nfunction ajax_callback1(msg){\n    let index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n       layer.close(index)\n    });\n}\n\n\n/*\n*ajax get callback2\n*/\nfunction ajax_callback2(msg, url){\n    let index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n        layer.close(index);\n        window.location=url;\n    });\n}\n</script>\n{% endblock %}"
  },
  {
    "path": "templates/batch_job/crontabs.html",
    "content": "{% extends 'base.html' %}\n{% load ygol_filter_tag %}\n\n{% block header_content %}\n<style>\n.center {\n width: auto;\n display: table;\n margin-left: auto;\n margin-right: auto;\n}\n.text-center > table > tbody > tr > th,\n.text-center > table > thead > tr > th {\n text-align: center;\n}\n\n.table-responsive {\nwidth: 100%;\nmargin-bottom: 15px;\noverflow-x: scroll;\noverflow-y: hidden;\nborder: 1px solid #dddddd;\n-ms-overflow-style: -ms-autohiding-scrollbar;\n-webkit-overflow-scrolling: touch;\n}\n.table-responsive > .table {\nmargin-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 {\nwhite-space: nowrap;\n}\n\n.NoNewline\n{\nword-break: keep-all;/*必须*/\nwhite-space: nowrap;\n}\n\n.text-overflow{\nwidth:100px;\noverflow:hidden;;/* 内容超出宽度时隐藏超出部分的内容 */\ntext-overflow:ellipsis;;/* 当对象内文本溢出时显示省略标记(...) ；需与overflow:hidden;一起使用。*/\nwhite-space:nowrap;/* 不换行 */\n}\n</style>\n\t<!-- Datepicker -->\n    <link href=\"/static/template/css/bootstrap-datepicker.min.css\" rel=\"stylesheet\"/>\n{% endblock %}\n\n\n{% block container %}\n<div id=\"main-container\">\n\t<div class=\"main-header clearfix\">\n\t\t<div class=\"page-title\">\n\t\t\t<h3 class=\"no-margin\">Crontabs</h3>\n\t\t</div><!-- /page-title -->\n\t</div><!-- /main-header -->\n\n\t<div class=\"padding-md\">\n\t\t<div class=\"panel panel-default table-responsive\">\n                <div class=\"form-inline\">\n\t\t\t\t\t<a href=\"/scheduled_tasks/add_crontab_index/\" id=\"add\" type=\"button\" class=\"btn btn-sm btn-info\">\n                        <i class=\"fa fa-plus\"></i> 新增</a>\n\t\t\t\t</div>\n            <div class=\"table-responsive\">\n\t\t\t\t<table class=\"table table-hover table-bordered NoNewline\" id=\"table\"></table>\n\t\t\t</div><!-- /.padding-md -->\n\n\t\t</div><!-- /panel -->\n\t</div><!-- /padding-md -->\n</div><!-- /main-container -->\n{% endblock %}\n\n{% block footer_content %}\n\n\n<!-- Datepicker -->\n<script src='/static/template/js/bootstrap-datepicker.js'></script>\n<script src='/static/template/js/bootstrap-datepicker.zh-CN.min.js'></script>\n<script>\n$(document).ready(function(){\n    $('body').on('mouseover', '.text-overflow', function() {\n        var _cont = $(this).children().text();\n        layer.tips(_cont.split('\\n').join('<br>'), $(this), {\n        tips: [1, '#0FA6D8'],\n        time: 0\n        });\n    });\n    $('body').on('mouseout', '.text-overflow', function() {\n        layer.closeAll('tips'); //关闭所有的tips层\n    });\n\n});\n\n\n/*\n*得到查询的参数\n*/\nfunction queryParams(params) {\n    var temp = {   //这里的键的名字和控制器的变量名必须一直，这边改动，控制器也需要改成一样的\n        limit: params.limit,   //页面大小\n        offset: params.offset,  //页码\n        time: $('#time').val(),\n        investor: $('#investor').val(),\n        investor_cn: $('#investor_cn').val(),\n        investor_id: $('#investor_id').val(),\n        invite_code: $('#invite_code').val(),\n        product: $('#product').val(),\n        investment_amount: $('#investment_amount').val(),\n        return_rate: $('#return_rate').val(),\n        account_manager: $('#account_manager').val(),\n        account_manager_cn: $('#account_manager_cn').val(),\n        emp_num: $('#emp_num').val(),\n        store: $('#store').val(),\n        large_area: $('#large_area').val(),\n        area: $('#area').val(),\n        city: $('#city').val(),\n        start_date: $('#start_date').val(),\n        end_date: $('#end_date').val(),\n        lending_id: $('#lending_id').val(),\n        discount_amount: $('#discount_amount').val(),\n    };\n    return temp;\n}\n\n\n\n\n/*\n*获取bootstraptable 的列columns\n*/\nfunction get_columns() {\n    var columns =[{\n        title: '序号',//标题  可不加\n        formatter: function (value, row, index) {\n            return index+1;\n            }\n    }, {\n        field: 'id',\n        title: 'ID',\n        visible: false\n    }, {\n        field: 'crontab',\n        title: 'crontab',\n        formatter: crontabFormatter\n    }];\n    return columns\n}\n\n/*\n*初始化表格\n*/\n$('#table').bootstrapTable({\n    url: '/scheduled_tasks/crontabs_get_data/',\n    pagination: true,                   //是否显示分页（*）\n    sortable: false,                     //是否启用排序\n    sortOrder: \"asc\",                   //排序方式\n    showColumns: true,\n    queryParams: queryParams,           //传递参数（*）\n    sidePagination: \"client\",           //分页方式：client客户端分页，server服务端分页（*）\n    pageNumber: 1,                       //初始化加载第一页，默认第一页\n    pageSize: 10,                       //每页的记录行数（*）\n    pageList: [10, 25, 50, 100],        //可供选择的每页的行数（*）\n    search: true,                  //是否显示搜索 --前端搜索\n    columns:get_columns()\n});\n\n\n/*\n*超链接crontab\n*/\nfunction crontabFormatter(value, row, index) {\n    var url = \"/scheduled_tasks/mod_crontabs_index/\" + row.id;\n    return [\n        '<div><a class=\"mod\" href='+ url +'>',\n        value,\n        '</a></div>'\n    ].join('');\n}\n\n\n\n/*\n*ajax get callback\n*/\nfunction ajax_callback1(msg){\n    var index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n       layer.close(index)\n    });\n}\n\n</script>\n{% endblock %}"
  },
  {
    "path": "templates/batch_job/index.html",
    "content": "{% extends 'base.html' %}\n\n{% block header_content %}\n<style>\n.center {\n width: auto;\n display: table;\n margin-left: auto;\n margin-right: auto;\n}\n.text-center > table > tbody > tr > th,\n.text-center > table > thead > tr > th {\n text-align: center;\n}\n\n.table-responsive {\nwidth: 100%;\nmargin-bottom: 15px;\noverflow-x: scroll;\noverflow-y: hidden;\nborder: 1px solid #dddddd;\n-ms-overflow-style: -ms-autohiding-scrollbar;\n-webkit-overflow-scrolling: touch;\n}\n.table-responsive > .table {\nmargin-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 {\nwhite-space: nowrap;\n}\n\n.NoNewline\n{\nword-break: keep-all;/*必须*/\nwhite-space: nowrap;\n}\n\n.text-overflow{\nwidth:100px;\noverflow:hidden;;/* 内容超出宽度时隐藏超出部分的内容 */\ntext-overflow:ellipsis;;/* 当对象内文本溢出时显示省略标记(...) ；需与overflow:hidden;一起使用。*/\nwhite-space:nowrap;/* 不换行 */\n}\n</style>\n\t<!-- Datepicker -->\n    <link href=\"/static/template/css/bootstrap-datepicker.min.css\" rel=\"stylesheet\"/>\n{% endblock %}\n\n\n{% block container %}\n<div id=\"main-container\">\n\t<div class=\"main-header clearfix\">\n\t\t<div class=\"page-title\">\n\t\t\t<h3 class=\"no-margin\">批处理作业</h3>\n\t\t</div><!-- /page-title -->\n\t</div><!-- /main-header -->\n\n\t<div class=\"padding-md\">\n\t\t<div class=\"panel panel-default table-responsive\">\n                <div class=\"form-inline\">\n\t\t\t\t\t<a href=\"/batch_job/add_batch_job/\" id=\"add\" type=\"button\" class=\"btn btn-sm btn-info\">\n                        <i class=\"fa fa-plus\"></i> 新增</a>\n\t\t\t\t</div>\n            <div class=\"table-responsive\">\n\t\t\t\t<table class=\"table table-hover table-bordered NoNewline\" id=\"table\"></table>\n\t\t\t</div><!-- /.padding-md -->\n\n\t\t</div><!-- /panel -->\n\t</div><!-- /padding-md -->\n</div><!-- /main-container -->\n{% endblock %}\n\n{% block footer_content %}\n\n\n<!-- Datepicker -->\n<script src='/static/template/js/bootstrap-datepicker.js'></script>\n<script src='/static/template/js/bootstrap-datepicker.zh-CN.min.js'></script>\n<script>\n$(document).ready(function(){\n    $('body').on('mouseover', '.text-overflow', function() {\n        var _cont = $(this).children().text();\n        layer.tips(_cont.split('\\n').join('<br>'), $(this), {\n        tips: [1, '#0FA6D8'],\n        time: 0\n        });\n    });\n    $('body').on('mouseout', '.text-overflow', function() {\n        layer.closeAll('tips'); //关闭所有的tips层\n    });\n\n});\n\n\n/*\n*得到查询的参数\n*/\nfunction queryParams(params) {\n    var temp = {   //这里的键的名字和控制器的变量名必须一直，这边改动，控制器也需要改成一样的\n        limit: params.limit,   //页面大小\n        offset: params.offset,  //页码\n        time: $('#time').val(),\n        investor: $('#investor').val(),\n        investor_cn: $('#investor_cn').val(),\n        investor_id: $('#investor_id').val(),\n        invite_code: $('#invite_code').val(),\n        product: $('#product').val(),\n        investment_amount: $('#investment_amount').val(),\n        return_rate: $('#return_rate').val(),\n        account_manager: $('#account_manager').val(),\n        account_manager_cn: $('#account_manager_cn').val(),\n        emp_num: $('#emp_num').val(),\n        store: $('#store').val(),\n        large_area: $('#large_area').val(),\n        area: $('#area').val(),\n        city: $('#city').val(),\n        start_date: $('#start_date').val(),\n        end_date: $('#end_date').val(),\n        lending_id: $('#lending_id').val(),\n        discount_amount: $('#discount_amount').val(),\n    };\n    return temp;\n}\n\n\n\n\n/*\n*获取bootstraptable 的列columns\n*/\nfunction get_columns() {\n    var columns =[{\n        title: '序号',//标题  可不加\n        formatter: function (value, row, index) {\n            return index+1;\n            }\n    }, {\n        field: 'id',\n        title: 'ID',\n        visible: false\n    }, {\n        field: 'name',\n        title: '名称',\n        formatter: nameFormatter\n    }, {\n        field: 'description',\n        title: '描述',\n        formatter: receiversFormatter\n    }, {\n        field: 'crontab',\n        title: '执行时间',\n    }, {\n        field: 'enabled',\n        title: '是否启用',\n        formatter: enabledFormatter\n    }, {\n        field: 'create_time',\n        title: '创建时间'\n    }, {\n        field: 'modify_time',\n        title: '修改时间'\n    }];\n    return columns\n}\n\n/*\n* 初始化表格\n* 数据量3千条以内的使用客户端分页\n*/\n$('#table').bootstrapTable({\n    url: '/batch_job/get_batch_job_data/',\n    pagination: true,                   //是否显示分页（*）\n    sortable: false,                     //是否启用排序\n    sortOrder: \"asc\",                   //排序方式\n    showColumns: true,\n    queryParams: queryParams,           //传递参数（*）\n    sidePagination: \"client\",           //分页方式：client客户端分页，server服务端分页（*）\n    pageNumber: 1,                       //初始化加载第一页，默认第一页\n    pageSize: 10,                       //每页的记录行数（*）\n    pageList: [10, 25, 50, 100],        //可供选择的每页的行数（*）\n    search: true,                  //是否显示搜索 --前端搜索\n    columns:get_columns()\n});\n\n/*\n*超链接显示收件人\n*/\nfunction receiversFormatter(value, row, index) {\n    return [\n        '<div class=\"text-overflow\"><a href=\"#\">',\n        value,\n        '</a></div>'\n    ].join('');\n}\n\n\n/*\n*超链接显示邮件标题\n*/\nfunction nameFormatter(value, row, index) {\n    var url = \"/batch_job/update_batch_job/\" + row.id;\n    return [\n        '<div><a class=\"mod\" href='+ url +'>',\n        value,\n        '</a></div>'\n    ].join('');\n}\n\n\n/*\n*格式化执行结果\n*/\nfunction enabledFormatter(value, row, index) {\n    let resultF = null;\n    let className = null;\n    switch (Number(value)){\n        case 0:\n            resultF = '否';\n            className = '';\n            break;\n        case 1:\n            resultF = '是';\n            className = '';\n            break;\n    }\n    return '<span class=\"label ' + className + '\">' + resultF + '</span>'\n}\n\n\n/*\n*ajax get callback\n*/\nfunction ajax_callback1(msg){\n    var index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n       layer.close(index)\n    });\n}\n\n</script>\n{% endblock %}"
  },
  {
    "path": "templates/batch_job/mod_crontabs.html",
    "content": "{% extends 'base.html' %}\n{% load ygol_filter_tag %}\n\n{% block header_content %}\n<style>\n.center {\n width: auto;\n display: table;\n margin-left: auto;\n margin-right: auto;\n}\n.text-center > table > tbody > tr > th,\n.text-center > table > thead > tr > th {\n text-align: center;\n}\n\n.table-responsive {\nwidth: 100%;\nmargin-bottom: 15px;\noverflow-x: scroll;\noverflow-y: hidden;\nborder: 1px solid #dddddd;\n-ms-overflow-style: -ms-autohiding-scrollbar;\n-webkit-overflow-scrolling: touch;\n}\n.table-responsive > .table {\nmargin-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 {\nwhite-space: nowrap;\n}\n\n.NoNewline\n{\nword-break: keep-all;/*必须*/\nwhite-space: nowrap;\n}\n</style>\n\t<!-- Datepicker -->\n    <link href=\"/static/template/css/bootstrap-datepicker.min.css\" rel=\"stylesheet\"/>\n    <!-- Gritter -->\n\t<link href=\"/static/template/css/gritter/jquery.gritter.css\" rel=\"stylesheet\">\n{% endblock %}\n\n\n{% block container %}\n<div id=\"main-container\">\n\t<div class=\"main-header clearfix\">\n\t\t<div class=\"page-title\">\n\t\t\t<h3 class=\"no-margin\">Mod crontab</h3>\n\t\t</div><!-- /page-title -->\n\t</div><!-- /main-header -->\n\n\n\t<div class=\"padding-md\">\n        <div class=\"row\">\n            <div class=\"col-md-12\">\n\t\t\t\t\t\t<div class=\"panel panel-default\">\n\t\t\t\t\t\t\t<form class=\"form-horizontal form-border no-margin\" id=\"basic-constraint\" data-validate=\"parsley\" novalidate>\n\t\t\t\t\t\t\t\t<div class=\"panel-heading\">\n\t\t\t\t\t\t\t\t\t请按照crontab格式填写，修改后请重新指定定时任务的执行时间\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div class=\"panel-body\">\n                                    <form class=\"form-horizontal form-border no-margin\" data-validate=\"parsley\" novalidate>\n                                        <div class=\"panel-body\" id=\"crontabModal\">\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">minute</label>\n                                                <div class=\"col-lg-5\">\n                                                    <input name=\"minute\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">hour</label>\n                                                <div class=\"col-lg-5\">\n                                                    <input name=\"hour\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">day_of_week</label>\n                                                <div class=\"col-lg-5\">\n                                                    <input name=\"day_of_week\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">day_of_month</label>\n                                                <div class=\"col-lg-5\">\n                                                    <input name=\"day_of_month\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">month_of_year</label>\n                                                <div class=\"col-lg-5\">\n                                                    <input name=\"month_of_year\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                        </div>\n                                    </form>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div class=\"panel-footer\">\n\t\t\t\t\t\t\t\t\t<button id=\"save_crontab\" type=\"button\" class=\"btn btn-success\">Save</button>\n\t\t\t\t\t\t\t\t\t<button id=\"delete_crontab\" type=\"button\" class=\"btn btn-danger pull-right\">Delete</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</form>\n\t\t\t\t\t\t</div><!-- /panel -->\n\t\t\t\t\t</div><!-- /.col-->\n        </div><!-- /.row -->\n\t</div><!-- /padding-md -->\n</div><!-- /main-container -->\n{% endblock %}\n\n{% block footer_content %}\n\n\n<!-- Datepicker -->\n<script src='/static/template/js/bootstrap-datepicker.js'></script>\n<script src='/static/template/js/bootstrap-datepicker.zh-CN.min.js'></script>\n<script src=\"/static/template/js/jquery.gritter.min.js\"></script>\n<!-- Modernizr -->\n{#<script src='/static/template/js/modernizr.min.js'></script>#}\n<script>\n$(document).ready(function(){\n    var index = layer.load();\n    Initialization_crontab();\n    layer.close(index);\n});\n\n\n/*\n*初始化crontab 时间\n*/\nfunction Initialization_crontab() {\n    var url = '/scheduled_tasks/get_mod_crontab_data/';\n    var str=location.href;\n    var args = str.split('/');\n    var _id = args[args.length-2];\n    var para = {'id': _id};\n    $.post(url, para, function (jdata) {\n        var _data = $.parseJSON(jdata);\n        console.log(_data)\n        $.each(_data, function (k, v) {\n            $(\"#crontabModal\").find('input').each(function () {\n            if ($(this).prop('name') == k) {\n                $(this).val(v);\n            }\n        });\n        });\n\n    })\n}\n\n\n/*\n*保存 crontab 时间\n*/\n$(\"#save_crontab\").click(function () {\n    var url = '/scheduled_tasks/add_crontab/';\n    var str=location.href;\n    var args = str.split('/');\n    var _id = args[args.length-2];\n    var para = {};\n    $(\"#crontabModal\").find('input').each(function () {\n        para[$(this).prop('name')] = $(this).val();\n    });\n    var jpara = JSON.stringify(para);\n    $.post(url, {'data': jpara}, function () {\n        var url =\"/scheduled_tasks/crontabs/\";\n        ajax_callback2('操作成功', url)\n    })\n});\n\n\n/*\n*删除 crontab 时间\n*/\n$(\"#delete_crontab\").click(function () {\n    var url = '/scheduled_tasks/delete_crontab/';\n    var str=location.href;\n    var args = str.split('/');\n    var _id = args[args.length-2];\n    var para = {'id': _id};\n    var jpara = JSON.stringify(para);\n        //询问框\n    layer.confirm('警告： 该执行时间所关联的任务也会全部删除！', {\n      btn: ['确定','取消'] //按钮\n    }, function () {\n            var index = layer.load();\n            $.post(url, {'data': jpara}, function () {\n                layer.close(index);\n                ajax_callback2('操作成功', \"/scheduled_tasks/crontabs/\");\n            });\n        }\n    );\n});\n\n\n/*\n*ajax get callback\n*/\nfunction ajax_callback1(msg){\n    var index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n       layer.close(index)\n    });\n}\n\n\n/*\n*ajax get callback2\n*/\nfunction ajax_callback2(msg, url){\n    var index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n        layer.close(index);\n        window.location=url;\n    });\n}\n</script>\n{% endblock %}"
  },
  {
    "path": "templates/batch_job/update_batch_job.html",
    "content": "{% extends 'base.html' %}\n\n{% block header_content %}\n<style>\n.center {\n width: auto;\n display: table;\n margin-left: auto;\n margin-right: auto;\n}\n.text-center > table > tbody > tr > th,\n.text-center > table > thead > tr > th {\n text-align: center;\n}\n\n.table-responsive {\nwidth: 100%;\nmargin-bottom: 15px;\noverflow-x: scroll;\noverflow-y: hidden;\nborder: 1px solid #dddddd;\n-ms-overflow-style: -ms-autohiding-scrollbar;\n-webkit-overflow-scrolling: touch;\n}\n.table-responsive > .table {\nmargin-bottom: 0;\n}\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 {\nwhite-space: nowrap;\n}\n\n.NoNewline\n{\nword-break: keep-all;/*必须*/\nwhite-space: nowrap;\n}\n\n/* 设置chosen菜单向上弹出 css样式 */\n.chosen-container .chosen-drop {\n    border-bottom: 0;\n    border-top: 1px solid #aaa;\n    top: auto;\n    bottom: 40px;\n}\n</style>\n\t<!-- Datepicker -->\n    <link href=\"/static/template/css/bootstrap-datepicker.min.css\" rel=\"stylesheet\"/>\n    <!-- Gritter -->\n\t<link href=\"/static/template/css/gritter/jquery.gritter.css\" rel=\"stylesheet\">\n{% endblock %}\n\n\n{% block container %}\n<div id=\"main-container\">\n\t<div class=\"main-header clearfix\">\n\t\t<div class=\"page-title\">\n\t\t\t<h3 class=\"no-margin\">更新批处理作业</h3>\n\t\t</div><!-- /page-title -->\n\t</div><!-- /main-header -->\n\n\n\t<div class=\"padding-md\">\n        <div class=\"row\">\n            <div class=\"col-md-12\">\n                <div class=\"panel panel-default\">\n                    <form class=\"form-horizontal form-border no-margin\" id=\"basic-constraint\" data-validate=\"parsley\" novalidate>\n                        <div class=\"panel-heading\">\n                            Update Batch Job\n                        </div>\n                        <div class=\"panel-body\">\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">任务名称</label>\n                                <div class=\"col-lg-4\">\n                                    <input type=\"text\" id=\"name\" class=\"form-control input-sm\" data-required=\"true\" placeholder=\"请输入英文\">\n                                </div><!-- /.col -->\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">描述</label>\n                                <div class=\"col-lg-4\">\n                                    <textarea id=\"description\" spellcheck=\"false\" class=\"form-control\" placeholder=\"describe the specific job\" rows=\"6\" data-required=\"true\"></textarea>\n                                </div><!-- /.col -->\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">任务模板</label>\n                                <div class=\"col-lg-3\">\n                                    <select id=\"task_template\" class=\"form-control\"></select>\n                                </div><!-- /.col -->\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">是否启用</label>\n                                <div class=\"col-lg-9\">\n                                    <div class=\"seperator\"></div>\n                                    <label class=\"label-checkbox inline\">\n                                        <input id=\"is_enable\" type=\"checkbox\" data-required=\"true\" name=\"chk-demo\" checked=\"checked\">\n                                        <span class=\"custom-checkbox\"></span>\n                                    </label>\n                                </div><!-- /.col -->\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">执行时间</label>\n                                <div class=\"col-lg-4\">\n                                    <select id=\"crontab\" class=\"form-control\">\n                                        <option>请选择</option>\n                                    </select>\n                                </div><!-- /.col -->\n                                <div class=\"col-lg-1\">\n                                    <a href=\"#crontabModal\" data-toggle=\"modal\" type=\"button\" class=\"btn btn-default\"><i class=\"fa fa-plus\"></i></a>\n                                </div>\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">作业详情</label>\n                                <div class=\"col-lg-9\">\n                                     <table class=\"table table-hover table-bordered NoNewline\" id=\"table\"></table>\n                                </div><!-- /.col -->\n                                <div class=\"col-lg-1\">\n                                    <button id=\"batch_job_delete_btn\" type=\"button\" class=\"btn btn-default\"><i class=\"fa fa-minus\"></i></button>\n                                </div>\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\"><span class=\"label label-info\">选择作业列表</span></label>\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">数据同步</label>\n                                <div class=\"col-lg-4\">\n                                    <select id=\"datax_job\" class=\"form-control chzn-select\">\n                                        <option value=\"-1\">请选择</option>\n                                    </select>\n                                </div><!-- /.col -->\n                                <div class=\"col-lg-1\">\n                                    <button data-toggle=\"modal\" type=\"button\" class=\"btn btn-default\"><i class=\"fa fa-plus\"></i></button>\n                                </div>\n                            </div><!-- /form-group -->\n                        </div>\n\n                        <div class=\"panel-footer\">\n                            <button id=\"save_job\" type=\"button\" class=\"btn btn-success\">Save</button>\n                            <button id=\"RunJob\" type=\"button\" class=\"btn btn-info\">Run</button>\n                        </div>\n                    </form>\n                    <div class=\"modal fade\" id=\"crontabModal\">\n                        <div class=\"modal-dialog\">\n                            <div class=\"modal-content\">\n                                <div class=\"modal-header\">\n                                    <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">&times;</button>\n                                    <h4>Add crontab</h4>\n                                </div>\n                                <div class=\"modal-body\">\n                                    <form class=\"form-horizontal form-border no-margin\" id=\"basic-constraint\" data-validate=\"parsley\" novalidate>\n                                        <div class=\"panel-body\">\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">minute</label>\n                                                <div class=\"col-lg-9\">\n                                                    <input name=\"minute\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">hour</label>\n                                                <div class=\"col-lg-9\">\n                                                    <input name=\"hour\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">day_of_week</label>\n                                                <div class=\"col-lg-9\">\n                                                    <input name=\"day_of_week\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">day_of_month</label>\n                                                <div class=\"col-lg-9\">\n                                                    <input name=\"day_of_month\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">month_of_year</label>\n                                                <div class=\"col-lg-9\">\n                                                    <input name=\"month_of_year\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                        </div>\n                                    </form>\n                                </div>\n                                <div class=\"modal-footer\">\n                                    <button class=\"btn btn-success btn-sm\" data-dismiss=\"modal\" aria-hidden=\"true\">Close</button>\n                                    <a id=\"save_crontab\" type=\"button\" class=\"btn btn-danger btn-sm\">Save</a>\n                                </div>\n                            </div><!-- /.modal-content -->\n                        </div><!-- /.modal-dialog -->\n                    </div><!-- /.modal -->\n                </div><!-- /panel -->\n            </div><!-- /.col-->\n        </div><!-- /.row -->\n\t</div><!-- /padding-md -->\n</div><!-- /main-container -->\n{% endblock %}\n\n{% block footer_content %}\n\n\n<!-- Datepicker -->\n<script src='/static/template/js/bootstrap-datepicker.js'></script>\n<script src='/static/template/js/bootstrap-datepicker.zh-CN.min.js'></script>\n<script src=\"/static/template/js/jquery.gritter.min.js\"></script>\n<!-- Modernizr -->\n{#<script src='/static/template/js/modernizr.min.js'></script>#}\n<script>\n$(document).ready(function(){\n    let index = layer.load();\n    Initialization_task_template();\n    Initialization_datax_job();\n    Initialization_crontab();\n    InitBatchjobDetailTable();\n    InitBatchJobData();\n    InitSubJob();\n    disableOperation();\n    layer.close(index);\n});\n\n\n/*\n*初始化任务模板\n*/\nfunction Initialization_task_template() {\n    let url = '/batch_job/get_task_template/';\n    $.ajax({\n        type: \"POST\",\n        url: url,\n        async: false, // false为同步，true为异步。默认为true\n        success: function(jdata){\n            let data = $.parseJSON(jdata);\n            $.each(data, function (k, v) {\n                let _option = \"<option value='\"+ v +\"'>\"+ v +\"</option>\";\n                $(\"#task_template\").append(_option);\n            });\n        }\n   })\n}\n\n\n/*\n*初始化 数据同步选择按钮select内容\n*/\nfunction Initialization_datax_job() {\n    let url = '/datax_web/get_job_data/';\n    let para = {};\n    $.post(url, para, function (jdata) {\n        let data = $.parseJSON(jdata);\n        $.each(data, function (k, v) {\n            let _option = \"<option value='\"+ v.id +\"'>\"+ v.name + \" \" + v.description +\"</option>\";\n            $(\"#datax_job\").append(_option);\n        });\n        $(\".chzn-select\").chosen({no_results_text: '没有找到', \"drop_direction\": \"down\", });\n    })\n}\n\n\n/*\n*初始化crontab 时间\n*/\nfunction Initialization_crontab() {\n    let url = '/batch_job/get_crontab/';\n    $.ajax({\n        type: \"POST\",\n        url: url,\n        async: false, // false为同步，true为异步。默认为true\n        success: function(jdata){\n            let _data = $.parseJSON(jdata);\n            $(\"#crontab\").empty();\n            $.each(_data, function (k, v) {\n                let _cont = [v.minute, v.hour, v.day_of_week, v.day_of_month, v.month_of_year];\n                let _option = \"<option value='\"+ v.id +\"'>\"+ _cont.join(' ')+ \" (分/时/周/日/月)\" +\"</option>\";\n                $(\"#crontab\").append(_option);\n            });\n        }\n   })\n}\n\n\n/**\n * 初始化批处理作业数据\n */\nfunction InitBatchJobData(){\n    let url = '/batch_job/get_batch_job_data_by_id/';\n    let _id = getId();\n    let para = {'_id': _id};\n    $.ajax({\n\t\ttype : \"post\",\n\t\turl : url,\n\t\tdata : para,\n\t\tsuccess : function (jdata) {\n\t\t\tlet data = $.parseJSON(jdata);\n\t\t\t$(\"#name\").val(data.name);\n\t\t\t$(\"#description\").val(data.description);\n\t\t\t$(\"#task_template\").val(data.task);\n\t\t\t$(\"#is_enable\").prop('checked', data.enabled);\n\t\t\t$(\"#crontab\").val(data.crontab_id);\n\n\t\t}\n  \t});\n}\n\n/**\n * 初始化子作业\n */\nfunction InitSubJob() {\n    let url = '/batch_job/get_batch_job_sub_job_by_id/';\n    let _id = getId();\n    let para = {'_id': _id};\n    $.ajax({\n\t\ttype : \"post\",\n\t\turl : url,\n\t\tdata : para,\n\t\tsuccess : function (jdata) {\n\t\t\tlet data = $.parseJSON(jdata);\n            $(\"#table\").bootstrapTable('append', data);\n\t\t}\n  \t});\n}\n\n\n/*\n*初始化批处理作业详情表格\n*/\nfunction InitBatchjobDetailTable(){\n    $('#table').bootstrapTable({\n        url: '#',\n        pagination: true,                   //是否显示分页（*）\n        sortable: false,                     //是否启用排序\n        sortOrder: \"asc\",                   //排序方式\n        showColumns: true,\n        queryParams: queryParams,           //传递参数（*）\n        sidePagination: \"client\",           //分页方式：client客户端分页，server服务端分页（*）\n        pageNumber: 1,                       //初始化加载第一页，默认第一页\n        pageSize: 10,                       //每页的记录行数（*）\n        pageList: [10, 25, 50, 100],        //可供选择的每页的行数（*）\n        search: true,                  //是否显示搜索 --前端搜索\n        columns:get_columns()\n    });\n}\n\n\n/*\n*得到查询的参数\n*/\nfunction queryParams(params) {\n    return {   //这里的键的名字和控制器的变量名必须一直，这边改动，控制器也需要改成一样的\n        limit: params.limit,   //页面大小\n        offset: params.offset,  //页码\n        name: $('#name').val(),\n        description: $('#description').val(),\n        reader_databaseinfo_host: $('#reader_databaseinfo_host').val(),\n        writer_databaseinfo_host: $('#writer_databaseinfo_host').val(),\n        status: $('#status').val(),\n        writer_table: $('#writer_table').val(),\n        result: $('#result').val(),\n        trigger_mode: $('#trigger_mode').val(),\n    };\n}\n\n\n/*\n*获取bootstraptable 的列columns\n*/\nfunction get_columns() {\n    return [{\n            field: 'checkbox',\n            checkbox: true,\n        },{\n            title: '序号',//标题  可不加\n            formatter: function (value, row, index) {\n                return index+1;\n                }\n        }, {\n            field: 'subjob_id',\n            title: 'ID',\n            visible: false\n        }, {\n            field: 'name',\n            title: '任务名称',\n            formatter: subjectFormatter\n        }, {\n            field: 'description',\n            title: '描述 '\n        }, {\n            field: 'type',\n            title: '类型',\n            formatter: typeFormatter\n    }];\n}\n\n\n/*\n*添加 crontab 时间\n*/\n$(\"#save_crontab\").click(function () {\n    var url = '/batch_job/add_crontab/';\n    var para = {};\n    $(\"#crontabModal\").find('input').each(function () {\n        para[$(this).prop('name')] = $(this).val();\n    });\n    var jpara = JSON.stringify(para);\n    $.post(url, {'data': jpara}, function () {\n        Initialization_crontab();\n        $('#crontabModal').modal('hide');\n        $.gritter.add({\n            title: \"<i class='fa fa-check-circle'></i> Success\",\n            text: ' 可选择新添加的crontab时间.',\n            sticky: false,\n            time: '',\n            class_name: 'gritter-success'\n        });\n        return false;\n    })\n});\n\n\n/*\n* 添加数据同步\n*/\n$('#datax_job').parent().next().click(function () {\n    let val = $(\"#datax_job\").val();\n    let text = $(\"#datax_job\").find(\"option:selected\").text();\n    let name = text.split(' ')[0];\n    let description = text.split(' ')[1];\n\n    if (val > 0){\n        let is_selected = false;\n        let selectedData = $(\"#table\").bootstrapTable('getData');\n        $.each(selectedData, function (k, v) {\n            if (v.subjob_id == val){\n                is_selected = true;\n                layer.msg(v.description + ' 已添加');\n           }\n        });\n        if (!is_selected){\n            let row = {'subjob_id': val, 'name':name, 'description': description, 'type': 1};\n            $(\"#table\").bootstrapTable('append', [row]);\n        }\n    }\n});\n\n\n/*\n*删除批处理作业详情\n*/\n$(\"#batch_job_delete_btn\").click(function () {\n    let selectedData = $(\"#table\").bootstrapTable('getSelections');\n    let ids = $.map(selectedData, function (row) {\n        return row.subjob_id\n    });\n    $('#table').bootstrapTable('remove', {field: 'subjob_id', values: ids});\n});\n\n\n/*\n*保存任务 save job\n*/\n$(\"#save_job\").click(function () {\n    let _id = getId();\n    let para = get_para();\n    para['_id'] = _id;\n    para['trigger_mode'] = 2;\n    let jpara = JSON.stringify(para);\n    let url = '/batch_job/add_batch_job_data/';\n    let index = layer.load();\n    $.post(url, {'data': jpara}, function (res) {\n        let _data = $.parseJSON(res);\n        layer.close(index);\n        // 成功则跳转列表页面，失败则提示错误信息继续修改。\n        if (_data.status == 0) {\n            let url =\"/batch_job/index/\";\n            ajax_callback2(_data.msg, url)\n        }\n        else{\n            ajax_callback1(_data.msg);\n        }\n    });\n});\n\n\n/*\n*获取提交的信息\n*/\nfunction get_para() {\n    let name = $(\"#name\").val().trim();\n    let description = $(\"#description\").val().trim();\n    let task_template = $(\"#task_template\").val().trim();\n    let is_enable = $(\"#is_enable\").is(\":checked\");\n    let crontab = $(\"#crontab\").val().trim();\n    let batch_job_details = $('#table').bootstrapTable('getData');\n\n    return {\n        'operation_type': 2,\n        'name': name,\n        'description': description,\n        'task_template': task_template,\n        'is_enable': is_enable,\n        'crontab': crontab,\n        'batch_job_details': batch_job_details,\n    }\n}\n\n\n/*\n* 超链接显示\n* 子作业扩展后，需要根据子作业类型生成url\n*/\nfunction subjectFormatter(value, row, index) {\n    let url = \"/datax_web/update_job/\" + row.subjob_id;\n    return [\n        '<div><a target=\"_black\" class=\"mod\" href='+ url +'>',\n        value,\n        '</a></div>'\n    ].join('');\n}\n\n\n/*\n*格式化执行结果\n*/\nfunction typeFormatter(value, row, index) {\n    let resultF = null;\n    let className = null;\n    switch (Number(value)){\n        case 1:\n            resultF = '数据同步';\n            className = '';\n            break;\n        case 2:\n            resultF = 'SQL脚本';\n            className = 'label-danger';\n            break;\n        case 3:\n            resultF = '备份';\n            className = 'label-info';\n            break;\n    }\n    return '<span class=\"label ' + className + '\">' + resultF + '</span>'\n}\n\n\n/**\n* 运行任务 run job\n*/\n$(\"#RunJob\").click(function () {\n    let para = get_para();\n    para['_id'] = getId();\n    para['trigger_mode'] = 2;\n    let jpara = JSON.stringify(para);\n    let url = '/batch_job/run_batch_job_task/';\n    let index = layer.load();\n    $.post(url, {'data': jpara}, function (res) {\n        let _data = $.parseJSON(res);\n        layer.close(index);\n        ajax_callback1(_data.msg)\n    });\n});\n\n\n\n\n\n/**\n * 获取URL后面的ID\n * return: _id\n */\nfunction getId() {\n    let str=location.href;\n    let args = str.split('/');\n    return args[args.length-2];\n}\n\n\n/**\n * 根据权限禁用用户操作\n */\nfunction disableOperation() {\n    let data = {'permission': 'batch_job.editBatchJob'};\n    $.ajax({\n        type: 'POST',\n        url: \"/check_permission/\",\n        data: data,\n        success: function (jret) {\n            let ret = $.parseJSON(jret);\n            if (ret.status == 1){\n                $('input,select,button,textarea').attr('disabled', 'disabled')\n            }\n        }\n    });\n}\n\n\n/*\n*ajax get callback\n*/\nfunction ajax_callback1(msg){\n    let index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n       layer.close(index)\n    });\n}\n\n\n/*\n*ajax get callback2\n*/\nfunction ajax_callback2(msg, url){\n    let index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n        layer.close(index);\n        window.location=url;\n    });\n}\n</script>\n{% endblock %}"
  },
  {
    "path": "templates/batch_job/update_job.html",
    "content": "{% extends 'base.html' %}\n\n{% block header_content %}\n<style>\n.center {\n width: auto;\n display: table;\n margin-left: auto;\n margin-right: auto;\n}\n.text-center > table > tbody > tr > th,\n.text-center > table > thead > tr > th {\n text-align: center;\n}\n\n.table-responsive {\nwidth: 100%;\nmargin-bottom: 15px;\noverflow-x: scroll;\noverflow-y: hidden;\nborder: 1px solid #dddddd;\n-ms-overflow-style: -ms-autohiding-scrollbar;\n-webkit-overflow-scrolling: touch;\n}\n.table-responsive > .table {\nmargin-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 {\nwhite-space: nowrap;\n}\n\n.NoNewline\n{\nword-break: keep-all;/*必须*/\nwhite-space: nowrap;\n}\n</style>\n\t<!-- Datepicker -->\n    <link href=\"/static/template/css/bootstrap-datepicker.min.css\" rel=\"stylesheet\"/>\n    <!-- Gritter -->\n\t<link href=\"/static/template/css/gritter/jquery.gritter.css\" rel=\"stylesheet\">\n{% endblock %}\n\n\n{% block container %}\n<div id=\"main-container\">\n\t<div class=\"main-header clearfix\">\n\t\t<div class=\"page-title\">\n\t\t\t<h3 class=\"no-margin\">更新 数据同步</h3>\n\t\t</div><!-- /page-title -->\n\t</div><!-- /main-header -->\n\n\n\t<div class=\"padding-md\">\n        <div class=\"row\">\n            <div class=\"col-md-12\">\n                <div class=\"panel panel-default\">\n                    <form class=\"form-horizontal form-border no-margin\" id=\"basic-constraint\" data-validate=\"parsley\" novalidate>\n                        <div class=\"panel-heading\">\n                            Add Job\n                        </div>\n                        <div class=\"panel-body\">\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">任务名称</label>\n                                <div class=\"col-lg-4\">\n                                    <input type=\"text\" id=\"name\" class=\"form-control input-sm\" data-required=\"true\" placeholder=\"请输入英文\">\n                                </div><!-- /.col -->\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">描述</label>\n                                <div class=\"col-lg-4\">\n                                    <textarea id=\"description\" spellcheck=\"false\" class=\"form-control\" placeholder=\"describe the specific job\" rows=\"6\" data-required=\"true\"></textarea>\n                                </div><!-- /.col -->\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">查询SQL语句</label>\n                                <div class=\"col-lg-4\">\n                                    <textarea id=\"querySql\" spellcheck=\"false\" class=\"form-control\" placeholder=\"SQL statement that reads data\" rows=\"6\" data-required=\"true\"></textarea>\n                                </div><!-- /.col -->\n                                <span class=\"col-lg-2\">SQL语句里指明数据库</span>\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">读取数据库</label>\n                                <div class=\"col-lg-4\">\n                                    <select id=\"reader_databaseinfo_id\" class=\"form-control\">\n                                        <option>请选择</option>\n                                    </select>\n                                </div><!-- /.col -->\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">写入表名</label>\n                                <div class=\"col-lg-4\">\n                                    <input type=\"text\" id=\"writer_table\" class=\"form-control input-sm\" data-required=\"true\" placeholder=\"请输入英文\">\n                                </div><!-- /.col -->\n                                <span class=\"col-lg-2\">指明数据库，如：jr_user.user_info. 末尾不用加分号 ;</span>\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">写入表的列</label>\n                                <div class=\"col-lg-4\">\n                                    <textarea id=\"writer_column_id\" spellcheck=\"false\" class=\"form-control\" placeholder=\"Write columns\" rows=\"6\" data-required=\"true\"></textarea>\n                                </div><!-- /.col -->\n                                <span class=\"col-lg-3\">每行一列, \"*\" 星号代表所有列。</span>\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">写入数据库</label>\n                                <div class=\"col-lg-4\">\n                                    <select id=\"writer_databaseinfo_id\" class=\"form-control\">\n                                        <option>请选择</option>\n                                    </select>\n                                </div><!-- /.col -->\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">写入数据前执行的SQL语句</label>\n                                <div class=\"col-lg-4\">\n                                    <textarea id=\"writer_preSql\" spellcheck=\"false\" class=\"form-control\" placeholder=\"SQL statements executed before writing data\" rows=\"6\" data-required=\"true\"></textarea>\n                                </div><!-- /.col -->\n                                <span class=\"col-lg-2\">每条SQL语句末尾要带；分号，指明数据库. 如 truncate table `admin-service`.as_user_info;</span>\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">写入数据后执行的SQL语句</label>\n                                <div class=\"col-lg-4\">\n                                    <textarea id=\"writer_postSql\" spellcheck=\"false\" class=\"form-control\" placeholder=\"SQL statements executed after writing data\" rows=\"6\" data-required=\"true\"></textarea>\n                                </div><!-- /.col -->\n                                <span class=\"col-lg-2\">每条SQL语句末尾要带；分号</span>\n                            </div><!-- /form-group -->\n                        </div>\n                        <div class=\"panel-footer\">\n                            <button id=\"save_job\" type=\"button\" class=\"btn btn-success\">Save</button>\n                            <button id=\"RunJob\" type=\"button\" class=\"btn btn-info\">Run</button>\n                        </div>\n                    </form>\n                </div><!-- /panel -->\n\t\t\t\t\t</div><!-- /.col-->\n        </div><!-- /.row -->\n\t</div><!-- /padding-md -->\n</div><!-- /main-container -->\n{% endblock %}\n\n{% block footer_content %}\n\n\n<!-- Datepicker -->\n<script src='/static/template/js/bootstrap-datepicker.js'></script>\n<script src='/static/template/js/bootstrap-datepicker.zh-CN.min.js'></script>\n<script src=\"/static/template/js/jquery.gritter.min.js\"></script>\n<!-- Modernizr -->\n{#<script src='/static/template/js/modernizr.min.js'></script>#}\n<script>\n$(document).ready(function(){\n    var index = layer.load();\n    Initialization_Database();\n    init_update_job_data();\n    layer.close(index);\n});\n\n\n\n/*\n*获取需要修改的周期任务数据\n*/\nfunction init_update_job_data() {\n    var url = '/datax_web/get_update_job_data/';\n    var str=location.href;\n    var args = str.split('/');\n    var _id = args[args.length-2];\n    var para = {'_id': _id};\n\t$.ajax({\n\t\ttype : \"post\",\n\t\turl : url,\n\t\tdata : para,\n\t\tsuccess : function (jdata) {\n\t\t\tvar data = $.parseJSON(jdata);\n\t\t\t$(\"#name\").val(data.name);\n\t\t\t$(\"#description\").val(data.description);\n\t\t\t$(\"#querySql\").val(data.querySql);\n\t\t\t$(\"#reader_databaseinfo_id\").val(data.reader_databaseinfo_id);\n\t\t\t$(\"#writer_table\").val(data.writer_table);\n\t\t\t$(\"#writer_databaseinfo_id\").val(data.writer_databaseinfo_id);\n\t\t\t$(\"#writer_preSql\").val(data.writer_preSql);\n\t\t\t$(\"#writer_postSql\").val(data.writer_postSql);\n\t\t\t$(\"#writer_column_id\").val(data.writer_column_id);\n\t\t}\n  \t});\n}\n\n\n/*\n*初始化数据库\n*/\nfunction Initialization_Database() {\n    var url = '/datax_web/get_database/';\n    var para = {};\n\t$.ajax({\n\t\ttype : \"post\",\n\t\turl : url,\n\t\tdata : para,\n\t\tasync: false,\n\t\tsuccess : function (jdata) {\n\t\t\tvar _data = $.parseJSON(jdata);\n\t\t\t$.each(_data, function (k, v) {\n\t\t\t\tvar _option = \"<option value='\"+ v.id +\"'>\"+ v.description + \"  \" + v.host +\"</option>\";\n\t\t\t\t$(\"#reader_databaseinfo_id\").append(_option);\n\t\t\t\t$(\"#writer_databaseinfo_id\").append(_option);\n\t\t\t});\n\t  \t}\n  \t});\n}\n\n\n/*\n*保存任务 save job\n*/\n$(\"#save_job\").click(function () {\n    var para = get_para();\n    var jpara = JSON.stringify(para);\n    var url = '/datax_web/add_job_data/';\n    var index = layer.load();\n    $.post(url, {'data': jpara}, function (res) {\n        var _data = $.parseJSON(res);\n        layer.close(index);\n        // 成功则跳转列表页面，失败则提示错误信息继续修改。\n        if (_data.status == 0) {\n            var url =\"/datax_web/index/\";\n            ajax_callback2(_data.msg, url)\n        }\n        else{\n            ajax_callback1(_data.msg);\n        }\n    });\n});\n\n\n/*\n*运行任务 run job\n*/\n$(\"#RunJob\").click(function () {\n    let para = get_para();\n    let jpara = JSON.stringify(para);\n    let url = '/datax_web/run_job/';\n    let index = layer.load();\n    $.post(url, {'data': jpara}, function (res) {\n        let _data = $.parseJSON(res);\n        console.log(_data);\n        layer.close(index);\n        ajax_callback1(_data.msg)\n    });\n});\n\n\n/*\n*获取提交的信息\n*/\nfunction get_para() {\n    let str=location.href;\n\tlet args = str.split('/');\n    let _id = args[args.length-2];\n    let name = $(\"#name\").val().trim();\n    let description = $(\"#description\").val().trim();\n    let querySql = $(\"#querySql\").val().trim();\n    let reader_databaseinfo_id = $(\"#reader_databaseinfo_id\").val().trim();\n    let writer_table = $(\"#writer_table\").val().trim();\n    let writer_column_id = strToArray($('#writer_column_id'));\n    let writer_databaseinfo_id = $(\"#writer_databaseinfo_id\").val().trim();\n    let writer_preSql = $(\"#writer_preSql\").val().trim();\n    let writer_postSql = $(\"#writer_postSql\").val().trim();\n\n    return {\n        '_id': _id,\n        'operation_type': 'mod',\n        'name': name,\n        'description': description,\n        'querySql': querySql,\n        'reader_databaseinfo_id': reader_databaseinfo_id,\n        'writer_table': writer_table,\n        'writer_column_id': writer_column_id,\n        'writer_databaseinfo_id': writer_databaseinfo_id,\n        'writer_preSql': writer_preSql,\n        'writer_postSql': writer_postSql,\n        'trigger_mode': 2,\n    }\n}\n\n\n/*\n*获取邮件人列表\n*/\nfunction strToArray (div) {\n    let data = [];\n    let val = div.val().trim();\n    if (val.length != 0) {\n        data = val.split(\"\\n\");\n    }\n    return data\n}\n\n\n/*\n*ajax get callback\n*/\nfunction ajax_callback1(msg){\n    let index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n       layer.close(index)\n    });\n}\n\n\n/*\n*ajax get callback2\n*/\nfunction ajax_callback2(msg, url){\n    let index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n        layer.close(index);\n        window.location=url;\n    });\n}\n</script>\n{% endblock %}"
  },
  {
    "path": "templates/datax_web/add_crontabs.html",
    "content": "{% extends 'base.html' %}\n{% load ygol_filter_tag %}\n\n{% block header_content %}\n<style>\n.center {\n width: auto;\n display: table;\n margin-left: auto;\n margin-right: auto;\n}\n.text-center > table > tbody > tr > th,\n.text-center > table > thead > tr > th {\n text-align: center;\n}\n\n.table-responsive {\nwidth: 100%;\nmargin-bottom: 15px;\noverflow-x: scroll;\noverflow-y: hidden;\nborder: 1px solid #dddddd;\n-ms-overflow-style: -ms-autohiding-scrollbar;\n-webkit-overflow-scrolling: touch;\n}\n.table-responsive > .table {\nmargin-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 {\nwhite-space: nowrap;\n}\n\n.NoNewline\n{\nword-break: keep-all;/*必须*/\nwhite-space: nowrap;\n}\n</style>\n\t<!-- Datepicker -->\n    <link href=\"/static/template/css/bootstrap-datepicker.min.css\" rel=\"stylesheet\"/>\n    <!-- Gritter -->\n\t<link href=\"/static/template/css/gritter/jquery.gritter.css\" rel=\"stylesheet\">\n{% endblock %}\n\n\n{% block container %}\n<div id=\"main-container\">\n\t<div class=\"main-header clearfix\">\n\t\t<div class=\"page-title\">\n\t\t\t<h3 class=\"no-margin\">Add crontab</h3>\n\t\t</div><!-- /page-title -->\n\t</div><!-- /main-header -->\n\n\n\t<div class=\"padding-md\">\n        <div class=\"row\">\n            <div class=\"col-md-12\">\n\t\t\t\t\t\t<div class=\"panel panel-default\">\n\t\t\t\t\t\t\t<form class=\"form-horizontal form-border no-margin\" id=\"basic-constraint\" data-validate=\"parsley\" novalidate>\n\t\t\t\t\t\t\t\t<div class=\"panel-heading\">\n\t\t\t\t\t\t\t\t\t请按照crontab格式修改，修改后请重新指定定时任务的执行时间\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div class=\"panel-body\">\n                                    <form class=\"form-horizontal form-border no-margin\" data-validate=\"parsley\" novalidate>\n                                        <div class=\"panel-body\" id=\"crontabModal\">\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">minute</label>\n                                                <div class=\"col-lg-5\">\n                                                    <input name=\"minute\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">hour</label>\n                                                <div class=\"col-lg-5\">\n                                                    <input name=\"hour\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">day_of_week</label>\n                                                <div class=\"col-lg-5\">\n                                                    <input name=\"day_of_week\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">day_of_month</label>\n                                                <div class=\"col-lg-5\">\n                                                    <input name=\"day_of_month\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">month_of_year</label>\n                                                <div class=\"col-lg-5\">\n                                                    <input name=\"month_of_year\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                        </div>\n                                    </form>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div class=\"panel-footer\">\n\t\t\t\t\t\t\t\t\t<button id=\"save_crontab\" type=\"button\" class=\"btn btn-success\">Save</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</form>\n\t\t\t\t\t\t</div><!-- /panel -->\n\t\t\t\t\t</div><!-- /.col-->\n        </div><!-- /.row -->\n\t</div><!-- /padding-md -->\n</div><!-- /main-container -->\n{% endblock %}\n\n{% block footer_content %}\n\n\n<!-- Datepicker -->\n<script src='/static/template/js/bootstrap-datepicker.js'></script>\n<script src='/static/template/js/bootstrap-datepicker.zh-CN.min.js'></script>\n<script src=\"/static/template/js/jquery.gritter.min.js\"></script>\n<!-- Modernizr -->\n{#<script src='/static/template/js/modernizr.min.js'></script>#}\n<script>\n/*\n*添加 crontab 时间\n*/\n$(\"#save_crontab\").click(function () {\n    var url = '/scheduled_tasks/add_crontab/';\n    var para = {};\n    $(\"#crontabModal\").find('input').each(function () {\n        para[$(this).prop('name')] = $(this).val();\n    });\n    var jpara = JSON.stringify(para);\n    $.post(url, {'data': jpara}, function () {\n        var url =\"/scheduled_tasks/crontabs/\";\n        ajax_callback2('操作成功', url)\n    })\n});\n\n\n/*\n*ajax get callback2\n*/\nfunction ajax_callback2(msg, url){\n    var index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n        layer.close(index);\n        window.location=url;\n    });\n}\n</script>\n{% endblock %}"
  },
  {
    "path": "templates/datax_web/add_job.html",
    "content": "{% extends 'base.html' %}\n\n{% block header_content %}\n<style>\n.center {\n width: auto;\n display: table;\n margin-left: auto;\n margin-right: auto;\n}\n.text-center > table > tbody > tr > th,\n.text-center > table > thead > tr > th {\n text-align: center;\n}\n\n.table-responsive {\nwidth: 100%;\nmargin-bottom: 15px;\noverflow-x: scroll;\noverflow-y: hidden;\nborder: 1px solid #dddddd;\n-ms-overflow-style: -ms-autohiding-scrollbar;\n-webkit-overflow-scrolling: touch;\n}\n.table-responsive > .table {\nmargin-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 {\nwhite-space: nowrap;\n}\n\n.NoNewline\n{\nword-break: keep-all;/*必须*/\nwhite-space: nowrap;\n}\n</style>\n\t<!-- Datepicker -->\n    <link href=\"/static/template/css/bootstrap-datepicker.min.css\" rel=\"stylesheet\"/>\n    <!-- Gritter -->\n\t<link href=\"/static/template/css/gritter/jquery.gritter.css\" rel=\"stylesheet\">\n{% endblock %}\n\n\n{% block container %}\n<div id=\"main-container\">\n\t<div class=\"main-header clearfix\">\n\t\t<div class=\"page-title\">\n\t\t\t<h3 class=\"no-margin\">新增 数据同步</h3>\n\t\t</div><!-- /page-title -->\n\t</div><!-- /main-header -->\n\n\n\t<div class=\"padding-md\">\n        <div class=\"row\">\n            <div class=\"col-md-12\">\n\t\t\t\t\t\t<div class=\"panel panel-default\">\n\t\t\t\t\t\t\t<form class=\"form-horizontal form-border no-margin\" id=\"basic-constraint\" data-validate=\"parsley\" novalidate>\n\t\t\t\t\t\t\t\t<div class=\"panel-heading\">\n\t\t\t\t\t\t\t\t\tAdd Job\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div class=\"panel-body\">\n\t\t\t\t\t\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t\t\t\t\t\t<label class=\"control-label col-lg-2\">任务名称</label>\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-4\">\n\t\t\t\t\t\t\t\t\t\t\t<input type=\"text\" id=\"name\" class=\"form-control input-sm\" data-required=\"true\" placeholder=\"请输入英文\">\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t\t\t\t</div><!-- /form-group -->\n                                    <div class=\"form-group\">\n\t\t\t\t\t\t\t\t\t\t<label class=\"control-label col-lg-2\">描述</label>\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-4\">\n\t\t\t\t\t\t\t\t\t\t\t<textarea id=\"description\" spellcheck=\"false\" class=\"form-control\" placeholder=\"describe the specific job\" rows=\"6\" data-required=\"true\"></textarea>\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t\t\t\t</div><!-- /form-group -->\n                                    <div class=\"form-group\">\n\t\t\t\t\t\t\t\t\t\t<label class=\"control-label col-lg-2\">查询SQL语句</label>\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-4\">\n\t\t\t\t\t\t\t\t\t\t\t<textarea id=\"querySql\" spellcheck=\"false\" class=\"form-control\" placeholder=\"SQL statement that reads data\" rows=\"6\" data-required=\"true\"></textarea>\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n                                        <span class=\"col-lg-2\">SQL语句里指明数据库</span>\n\t\t\t\t\t\t\t\t\t</div><!-- /form-group -->\n                                    <div class=\"form-group\">\n\t\t\t\t\t\t\t\t\t\t<label class=\"control-label col-lg-2\">读取数据库</label>\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-4\">\n                                            <select id=\"reader_databaseinfo_id\" class=\"form-control\">\n                                                <option>请选择</option>\n                                            </select>\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t\t\t\t</div><!-- /form-group -->\n                                    <div class=\"form-group\">\n\t\t\t\t\t\t\t\t\t\t<label class=\"control-label col-lg-2\">写入表名</label>\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-4\">\n\t\t\t\t\t\t\t\t\t\t\t<input type=\"text\" id=\"writer_table\" class=\"form-control input-sm\" data-required=\"true\" placeholder=\"请输入英文\">\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n                                        <span class=\"col-lg-2\">指明数据库，如：jr_user.user_info. 末尾不用加分号 ;</span>\n\t\t\t\t\t\t\t\t\t</div><!-- /form-group -->\n\t\t\t\t\t\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t\t\t\t\t\t<label class=\"control-label col-lg-2\">写入表的列</label>\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-4\">\n\t\t\t\t\t\t\t\t\t\t\t<textarea id=\"writer_column_id\" spellcheck=\"false\" class=\"form-control\" placeholder=\"Write columns\" rows=\"6\" data-required=\"true\"></textarea>\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n                                        <span class=\"col-lg-3\">每行一列, \"*\" 星号代表所有列。</span>\n\t\t\t\t\t\t\t\t\t</div><!-- /form-group -->\n                                    <div class=\"form-group\">\n\t\t\t\t\t\t\t\t\t\t<label class=\"control-label col-lg-2\">写入数据库</label>\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-4\">\n                                            <select id=\"writer_databaseinfo_id\" class=\"form-control\">\n                                                <option>请选择</option>\n                                            </select>\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t\t\t\t</div><!-- /form-group -->\n                                    <div class=\"form-group\">\n\t\t\t\t\t\t\t\t\t\t<label class=\"control-label col-lg-2\">写入数据前执行的SQL语句</label>\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-4\">\n\t\t\t\t\t\t\t\t\t\t\t<textarea id=\"writer_preSql\" spellcheck=\"false\" class=\"form-control\" placeholder=\"SQL statements executed before writing data\" rows=\"6\" data-required=\"true\"></textarea>\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n                                        <span class=\"col-lg-2\">每条SQL语句末尾要带；分号，指明数据库. 如 truncate table `admin-service`.as_user_info; 注意：SQL语句里面不要带分号;</span>\n\t\t\t\t\t\t\t\t\t</div><!-- /form-group -->\n                                    <div class=\"form-group\">\n\t\t\t\t\t\t\t\t\t\t<label class=\"control-label col-lg-2\">写入数据后执行的SQL语句</label>\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-4\">\n\t\t\t\t\t\t\t\t\t\t\t<textarea id=\"writer_postSql\" spellcheck=\"false\" class=\"form-control\" placeholder=\"SQL statements executed after writing data\" rows=\"6\" data-required=\"true\"></textarea>\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n                                        <span class=\"col-lg-2\">每条SQL语句末尾要带；分号。 注意：SQL语句里面不要带分号;</span>\n\t\t\t\t\t\t\t\t\t</div><!-- /form-group -->\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div class=\"panel-footer\">\n\t\t\t\t\t\t\t\t\t<button id=\"save_job\" type=\"button\" class=\"btn btn-success\">Save</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</form>\n\t\t\t\t\t\t</div><!-- /panel -->\n\t\t\t\t\t</div><!-- /.col-->\n        </div><!-- /.row -->\n\t</div><!-- /padding-md -->\n</div><!-- /main-container -->\n{% endblock %}\n\n{% block footer_content %}\n\n\n<!-- Datepicker -->\n<script src='/static/template/js/bootstrap-datepicker.js'></script>\n<script src='/static/template/js/bootstrap-datepicker.zh-CN.min.js'></script>\n<script src=\"/static/template/js/jquery.gritter.min.js\"></script>\n<!-- Modernizr -->\n{#<script src='/static/template/js/modernizr.min.js'></script>#}\n<script>\n$(document).ready(function(){\n    var index = layer.load();\n    // Initialization_task_template();\n    // Initialization_cc();\n    // Initialization_crontab();\n    Initialization_Database();\n    layer.close(index);\n});\n\n\n/*\n*初始化任务模板\n*/\nfunction Initialization_task_template() {\n    var url = '/scheduled_tasks/get_task_template/';\n    var para = {};\n    $.post(url, para, function (jdata) {\n        var data = $.parseJSON(jdata);\n        $.each(data, function (k, v) {\n            var _option = \"<option value='\"+ v +\"'>\"+ v +\"</option>\";\n            $(\"#task_template\").append(_option);\n        });\n    })\n}\n\n\n/*\n*初始化 抄送人列表\n*/\nfunction Initialization_cc() {\n    var _cc_list = ['liudongdong@yingu.com', 'huangxiaoxue@yingu.com', 'database@yingu.com'];\n    $.each(_cc_list, function (k, v) {\n        $(\"#cc\").append(v);\n        $(\"#cc\").append('\\n');\n    })\n}\n\n\n/*\n*初始化crontab 时间\n*/\nfunction Initialization_crontab() {\n    var url = '/scheduled_tasks/get_crontab/';\n    var para = {};\n    $.post(url, para, function (jdata) {\n        var _data = $.parseJSON(jdata);\n        $(\"#crontab\").empty();\n        $.each(_data, function (k, v) {\n            var _cont = [v.minute, v.hour, v.day_of_week, v.day_of_month, v.month_of_year];\n            var _option = \"<option value='\"+ v.id +\"'>\"+ _cont.join(' ')+ \" (分/时/周/日/月)\" +\"</option>\";\n            $(\"#crontab\").append(_option);\n        });\n    })\n}\n\n\n/*\n*添加 crontab 时间\n*/\n$(\"#save_crontab\").click(function () {\n    var url = '/scheduled_tasks/add_crontab/';\n    var para = {};\n    $(\"#crontabModal\").find('input').each(function () {\n        para[$(this).prop('name')] = $(this).val();\n    });\n    var jpara = JSON.stringify(para);\n    $.post(url, {'data': jpara}, function () {\n        Initialization_crontab();\n        $('#crontabModal').modal('hide');\n        $.gritter.add({\n            title: \"<i class='fa fa-check-circle'></i> Success\",\n            text: ' 可选择新添加的crontab时间.',\n            sticky: false,\n            time: '',\n            class_name: 'gritter-success'\n        });\n        return false;\n    })\n});\n\n\n/*\n*初始化数据库\n*/\nfunction Initialization_Database() {\n    var url = '/datax_web/get_database/';\n    var para = {};\n    $.post(url, para, function (jdata) {\n        var _data = $.parseJSON(jdata);\n        $.each(_data, function (k, v) {\n            // var _option = \"<option ip='\"+ v.host +\"' value='\"+ v.id +\"'>\"+ v.description + \"</option>\";\n            var _option = \"<option value='\"+ v.id +\"'>\"+ v.description + \"  \" + v.host +\"</option>\";\n            $(\"#reader_databaseinfo_id\").append(_option);\n            $(\"#writer_databaseinfo_id\").append(_option);\n        });\n    })\n}\n\n\n/*\n*设置数据响应类型\n*/\n$('body').on('change', '#response_type', function() {\n    if ($(this).val() == 2){\n        $('#max_excel_num').parents(\".form-group\").removeClass('hide');\n        $('#add_sql').parents(\".form-group\").nextAll().find(\"input[name='interval']\").parents('tr').show();\n\n    }\n    else {\n        $('#max_excel_num').parents(\".form-group\").addClass('hide');\n        $('#add_sql').parents(\".form-group\").nextAll().find(\"input[name='interval']\").parents('tr').hide();\n    }\n});\n\n\n/*\n*添加 sql div\n*/\n$(\"#add_sql\").click(function () {\n    var sqldiv = $(this).parents('.panel-body');\n    var _sql_html = $(this).parents('.form-group').prev().html();\n    sqldiv.append(\"<div class='form-group'></div>\");\n    sqldiv.children().last().html(_sql_html);\n    if ($(\"#response_type\").val() != 2){\n        $('#add_sql').parents(\".form-group\").nextAll().find(\"input[name='interval']\").parents('tr').hide();\n    };\n    count_sqldiv();\n});\n\n\n/*\n*设置 sql div 元素个数\n*/\nfunction count_sqldiv() {\n   var _count = $(\"#add_sql\").parents('.form-group').nextAll().length;\n    $(\"#add_sql\").next().text(\"总数 \"+ _count + \"条\");\n}\n\n\n/*\n*sql div 元素 checkbox 全选/反选\n*/\n$(\"#select_sql\").click(function () {\n    var _result = $(this).is(':checked');\n    if (_result){\n        $(\"input[name='chk_sql']\").prop(\"checked\", true);\n    }\n    else {\n        $(\"input[name='chk_sql']\").prop(\"checked\", false);\n    }\n});\n\n\n/*\n*sql apply 按钮,  显示、隐藏、删除 sql div元素\n*/\n$(\"#sql_apply\").click(function () {\n    var _result = $(this).prev().val();\n    if (_result==0){\n        hide_sql_div($(this));\n    }\n    else if(_result==1) {\n        show_sql_div($(this));\n    }\n    else {\n        delete_sql_div($(this));\n    }\n});\n\n\n/*\n*隐藏所有选中的 sql div 元素\n*/\nfunction hide_sql_div(div) {\n    div.parents(\".form-group\").nextAll().find(\"input[name='chk_sql']\").each(function () {\n        var _result = $(this).prop(\"checked\");\n        if (_result) {\n            $(this).parent().nextAll().eq(0).addClass(\"hide\");\n            var _div2 = $(this).parent().nextAll().eq(1);\n            _div2.addClass(\"hide\");\n            var sqlname = _div2.find('input').val();\n            var _div3 = $(this).parent().nextAll().eq(2);\n            _div3.children().text(sqlname);\n            _div3.removeClass(\"hide\");\n        }\n    })\n}\n\n/*\n*显示所有选中的 sql div 元素\n*/\nfunction show_sql_div(div) {\n    div.parents(\".form-group\").nextAll().find(\"input[name='chk_sql']\").each(function () {\n        var _result = $(this).prop(\"checked\");\n        if (_result) {\n            $(this).parent().nextAll().eq(0).removeClass(\"hide\");\n            var _div2 = $(this).parent().nextAll().eq(1);\n            _div2.removeClass(\"hide\");\n            var sqlname = _div2.find('input').val();\n            var _div3 = $(this).parent().nextAll().eq(2);\n            _div3.children().text(sqlname);\n            _div3.addClass(\"hide\");\n        }\n    })\n}\n\n\n/*\n*删除所有选中的 sql div 元素\n*/\nfunction delete_sql_div(div) {\n    div.parents(\".form-group\").nextAll().find(\"input[name='chk_sql']\").each(function () {\n        var _result = $(this).prop(\"checked\");\n        if (_result) {\n            $(this).parents(\".form-group\").remove();\n            count_sqldiv();\n        }\n    })\n}\n\n\n/*\n*选择数据库后修改IP地址\n*/\n$(document).on('change', \"select[name='database']\", function () {\n    var _ip = $(this).find(\"option:selected\").attr(\"ip\");\n    $(this).parents(\"tr\").next().find(\"p\").text(_ip);\n});\n\n\n/*\n*保存任务 save job\n*/\n$(\"#save_job\").click(function () {\n    var para = get_para();\n    var jpara = JSON.stringify(para);\n    var url = '/datax_web/add_job_data/';\n    var index = layer.load();\n    $.post(url, {'data': jpara}, function (res) {\n        var _data = $.parseJSON(res);\n        layer.close(index);\n        // 成功则跳转列表页面，失败则提示错误信息继续修改。\n        if (_data.status == 0) {\n            var url =\"/datax_web/index/\";\n            ajax_callback2(_data.msg, url)\n        }\n        else{\n            ajax_callback1(_data.msg);\n        }\n    });\n});\n\n\n/*\n*获取提交的信息\n*/\nfunction get_para() {\n    var name = $(\"#name\").val().trim();\n    var description = $(\"#description\").val().trim();\n    var querySql = $(\"#querySql\").val().trim();\n    var reader_databaseinfo_id = $(\"#reader_databaseinfo_id\").val().trim();\n    var writer_table = $(\"#writer_table\").val().trim();\n    var writer_column_id = strToArray($('#writer_column_id'));\n    var writer_databaseinfo_id = $(\"#writer_databaseinfo_id\").val().trim();\n    var writer_preSql = $(\"#writer_preSql\").val().trim();\n    var writer_postSql = $(\"#writer_postSql\").val().trim();\n\n    return {\n        'operation_type': 'add',\n        'name': name,\n        'description': description,\n        'querySql': querySql,\n        'reader_databaseinfo_id': reader_databaseinfo_id,\n        'writer_table': writer_table,\n        'writer_column_id': writer_column_id,\n        'writer_databaseinfo_id': writer_databaseinfo_id,\n        'writer_preSql': writer_preSql,\n        'writer_postSql': writer_postSql\n    }\n}\n\n/*\n*获取邮件人列表\n*/\nfunction strToArray (div) {\n    var data = [];\n    var val = div.val().trim();\n    if (val.length != 0) {\n        data = val.split(\"\\n\");\n    }\n    return data\n}\n\n\n/*\n*获取SQL\n*/\nfunction get_sql_list() {\n    var _sql_list = [];\n    $(\"#add_sql\").parents('.form-group').nextAll().each(function () {\n        var sentence = $(this).find(\"textarea[name='sentence']\").val().trim();\n        var name = $(this).find(\"input[name='name']\").val().trim();\n        var database = $(this).find(\"select[name='database']\").val().trim();\n        var interval = $(this).find(\"input[name='interval']\").val().trim();\n        var cont = {'database': database, 'sentence':sentence, 'name':name,\n                    'interval': interval};\n        _sql_list.push(cont)\n    });\n    return _sql_list\n}\n\n/*\n*ajax get callback\n*/\nfunction ajax_callback1(msg){\n    var index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n       layer.close(index)\n    });\n}\n\n\n/*\n*ajax get callback2\n*/\nfunction ajax_callback2(msg, url){\n    var index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n        layer.close(index);\n        window.location=url;\n    });\n}\n</script>\n{% endblock %}"
  },
  {
    "path": "templates/datax_web/crontabs.html",
    "content": "{% extends 'base.html' %}\n{% load ygol_filter_tag %}\n\n{% block header_content %}\n<style>\n.center {\n width: auto;\n display: table;\n margin-left: auto;\n margin-right: auto;\n}\n.text-center > table > tbody > tr > th,\n.text-center > table > thead > tr > th {\n text-align: center;\n}\n\n.table-responsive {\nwidth: 100%;\nmargin-bottom: 15px;\noverflow-x: scroll;\noverflow-y: hidden;\nborder: 1px solid #dddddd;\n-ms-overflow-style: -ms-autohiding-scrollbar;\n-webkit-overflow-scrolling: touch;\n}\n.table-responsive > .table {\nmargin-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 {\nwhite-space: nowrap;\n}\n\n.NoNewline\n{\nword-break: keep-all;/*必须*/\nwhite-space: nowrap;\n}\n\n.text-overflow{\nwidth:100px;\noverflow:hidden;;/* 内容超出宽度时隐藏超出部分的内容 */\ntext-overflow:ellipsis;;/* 当对象内文本溢出时显示省略标记(...) ；需与overflow:hidden;一起使用。*/\nwhite-space:nowrap;/* 不换行 */\n}\n</style>\n\t<!-- Datepicker -->\n    <link href=\"/static/template/css/bootstrap-datepicker.min.css\" rel=\"stylesheet\"/>\n{% endblock %}\n\n\n{% block container %}\n<div id=\"main-container\">\n\t<div class=\"main-header clearfix\">\n\t\t<div class=\"page-title\">\n\t\t\t<h3 class=\"no-margin\">Crontabs</h3>\n\t\t</div><!-- /page-title -->\n\t</div><!-- /main-header -->\n\n\t<div class=\"padding-md\">\n\t\t<div class=\"panel panel-default table-responsive\">\n                <div class=\"form-inline\">\n\t\t\t\t\t<a href=\"/scheduled_tasks/add_crontab_index/\" id=\"add\" type=\"button\" class=\"btn btn-sm btn-info\">\n                        <i class=\"fa fa-plus\"></i> 新增</a>\n\t\t\t\t</div>\n            <div class=\"table-responsive\">\n\t\t\t\t<table class=\"table table-hover table-bordered NoNewline\" id=\"table\"></table>\n\t\t\t</div><!-- /.padding-md -->\n\n\t\t</div><!-- /panel -->\n\t</div><!-- /padding-md -->\n</div><!-- /main-container -->\n{% endblock %}\n\n{% block footer_content %}\n\n\n<!-- Datepicker -->\n<script src='/static/template/js/bootstrap-datepicker.js'></script>\n<script src='/static/template/js/bootstrap-datepicker.zh-CN.min.js'></script>\n<script>\n$(document).ready(function(){\n    $('body').on('mouseover', '.text-overflow', function() {\n        var _cont = $(this).children().text();\n        layer.tips(_cont.split('\\n').join('<br>'), $(this), {\n        tips: [1, '#0FA6D8'],\n        time: 0\n        });\n    });\n    $('body').on('mouseout', '.text-overflow', function() {\n        layer.closeAll('tips'); //关闭所有的tips层\n    });\n\n});\n\n\n/*\n*得到查询的参数\n*/\nfunction queryParams(params) {\n    var temp = {   //这里的键的名字和控制器的变量名必须一直，这边改动，控制器也需要改成一样的\n        limit: params.limit,   //页面大小\n        offset: params.offset,  //页码\n        time: $('#time').val(),\n        investor: $('#investor').val(),\n        investor_cn: $('#investor_cn').val(),\n        investor_id: $('#investor_id').val(),\n        invite_code: $('#invite_code').val(),\n        product: $('#product').val(),\n        investment_amount: $('#investment_amount').val(),\n        return_rate: $('#return_rate').val(),\n        account_manager: $('#account_manager').val(),\n        account_manager_cn: $('#account_manager_cn').val(),\n        emp_num: $('#emp_num').val(),\n        store: $('#store').val(),\n        large_area: $('#large_area').val(),\n        area: $('#area').val(),\n        city: $('#city').val(),\n        start_date: $('#start_date').val(),\n        end_date: $('#end_date').val(),\n        lending_id: $('#lending_id').val(),\n        discount_amount: $('#discount_amount').val(),\n    };\n    return temp;\n}\n\n\n\n\n/*\n*获取bootstraptable 的列columns\n*/\nfunction get_columns() {\n    var columns =[{\n        title: '序号',//标题  可不加\n        formatter: function (value, row, index) {\n            return index+1;\n            }\n    }, {\n        field: 'id',\n        title: 'ID',\n        visible: false\n    }, {\n        field: 'crontab',\n        title: 'crontab',\n        formatter: crontabFormatter\n    }];\n    return columns\n}\n\n/*\n*初始化表格\n*/\n$('#table').bootstrapTable({\n    url: '/scheduled_tasks/crontabs_get_data/',\n    pagination: true,                   //是否显示分页（*）\n    sortable: false,                     //是否启用排序\n    sortOrder: \"asc\",                   //排序方式\n    showColumns: true,\n    queryParams: queryParams,           //传递参数（*）\n    sidePagination: \"client\",           //分页方式：client客户端分页，server服务端分页（*）\n    pageNumber: 1,                       //初始化加载第一页，默认第一页\n    pageSize: 10,                       //每页的记录行数（*）\n    pageList: [10, 25, 50, 100],        //可供选择的每页的行数（*）\n    search: true,                  //是否显示搜索 --前端搜索\n    columns:get_columns()\n});\n\n\n/*\n*超链接crontab\n*/\nfunction crontabFormatter(value, row, index) {\n    var url = \"/scheduled_tasks/mod_crontabs_index/\" + row.id;\n    return [\n        '<div><a class=\"mod\" href='+ url +'>',\n        value,\n        '</a></div>'\n    ].join('');\n}\n\n\n\n/*\n*ajax get callback\n*/\nfunction ajax_callback1(msg){\n    var index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n       layer.close(index)\n    });\n}\n\n</script>\n{% endblock %}"
  },
  {
    "path": "templates/datax_web/index.html",
    "content": "{% extends 'base.html' %}\n\n{% block header_content %}\n<style>\n.center {\n width: auto;\n display: table;\n margin-left: auto;\n margin-right: auto;\n}\n.text-center > table > tbody > tr > th,\n.text-center > table > thead > tr > th {\n text-align: center;\n}\n\n.table-responsive {\nwidth: 100%;\nmargin-bottom: 15px;\noverflow-x: scroll;\noverflow-y: hidden;\nborder: 1px solid #dddddd;\n-ms-overflow-style: -ms-autohiding-scrollbar;\n-webkit-overflow-scrolling: touch;\n}\n.table-responsive > .table {\nmargin-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 {\nwhite-space: nowrap;\n}\n\n.NoNewline\n{\nword-break: keep-all;/*必须*/\nwhite-space: nowrap;\n}\n\n.text-overflow{\nwidth:100px;\noverflow:hidden;;/* 内容超出宽度时隐藏超出部分的内容 */\ntext-overflow:ellipsis;;/* 当对象内文本溢出时显示省略标记(...) ；需与overflow:hidden;一起使用。*/\nwhite-space:nowrap;/* 不换行 */\n}\n</style>\n\t<!-- Datepicker -->\n    <link href=\"/static/template/css/bootstrap-datepicker.min.css\" rel=\"stylesheet\"/>\n{% endblock %}\n\n\n{% block container %}\n<div id=\"main-container\">\n\t<div class=\"main-header clearfix\">\n\t\t<div class=\"page-title\">\n\t\t\t<h3 class=\"no-margin\">数据同步</h3>\n\t\t</div><!-- /page-title -->\n\t</div><!-- /main-header -->\n\n\t<div class=\"padding-md\">\n\t\t<div class=\"panel panel-default table-responsive\">\n                <div class=\"form-inline\">\n\t\t\t\t\t<a href=\"/datax_web/add_job/\" id=\"add\" type=\"button\" class=\"btn btn-sm btn-info\">\n                        <i class=\"fa fa-plus\"></i> 新增</a>\n\t\t\t\t</div>\n            <div class=\"table-responsive\">\n\t\t\t\t<table class=\"table table-hover table-bordered NoNewline\" id=\"table\"></table>\n\t\t\t</div><!-- /.padding-md -->\n\n\t\t</div><!-- /panel -->\n\t</div><!-- /padding-md -->\n</div><!-- /main-container -->\n{% endblock %}\n\n{% block footer_content %}\n\n\n<!-- Datepicker -->\n<script src='/static/template/js/bootstrap-datepicker.js'></script>\n<script src='/static/template/js/bootstrap-datepicker.zh-CN.min.js'></script>\n<script>\n$(document).ready(function(){\n    $('body').on('mouseover', '.text-overflow', function() {\n        var _cont = $(this).children().text();\n        layer.tips(_cont.split('\\n').join('<br>'), $(this), {\n        tips: [1, '#0FA6D8'],\n        time: 0\n        });\n    });\n    $('body').on('mouseout', '.text-overflow', function() {\n        layer.closeAll('tips'); //关闭所有的tips层\n    });\n\n});\n\n\n/*\n*初始化表格\n*/\nfunction Initialization_table(columns) {\n    var bst = $('#table').bootstrapTable({\n        pagination: true,                   //是否显示分页（*）\n        sortable: false,                     //是否启用排序\n        sortOrder: \"asc\",                   //排序方式\n        showColumns: true,\n        queryParams: queryParams,           //传递参数（*）\n        sidePagination: \"client\",           //分页方式：client客户端分页，server服务端分页（*）\n        pageNumber: 1,                       //初始化加载第一页，默认第一页\n        pageSize: 10,                       //每页的记录行数（*）\n        pageList: [10, 25, 50, 100],        //可供选择的每页的行数（*）\n        search: true,                  //是否显示搜索 --前端搜索\n        columns:columns\n    });\n    return bst\n}\n\n\n/*\n*得到查询的参数\n*/\nfunction queryParams(params) {\n    var temp = {   //这里的键的名字和控制器的变量名必须一直，这边改动，控制器也需要改成一样的\n        limit: params.limit,   //页面大小\n        offset: params.offset,  //页码\n        time: $('#time').val(),\n        investor: $('#investor').val(),\n        investor_cn: $('#investor_cn').val(),\n        investor_id: $('#investor_id').val(),\n        invite_code: $('#invite_code').val(),\n        product: $('#product').val(),\n        investment_amount: $('#investment_amount').val(),\n        return_rate: $('#return_rate').val(),\n        account_manager: $('#account_manager').val(),\n        account_manager_cn: $('#account_manager_cn').val(),\n        emp_num: $('#emp_num').val(),\n        store: $('#store').val(),\n        large_area: $('#large_area').val(),\n        area: $('#area').val(),\n        city: $('#city').val(),\n        start_date: $('#start_date').val(),\n        end_date: $('#end_date').val(),\n        lending_id: $('#lending_id').val(),\n        discount_amount: $('#discount_amount').val(),\n    };\n    return temp;\n}\n\n\n\n\n/*\n*获取bootstraptable 的列columns\n*/\nfunction get_columns() {\n    var columns =[{\n        title: '序号',//标题  可不加\n        formatter: function (value, row, index) {\n            return index+1;\n            }\n    }, {\n        field: 'id',\n        title: 'ID',\n        visible: false\n    }, {\n        field: 'name',\n        title: '名称',\n        formatter: nameFormatter\n    }, {\n        field: 'description',\n        title: '描述',\n        formatter: nameFormatter\n    }, {\n        field: 'querySql',\n        title: '查询SQL语句 ',\n        formatter: receiversFormatter\n    }, {\n        field: 'reader_databaseinfo_id',\n        title: '读取数据库',\n\t\tformatter: receiversFormatter\n    }, {\n        field: 'writer_table',\n        title: '写入表名 '\n    }, {\n        field: 'writer_databaseinfo_id',\n        title: '写入数据库',\n\t\tformatter: receiversFormatter\n    }, {\n        field: 'create_time',\n        title: '创建时间'\n    }, {\n        field: 'modify_time',\n        title: '修改时间'\n    }];\n    return columns\n}\n\n/*\n*初始化表格\n*/\n$('#table').bootstrapTable({\n    url: '/datax_web/get_job_data/',\n    pagination: true,                   //是否显示分页（*）\n    sortable: false,                     //是否启用排序\n    sortOrder: \"asc\",                   //排序方式\n    showColumns: true,\n    queryParams: queryParams,           //传递参数（*）\n    sidePagination: \"client\",           //分页方式：client客户端分页，server服务端分页（*）\n    pageNumber: 1,                       //初始化加载第一页，默认第一页\n    pageSize: 10,                       //每页的记录行数（*）\n    pageList: [10, 25, 50, 100],        //可供选择的每页的行数（*）\n    search: true,                  //是否显示搜索 --前端搜索\n    columns:get_columns()\n});\n\n/*\n*超链接显示收件人\n*/\nfunction receiversFormatter(value, row, index) {\n    return [\n        '<div class=\"text-overflow\"><a href=\"#\">',\n        value,\n        '</a></div>'\n    ].join('');\n}\n\n\n/*\n*超链接显示邮件标题\n*/\nfunction nameFormatter(value, row, index) {\n    var url = \"/datax_web/update_job/\" + row.id;\n    return [\n        '<div><a class=\"mod\" href='+ url +'>',\n        value,\n        '</a></div>'\n    ].join('');\n}\n\n\n\n/*\n*ajax get callback\n*/\nfunction ajax_callback1(msg){\n    var index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n       layer.close(index)\n    });\n}\n\n</script>\n{% endblock %}"
  },
  {
    "path": "templates/datax_web/mod_crontabs.html",
    "content": "{% extends 'base.html' %}\n{% load ygol_filter_tag %}\n\n{% block header_content %}\n<style>\n.center {\n width: auto;\n display: table;\n margin-left: auto;\n margin-right: auto;\n}\n.text-center > table > tbody > tr > th,\n.text-center > table > thead > tr > th {\n text-align: center;\n}\n\n.table-responsive {\nwidth: 100%;\nmargin-bottom: 15px;\noverflow-x: scroll;\noverflow-y: hidden;\nborder: 1px solid #dddddd;\n-ms-overflow-style: -ms-autohiding-scrollbar;\n-webkit-overflow-scrolling: touch;\n}\n.table-responsive > .table {\nmargin-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 {\nwhite-space: nowrap;\n}\n\n.NoNewline\n{\nword-break: keep-all;/*必须*/\nwhite-space: nowrap;\n}\n</style>\n\t<!-- Datepicker -->\n    <link href=\"/static/template/css/bootstrap-datepicker.min.css\" rel=\"stylesheet\"/>\n    <!-- Gritter -->\n\t<link href=\"/static/template/css/gritter/jquery.gritter.css\" rel=\"stylesheet\">\n{% endblock %}\n\n\n{% block container %}\n<div id=\"main-container\">\n\t<div class=\"main-header clearfix\">\n\t\t<div class=\"page-title\">\n\t\t\t<h3 class=\"no-margin\">Mod crontab</h3>\n\t\t</div><!-- /page-title -->\n\t</div><!-- /main-header -->\n\n\n\t<div class=\"padding-md\">\n        <div class=\"row\">\n            <div class=\"col-md-12\">\n\t\t\t\t\t\t<div class=\"panel panel-default\">\n\t\t\t\t\t\t\t<form class=\"form-horizontal form-border no-margin\" id=\"basic-constraint\" data-validate=\"parsley\" novalidate>\n\t\t\t\t\t\t\t\t<div class=\"panel-heading\">\n\t\t\t\t\t\t\t\t\t请按照crontab格式填写，修改后请重新指定定时任务的执行时间\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div class=\"panel-body\">\n                                    <form class=\"form-horizontal form-border no-margin\" data-validate=\"parsley\" novalidate>\n                                        <div class=\"panel-body\" id=\"crontabModal\">\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">minute</label>\n                                                <div class=\"col-lg-5\">\n                                                    <input name=\"minute\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">hour</label>\n                                                <div class=\"col-lg-5\">\n                                                    <input name=\"hour\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">day_of_week</label>\n                                                <div class=\"col-lg-5\">\n                                                    <input name=\"day_of_week\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">day_of_month</label>\n                                                <div class=\"col-lg-5\">\n                                                    <input name=\"day_of_month\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                            <div class=\"form-group\">\n                                                <label class=\"control-label col-lg-2\">month_of_year</label>\n                                                <div class=\"col-lg-5\">\n                                                    <input name=\"month_of_year\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                </div><!-- /.col -->\n                                            </div><!-- /form-group -->\n                                        </div>\n                                    </form>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div class=\"panel-footer\">\n\t\t\t\t\t\t\t\t\t<button id=\"save_crontab\" type=\"button\" class=\"btn btn-success\">Save</button>\n\t\t\t\t\t\t\t\t\t<button id=\"delete_crontab\" type=\"button\" class=\"btn btn-danger pull-right\">Delete</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</form>\n\t\t\t\t\t\t</div><!-- /panel -->\n\t\t\t\t\t</div><!-- /.col-->\n        </div><!-- /.row -->\n\t</div><!-- /padding-md -->\n</div><!-- /main-container -->\n{% endblock %}\n\n{% block footer_content %}\n\n\n<!-- Datepicker -->\n<script src='/static/template/js/bootstrap-datepicker.js'></script>\n<script src='/static/template/js/bootstrap-datepicker.zh-CN.min.js'></script>\n<script src=\"/static/template/js/jquery.gritter.min.js\"></script>\n<!-- Modernizr -->\n{#<script src='/static/template/js/modernizr.min.js'></script>#}\n<script>\n$(document).ready(function(){\n    var index = layer.load();\n    Initialization_crontab();\n    layer.close(index);\n});\n\n\n/*\n*初始化crontab 时间\n*/\nfunction Initialization_crontab() {\n    var url = '/scheduled_tasks/get_mod_crontab_data/';\n    var str=location.href;\n    var args = str.split('/');\n    var _id = args[args.length-2];\n    var para = {'id': _id};\n    $.post(url, para, function (jdata) {\n        var _data = $.parseJSON(jdata);\n        console.log(_data)\n        $.each(_data, function (k, v) {\n            $(\"#crontabModal\").find('input').each(function () {\n            if ($(this).prop('name') == k) {\n                $(this).val(v);\n            }\n        });\n        });\n\n    })\n}\n\n\n/*\n*保存 crontab 时间\n*/\n$(\"#save_crontab\").click(function () {\n    var url = '/scheduled_tasks/add_crontab/';\n    var str=location.href;\n    var args = str.split('/');\n    var _id = args[args.length-2];\n    var para = {};\n    $(\"#crontabModal\").find('input').each(function () {\n        para[$(this).prop('name')] = $(this).val();\n    });\n    var jpara = JSON.stringify(para);\n    $.post(url, {'data': jpara}, function () {\n        var url =\"/scheduled_tasks/crontabs/\";\n        ajax_callback2('操作成功', url)\n    })\n});\n\n\n/*\n*删除 crontab 时间\n*/\n$(\"#delete_crontab\").click(function () {\n    var url = '/scheduled_tasks/delete_crontab/';\n    var str=location.href;\n    var args = str.split('/');\n    var _id = args[args.length-2];\n    var para = {'id': _id};\n    var jpara = JSON.stringify(para);\n        //询问框\n    layer.confirm('警告： 该执行时间所关联的任务也会全部删除！', {\n      btn: ['确定','取消'] //按钮\n    }, function () {\n            var index = layer.load();\n            $.post(url, {'data': jpara}, function () {\n                layer.close(index);\n                ajax_callback2('操作成功', \"/scheduled_tasks/crontabs/\");\n            });\n        }\n    );\n});\n\n\n/*\n*ajax get callback\n*/\nfunction ajax_callback1(msg){\n    var index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n       layer.close(index)\n    });\n}\n\n\n/*\n*ajax get callback2\n*/\nfunction ajax_callback2(msg, url){\n    var index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n        layer.close(index);\n        window.location=url;\n    });\n}\n</script>\n{% endblock %}"
  },
  {
    "path": "templates/datax_web/mod_periodic_task.html",
    "content": "{% extends 'base.html' %}\n{% load ygol_filter_tag %}\n\n{% block header_content %}\n<style>\n.center {\n width: auto;\n display: table;\n margin-left: auto;\n margin-right: auto;\n}\n.text-center > table > tbody > tr > th,\n.text-center > table > thead > tr > th {\n text-align: center;\n}\n\n.table-responsive {\nwidth: 100%;\nmargin-bottom: 15px;\noverflow-x: scroll;\noverflow-y: hidden;\nborder: 1px solid #dddddd;\n-ms-overflow-style: -ms-autohiding-scrollbar;\n-webkit-overflow-scrolling: touch;\n}\n.table-responsive > .table {\nmargin-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 {\nwhite-space: nowrap;\n}\n\n.NoNewline\n{\nword-break: keep-all;/*必须*/\nwhite-space: nowrap;\n}\n</style>\n\t<!-- Datepicker -->\n    <link href=\"/static/template/css/bootstrap-datepicker.min.css\" rel=\"stylesheet\"/>\n    <!-- Gritter -->\n\t<link href=\"/static/template/css/gritter/jquery.gritter.css\" rel=\"stylesheet\">\n{% endblock %}\n\n\n{% block container %}\n<div id=\"main-container\">\n\t<div class=\"main-header clearfix\">\n\t\t<div class=\"page-title\">\n\t\t\t<h3 class=\"no-margin\">修改 周期任务 数据申请</h3>\n\t\t</div><!-- /page-title -->\n\t</div><!-- /main-header -->\n\n\n\t<div class=\"padding-md\">\n        <div class=\"row\">\n            <div class=\"col-md-12\">\n\t\t\t\t\t\t<div class=\"panel panel-default\">\n\t\t\t\t\t\t\t<form class=\"form-horizontal form-border no-margin\" id=\"basic-constraint\" data-validate=\"parsley\" novalidate>\n\t\t\t\t\t\t\t\t<div class=\"panel-heading\">\n\t\t\t\t\t\t\t\t\tMod periodic task\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div class=\"panel-body\">\n\t\t\t\t\t\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t\t\t\t\t\t<label class=\"control-label col-lg-2\">任务名称</label>\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-4\">\n\t\t\t\t\t\t\t\t\t\t\t<input type=\"text\" id=\"task_name\" class=\"form-control input-sm\" data-required=\"true\" placeholder=\"请输入英文\">\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t\t\t\t</div><!-- /form-group -->\n\t\t\t\t\t\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t\t\t\t\t\t<label class=\"control-label col-lg-2\">任务模板</label>\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-3\">\n                                            <select id=\"task_template\" class=\"form-control\">\n                                                <option value=\"\">请选择</option>\n                                            </select>\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t\t\t\t</div><!-- /form-group -->\n\t\t\t\t\t\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t\t\t\t\t\t<label class=\"control-label col-lg-2\">是否启用</label>\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-9\">\n                                            <div class=\"seperator\"></div>\n                                            <label class=\"label-checkbox inline\">\n\t\t\t\t\t\t\t\t\t\t\t\t<input id=\"is_enable\" type=\"checkbox\" data-required=\"true\" name=\"chk-demo\" checked=\"checked\">\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"custom-checkbox\"></span>\n\t\t\t\t\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t\t\t\t</div><!-- /form-group -->\n\t\t\t\t\t\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t\t\t\t\t\t<label class=\"control-label col-lg-2\">邮件标题</label>\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-5\">\n\t\t\t\t\t\t\t\t\t\t\t<input id=\"subject\" type=\"text\" class=\"form-control input-sm\" data-max=\"30\" placeholder=\"mail header\">\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t\t\t\t</div><!-- /form-group -->\n\t\t\t\t\t\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t\t\t\t\t\t<label class=\"control-label col-lg-2\">收件人</label>\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-4\">\n\t\t\t\t\t\t\t\t\t\t\t<textarea id=\"receivers\" spellcheck=\"false\" class=\"form-control\" placeholder=\"Your receivers here...\" rows=\"6\" data-required=\"true\"></textarea>\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n                                        <span class=\"col-lg-1\">每行一个</span>\n\t\t\t\t\t\t\t\t\t</div><!-- /form-group -->\n\t\t\t\t\t\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t\t\t\t\t\t<label class=\"control-label col-lg-2\">抄送人</label>\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-4\">\n\t\t\t\t\t\t\t\t\t\t\t<textarea id=\"cc\" spellcheck=\"false\" class=\"form-control\" placeholder=\"Your CC here...\" rows=\"6\" data-required=\"true\"></textarea>\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n                                        <span class=\"col-lg-1\">每行一个</span>\n\t\t\t\t\t\t\t\t\t</div><!-- /form-group -->\n\t\t\t\t\t\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t\t\t\t\t\t<label class=\"control-label col-lg-2\">执行时间</label>\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-4\">\n                                            <select id=\"crontab\" class=\"form-control\">\n                                                <option>请选择</option>\n                                            </select>\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n                                        <div class=\"col-lg-1\">\n                                            <a href=\"#crontabModal\" data-toggle=\"modal\" type=\"button\" class=\"btn btn-default\"><i class=\"fa fa-plus\"></i></a>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</div><!-- /form-group -->\n\t\t\t\t\t\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t\t\t\t\t\t<label class=\"control-label col-lg-2\">是否加密</label>\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-9\">\n                                            <div class=\"seperator\"></div>\n                                            <label class=\"label-checkbox inline\">\n\t\t\t\t\t\t\t\t\t\t\t\t<input id=\"is_encrypt\" type=\"checkbox\" data-required=\"true\" name=\"is_encrypt\" checked=\"checked\">\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"custom-checkbox\"></span>\n\t\t\t\t\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t\t\t\t</div><!-- /form-group -->\n\t\t\t\t\t\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t\t\t\t\t\t<label class=\"control-label col-lg-2\">是否含有敏感信息</label>\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-2\">\n                                                <div class=\"seperator\"></div>\n                                                <label class=\"label-radio inline\">\n                                                    <input type=\"radio\" name=\"is_sensitive\" checked=\"checked\" value=\"1\">\n                                                    <span class=\"custom-radio\"></span>\n                                                    否\n                                                </label>\n                                                <label class=\"label-radio inline\">\n                                                    <input type=\"radio\" name=\"is_sensitive\" value=\"0\">\n                                                    <span class=\"custom-radio\"></span>\n                                                    是\n                                                </label>\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t\t\t\t</div><!-- /form-group -->\n                                    <div class=\"form-group\">\n\t\t\t\t\t\t\t\t\t\t<label class=\"control-label col-lg-2\">任务执行机器</label>\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-2\">\n\t\t\t\t\t\t\t\t\t\t\t<input id=\"run_server\" type=\"text\" class=\"form-control input-sm\" data-max=\"30\" value=\"172.24.132.99\" disabled=\"disabled\">\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t\t\t\t</div><!-- /form-group -->\n                                    <div class=\"form-group\">\n\t\t\t\t\t\t\t\t\t\t<label class=\"control-label col-lg-2\">响应类型</label>\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-2\">\n                                            <select id=\"response_type\" class=\"form-control\">\n                                                <option value=\"1\">small</option>\n                                                <option value=\"2\">large</option>\n                                                <option value=\"3\">HTML</option>\n                                            </select>\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t\t\t\t</div><!-- /form-group -->\n                                    <div class=\"form-group hide\">\n\t\t\t\t\t\t\t\t\t\t<label class=\"control-label col-lg-2\">最大文件数量</label>\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-2\">\n\t\t\t\t\t\t\t\t\t\t\t<input id=\"max_excel_num\" type=\"text\" class=\"form-control input-sm\" data-max=\"30\" value=\"5\">\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t\t\t\t</div><!-- /form-group -->\n                                    <div id=\"sqldiv_template\" class=\"form-group hide\"> <!-- sql div template -->\n                                        <label class=\"control-label col-lg-2\">\n                                            <input type=\"checkbox\" data-required=\"true\" name=\"chk_sql\">\n                                            <span class=\"custom-checkbox\"></span>\n                                        </label>\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-4\">\n\t\t\t\t\t\t\t\t\t\t\t<textarea name=\"sentence\" spellcheck=\"false\" class=\"form-control\" placeholder=\"Your sql here...\" rows=\"10\" data-required=\"true\"></textarea>\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-4\">\n                                            <table class=\"table\">\n                                                <tr>\n                                                    <td><label class=\"control-label\">sql名称</label></td>\n                                                    <td><input name=\"name\" type=\"text\" class=\"form-control input-sm\" data-max=\"30\" placeholder=\"name\"></td>\n                                                </tr>\n                                                <tr>\n                                                    <td><label class=\"control-label\">执行数据库</label></td>\n                                                    <td>\n                                                        <select name=\"database\" class=\"form-control\">\n                                                            <option ip=\"\" value=\"\">请选择</option>\n                                                        </select>\n                                                    </td>\n                                                </tr>\n                                                <tr>\n                                                    <td><label class=\"control-label\">IP</label></td>\n                                                    <td>\n                                                        <p class=\"form-control-static\"></p>\n                                                    </td>\n                                                </tr>\n                                                <tr>\n                                                    <td><label class=\"control-label\">interval</label></td>\n                                                    <td><input name=\"interval\" type=\"text\" class=\"form-control input-sm\" data-max=\"30\" value=\"10000\" placeholder=\"每提取n行数据生成一个excel\"></td>\n                                                </tr>\n                                            </table>\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n                                        <div class=\"col-lg-2 hide\"><label class=\"control-label\"></label></div>\n\t\t\t\t\t\t\t\t\t</div><!-- /form-group --> <!-- /sql div template -->\n\t\t\t\t\t\t\t\t\t<div class=\"form-group\">\n                                        <label class=\"control-label col-lg-2\">\n                                            SQL\n                                            <input id=\"select_sql\" type=\"checkbox\" data-required=\"true\" name=\"chk-demo\">\n                                            <span class=\"custom-checkbox\"></span>\n                                        </label>\n                                        <div class=\"col-md-4 col-sm-4\">\n                                            <select class=\"input-sm form-control inline\" style=\"width:130px;\">\n                                                <option value=\"0\">hide</option>\n                                                <option value=\"1\">show</option>\n                                                <option value=\"2\">delete</option>\n                                            </select>\n                                            <a id=\"sql_apply\" class=\"btn btn-default btn-sm\">Apply</a>\n                                        </div><!-- /.col -->\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-lg-2\">\n\t\t\t\t\t\t\t\t\t\t\t<a id=\"add_sql\" type=\"button\" class=\"btn btn-default\"><i class=\"fa fa-plus\"></i></a>\n                                            <span>总数 0条</span>\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n                                        <div class=\"col-lg-3\">\n                                            <div class=\"seperator\"></div>\n\t\t\t\t\t\t\t\t\t\t\t<span>数据脱敏、指定时间段请在SQL中完成</span>\n\t\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t\t\t\t</div><!-- /form-group -->\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div class=\"panel-footer\">\n\t\t\t\t\t\t\t\t\t<button id=\"save_task\" type=\"button\" class=\"btn btn-success\">Save</button>\n\t\t\t\t\t\t\t\t\t<button id=\"RunTask\" type=\"button\" class=\"btn btn-info\">Run</button>\n\t\t\t\t\t\t\t\t\t{% comment %}<button id=\"delete_task\" type=\"button\" class=\"btn btn-danger pull-right\">Delete</button>{% endcomment %}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</form>\n                            <div class=\"modal fade\" id=\"crontabModal\">\n                                <div class=\"modal-dialog\">\n                                    <div class=\"modal-content\">\n                                        <div class=\"modal-header\">\n                                            <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">&times;</button>\n                                            <h4>Add crontab</h4>\n                                        </div>\n                                        <div class=\"modal-body\">\n                                            <form class=\"form-horizontal form-border no-margin\" id=\"basic-constraint\" data-validate=\"parsley\" novalidate>\n                                                <div class=\"panel-body\">\n                                                    <div class=\"form-group\">\n                                                        <label class=\"control-label col-lg-2\">minute</label>\n                                                        <div class=\"col-lg-9\">\n                                                            <input name=\"minute\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                        </div><!-- /.col -->\n                                                    </div><!-- /form-group -->\n                                                    <div class=\"form-group\">\n                                                        <label class=\"control-label col-lg-2\">hour</label>\n                                                        <div class=\"col-lg-9\">\n                                                            <input name=\"hour\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                        </div><!-- /.col -->\n                                                    </div><!-- /form-group -->\n                                                    <div class=\"form-group\">\n                                                        <label class=\"control-label col-lg-2\">day_of_week</label>\n                                                        <div class=\"col-lg-9\">\n                                                            <input name=\"day_of_week\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                        </div><!-- /.col -->\n                                                    </div><!-- /form-group -->\n                                                    <div class=\"form-group\">\n                                                        <label class=\"control-label col-lg-2\">day_of_month</label>\n                                                        <div class=\"col-lg-9\">\n                                                            <input name=\"day_of_month\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                        </div><!-- /.col -->\n                                                    </div><!-- /form-group -->\n                                                    <div class=\"form-group\">\n                                                        <label class=\"control-label col-lg-2\">month_of_year</label>\n                                                        <div class=\"col-lg-9\">\n                                                            <input name=\"month_of_year\" type=\"text\" class=\"form-control input-sm\" data-required=\"true\" value=\"*\" placeholder=\"Required Field\">\n                                                        </div><!-- /.col -->\n                                                    </div><!-- /form-group -->\n                                                </div>\n                                            </form>\n                                        </div>\n                                        <div class=\"modal-footer\">\n                                            <button class=\"btn btn-success btn-sm\" data-dismiss=\"modal\" aria-hidden=\"true\">Close</button>\n                                            <a id=\"save_crontab\" type=\"button\" class=\"btn btn-danger btn-sm\">Save</a>\n                                        </div>\n                                    </div><!-- /.modal-content -->\n                                </div><!-- /.modal-dialog -->\n                            </div><!-- /.modal -->\n\t\t\t\t\t\t</div><!-- /panel -->\n\t\t\t\t\t</div><!-- /.col-->\n        </div><!-- /.row -->\n\t</div><!-- /padding-md -->\n</div><!-- /main-container -->\n{% endblock %}\n\n{% block footer_content %}\n\n\n<!-- Datepicker -->\n<script src='/static/template/js/bootstrap-datepicker.js'></script>\n<script src='/static/template/js/bootstrap-datepicker.zh-CN.min.js'></script>\n<script src=\"/static/template/js/jquery.gritter.min.js\"></script>\n<!-- Modernizr -->\n{#<script src='/static/template/js/modernizr.min.js'></script>#}\n<script>\n$(document).ready(function(){\n    var index = layer.load();\n    Initialization_task_template();\n    Initialization_cc();\n    Initialization_crontab();\n    Initialization_Database();\n    get_mod_periodic_task_data();\n    layer.close(index);\n    disableOperation();\n});\n\n\n/*\n*初始化任务模板\n*/\nfunction Initialization_task_template() {\n    var url = '/scheduled_tasks/get_task_template/';\n    var para = {};\n    $.ajax({\n          type : \"post\",\n          url : url,\n          data : para,\n          async : false,\n          success : function (jdata) {\n                    var data = $.parseJSON(jdata);\n                    $.each(data, function (k, v) {\n                        var _option = \"<option value='\"+ v +\"'>\"+ v +\"</option>\";\n                        $(\"#task_template\").append(_option);\n                        });\n                    }\n          });\n}\n\n\n/*\n*初始化 抄送人列表\n*/\nfunction Initialization_cc() {\n    var _cc_list = ['liudongdong@yingu.com', 'huangxiaoxue@yingu.com', 'database@yingu.com'];\n    $.each(_cc_list, function (k, v) {\n        $(\"#cc\").append(v);\n        $(\"#cc\").append('\\n');\n    })\n}\n\n\n/*\n*初始化crontab 时间\n*/\nfunction Initialization_crontab() {\n    var url = '/scheduled_tasks/get_crontab/';\n    var para = {};\n    $.ajax({\n      type : \"post\",\n      url : url,\n      data : para,\n      async : false,\n      success : function (jdata) {\n                var _data = $.parseJSON(jdata);\n                $(\"#crontab\").empty();\n                $.each(_data, function (k, v) {\n                    var _cont = [v.minute, v.hour, v.day_of_week, v.day_of_month, v.month_of_year];\n                    var _option = \"<option value='\"+ v.id +\"'>\"+ _cont.join(' ')+ \" (分/时/周/日/月)\" +\"</option>\";\n                    $(\"#crontab\").append(_option);\n                });\n            }\n      });\n}\n\n\n/*\n*添加 crontab 时间\n*/\n$(\"#save_crontab\").click(function () {\n    var url = '/scheduled_tasks/add_crontab/';\n    var para = {};\n    $(\"#crontabModal\").find('input').each(function () {\n        para[$(this).prop('name')] = $(this).val();\n    });\n    var jpara = JSON.stringify(para);\n    $.ajax({\n        type : \"post\",\n        url : url,\n        data : {'data': jpara},\n        async : false,\n        success : function () {\n                    Initialization_crontab();\n                    $('#crontabModal').modal('hide');\n                    $.gritter.add({\n                        title: \"<i class='fa fa-check-circle'></i> Success\",\n                        text: ' 可选择新添加的crontab时间.',\n                        sticky: false,\n                        time: '',\n                        class_name: 'gritter-success'\n                    });\n                    return false;\n                }\n    });\n});\n\n\n/*\n*初始化数据库\n*/\nfunction Initialization_Database() {\n    var url = '/scheduled_tasks/get_database/';\n    $.ajax({\n        type : \"post\",\n        url : url,\n        async : false,\n        success : function (jdata) {\n            var _data = $.parseJSON(jdata);\n            $.each(_data, function (k, v) {\n                var _option = \"<option ip='\"+ v.host +\"' value='\"+ v.id +\"'>\"+ v.description + \"</option>\";\n                $(\"#sqldiv_template\").find(\"select[name='database']\").append(_option);\n            });\n        }\n    });\n}\n\n\n/*\n*获取需要修改的周期任务数据\n*/\nfunction get_mod_periodic_task_data() {\n    var url = '/scheduled_tasks/get_mod_periodic_task_data/';\n    var str=location.href;\n    var args = str.split('/');\n    var _id = args[args.length-2];\n    var para = {'_id': _id};\n    $.post(url, para, function (jdata) {\n        var data = $.parseJSON(jdata);\n        $(\"#task_name\").val(data.name);\n        $(\"#task_template\").val(data.task_template);\n        $(\"#is_enable\").prop('checked', data.enabled);\n        $(\"#subject\").val(data.subject);\n        $(\"#max_excel_num\").val(data.max_excel_num);\n        $(\"#response_type\").val(data.response_type);\n        var receivers = data.receivers;\n        var cc = data.cc;\n        $(\"#is_encrypt\").prop('checked', data.is_encrypt);\n        $(\"#receivers\").val(receivers.join('\\n'));\n        $(\"#cc\").val(cc.join('\\n'));\n        $(\"#crontab\").val(data.crontab);\n        $.each(data.data_apply_sql, function (k, v) {\n            set_data_apply_sql(v);\n        });\n        SetResponseType(data.response_type);\n    })\n}\n\n\n/*\n*设置需要修改的计划任务SQL\n*/\nfunction set_data_apply_sql(v) {\n    var sqldiv_body = $(\"#add_sql\").parents('.panel-body');\n    var _sql_html = $(\"#add_sql\").parents('.form-group').prev().html();\n    sqldiv_body.append(\"<div class='form-group'></div>\");\n    sqldiv = sqldiv_body.children().last();\n    sqldiv.html(_sql_html);\n    sqldiv.find(\"textarea[name='sentence']\").val(v.sentence); //设置SQL语句\n    sqldiv.find(\"input[name='name']\").val(v.name);  //设置SQL语句名称\n    sqldiv.find(\"input[name='interval']\").val(v.interval);  //设置SQL语句提取数据时的间隔行数\n    var database_div = sqldiv.find(\"select[name='database']\");\n    database_div.val(v.databaseinfo_id);\n    database_div.find(\"option\").each(function () {\n        var val = $(this).val();\n        var _ip = $(this).attr(\"ip\");\n        if (v.databaseinfo_id == val){\n            $(this).parents(\"tr\").next().find(\"p\").text(_ip);\n        }\n    });\n    count_sqldiv();\n}\n\n\n/*\n*点击response_type按钮，设置数据响应类型\n*/\n$('body').on('change', '#response_type', function() {\n    SetResponseType($(this).val())\n});\n\n\n/*\n*设置数据响应类型\n*/\nfunction SetResponseType(val) {\n    if (val == 2){\n        $('#max_excel_num').parents(\".form-group\").removeClass('hide');\n        $('#add_sql').parents(\".form-group\").nextAll().find(\"input[name='interval']\").parents('tr').show();\n\n    }\n    else {\n        $('#max_excel_num').parents(\".form-group\").addClass('hide');\n        $('#add_sql').parents(\".form-group\").nextAll().find(\"input[name='interval']\").parents('tr').hide();\n    }\n}\n\n\n/*\n*添加 sql div\n*/\n$(\"#add_sql\").click(function () {\n    var sqldiv = $(this).parents('.panel-body');\n    var _sql_html = $(this).parents('.form-group').prev().html();\n    sqldiv.append(\"<div class='form-group'></div>\");\n    sqldiv.children().last().html(_sql_html);\n    if ($(\"#response_type\").val() != 2){\n        $('#add_sql').parents(\".form-group\").nextAll().find(\"input[name='interval']\").parents('tr').hide();\n    };\n    count_sqldiv();\n});\n\n/*\n*设置 sql div 元素个数\n*/\nfunction count_sqldiv() {\n   var _count = $(\"#add_sql\").parents('.form-group').nextAll().length;\n    $(\"#add_sql\").next().text(\"总数 \"+ _count + \"条\");\n}\n\n\n/*\n*sql div 元素 checkbox 全选/反选\n*/\n$(\"#select_sql\").click(function () {\n    var _result = $(this).is(':checked');\n    if (_result){\n        $(\"input[name='chk_sql']\").prop(\"checked\", true);\n    }\n    else {\n        $(\"input[name='chk_sql']\").prop(\"checked\", false);\n    }\n});\n\n\n/*\n*sql apply 按钮,  显示、隐藏、删除 sql div元素\n*/\n$(\"#sql_apply\").click(function () {\n    var _result = $(this).prev().val();\n    if (_result==0){\n        hide_sql_div($(this));\n    }\n    else if(_result==1) {\n        show_sql_div($(this));\n    }\n    else {\n        delete_sql_div($(this));\n    }\n});\n\n\n/*\n*隐藏所有选中的 sql div 元素\n*/\nfunction hide_sql_div(div) {\n    div.parents(\".form-group\").nextAll().find(\"input[name='chk_sql']\").each(function () {\n        var _result = $(this).prop(\"checked\");\n        if (_result) {\n            $(this).parent().nextAll().eq(0).addClass(\"hide\");\n            var _div2 = $(this).parent().nextAll().eq(1);\n            _div2.addClass(\"hide\");\n            var sqlname = _div2.find('input').val();\n            var _div3 = $(this).parent().nextAll().eq(2);\n            _div3.children().text(sqlname);\n            _div3.removeClass(\"hide\");\n        }\n    })\n}\n\n/*\n*显示所有选中的 sql div 元素\n*/\nfunction show_sql_div(div) {\n    div.parents(\".form-group\").nextAll().find(\"input[name='chk_sql']\").each(function () {\n        var _result = $(this).prop(\"checked\");\n        if (_result) {\n            $(this).parent().nextAll().eq(0).removeClass(\"hide\");\n            var _div2 = $(this).parent().nextAll().eq(1);\n            _div2.removeClass(\"hide\");\n            var sqlname = _div2.find('input').val();\n            var _div3 = $(this).parent().nextAll().eq(2);\n            _div3.children().text(sqlname);\n            _div3.addClass(\"hide\");\n        }\n    })\n}\n\n\n/*\n*删除所有选中的 sql div 元素\n*/\nfunction delete_sql_div(div) {\n    div.parents(\".form-group\").nextAll().find(\"input[name='chk_sql']\").each(function () {\n        var _result = $(this).prop(\"checked\");\n        if (_result) {\n            $(this).parents(\".form-group\").remove();\n            count_sqldiv();\n        }\n    })\n}\n\n\n/*\n*选择数据库后修改IP地址\n*/\n$(document).on('change', \"select[name='database']\", function () {\n    var _ip = $(this).find(\"option:selected\").attr(\"ip\");\n    $(this).parents(\"tr\").next().find(\"p\").text(_ip);\n});\n\n\n/*\n*保存周期任务 save periodic task\n*/\n$(\"#save_task\").click(function () {\n    var para = get_para();\n    console.log(para)\n    var jpara = JSON.stringify(para);\n    var url = '/scheduled_tasks/add_periodic_task_data/';\n    var index = layer.load();\n    $.post(url, {'data': jpara}, function (res) {\n        var _data = $.parseJSON(res);\n        var msg = _data.msg;\n        layer.close(index);\n        // 成功则跳转列表页面，失败则提示错误信息继续修改。\n        if (_data.status == 0) {\n            var url =\"/scheduled_tasks/periodic_task/\";\n            ajax_callback2(msg, url)\n        }\n        else{\n            ajax_callback1(msg);\n        }\n    });\n});\n\n\n/*\n*运行周期任务 run periodic task\n*/\n$(\"#RunTask\").click(function () {\n    var para = get_para();\n    var _random = _getRandomString(6);\n    para['_random'] = _random;\n    var jpara = JSON.stringify(para);\n    var url = '/scheduled_tasks/run_periodic_task/';\n    var index = layer.load();\n    $.post(url, {'data': jpara}, function (res) {\n        var _data = $.parseJSON(res);\n        layer.close(index);\n        ajax_callback1(_data.msg)\n    });\n});\n\n\n/*\n*删除周期任务 periodic task\n*/\n$(\"#delete_task\").click(function () {\n    var para = get_para();\n    var jpara = JSON.stringify(para);\n    var url = '/scheduled_tasks/delete_periodic_task/';\n    //询问框\n    layer.confirm('确认删除吗？', {\n      btn: ['确定','取消'] //按钮\n    }, function () {\n            var index = layer.load();\n            $.post(url, {'data': jpara}, function (res) {\n                var _data = $.parseJSON(res);\n                var msg = _data.msg.join('<br>');\n                layer.close(index);\n                ajax_callback2(msg, \"/scheduled_tasks/periodic_task/\");\n            });\n        }\n    );\n\n});\n\n\n/*\n*获取提交的信息\n*/\nfunction get_para() {\n    var str=location.href;\n    var args = str.split('/');\n    var _id = args[args.length-2];\n    var task_name = $(\"#task_name\").val().trim();\n    var task_template = $(\"#task_template\").val().trim();\n    var is_enable = $(\"#is_enable\").is(\":checked\");\n    var subject = $(\"#subject\").val().trim();\n    var receivers = mail_receivers($(\"#receivers\"));\n    var cc = mail_receivers($(\"#cc\"));\n    var crontab = $(\"#crontab\").val().trim();\n    var is_encrypt = $(\"#is_encrypt\").is(\":checked\");\n    var is_sensitive = $(\"input[name='is_sensitive']:checked\").val().trim();\n    var run_server = $(\"#run_server\").val().trim();\n    var response_type = $(\"#response_type\").val().trim();\n    var max_excel_num = $(\"#max_excel_num\").val().trim();\n\n    var _sql_list = get_sql_list();\n    var para = {\n        'operation_type': 'mod',\n        'task_name': task_name,\n        'task_template': task_template,\n        'is_enable': is_enable,\n        'subject': subject,\n        'receivers': receivers,\n        'cc': cc,\n        'crontab': crontab,\n        'is_encrypt': is_encrypt,\n        'is_sensitive': is_sensitive,\n        'run_server': run_server,\n        'response_type': response_type,\n        'max_excel_num': max_excel_num,\n        'sql_list': _sql_list,\n        '_id': _id\n    };\n    return para\n}\n\n\n/*\n*获取邮件人列表\n*/\nfunction mail_receivers (div) {\n    var data = [];\n    var val = div.val().trim();\n    if (val.length != 0) {\n        data = val.split(\"\\n\");\n    }\n    return data\n}\n\n\n/*\n*获取SQL\n*/\nfunction get_sql_list() {\n    var _sql_list = [];\n    $(\"#add_sql\").parents('.form-group').nextAll().each(function () {\n        var sentence = $(this).find(\"textarea[name='sentence']\").val().trim();\n        var name = $(this).find(\"input[name='name']\").val().trim();\n        var database = $(this).find(\"select[name='database']\").val().trim();\n        var interval = $(this).find(\"input[name='interval']\").val().trim();\n        var cont = {'database': database, 'sentence':sentence, 'name':name,\n                    'interval': interval};\n        _sql_list.push(cont)\n    });\n    return _sql_list\n}\n\n\n// 获取长度为len的随机字符串\nfunction _getRandomString(len) {\n    len = len || 32;\n    var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; // 默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1\n    var maxPos = $chars.length;\n    var pwd = '';\n    for (i = 0; i < len; i++) {\n        pwd += $chars.charAt(Math.floor(Math.random() * maxPos));\n    }\n    return pwd;\n}\n\n\n/*\n*实时获取测试结果\n*/\nfunction test_result(_random) {\n    var url = '/scheduled_tasks/test_periodic_task_result/';\n        $.post(url, {'_random': _random}, function (res) {\n        var _data = $.parseJSON(res);\n        var msg = _data.msg.join('<br>');\n        $(\"#test_result\").children().append(msg);\n    });\n}\n\n\n/**\n * 根据权限禁用用户操作\n */\nfunction disableOperation() {\n    var data = {'permission': 'scheduled_tasks.editTask'};\n    $.ajax({\n        type: 'POST',\n        url: \"/check_permission/\",\n        data: data,\n        success: function (jret) {\n            var ret = $.parseJSON(jret);\n            if (ret.status == 1){\n                $('input,select,a,button,textarea').attr('disabled', 'disabled')\n            }\n        }\n    });\n}\n\n\n\n/*\n*ajax get callback\n*/\nfunction ajax_callback1(msg){\n    var index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n       layer.close(index)\n    });\n}\n\n\n/*\n*ajax get callback2\n*/\nfunction ajax_callback2(msg, url){\n    var index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n        layer.close(index);\n        window.location=url;\n    });\n}\n</script>\n{% endblock %}"
  },
  {
    "path": "templates/datax_web/monitor_job.html",
    "content": "{% extends 'base.html' %}\n\n{% block header_content %}\n<style>\n.center {\n width: auto;\n display: table;\n margin-left: auto;\n margin-right: auto;\n}\n.text-center > table > tbody > tr > th,\n.text-center > table > thead > tr > th {\n text-align: center;\n}\n\n.table-responsive {\nwidth: 100%;\nmargin-bottom: 15px;\noverflow-x: scroll;\noverflow-y: hidden;\nborder: 1px solid #dddddd;\n-ms-overflow-style: -ms-autohiding-scrollbar;\n-webkit-overflow-scrolling: touch;\n}\n.table-responsive > .table {\nmargin-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 {\nwhite-space: nowrap;\n}\n\n.NoNewline\n{\nword-break: keep-all;/*必须*/\nwhite-space: nowrap;\n}\n\n.text-overflow{\nwidth:100px;\noverflow:hidden;;/* 内容超出宽度时隐藏超出部分的内容 */\ntext-overflow:ellipsis;;/* 当对象内文本溢出时显示省略标记(...) ；需与overflow:hidden;一起使用。*/\nwhite-space:nowrap;/* 不换行 */\n}\n</style>\n\t<!-- Datepicker -->\n    <link href=\"/static/template/css/bootstrap-datepicker.min.css\" rel=\"stylesheet\"/>\n{% endblock %}\n\n\n{% block container %}\n<div id=\"main-container\">\n\t<div class=\"main-header clearfix\">\n\t\t<div class=\"page-title\">\n\t\t\t<h3 class=\"no-margin\">数据同步 - 执行历史</h3>\n\t\t</div><!-- /page-title -->\n\t</div><!-- /main-header -->\n\n\t<div class=\"padding-md\">\n\t\t<div class=\"panel panel-default table-responsive\">\n            <div class=\"panel-body\">\n                <table class=\"table-condensed\" id=\"search_tb\">\n                    <tr>\n                        <td><label>任务名称</label></td>\n                        <td><input type=\"text\" id=\"name\" name=\"store\" class=\"form-control input-sm\"></td>\n                        <td><label>描述</label></td>\n                        <td><input type=\"text\" id=\"description\" name=\"account_manager\" class=\"form-control input-sm\"></td>\n                        <td><label>读取数据库</label></td>\n                        <td>\n                            <select id=\"reader_databaseinfo_host\" name=\"database\" class=\"form-control\">\n                                <option value=\"\">请选择</option>\n                            </select>\n                        </td>\n                        <td><label>执行状态</label></td>\n                        <td>\n    \t\t\t\t\t\t<select id=\"status\" name=\"status\" class=\"form-control\">\n                                <option value=\"\">请选择</option>\n                                <option value=\"0\">正在执行</option>\n                                <option value=\"1\">执行完成</option>\n                            </select>\n                        </td>\n                    </tr>\n                    <tr>\n                        <td><label>写入表</label></td>\n                        <td><input type=\"text\" id=\"writer_table\" name=\"account_manager_cn\" class=\"form-control input-sm\"></td>\n                        <td><label>写入数据库</label></td>\n                        <td>\n                            <select id=\"writer_databaseinfo_host\" name=\"database\" class=\"form-control\">\n                                <option value=\"\">请选择</option>\n                            </select>\n                        </td>\n                        <td><label>执行结果</label></td>\n                        <td>\n    \t\t\t\t\t\t<select id=\"result\" name=\"result\" class=\"form-control\">\n                                <option value=\"\">请选择</option>\n                                <option value=\"0\">成功</option>\n                                <option value=\"1\">失败</option>\n                                <option value=\"2\">未知</option>\n                            </select>\n                        </td>\n                        <td><label>触发模式</label></td>\n                        <td>\n    \t\t\t\t\t\t<select id=\"trigger_mode\" name=\"status\" class=\"form-control\">\n                                <option value=\"\">请选择</option>\n                                <option value=\"1\">自动</option>\n                                <option value=\"2\">手动</option>\n                            </select>\n                        </td>\n                    </tr>\n\n                </table>\n                <button id=\"search\" type=\"button\" class=\"btn btn-sm btn-success\">搜索</button>\n            </div>\n            <div class=\"form-inline\">\n\n            </div>\n            <div class=\"table-responsive\">\n\t\t\t\t<table class=\"table table-hover table-bordered NoNewline\" id=\"table\"></table>\n\t\t\t</div><!-- /.padding-md -->\n\t\t</div><!-- /panel -->\n\t</div><!-- /padding-md -->\n</div><!-- /main-container -->\n{% endblock %}\n\n{% block footer_content %}\n\n\n<!-- Datepicker -->\n<script src='/static/template/js/bootstrap-datepicker.js'></script>\n<script src='/static/template/js/bootstrap-datepicker.zh-CN.min.js'></script>\n<script>\n$(document).ready(function(){\n    $('body').on('mouseover', '.text-overflow', function() {\n        var _cont = $(this).children().text();\n        layer.tips(_cont.split('\\n').join('<br>'), $(this), {\n        tips: [1, '#0FA6D8'],\n        time: 0\n        });\n    });\n    $('body').on('mouseout', '.text-overflow', function() {\n        layer.closeAll('tips'); //关闭所有的tips层\n    });\n\n    Initialization_Database();\n});\n\n\n/*\n*初始化表格\n*/\n$('#table').bootstrapTable({\n    url: '/datax_web/get_datax_job_instance/',\n    pagination: true,                   //是否显示分页（*）\n    sortable: false,                     //是否启用排序\n    sortOrder: \"asc\",                   //排序方式\n    showColumns: true,\n    queryParams: queryParams,           //传递参数（*）\n    sidePagination: \"server\",           //分页方式：client客户端分页，server服务端分页（*）\n    pageNumber: 1,                       //初始化加载第一页，默认第一页\n    pageSize: 10,                       //每页的记录行数（*）\n    pageList: [10, 25, 50, 100],        //可供选择的每页的行数（*）\n    search: true,                  //是否显示搜索 --前端搜索\n    columns:get_columns()\n});\n\n\n/*\n*得到查询的参数\n*/\nfunction queryParams(params) {\n    return {   //这里的键的名字和控制器的变量名必须一直，这边改动，控制器也需要改成一样的\n        limit: params.limit,   //页面大小\n        offset: params.offset,  //页码\n        name: $('#name').val(),\n        description: $('#description').val(),\n        reader_databaseinfo_host: $('#reader_databaseinfo_host').val(),\n        writer_databaseinfo_host: $('#writer_databaseinfo_host').val(),\n        status: $('#status').val(),\n        writer_table: $('#writer_table').val(),\n        result: $('#result').val(),\n        trigger_mode: $('#trigger_mode').val(),\n    };\n}\n\n\n/*\n*获取bootstraptable 的列columns\n*/\nfunction get_columns() {\n    var columns =[{\n        title: '序号',//标题  可不加\n        formatter: function (value, row, index) {\n            return index+1;\n            }\n    }, {\n        field: 'id',\n        title: 'ID',\n        visible: false\n    }, {\n        field: 'name',\n        title: '任务名称',\n        formatter: subjectFormatter\n    }, {\n        field: 'description',\n        title: '描述 '\n    }, {\n        field: 'querySql',\n        title: '查询sql',\n        formatter: receiversFormatter\n    }, {\n        field: 'reader_databaseinfo_host',\n        title: '读取数据库',\n        formatter: receiversFormatter\n    }, {\n        field: 'writer_table',\n        title: '写入表',\n        formatter: receiversFormatter\n    }, {\n        field: 'writer_databaseinfo_host',\n        title: '写入数据库',\n        formatter: receiversFormatter\n    }, {\n        field: 'writer_preSql',\n        title: '写入前SQL',\n        formatter: receiversFormatter\n    }, {\n        field: 'writer_postSql',\n        title: '写入后SQL',\n        formatter: receiversFormatter\n    }, {\n        field: 'trigger_mode',\n        title: '触发模式',\n        formatter: triggerModeFormatter\n    }, {\n        field: 'status',\n        title: '执行状态',\n        formatter: statusFormatter\n    }, {\n        field: 'result',\n        title: '执行结果 ',\n        formatter: resultFormatter\n    }, {\n        field: 'start_time',\n        title: '开始时间 '\n    }, {\n        field: 'end_time',\n        title: '结束时间 '\n    }];\n    return columns\n}\n\n\n$('#search').click(function(){\n    var opt = {\n        url: '/datax_web/get_datax_job_instance/',\n        silent: true\n    };\n    $('#table').bootstrapTable('refresh', opt)\n});\n\n\n/*\n*刷新表格\n*/\nfunction refreshTable()\n{\n    $('#table').bootstrapTable('refresh')\n}\n\n\n/*\n*开启自动刷新\n*/\nvar refreshId = null;\n$('#OpenAutomaticRefresh').click(function () {\n    if (refreshId){\n        layer.msg('自动刷新已开启');\n    }\n    else{\n        refreshId = setInterval(\"refreshTable()\",\"10000\");\n        layer.msg('已开启自动刷新，每隔10秒刷新结果！');\n    }\n});\n\n\n/*\n*关闭自动刷新\n*/\n$('#CloseAutomaticRefresh').click(function () {\n    clearInterval(refreshId);\n    refreshId = null;\n    layer.msg('已关闭自动刷新');\n});\n\n\n/*\n*超链接显示收件人\n*/\nfunction receiversFormatter(value, row, index) {\n    return [\n        '<div class=\"text-overflow\"><a href=\"#\">',\n        value,\n        '</a></div>'\n    ].join('');\n}\n\n\n/*\n*超链接显示邮件标题\n*/\nfunction subjectFormatter(value, row, index) {\n    var url = \"/datax_web/monitor_job_detail/\" + row.instance_id;\n    return [\n        '<div><a class=\"mod\" href='+ url +'>',\n        value,\n        '</a></div>'\n    ].join('');\n}\n\n\n/*\n*格式化执行结果\n*/\nfunction resultFormatter(value, row, index) {\n    switch (Number(value)){\n        case 0:\n            var resultF = '成功';\n            var className = 'label-success';\n            break;\n        case 1:\n            var resultF = '失败';\n            className = 'label-danger';\n            break;\n        case 2:\n            resultF = '';\n            className = 'label-info';\n            break;\n    }\n    return '<span class=\"label ' + className + '\">' + resultF + '</span>'\n}\n\n\n/*\n*格式化执行状态\n*/\nfunction statusFormatter(value, row, index) {\n    switch (Number(value)){\n        case 0:\n            var resultF = '正在执行';\n            var className = '';\n            break;\n        case 1:\n            var resultF = '执行完成';\n            className = '';\n            break;\n    }\n    return '<span class=\"label ' + className + '\">' + resultF + '</span>'\n}\n\n\n/*\n*格式化触发模式\n*/\nfunction triggerModeFormatter(value, row, index) {\n    switch (Number(value)){\n        case 1:\n            var resultF = '自动';\n            var className = '';\n            break;\n        case 2:\n            var resultF = '手动';\n            className = '';\n            break;\n    }\n    return '<span class=\"label ' + className + '\">' + resultF + '</span>'\n}\n\n\n/*\n*初始化数据库\n*/\nfunction Initialization_Database() {\n    var url = '/datax_web/get_database/';\n    var para = {};\n    $.post(url, para, function (jdata) {\n        var _data = $.parseJSON(jdata);\n        $.each(_data, function (k, v) {\n            var _option = \"<option value='\"+ v.host +\"'>\"+ v.description + \" \" + v.host.substr(0, 15) + \"</option>\";\n            $(\"#reader_databaseinfo_host\").append(_option);\n            $(\"#writer_databaseinfo_host\").append(_option);\n        });\n    })\n}\n\n\n/*\n*ajax get callback\n*/\nfunction ajax_callback1(msg){\n    var index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n       layer.close(index)\n    });\n}\n\n</script>\n{% endblock %}"
  },
  {
    "path": "templates/datax_web/monitor_job_detail.html",
    "content": "{% extends 'base.html' %}\n\n{% block header_content %}\n<style>\n.center {\n width: auto;\n display: table;\n margin-left: auto;\n margin-right: auto;\n}\n.text-center > table > tbody > tr > th,\n.text-center > table > thead > tr > th {\n text-align: center;\n}\n\n.table-responsive {\nwidth: 100%;\nmargin-bottom: 15px;\noverflow-x: scroll;\noverflow-y: hidden;\nborder: 1px solid #dddddd;\n-ms-overflow-style: -ms-autohiding-scrollbar;\n-webkit-overflow-scrolling: touch;\n}\n.table-responsive > .table {\nmargin-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 {\nwhite-space: nowrap;\n}\n\n.NoNewline\n{\nword-break: keep-all;/*必须*/\nwhite-space: nowrap;\n}\n\n.text-overflow{\nwidth:100px;\noverflow:hidden;;/* 内容超出宽度时隐藏超出部分的内容 */\ntext-overflow:ellipsis;;/* 当对象内文本溢出时显示省略标记(...) ；需与overflow:hidden;一起使用。*/\nwhite-space:nowrap;/* 不换行 */\n}\n\n.code_pre{ /* 取消自动换行 */\nwhite-space:pre-wrap;\nwhite-space:-moz-pre-wrap;\nwhite-space:-pre-wrap;\nwhite-space:-o-pre-wrap;\nword-wrap:break-word;\n}\n</style>\n\t<!-- Datepicker -->\n    <link href=\"/static/template/css/bootstrap-datepicker.min.css\" rel=\"stylesheet\"/>\n{% endblock %}\n\n\n{% block container %}\n<div id=\"main-container\">\n\t<div class=\"main-header clearfix\">\n\t\t<div class=\"page-title\">\n\t\t\t<h3 class=\"no-margin\">任务实例执行详情</h3>\n\t\t</div><!-- /page-title -->\n\t</div><!-- /main-header -->\n\n\t<div class=\"padding-md\">\n\t\t<div class=\"panel panel-default\">\n            <pre id=\"datax_web_instance_detail\" class=\"code_pre\"></pre>\n\t\t</div><!-- /panel -->\n\t</div><!-- /padding-md -->\n\n</div><!-- /main-container -->\n{% endblock %}\n\n{% block footer_content %}\n\n\n<!-- Datepicker -->\n<script src='/static/template/js/bootstrap-datepicker.js'></script>\n<script src='/static/template/js/bootstrap-datepicker.zh-CN.min.js'></script>\n<script>\n$(document).ready(function(){\n    let host = document.domain;\n    let url = 'ws://'+ host +':8080/';\n    let ws = new WebSocket(url);\n    ws.onmessage = function(event) {\n        let cont = event.data + '\\n';\n        console.log(event.data, event.data.length);\n        $('#datax_web_instance_detail').append(cont);\n    };\n    ws.onopen = function () {\n        ws.send(getId());\n    };\n});\n\n\n\n/*\n*超链接显示收件人\n*/\nfunction receiversFormatter(value, row, index) {\n    return [\n        '<div class=\"text-overflow\"><a href=\"#\">',\n        value,\n        '</a></div>'\n    ].join('');\n}\n\n\n/*\n*超链接显示邮件标题\n*/\nfunction subjectFormatter(value, row, index) {\n    let url = \"/scheduled_tasks/mod_periodic_task/\" + row.djcelery_periodictask_id;\n    return [\n        '<div><a class=\"mod\" href='+ url +'>',\n        value,\n        '</a></div>'\n    ].join('');\n}\n\n\n\n/*\n*格式化执行结果\n*/\nfunction resultFormatter(value, row, index) {\n    let resultF = '成功';\n    let className = 'label-success';\n    if (value==1){\n        resultF = '失败';\n        className = 'label-danger';\n    }\n    return '<span class=\"label ' + className + '\">' + resultF + '</span>'\n}\n\n\n/**\n * 获取URL后面的ID\n * return: _id\n */\nfunction getId() {\n    let str=location.href;\n    let args = str.split('/');\n    return args[args.length-2];\n}\n\n\n/*\n*ajax get callback\n*/\nfunction ajax_callback1(msg){\n    let index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n       layer.close(index)\n    });\n}\n</script>\n{% endblock %}"
  },
  {
    "path": "templates/datax_web/update_job.html",
    "content": "{% extends 'base.html' %}\n\n{% block header_content %}\n<style>\n.center {\n width: auto;\n display: table;\n margin-left: auto;\n margin-right: auto;\n}\n.text-center > table > tbody > tr > th,\n.text-center > table > thead > tr > th {\n text-align: center;\n}\n\n.table-responsive {\nwidth: 100%;\nmargin-bottom: 15px;\noverflow-x: scroll;\noverflow-y: hidden;\nborder: 1px solid #dddddd;\n-ms-overflow-style: -ms-autohiding-scrollbar;\n-webkit-overflow-scrolling: touch;\n}\n.table-responsive > .table {\nmargin-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 {\nwhite-space: nowrap;\n}\n\n.NoNewline\n{\nword-break: keep-all;/*必须*/\nwhite-space: nowrap;\n}\n</style>\n\t<!-- Datepicker -->\n    <link href=\"/static/template/css/bootstrap-datepicker.min.css\" rel=\"stylesheet\"/>\n    <!-- Gritter -->\n\t<link href=\"/static/template/css/gritter/jquery.gritter.css\" rel=\"stylesheet\">\n{% endblock %}\n\n\n{% block container %}\n<div id=\"main-container\">\n\t<div class=\"main-header clearfix\">\n\t\t<div class=\"page-title\">\n\t\t\t<h3 class=\"no-margin\">更新 数据同步</h3>\n\t\t</div><!-- /page-title -->\n\t</div><!-- /main-header -->\n\n\n\t<div class=\"padding-md\">\n        <div class=\"row\">\n            <div class=\"col-md-12\">\n                <div class=\"panel panel-default\">\n                    <form class=\"form-horizontal form-border no-margin\" id=\"basic-constraint\" data-validate=\"parsley\" novalidate>\n                        <div class=\"panel-heading\">\n                            Add Job\n                        </div>\n                        <div class=\"panel-body\">\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">任务名称</label>\n                                <div class=\"col-lg-4\">\n                                    <input type=\"text\" id=\"name\" class=\"form-control input-sm\" data-required=\"true\" placeholder=\"请输入英文\">\n                                </div><!-- /.col -->\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">描述</label>\n                                <div class=\"col-lg-4\">\n                                    <textarea id=\"description\" spellcheck=\"false\" class=\"form-control\" placeholder=\"describe the specific job\" rows=\"6\" data-required=\"true\"></textarea>\n                                </div><!-- /.col -->\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">查询SQL语句</label>\n                                <div class=\"col-lg-4\">\n                                    <textarea id=\"querySql\" spellcheck=\"false\" class=\"form-control\" placeholder=\"SQL statement that reads data\" rows=\"6\" data-required=\"true\"></textarea>\n                                </div><!-- /.col -->\n                                <span class=\"col-lg-2\">SQL语句里指明数据库</span>\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">读取数据库</label>\n                                <div class=\"col-lg-4\">\n                                    <select id=\"reader_databaseinfo_id\" class=\"form-control\">\n                                        <option>请选择</option>\n                                    </select>\n                                </div><!-- /.col -->\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">写入表名</label>\n                                <div class=\"col-lg-4\">\n                                    <input type=\"text\" id=\"writer_table\" class=\"form-control input-sm\" data-required=\"true\" placeholder=\"请输入英文\">\n                                </div><!-- /.col -->\n                                <span class=\"col-lg-2\">指明数据库，如：jr_user.user_info. 末尾不用加分号 ;</span>\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">写入表的列</label>\n                                <div class=\"col-lg-4\">\n                                    <textarea id=\"writer_column_id\" spellcheck=\"false\" class=\"form-control\" placeholder=\"Write columns\" rows=\"6\" data-required=\"true\"></textarea>\n                                </div><!-- /.col -->\n                                <span class=\"col-lg-3\">每行一列, \"*\" 星号代表所有列。</span>\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">写入数据库</label>\n                                <div class=\"col-lg-4\">\n                                    <select id=\"writer_databaseinfo_id\" class=\"form-control\">\n                                        <option>请选择</option>\n                                    </select>\n                                </div><!-- /.col -->\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">写入数据前执行的SQL语句</label>\n                                <div class=\"col-lg-4\">\n                                    <textarea id=\"writer_preSql\" spellcheck=\"false\" class=\"form-control\" placeholder=\"SQL statements executed before writing data\" rows=\"6\" data-required=\"true\"></textarea>\n                                </div><!-- /.col -->\n                                <span class=\"col-lg-2\">每条SQL语句末尾要带；分号，指明数据库. 如 truncate table `admin-service`.as_user_info; 注意：SQL语句里面不要带分号;</span>\n                            </div><!-- /form-group -->\n                            <div class=\"form-group\">\n                                <label class=\"control-label col-lg-2\">写入数据后执行的SQL语句</label>\n                                <div class=\"col-lg-4\">\n                                    <textarea id=\"writer_postSql\" spellcheck=\"false\" class=\"form-control\" placeholder=\"SQL statements executed after writing data\" rows=\"6\" data-required=\"true\"></textarea>\n                                </div><!-- /.col -->\n                                <span class=\"col-lg-2\">每条SQL语句末尾要带；分号。 注意：SQL语句里面不要带分号;</span>\n                            </div><!-- /form-group -->\n                        </div>\n                        <div class=\"panel-footer\">\n                            <button id=\"save_job\" type=\"button\" class=\"btn btn-success\">Save</button>\n                            <button id=\"RunJob\" type=\"button\" class=\"btn btn-info\">Run</button>\n                        </div>\n                    </form>\n                </div><!-- /panel -->\n\t\t\t\t\t</div><!-- /.col-->\n        </div><!-- /.row -->\n\t</div><!-- /padding-md -->\n</div><!-- /main-container -->\n{% endblock %}\n\n{% block footer_content %}\n\n\n<!-- Datepicker -->\n<script src='/static/template/js/bootstrap-datepicker.js'></script>\n<script src='/static/template/js/bootstrap-datepicker.zh-CN.min.js'></script>\n<script src=\"/static/template/js/jquery.gritter.min.js\"></script>\n<!-- Modernizr -->\n{#<script src='/static/template/js/modernizr.min.js'></script>#}\n<script>\n$(document).ready(function(){\n    let index = layer.load();\n    Initialization_Database();\n    init_update_job_data();\n    disableOperation();\n    layer.close(index);\n});\n\n\n\n/*\n*获取需要修改的周期任务数据\n*/\nfunction init_update_job_data() {\n    let url = '/datax_web/get_update_job_data/';\n    let str=location.href;\n    let args = str.split('/');\n    let _id = args[args.length-2];\n    let para = {'_id': _id};\n\t$.ajax({\n\t\ttype : \"post\",\n\t\turl : url,\n\t\tdata : para,\n\t\tsuccess : function (jdata) {\n\t\t\tlet data = $.parseJSON(jdata);\n\t\t\t$(\"#name\").val(data.name);\n\t\t\t$(\"#description\").val(data.description);\n\t\t\t$(\"#querySql\").val(data.querySql);\n\t\t\t$(\"#reader_databaseinfo_id\").val(data.reader_databaseinfo_id);\n\t\t\t$(\"#writer_table\").val(data.writer_table);\n\t\t\t$(\"#writer_databaseinfo_id\").val(data.writer_databaseinfo_id);\n\t\t\t$(\"#writer_preSql\").val(data.writer_preSql);\n\t\t\t$(\"#writer_postSql\").val(data.writer_postSql);\n\t\t\t$(\"#writer_column_id\").val(data.writer_column_id);\n\t\t}\n  \t});\n}\n\n\n/*\n*初始化数据库\n*/\nfunction Initialization_Database() {\n    var url = '/datax_web/get_database/';\n    var para = {};\n\t$.ajax({\n\t\ttype : \"post\",\n\t\turl : url,\n\t\tdata : para,\n\t\tasync: false,\n\t\tsuccess : function (jdata) {\n\t\t\tvar _data = $.parseJSON(jdata);\n\t\t\t$.each(_data, function (k, v) {\n\t\t\t\tvar _option = \"<option value='\"+ v.id +\"'>\"+ v.description + \"  \" + v.host +\"</option>\";\n\t\t\t\t$(\"#reader_databaseinfo_id\").append(_option);\n\t\t\t\t$(\"#writer_databaseinfo_id\").append(_option);\n\t\t\t});\n\t  \t}\n  \t});\n}\n\n\n/*\n*保存任务 save job\n*/\n$(\"#save_job\").click(function () {\n    var para = get_para();\n    var jpara = JSON.stringify(para);\n    var url = '/datax_web/add_job_data/';\n    var index = layer.load();\n    $.post(url, {'data': jpara}, function (res) {\n        var _data = $.parseJSON(res);\n        layer.close(index);\n        // 成功则跳转列表页面，失败则提示错误信息继续修改。\n        if (_data.status == 0) {\n            var url =\"/datax_web/index/\";\n            ajax_callback2(_data.msg, url)\n        }\n        else{\n            ajax_callback1(_data.msg);\n        }\n    });\n});\n\n\n/*\n*运行任务 run job\n*/\n$(\"#RunJob\").click(function () {\n    let para = get_para();\n    let jpara = JSON.stringify(para);\n    let url = '/datax_web/run_job/';\n    let index = layer.load();\n    $.post(url, {'data': jpara}, function (res) {\n        let _data = $.parseJSON(res);\n        console.log(_data);\n        layer.close(index);\n        ajax_callback1(_data.msg)\n    });\n});\n\n\n/*\n*获取提交的信息\n*/\nfunction get_para() {\n    let str=location.href;\n\tlet args = str.split('/');\n    let _id = args[args.length-2];\n    let name = $(\"#name\").val().trim();\n    let description = $(\"#description\").val().trim();\n    let querySql = $(\"#querySql\").val().trim();\n    let reader_databaseinfo_id = $(\"#reader_databaseinfo_id\").val().trim();\n    let writer_table = $(\"#writer_table\").val().trim();\n    let writer_column_id = strToArray($('#writer_column_id'));\n    let writer_databaseinfo_id = $(\"#writer_databaseinfo_id\").val().trim();\n    let writer_preSql = $(\"#writer_preSql\").val().trim();\n    let writer_postSql = $(\"#writer_postSql\").val().trim();\n\n    return {\n        '_id': _id,\n        'operation_type': 'mod',\n        'name': name,\n        'description': description,\n        'querySql': querySql,\n        'reader_databaseinfo_id': reader_databaseinfo_id,\n        'writer_table': writer_table,\n        'writer_column_id': writer_column_id,\n        'writer_databaseinfo_id': writer_databaseinfo_id,\n        'writer_preSql': writer_preSql,\n        'writer_postSql': writer_postSql,\n        'trigger_mode': 2,\n    }\n}\n\n\n/**\n * 根据权限禁用用户操作\n */\nfunction disableOperation() {\n    let data = {'permission': 'batch_job.editBatchJob'};\n    $.ajax({\n        type: 'POST',\n        url: \"/check_permission/\",\n        data: data,\n        success: function (jret) {\n            let ret = $.parseJSON(jret);\n            if (ret.status == 1){\n                $('input,select,button,textarea').attr('disabled', 'disabled')\n            }\n        }\n    });\n}\n\n\n/*\n*获取邮件人列表\n*/\nfunction strToArray (div) {\n    let data = [];\n    let val = div.val().trim();\n    if (val.length != 0) {\n        data = val.split(\"\\n\");\n    }\n    return data\n}\n\n\n/*\n*ajax get callback\n*/\nfunction ajax_callback1(msg){\n    let index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n       layer.close(index)\n    });\n}\n\n\n/*\n*ajax get callback2\n*/\nfunction ajax_callback2(msg, url){\n    let index = layer.alert(msg, {\n        skin: 'layui-layer-molv' //样式类名\n    },function(){\n        layer.close(index);\n        window.location=url;\n    });\n}\n</script>\n{% endblock %}"
  },
  {
    "path": "templates/index.html",
    "content": "{% extends 'base.html' %}\n\n{% block container %}\n<div id=\"main-container\">\n\t\t\t<div id=\"breadcrumb\">\n\t\t\t\t<ul class=\"breadcrumb\">\n\t\t\t\t\t <li><i class=\"fa fa-home\"></i><a href=\"index.html\"> Home</a></li>\n\t\t\t\t\t <li class=\"active\">Dashboard</li>\n\t\t\t\t</ul>\n\t\t\t</div><!-- /breadcrumb-->\n\t\t\t<div class=\"main-header clearfix\">\n\t\t\t\t<div class=\"page-title\">\n\t\t\t\t\t<h3 class=\"no-margin\">Dashboard</h3>\n\t\t\t\t\t<span>Welcome back Mr.John Doe</span>\n\t\t\t\t</div><!-- /page-title -->\n\t\t\t\t\n\t\t\t\t<ul class=\"page-stats\">\n\t\t\t    \t<li>\n\t\t\t    \t\t<div class=\"value\">\n\t\t\t    \t\t\t<span>New visits</span>\n\t\t\t    \t\t\t<h4 id=\"currentVisitor\">4256</h4>\n\t\t\t    \t\t</div>\n\t\t\t\t\t\t<span id=\"visits\" class=\"sparkline\"></span>\n\t\t\t    \t</li>\n\t\t\t    \t<li>\n\t\t\t    \t\t<div class=\"value\">\n\t\t\t    \t\t\t<span>My balance</span>\n\t\t\t    \t\t\t<h4>$<strong id=\"currentBalance\">32153</strong></h4>\n\t\t\t    \t\t</div>\n\t\t\t    \t\t<span id=\"balances\" class=\"sparkline\"></span>\n\t\t\t    \t</li>\n\t\t\t    </ul><!-- /page-stats -->\n\t\t\t</div><!-- /main-header -->\n\t\t\t\n\t\t\t<div class=\"grey-container shortcut-wrapper\">\n\t\t\t\t<a href=\"#\" class=\"shortcut-link\">\n\t\t\t\t\t<span class=\"shortcut-icon\">\n\t\t\t\t\t\t<i class=\"fa fa-bar-chart-o\"></i>\n\t\t\t\t\t</span>\n\t\t\t\t\t<span class=\"text\">Statistic</span>\n\t\t\t\t</a>\n\t\t\t\t<a href=\"#\" class=\"shortcut-link\">\n\t\t\t\t\t<span class=\"shortcut-icon\">\n\t\t\t\t\t\t<i class=\"fa fa-envelope-o\"></i>\n\t\t\t\t\t\t<span class=\"shortcut-alert\">\n\t\t\t\t\t\t\t5\n\t\t\t\t\t\t</span>\t\n\t\t\t\t\t</span>\n\t\t\t\t\t<span class=\"text\">Messages</span>\n\t\t\t\t</a>\n\t\t\t\t<a href=\"#\" class=\"shortcut-link\">\n\t\t\t\t\t<span class=\"shortcut-icon\">\n\t\t\t\t\t\t<i class=\"fa fa-user\"></i>\n\t\t\t\t\t</span>\n\t\t\t\t\t<span class=\"text\">New Users</span>\n\t\t\t\t</a>\n\t\t\t\t<a href=\"#\" class=\"shortcut-link\">\n\t\t\t\t\t<span class=\"shortcut-icon\">\n\t\t\t\t\t\t<i class=\"fa fa-globe\"></i>\n\t\t\t\t\t\t<span class=\"shortcut-alert\">\n\t\t\t\t\t\t\t7\n\t\t\t\t\t\t</span>\t\n\t\t\t\t\t</span>\n\t\t\t\t\t<span class=\"text\">Notification</span>\n\t\t\t\t</a>\n\t\t\t\t<a href=\"#\" class=\"shortcut-link\">\n\t\t\t\t\t<span class=\"shortcut-icon\">\n\t\t\t\t\t\t<i class=\"fa fa-list\"></i>\n\t\t\t\t\t</span>\n\t\t\t\t\t<span class=\"text\">Activity</span>\n\t\t\t\t</a>\n\t\t\t\t<a href=\"#\" class=\"shortcut-link\">\n\t\t\t\t\t<span class=\"shortcut-icon\">\n\t\t\t\t\t\t<i class=\"fa fa-cog\"></i></span>\n\t\t\t\t\t<span class=\"text\">Setting</span>\n\t\t\t\t</a>\n\t\t\t</div><!-- /grey-container -->\n\t\t\t\n\t\t\t<div class=\"padding-md\">\n\t\t\t\t<div class=\"row\">\n\t\t\t\t\t<div class=\"col-sm-6 col-md-3\">\n\t\t\t\t\t\t<div class=\"panel-stat3 bg-danger\">\n\t\t\t\t\t\t\t<h2 class=\"m-top-none\" id=\"userCount\">0</h2>\n\t\t\t\t\t\t\t<h5>银谷在线账户总余额</h5>\n\t\t\t\t\t\t\t<i class=\"fa fa-arrow-circle-o-up fa-lg\"></i><span class=\"m-left-xs\">5% Higher than last week</span>\n\t\t\t\t\t\t\t<div class=\"stat-icon\">\n\t\t\t\t\t\t\t\t<i class=\"fa fa-user fa-3x\"></i>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"refresh-button\">\n\t\t\t\t\t\t\t\t<i class=\"fa fa-refresh\"></i>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"loading-overlay\">\n\t\t\t\t\t\t\t\t<i class=\"loading-icon fa fa-refresh fa-spin fa-lg\"></i>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t<div class=\"col-sm-6 col-md-3\">\n\t\t\t\t\t\t<div class=\"panel-stat3 bg-info\">\n                            <h2 class=\"m-top-none\"><span id=\"available_amount100\">1</span></h2>\n                            <h2 class=\"m-top-none\"><span id=\"available_amount100_count\">1</span></h2>\n\t\t\t\t\t\t\t<h5>银谷在线总账户余额大于100万</h5>\n\t\t\t\t\t\t\t<i class=\"fa fa-arrow-circle-o-up fa-lg\"></i><span class=\"m-left-xs\">1% Higher than last week</span>\n\t\t\t\t\t\t\t<div class=\"stat-icon\">\n\t\t\t\t\t\t\t\t<i class=\"fa fa-hdd-o fa-3x\"></i>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"refresh-button\">\n\t\t\t\t\t\t\t\t<i class=\"fa fa-refresh\"></i>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"loading-overlay\">\n\t\t\t\t\t\t\t\t<i class=\"loading-icon fa fa-refresh fa-spin fa-lg\"></i>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t<div class=\"col-sm-6 col-md-3\">\n\t\t\t\t\t\t<div class=\"panel-stat3 bg-warning\">\n\t\t\t\t\t\t\t<h2 class=\"m-top-none\" id=\"orderCount\">593</h2>\n\t\t\t\t\t\t\t<h5>New Orders</h5>\n\t\t\t\t\t\t\t<i class=\"fa fa-arrow-circle-o-up fa-lg\"></i><span class=\"m-left-xs\">3% Higher than last week</span>\n\t\t\t\t\t\t\t<div class=\"stat-icon\">\n\t\t\t\t\t\t\t\t<i class=\"fa fa-shopping-cart fa-3x\"></i>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"refresh-button\">\n\t\t\t\t\t\t\t\t<i class=\"fa fa-refresh\"></i>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"loading-overlay\">\n\t\t\t\t\t\t\t\t<i class=\"loading-icon fa fa-refresh fa-spin fa-lg\"></i>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t<div class=\"col-sm-6 col-md-3\">\n\t\t\t\t\t\t<div class=\"panel-stat3 bg-success\">\n\t\t\t\t\t\t\t<h2 class=\"m-top-none\" id=\"visitorCount\">7214</h2>\n\t\t\t\t\t\t\t<h5>Total Visitors</h5>\n\t\t\t\t\t\t\t<i class=\"fa fa-arrow-circle-o-up fa-lg\"></i><span class=\"m-left-xs\">15% Higher than last week</span>\n\t\t\t\t\t\t\t<div class=\"stat-icon\">\n\t\t\t\t\t\t\t\t<i class=\"fa fa-bar-chart-o fa-3x\"></i>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"refresh-button\">\n\t\t\t\t\t\t\t\t<i class=\"fa fa-refresh\"></i>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"loading-overlay\">\n\t\t\t\t\t\t\t\t<i class=\"loading-icon fa fa-refresh fa-spin fa-lg\"></i>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t</div>\n\t\t\t\t<div class=\"row\">\n\t\t\t\t\t<div class=\"col-lg-8\">\n\t\t\t\t\t\t<div class=\"panel panel-default\">\n\t\t\t\t\t\t\t<div class=\"panel-heading clearfix\">\n\t\t\t\t\t\t\t\t<span class=\"pull-left\"><i class=\"fa fa-bar-chart-o fa-lg\"></i> Website Traffic</span>\n\t\t\t\t\t\t\t\t<ul class=\"tool-bar\">\n\t\t\t\t\t\t\t\t\t<li><a href=\"#\" class=\"refresh-widget\" data-toggle=\"tooltip\" data-placement=\"bottom\" title=\"\" data-original-title=\"Refresh\"><i class=\"fa fa-refresh\"></i></a></li>\n\t\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"panel-body\" id=\"trafficWidget\">\n\t\t\t\t\t\t\t\t<div id=\"placeholder\" class=\"graph\" style=\"height:250px\"></div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"panel-footer\">\n\t\t\t\t\t\t\t\t<div class=\"row row-merge\">\n\t\t\t\t\t\t\t\t\t<div class=\"col-xs-3 text-center border-right\">\n\t\t\t\t\t\t\t\t\t\t<h4 class=\"no-margin\">1232</h4>\n\t\t\t\t\t\t\t\t\t\t<small class=\"text-muted\">Visitors</small>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t<div class=\"col-xs-3 text-center border-right\">\n\t\t\t\t\t\t\t\t\t\t<h4 class=\"no-margin\">5421</h4>\n\t\t\t\t\t\t\t\t\t\t<small class=\"text-muted\">Orders</small>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t<div class=\"col-xs-3 text-center border-right\">\n\t\t\t\t\t\t\t\t\t\t<h4 class=\"no-margin\">3021</h4>\n\t\t\t\t\t\t\t\t\t\t<small class=\"text-muted\">Tickets</small>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t<div class=\"col-xs-3 text-center\">\n\t\t\t\t\t\t\t\t\t\t<h4 class=\"no-margin\">7098</h4>\n\t\t\t\t\t\t\t\t\t\t<small class=\"text-muted\">Customers</small>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div><!-- ./row -->\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"loading-overlay\">\n\t\t\t\t\t\t\t\t<i class=\"loading-icon fa fa-refresh fa-spin fa-lg\"></i>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div><!-- /panel -->\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t<div class=\"row\">\n\t\t\t\t\t\t\t<div class=\"col-md-4 col-sm-4\">\n\t\t\t\t\t\t\t\t<div class=\"panel panel-default panel-stat1 bg-success\">\n\t\t\t\t\t\t\t\t\t<div class=\"panel-body\">\n\t\t\t\t\t\t\t\t\t\t<div class=\"value\">99</div>\n\t\t\t\t\t\t\t\t\t\t<div class=\"title\">\n\t\t\t\t\t\t\t\t\t\t\t<i class=\"fa fa-usd\"></i>\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"m-left-xs\">Sales</span>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div><!-- /panel -->\n\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t\t<div class=\"col-md-4 col-sm-4\">\n\t\t\t\t\t\t\t\t<div class=\"panel panel-default panel-stat2 bg-warning\">\n\t\t\t\t\t\t\t\t\t<div class=\"panel-body\">\n\t\t\t\t\t\t\t\t\t\t<span class=\"stat-icon\">\n\t\t\t\t\t\t\t\t\t\t\t<i class=\"fa fa-bar-chart-o\"></i>\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t<div class=\"pull-right text-right\">\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"value\">58</div>\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"title\">New Visits</div>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div><!-- /panel -->\n\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t\t<div class=\"col-md-4 col-sm-4\">\n\t\t\t\t\t\t\t\t<div class=\"panel panel-default panel-stat2 bg-info\">\n\t\t\t\t\t\t\t\t\t<div class=\"panel-body\">\n\t\t\t\t\t\t\t\t\t\t<span class=\"stat-icon\">\n\t\t\t\t\t\t\t\t\t\t\t<i class=\"fa fa-envelope\"></i>\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t<div class=\"pull-right text-right\">\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"value\">41</div>\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"title\">Emails</div>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div><!-- /panel -->\n\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t</div><!-- /.row -->\n\t\t\t\t\t\t<div class=\"panel panel-default\">\n\t\t\t\t\t\t\t<div class=\"panel-heading\">\n\t\t\t\t\t\t\t\tWork Progress\n\n\t\t\t\t\t\t\t\t<span class=\"badge badge-info pull-right\">\t\n\t\t\t\t\t\t\t\t\t4 left\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<table class=\"table table-striped\">\n\t\t\t\t\t\t\t\t<thead>\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<th>Task</th>\n\t\t\t\t\t\t\t\t\t\t<th>Progress</th>\n\t\t\t\t\t\t\t\t\t\t<th></th>\n\t\t\t\t\t\t\t\t\t\t<th>Time</th>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</thead>\n\t\t\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td>Bug Fixes</td>\n\t\t\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"progress progress-striped active\" style=\"height:8px; margin:5px 0 0 0;\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"progress-bar\" style=\"width: 45%\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"sr-only\">45% Complete</span>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t\t\t<td>45%</td>\n\t\t\t\t\t\t\t\t\t\t<td><span class=\"badge badge-info\">2hr</span></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td>Mobile Development</td>\n\t\t\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"progress progress-striped active\" style=\"height:8px; margin:5px 0 0 0;\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"progress-bar progress-bar-success\" style=\"width: 61%\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"sr-only\">61% Complete</span>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t\t\t<td>61%</td>\n\t\t\t\t\t\t\t\t\t\t<td><span class=\"badge badge-info\">1hr</span></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td>Unit Testing</td>\n\t\t\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"progress progress-striped active\" style=\"height:8px; margin:5px 0 0 0;\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"progress-bar progress-bar-danger\" style=\"width: 97%\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"sr-only\">97% Complete</span>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t\t\t<td>97%</td>\n\t\t\t\t\t\t\t\t\t\t<td><span class=\"badge badge-info\">5m</span></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td>New frontend layout</td>\n\t\t\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"progress progress-striped active\" style=\"height:8px; margin:5px 0 0 0;\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"progress-bar progress-bar-warning\" style=\"width: 18%\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"sr-only\">18% Complete</span>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t\t\t<td>18%</td>\n\t\t\t\t\t\t\t\t\t\t<td><span class=\"badge badge-info\">12hr</span></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</tbody>\n\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t</div><!-- /panel -->\n\t\t\t\t\t\t<div class=\"row\">\n\t\t\t\t\t\t\t<div class=\"col-lg-6\">\n\t\t\t\t\t\t\t\t<div class=\"panel panel-default\">\n\t\t\t\t\t\t\t\t\t<div class=\"panel-heading clearfix\">\n\t\t\t\t\t\t\t\t\t\t<span class=\"pull-left\">\n\t\t\t\t\t\t\t\t\t\t\tTo Do List <span class=\"text-success m-left-xs\"><i class=\"fa fa-check\"></i></span>\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t<ul class=\"tool-bar\">\n\t\t\t\t\t\t\t\t\t\t\t<li><a href=\"#\" class=\"refresh-widget\" data-toggle=\"tooltip\" data-placement=\"bottom\" title=\"\" data-original-title=\"Refresh\"><i class=\"fa fa-refresh\"></i></a></li>\n\t\t\t\t\t\t\t\t\t\t\t<li><a href=\"#toDoListWidget\" data-toggle=\"collapse\"><i class=\"fa fa-arrows-v\"></i></a></li>\n\t\t\t\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t<div class=\"panel-body no-padding collapse in\" id=\"toDoListWidget\">\n\t\t\t\t\t\t\t\t\t\t<ul class=\"list-group task-list no-margin collapse in\">\n\t\t\t\t\t\t\t\t\t\t\t<li class=\"list-group-item selected\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label class=\"label-checkbox inline\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t <input type=\"checkbox\" class=\"task-finish\" checked>\n\t\t\t\t\t\t\t\t\t\t\t\t\t <span class=\"custom-checkbox\"></span>\n\t\t\t\t\t\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t\t\t\t\t\t\tSEO Optimisation\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"pull-right\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<a href=\"#\" class=\"task-del\"><i class=\"fa fa-trash-o fa-lg text-danger\"></i></a>\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t\t\t\t<li class=\"list-group-item\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label class=\"label-checkbox inline\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t <input type=\"checkbox\" class=\"task-finish\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t <span class=\"custom-checkbox\"></span>\n\t\t\t\t\t\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t\t\t\t\t\t\tUnit Testing\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"pull-right\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<a href=\"#\" class=\"task-del\"><i class=\"fa fa-trash-o fa-lg text-danger\"></i></a>\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t\t\t\t<li class=\"list-group-item\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label class=\"label-checkbox inline\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t <input type=\"checkbox\" class=\"task-finish\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t <span class=\"custom-checkbox\"></span>\n\t\t\t\t\t\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t\t\t\t\t\t\tMobile Development \n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"pull-right\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<a href=\"#\" class=\"task-del\"><i class=\"fa fa-trash-o fa-lg text-danger\"></i></a>\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"badge badge-success m-right-xs\">3</span>\n\t\t\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t\t\t\t<li class=\"list-group-item\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label class=\"label-checkbox inline\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t <input type=\"checkbox\" class=\"task-finish\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t <span class=\"custom-checkbox\"></span>\n\t\t\t\t\t\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t\t\t\t\t\t\tDatabase Migration\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"pull-right\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<a href=\"#\" class=\"task-del\"><i class=\"fa fa-trash-o fa-lg text-danger\"></i></a>\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t\t\t\t<li class=\"list-group-item\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label class=\"label-checkbox inline\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t <input type=\"checkbox\" class=\"task-finish\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t <span class=\"custom-checkbox\"></span>\n\t\t\t\t\t\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t\t\t\t\t\t\tNew Frontend Layout <span class=\"label label-warning m-left-xs\">PENDING</span>\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"pull-right\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<a href=\"#\" class=\"task-del\"><i class=\"fa fa-trash-o fa-lg text-danger\"></i></a>\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t\t\t\t<li class=\"list-group-item\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label class=\"label-checkbox inline\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t <input type=\"checkbox\" class=\"task-finish\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t <span class=\"custom-checkbox\"></span>\n\t\t\t\t\t\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t\t\t\t\t\t\tBug Fixes <span class=\"label label-danger m-left-xs\">IMPORTANT</span>\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"pull-right\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<a href=\"#\" class=\"task-del\"><i class=\"fa fa-trash-o fa-lg text-danger\"></i></a>\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t\t\t</ul><!-- /list-group -->\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t<div class=\"loading-overlay\">\n\t\t\t\t\t\t\t\t\t\t<i class=\"loading-icon fa fa-refresh fa-spin fa-lg\"></i>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div><!-- /panel -->\n\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t\t<div class=\"col-lg-6\">\n\t\t\t\t\t\t\t\t<div class=\"panel panel-default\">\t\n\t\t\t\t\t\t\t\t\t<div class=\"panel-heading clearfix\">\n\t\t\t\t\t\t\t\t\t\t<span class=\"pull-left\">Feeds</span>\n\t\t\t\t\t\t\t\t\t\t<ul class=\"tool-bar\">\n\t\t\t\t\t\t\t\t\t\t\t<li><a href=\"#\" class=\"refresh-widget\" data-toggle=\"tooltip\" data-placement=\"bottom\" title=\"\" data-original-title=\"Refresh\"><i class=\"fa fa-refresh\"></i></a></li>\n\t\t\t\t\t\t\t\t\t\t\t<li><a href=\"#feedList\" data-toggle=\"collapse\"><i class=\"fa fa-arrows-v\"></i></a></li>\n\t\t\t\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t\t\t\t</div>\t\t\n\t\t\t\t\t\t\t\t\t<ul class=\"list-group collapse in\" id=\"feedList\">\n\t\t\t\t\t\t\t\t\t\t<li class=\"list-group-item clearfix\">\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"activity-icon small\">\n\t\t\t\t\t\t\t\t\t\t\t\t<i class=\"fa fa-camera\"></i>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"pull-left m-left-sm\">\n\t\t\t\t\t\t\t\t\t\t\t\t<span>John Doe Add a new photo.</span><br/>\n\t\t\t\t\t\t\t\t\t\t\t\t<small class=\"text-muted\"><i class=\"fa fa-clock-o\"></i> 2m ago</small>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t\t\t<li class=\"list-group-item clearfix\">\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"activity-icon bg-success small\">\n\t\t\t\t\t\t\t\t\t\t\t\t<i class=\"fa fa-usd\"></i>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"pull-left m-left-sm\">\n\t\t\t\t\t\t\t\t\t\t\t\t<span>2 items sold.</span><br/>\n\t\t\t\t\t\t\t\t\t\t\t\t<small class=\"text-muted\"><i class=\"fa fa-clock-o\"></i> 30m ago</small>\n\t\t\t\t\t\t\t\t\t\t\t</div>\t\n\t\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t\t\t<li class=\"list-group-item clearfix\">\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"activity-icon bg-info small\">\n\t\t\t\t\t\t\t\t\t\t\t\t<i class=\"fa fa-comment\"></i>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"pull-left m-left-sm\">\n\t\t\t\t\t\t\t\t\t\t\t\t<span>John Doe commented on <a href=\"#\">This Article</a></span><br/>\n\t\t\t\t\t\t\t\t\t\t\t\t<small class=\"text-muted\"><i class=\"fa fa-clock-o\"></i> 1hr ago</small>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t\t\t<li class=\"list-group-item clearfix\">\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"activity-icon bg-success small\">\n\t\t\t\t\t\t\t\t\t\t\t\t<i class=\"fa fa-usd\"></i>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"pull-left m-left-sm\">\n\t\t\t\t\t\t\t\t\t\t\t\t<span>3 items sold.</span><br/>\n\t\t\t\t\t\t\t\t\t\t\t\t<small class=\"text-muted\"><i class=\"fa fa-clock-o\"></i> 2days ago</small>\n\t\t\t\t\t\t\t\t\t\t\t</div>\t\n\t\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t\t</ul><!-- /list-group -->\t\n\t\t\t\t\t\t\t\t\t<div class=\"loading-overlay\">\n\t\t\t\t\t\t\t\t\t\t<i class=\"loading-icon fa fa-refresh fa-spin fa-lg\"></i>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div><!-- /panel -->\n\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t</div><!-- ./row -->\n\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t<div class=\"col-lg-4\">\n\t\t\t\t\t\t<div class=\"panel bg-info fadeInDown animation-delay4\">\n\t\t\t\t\t\t\t<div class=\"panel-body\">\n\t\t\t\t\t\t\t\t<div id=\"lineChart\" style=\"height: 150px;\"></div>\n\t\t\t\t\t\t\t\t<div class=\"pull-right text-right\">\n\t\t\t\t\t\t\t\t\t<strong class=\"font-14\">Balance $3210</strong><br/>\n\t\t\t\t\t\t\t\t\t<span><i class=\"fa fa-shopping-cart\"></i> Total Sales 867</span>\n\t\t\t\t\t\t\t\t\t<div class=\"seperator\"></div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"panel-footer\">\n\t\t\t\t\t\t\t\t<div class=\"row\">\n\t\t\t\t\t\t\t\t\t<div class=\"col-xs-4\">\n\t\t\t\t\t\t\t\t\t\tSales in June\n\t\t\t\t\t\t\t\t\t\t<strong class=\"block\">$664</strong>\n\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t\t\t\t<div class=\"col-xs-4\">\n\t\t\t\t\t\t\t\t\t\tSales in July\n\t\t\t\t\t\t\t\t\t\t<strong class=\"block\">$731</strong>\n\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t\t\t\t<div class=\"col-xs-4\">\n\t\t\t\t\t\t\t\t\t\tSales in August\n\t\t\t\t\t\t\t\t\t\t<strong class=\"block\">$912</strong>\n\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t\t\t</div><!-- /.row -->\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div><!-- /panel -->\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t<div class=\"panel bg-success fadeInDown animation-delay5\">\n\t\t\t\t\t\t\t<div class=\"panel-body\">\n\t\t\t\t\t\t\t\t<div id=\"barChart\" style=\"height: 150px;\"></div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"panel-footer\">\n\t\t\t\t\t\t\t\t<div class=\"row\">\n\t\t\t\t\t\t\t\t\t<div class=\"col-xs-6\">\n\t\t\t\t\t\t\t\t\t\t<h4 class=\"no-margin\">Total Earnings</h4>\n\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t\t\t\t<div class=\"col-xs-6 text-right\">\n\t\t\t\t\t\t\t\t\t\t<h4 class=\"no-margin\">$17,531</h4>\n\t\t\t\t\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t\t\t\t\t</div><!-- /.row -->\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div><!-- /panel -->\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t<div class=\"panel bg-danger\">\n\t\t\t\t\t\t\t<div class=\"panel-body\">\n\t\t\t\t\t\t\t\t<h4>Database Migration</h4>\n\t\t\t\t\t\t\t\t<div class=\"progress progress-striped active\" style=\"height:8px; margin:5px 0 0 0;\">\n\t\t\t\t\t\t\t\t\t<div class=\"progress-bar progress-bar-danger\" style=\"width: 65%\">\n\t\t\t\t\t\t\t\t\t\t<span class=\"sr-only\">65% Complete</span>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<strong class=\"pull-left m-top-xs\">65% Complete</strong>\n\t\t\t\t\t\t\t\t<strong class=\"pull-right m-top-xs\">1hr left</strong>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div><!-- /panel -->\n\t\t\t\t\t\t<div class=\"panel panel-default\">\n\t\t\t\t\t\t\t<div class=\"panel-body\">\n\t\t\t\t\t\t\t\t<div id=\"donutChart\" style=\"height: 250px;\"></div>\n\t\t\t\t\t\t\t\t<div class=\"panel-group\" id=\"accordion\">\n\t\t\t\t\t\t\t\t\t<div class=\"panel panel-default\">\n\t\t\t\t\t\t\t\t\t\t<div class=\"panel-heading\">\n\t\t\t\t\t\t\t\t\t\t\t<h4 class=\"panel-title\">\n\t\t\t\t\t\t\t\t\t\t\t\t<a class=\"accordion-toggle\" data-toggle=\"collapse\" data-parent=\"#accordion\" href=\"#collapseOne\">\n\t\t\t\t\t\t\t\t\t\t\t\t\tIN-STORE Sales\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"badge badge-success pull-right\">75%</span>\n\t\t\t\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t\t\t\t</h4>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t<div id=\"collapseOne\" class=\"panel-collapse collapse\">\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"panel-body\">\n\t\t\t\t\t\t\t\t\t\t\t\tRaw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. \n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</div><!-- panel -->\n\t\t\t\t\t\t\t\t\t<div class=\"panel panel-default\">\n\t\t\t\t\t\t\t\t\t\t<div class=\"panel-heading\">\n\t\t\t\t\t\t\t\t\t\t\t<h4 class=\"panel-title\">\n\t\t\t\t\t\t\t\t\t\t\t\t<a class=\"accordion-toggle\" data-toggle=\"collapse\" data-parent=\"#accordion\" href=\"#collapseTwo\">\n\t\t\t\t\t\t\t\t\t\t\t\t\tDOWMLOAD Sales\n\t\t\t\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t\t\t\t</h4>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t<div id=\"collapseTwo\" class=\"panel-collapse collapse\">\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"panel-body\">\n\t\t\t\t\t\t\t\t\t\t\t\tRaw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. \n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</div><!-- panel -->\n\t\t\t\t\t\t\t\t\t<div class=\"panel panel-default\">\n\t\t\t\t\t\t\t\t\t\t<div class=\"panel-heading\">\n\t\t\t\t\t\t\t\t\t\t\t<h4 class=\"panel-title\">\n\t\t\t\t\t\t\t\t\t\t\t\t<a class=\"accordion-toggle\" data-toggle=\"collapse\" data-parent=\"#accordion\" href=\"#collapseThree\">\n\t\t\t\t\t\t\t\t\t\t\t\t\tMAIL-ORDER Sales \n\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"badge badge-danger pull-right\"><i class=\"fa fa-arrow-down\"></i> 3%</span>\n\t\t\t\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t\t\t\t</h4>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t<div id=\"collapseThree\" class=\"panel-collapse collapse\">\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"panel-body\">\n\t\t\t\t\t\t\t\t\t\t\t\tRaw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. \n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</div><!-- panel -->\n\t\t\t\t\t\t\t\t</div><!-- panel-group -->\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div><!-- /panel -->\n\t\t\t\t\t</div><!-- /.col -->\n\t\t\t\t</div><!-- /.row -->\n\t\t\t</div><!-- /.padding-md -->\n\t\t</div><!-- /main-container -->\n{% endblock %}\n\n{% block footer_content %}\n\t<!-- Flot -->\n\t<script src='/static/template/js/jquery.flot.min.js'></script>\n\n\t<!-- Morris -->\n\t<script src='/static/template/js/rapheal.min.js'></script>\n\t<script src='/static/template/js/morris.min.js'></script>\n\n\t<!-- Colorbox -->\n\t<script src='/static/template/js/jquery.colorbox.min.js'></script>\n\n\t<!-- Sparkline -->\n\t<script src='/static/template/js/jquery.sparkline.min.js'></script>\n\n\t<!-- Pace -->\n\t<script src='/static/template/js/uncompressed/pace.js'></script>\n\n\n\t<!-- Slimscroll -->\n\t<script src='/static/template/js/jquery.slimscroll.min.js'></script>\n\n    <!-- Endless -->\n{#    <script src=\"/static/template/js/endless/endless_dashboard.js\"></script>#}\n<script>\n$(window).load(function(e) {\n    get_total_available_amount();\n{#    setInterval(\"setInterval_available_amount()\", 3000);#}\n    get_total_available_amount100();\n});\n\nfunction get_total_available_amount () {\n    var url = \"/report/get_available_amount/\";\n    $.post(url, function(jdata){\n        var data = $.parseJSON(jdata);\n        $('#userCount').text(data.total_available_amount)\n     });\n}\n\nfunction setInterval_available_amount() {\n    var url = \"/report/get_available_amount/\";\n    $.post(url, function(jdata){\n        var data = $.parseJSON(jdata);\n        var currentNumber = $('#userCount').text();\n        var newNumber = data.total_available_amount;\n\n        $({numberValue: currentNumber}).animate({numberValue: newNumber}, {\n            duration: 500,\n            easing: 'linear',\n            step: function() {\n                $('#userCount').text(Math.ceil(this.numberValue));\n            }\n        });\n     });\n}\n\nfunction get_total_available_amount100 () {\n    var url = \"/report/get_available_amount100/\";\n    $.post(url, function(jdata){\n        var data = $.parseJSON(jdata);\n        $('#available_amount100').text(data.total_available_amount);\n        $('#available_amount100_count').text(data.count);\n     });\n}\n\n</script>\n{% endblock %}"
  },
  {
    "path": "templates/registered/login.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <title>Login</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n\n    <!-- Bootstrap core CSS -->\n    <link href=\"/static/template/bootstrap/css/bootstrap.min.css\" rel=\"stylesheet\">\n\t\n\t<!-- Font Awesome -->\n\t<link href=\"/static/template/css/font-awesome.min.css\" rel=\"stylesheet\">\n\t\n\t<!-- Endless -->\n\t<link href=\"/static/template/css/endless.min.css\" rel=\"stylesheet\">\n\n  </head>\n\n  <body>\n\t<div class=\"login-wrapper\">\n\t\t<div class=\"text-center\">\n\t\t\t<h2 class=\"fadeInUp animation-delay8\" style=\"font-weight:bold\">\n\t\t\t\t<span class=\"text-success\">First</span> <span style=\"color:#ccc; text-shadow:0 1px #fff\">Blood</span>\n\t\t\t</h2>\n\t\t</div>\n\t\t<div class=\"login-widget animation-delay1\">\t\n\t\t\t<div class=\"panel panel-default\">\n\t\t\t\t<div class=\"panel-heading clearfix\">\n\t\t\t\t\t<div class=\"pull-left\">\n\t\t\t\t\t\t<i class=\"fa fa-lock fa-lg\"></i> Login\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"pull-right\">\n\t\t\t\t\t\t<span style=\"font-size:11px;\">Don't have any account?</span>\n\t\t\t\t\t\t<a class=\"btn btn-default btn-xs login-link\" href=\"#\" style=\"margin-top:-2px;\"><i class=\"fa fa-plus-circle\"></i> Sign up</a>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"panel-body\">\n\t\t\t\t\t<form class=\"form-login\" method=\"post\" action=\"{% url 'django.contrib.auth.views.login' %}\">\n                        {% csrf_token %}\n\t\t\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t\t\t<label>Username</label>\n                            <input type=\"hidden\" name=\"next\" value=\"{{ next }}\"/>\n\t\t\t\t\t\t\t<input type=\"text\" name=\"username\" placeholder=\"Username\" class=\"form-control input-sm bounceIn animation-delay2\" >\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t\t\t<label>Password</label>\n\t\t\t\t\t\t\t<input type=\"password\" name=\"password\" placeholder=\"Password\" class=\"form-control input-sm bounceIn animation-delay4\">\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"form-group\">\n                            <label class=\"label-checkbox inline\">\n\t\t\t\t\t\t\t\t<input type=\"checkbox\" class=\"regular-checkbox chk-delete\" />\n\t\t\t\t\t\t\t\t<span class=\"custom-checkbox info bounceIn animation-delay4\"></span>\n\t\t\t\t\t\t\t</label>\n                            Remember me\n                            {% if form.errors %}\n                                <span class=\"text-danger pull-right\">username or password error</span>\n                            {% endif %}\n                        </div>\n\n                        <div class=\"seperator\"></div>\n\t\t\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t\t\tForgot your password?<br/>\n\t\t\t\t\t\t\tClick <a href=\"#\">here</a> to reset your password\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<hr/>\n\t\t\t\t\t\t<button class=\"btn btn-success btn-sm bounceIn animation-delay5 pull-right\" type=\"submit\">\n                            <i class=\"fa fa-sign-in\"></i> Sign in\n                        </button>\n\t\t\t\t\t</form>\n\t\t\t\t</div>\n\t\t\t</div><!-- /panel -->\n\t\t</div><!-- /login-widget -->\n\t</div><!-- /login-wrapper -->\n\n    <!-- Le javascript\n    ================================================== -->\n    <!-- Placed at the end of the document so the pages load faster -->\n    \n    <!-- Jquery -->\n\t<script src=\"/static/template/js/jquery-1.10.2.min.js\"></script>\n    \n    <!-- Bootstrap -->\n    <script src=\"/static/template/bootstrap/js/bootstrap.min.js\"></script>\n   \n\t<!-- Modernizr -->\n\t<script src='/static/template/js/modernizr.min.js'></script>\n   \n    <!-- Pace -->\n\t<script src='/static/template/js/pace.min.js'></script>\n   \n\t<!-- Popup Overlay -->\n\t<script src='/static/template/js/jquery.popupoverlay.min.js'></script>\n   \n    <!-- Slimscroll -->\n\t<script src='/static/template/js/jquery.slimscroll.min.js'></script>\n   \n\t<!-- Cookie -->\n\t<script src='/static/template/js/jquery.cookie.min.js'></script>\n\n\t<!-- Endless -->\n\t<script src=\"/static/template/js/endless/endless.js\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "templates/registered/password_change.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <title>Password Change</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n\n    <!-- Bootstrap core CSS -->\n    <link href=\"/static/template/bootstrap/css/bootstrap.min.css\" rel=\"stylesheet\">\n\t\n\t<!-- Font Awesome -->\n\t<link href=\"/static/template/css/font-awesome.min.css\" rel=\"stylesheet\">\n\t\n\t<!-- Endless -->\n\t<link href=\"/static/template/css/endless.min.css\" rel=\"stylesheet\">\n\n  </head>\n\n  <body>\n\t<div class=\"login-wrapper\">\n\t\t<div class=\"text-center\">\n\t\t\t<h2 class=\"fadeInUp animation-delay8\" style=\"font-weight:bold\">\n\t\t\t\t<span class=\"text-success\">Yingu</span> <span style=\"color:#ccc; text-shadow:0 1px #fff\">Online</span>\n\t\t\t</h2>\n\t\t</div>\n\t\t<div class=\"login-widget animation-delay1\">\t\n\t\t\t<div class=\"panel panel-default\">\n\t\t\t\t<div class=\"panel-heading clearfix\">\n\t\t\t\t\t<div class=\"pull-left\">\n\t\t\t\t\t\t<i class=\"fa fa-lock fa-lg\"></i> Password Change\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"panel-body\">\n\t\t\t\t\t<form class=\"form-login\" method=\"post\" action=\"{% url 'django.contrib.auth.views.password_change' %}\">\n                        {% csrf_token %}\n\t\t\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t\t\t<label>Old password</label>\n                            <input type=\"hidden\" name=\"next\" value=\"{{ next }}\"/>\n\t\t\t\t\t\t\t<input type=\"password\" name=\"old_password\" placeholder=\"old password\" class=\"form-control input-sm bounceIn animation-delay2\" >\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t\t\t<label>New Password</label>\n\t\t\t\t\t\t\t<input type=\"password\" name=\"new_password1\" placeholder=\"new password\" class=\"form-control input-sm bounceIn animation-delay4\">\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t\t\t<label>New Password confirmation</label>\n\t\t\t\t\t\t\t<input type=\"password\" name=\"new_password2\" placeholder=\"new password\" class=\"form-control input-sm bounceIn animation-delay4\">\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"form-group\">\n                            {{ form.errors }}\n                        </div>\n                        <div class=\"seperator\"></div>\n\t\t\t\t\t\t<hr/>\n\t\t\t\t\t\t<button class=\"btn btn-success btn-sm bounceIn animation-delay5 pull-right\" type=\"submit\">\n                            <i class=\"fa fa-sign-in\"></i> Change My Password\n                        </button>\n\t\t\t\t\t</form>\n\t\t\t\t</div>\n\t\t\t</div><!-- /panel -->\n\t\t</div><!-- /login-widget -->\n\t</div><!-- /login-wrapper -->\n\n    <!-- Le javascript\n    ================================================== -->\n    <!-- Placed at the end of the document so the pages load faster -->\n    \n    <!-- Jquery -->\n\t<script src=\"/static/template/js/jquery-1.10.2.min.js\"></script>\n    \n    <!-- Bootstrap -->\n    <script src=\"/static/template/bootstrap/js/bootstrap.min.js\"></script>\n   \n\t<!-- Modernizr -->\n\t<script src='/static/template/js/modernizr.min.js'></script>\n   \n    <!-- Pace -->\n\t<script src='/static/template/js/pace.min.js'></script>\n   \n\t<!-- Popup Overlay -->\n\t<script src='/static/template/js/jquery.popupoverlay.min.js'></script>\n   \n    <!-- Slimscroll -->\n\t<script src='/static/template/js/jquery.slimscroll.min.js'></script>\n   \n\t<!-- Cookie -->\n\t<script src='/static/template/js/jquery.cookie.min.js'></script>\n\n\t<!-- Endless -->\n\t<script src=\"/static/template/js/endless/endless.js\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "templates/registered/password_change_done.html",
    "content": "{% extends 'base.html' %}\n\n{% block container %}\n<div id=\"main-container\">\n    <div id=\"breadcrumb\">\n        <ul class=\"breadcrumb\">\n             <li><i class=\"fa fa-home\"></i><a href=\"index.html\"> Home</a></li>\n             <li class=\"active\">Password Change</li>\n        </ul>\n    </div><!-- /breadcrumb-->\n    <div class=\"main-header clearfix\">\n        <div class=\"alert alert-success\">\n            <strong>Password change successful !</strong> &nbsp;&nbsp;&nbsp;Your password was changed.\n        </div>\n    </div><!-- /main-header -->\n</div><!-- /main-container -->\n{% endblock %}\n\n{% block footer_content %}\n\t<!-- Flot -->\n\t<script src='/static/template/js/jquery.flot.min.js'></script>\n\n\t<!-- Morris -->\n\t<script src='/static/template/js/rapheal.min.js'></script>\n\t<script src='/static/template/js/morris.min.js'></script>\n\n\t<!-- Colorbox -->\n\t<script src='/static/template/js/jquery.colorbox.min.js'></script>\n\n\t<!-- Sparkline -->\n\t<script src='/static/template/js/jquery.sparkline.min.js'></script>\n\n\t<!-- Pace -->\n\t<script src='/static/template/js/uncompressed/pace.js'></script>\n\n\n\t<!-- Slimscroll -->\n\t<script src='/static/template/js/jquery.slimscroll.min.js'></script>\n\n    <!-- Endless -->\n{#    <script src=\"/static/template/js/endless/endless_dashboard.js\"></script>#}\n{% endblock %}"
  },
  {
    "path": "websockted/CHANGES",
    "content": "Version 0.3.0  (??, 2017)\n\n* Migration of underlying websocket server to Gorilla Websocket lib.\n* Binaries build code switched to 1.9.2\n\nVersion 0.2.12  (Feb 17, 2016)\n\n* Update of underlying go standard libraries change how SSL works. SSL3 is no longer supported.\n* Support of commands that do not provide text IO (using them as binary websocket frames)\n* Minor changes in examples and --help output \n\nVersion 0.2.11  (Jul 1, 2015)\n\n* PATH env variable is now passed to process by default\n* new --header* flags could generate custom HTTP headers for all websocketd-generated answers\n* fixed bug causing process to hang when WebSockets client disconnect is detected\n* minor changes for console app (default url building logic and tab char printing)\n* multiple changes of examples.\n\n\nVersion 0.2.10  (Feb 16, 2015)\n\n* fixes for null-origin situations (#75, #96)\n* better bash examples (#103)\n* changelog and checksums for released files (#101, #105)\n\n\nVersion 0.2.9  (May 19, 2014)\n\n* ability to listen multiple IP addresses (#40, #43)\n* proper support for TLS (#17)\n* resource limits enforcement (a.k.a. maxforks feature, #46)\n* passenv option to limit environment variables visible by running commands (#4)\n* fix for problem of closing upgraded websocket connection when script is not found (#29)\n* websocket origin restrictions via command line option (#20)\n* minor update for help flag behavior\n* minor fix for devconsole\n\nVersion 0.2.8  (Jan 11, 2014)\n\n* ..."
  },
  {
    "path": "websockted/LICENSE",
    "content": "Copyright (c) 2014, Joe Walnes and the websocketd authors.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met: \n\n1. Redistributions of source code must retain the above copyright notice, this\n   list of conditions and the following disclaimer. \n2. Redistributions in binary form must reproduce the above copyright notice,\n   this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution. \n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "websockted/README.md",
    "content": "websocketd\n==========\n\n`websocketd` is a small command-line tool that will wrap an existing command-line interface program, and allow it to be accessed via a WebSocket.\n\nWebSocket-capable applications can now be built very easily. As long as you can write an executable program that reads `STDIN` and writes to `STDOUT`, you can build a WebSocket server. Do it in Python, Ruby, Perl, Bash, .NET, C, Go, PHP, Java, Clojure, Scala, Groovy, Expect, Awk, VBScript, Haskell, Lua, R, whatever! No networking libraries necessary.\n\n-[@joewalnes](https://twitter.com/joewalnes)\n\nDetails\n-------\n\nUpon startup, `websocketd` will start a WebSocket server on a specified port, and listen for connections.\n\nUpon a connection, it will fork the appropriate process, and disconnect the process when the WebSocket connection closes (and vice-versa).\n\nAny message sent from the WebSocket client will be piped to the process's `STDIN` stream, followed by a `\\n` newline.\n\nAny text printed by the process to `STDOUT` shall be sent as a WebSocket message whenever a `\\n` newline is encountered.\n\n\nDownload\n--------\n\nIf you're on a Mac, you can install `websocketd` using [Homebrew](http://brew.sh/). Just run `brew install websocketd`. For other operating systems, or if you don't want to use Homebrew, check out the link below.\n\n**[Download for Linux, OS X and Windows](https://github.com/joewalnes/websocketd/wiki/Download-and-install)**\n\n\nQuickstart\n----------\n\nTo get started, we'll create a WebSocket endpoint that will accept connections, then send back messages, counting to 10 with 1 second pause between each one, before disconnecting.\n\nTo show how simple it is, let's do it in Bash!\n\n__count.sh__:\n\n```sh\n#!/bin/bash\nfor ((COUNT = 1; COUNT <= 10; COUNT++)); do\n  echo $COUNT\n  sleep 1\ndone\n```\n\nBefore turning it into a WebSocket server, let's test it from the command line. The beauty of `websocketd` is that servers work equally well in the command line, or in shell scripts, as they do in the server - with no modifications required.\n\n```sh\n$ chmod +x count.sh\n$ ./count.sh\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n```\n\nNow let's turn it into a WebSocket server:\n\n```sh\n$ websocketd --port=8080 ./count.sh\n```\n\nFinally, let's create a web-page that to test it.\n\n__count.html__:\n\n```html\n<!DOCTYPE html>\n<pre id=\"log\"></pre>\n<script>\n  // helper function: log message to screen\n  function log(msg) {\n    document.getElementById('log').textContent += msg + '\\n';\n  }\n\n  // setup websocket with callbacks\n  var ws = new WebSocket('ws://localhost:8080/');\n  ws.onopen = function() {\n    log('CONNECT');\n  };\n  ws.onclose = function() {\n    log('DISCONNECT');\n  };\n  ws.onmessage = function(event) {\n    log('MESSAGE: ' + event.data);\n  };\n</script>\n```\nOpen this page in your web-browser. It will even work if you open it directly\nfrom disk using a `file://` URL.\n\nMore Features\n-------------\n\n*   Very simple install. Just [download](https://github.com/joewalnes/websocketd/wiki/Download-and-install) the single executable for Linux, Mac or Windows and run it. Minimal dependencies, no installers, no package managers, no external libraries. Suitable for development and production servers.\n*   Server side scripts can access details about the WebSocket HTTP request (e.g. remote host, query parameters, cookies, path, etc) via standard [CGI environment variables](https://github.com/joewalnes/websocketd/wiki/Environment-variables).\n*   As well as serving websocket daemons it also includes a static file server and classic CGI server for convenience.\n*   Command line help available via `websocketd --help`.\n*   Includes [WebSocket developer console](https://github.com/joewalnes/websocketd/wiki/Developer-console) to make it easy to test your scripts before you've built a JavaScript frontend.\n*   [Examples in many programming languages](https://github.com/joewalnes/websocketd/tree/master/examples) are available to help you getting started.\n\nUser Manual\n-----------\n\n**[More documentation in the user manual](https://github.com/joewalnes/websocketd/wiki)**\n\nExample Projects\n----------------\n\n*   [Plot real time Linux CPU/IO/Mem stats to a HTML5 dashboard using websocketd and vmstat](https://github.com/joewalnes/web-vmstats) _(for Linux)_\n*   [Remote JScript & VBScript code execution tool based on websocketd](https://github.com/dab00/ws-console) _(for Windows)_\n*   [Arbitrary REPL in the browser using websocketd](https://github.com/rowanthorpe/ws-repl)\n\nGot more examples? Open a pull request.\n\nMy Other Projects\n-----------------\n\n*   [ReconnectingWebSocket](https://github.com/joewalnes/reconnecting-websocket) - Simplest way to add some robustness to your WebSocket connections.\n*   [Smoothie Charts](http://smoothiecharts.org/) - JavaScript charts for streaming data.\n*   Visit [The Igloo Lab](http://theigloolab.com/) to see and subscribe to other thingies I make.\n\nAnd [follow @joewalnes](https://twitter.com/joewalnes)!\n"
  },
  {
    "path": "websockted/__init__.py",
    "content": ""
  },
  {
    "path": "websockted/datax_web_job_instance.py",
    "content": "#!/usr/bin/python3\r\n# -*- coding: utf-8 -*-\r\n# @Function: 实时获取 datax 任务实例执行详情\r\n# @Time    : 2018/7/13 9:34\r\n# @Author  : Hanson\r\n# @Email   : @qq.com\r\n# @File    : datax_web_job_instance.py\r\n# @Software: PyCharm\r\n# @Company : 东方银谷\r\nimport sys\r\nimport os\r\nimport time\r\nfrom sys import stdin, stdout\r\nreload(sys)\r\nsys.setdefaultencoding(\"utf-8\")\r\n\r\nparentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\r\nsys.path.append(parentdir)\r\n\r\nlog_dir = parentdir + '/datax/web_log/%s.json.log'\r\n\r\ndef follow(thefile):\r\n    thefile.seek(0,2)\r\n    while True:\r\n        line = thefile.readline()\r\n        if not line:\r\n            time.sleep(1)\r\n            continue\r\n        yield line\r\n\r\n\r\nif __name__ == '__main__':\r\n    file_id = stdin.readline().strip()\r\n    logfile = log_dir % file_id\r\n    print('logfile: %s!' % logfile)\r\n    stdout.flush()  # Remember to flush\r\n\r\n    logfile_open = open(logfile, 'r')\r\n    cont = logfile_open.readlines()\r\n    print ''.join(cont)\r\n    stdout.flush()\r\n\r\n    # For each line FOO received on STDIN, respond with \"Hello FOO!\".\r\n    loglines = follow(logfile_open)\r\n    for line in loglines:\r\n        print line,\r\n        stdout.flush()  # Remember to flush"
  }
]